pythonpython-3.xtypeerrorsympyfree-variable

sympy TypeError: cannot determine truth value of Relational


I am running this git repo code which is supposed to run out of the box with no error (new repo). So, I am not sure why I get this error. I have not change the original code and I am using the same exact dataset as the DJ-RN repo maintainer:

Initially, the error is happening here (even after changing and to & and or to |).

    if radius is not None:
        value = {t1: _t1, t2: _t2, t3: _t3, x_mid: _x_mid, theta: _theta, focal_length: _focal_length, vec_20: vec_2[0],
                 vec_21: vec_2[1], vec_22: vec_2[2], r: radius}
        for i in range(4):
            ansx = root1[i][0].evalf(subs=value)
            ansy = root1[i][1].evalf(subs=value)
            ansz = root1[i][2].evalf(subs=value)
            print('ansx is: ', ansx)
            print('ansy is: ', ansy)
            print('ansz is: ', ansz)
            print('_t1 is: ', _t1)
            print('_t2 is: ', _t2)
            print('_t3 is: ', _t3)
            print('_focal_length is: ', _focal_length)
            y2D = (-ansy + _t2) / (ansz + _t3) * _focal_length
            x2D = (-ansx + _t1) / (ansz + _t3) * _focal_length
            print('y2D is: ', y2D)
            print('x2D is: ', x2D)
            if (((y2D >= obox[1]) & (y2D <= obox[3])) | ((y2D <= obox[1]) & (y2D >= obox[3]))):
                idx = i

        ansx = root1[idx][0].evalf(subs=value)
        ansy = root1[idx][1].evalf(subs=value)
        ansz = root1[idx][2].evalf(subs=value)
        print('ansz free symbols: ', ansz.free_symbols)
        print('line 259: ansz is: ', ansz)
        print('maxz is: ', maxz)
        print('minz is: ', minz)
        if ((ansz > maxz) or  (ansz < minz)):
Previously this is the line that threw an error (same as title):

    if (((y2D >= obox[1]) and (y2D <= obox[3])) or ((y2D <= obox[1]) and (y2D >= obox[3]))):

Then following this Stackoverflow answer by @sylee957 , I changed it to the following but no solution:

if (((y2D >= obox[1]) & (y2D <= obox[3])) | ((y2D <= obox[1]) & (y2D >= obox[3]))):

and I get:

....
y2D is:  5000*(0.321072 - (focal_length*t2*sin(theta/2)*Abs(focal_length**2*vec_21**2 + focal_length**2*vec_22**2 + 2*focal_length*vec_20*vec_22*x_mid + vec_20**2*x_mid**2 + vec_21**2*x_mid**2) + ((-2.0*t3*(focal_length**2 + x_mid**2)*(focal_length**2*vec_22*(vec_20**2 + vec_21**2 + vec_22**2)**0.5*cos(theta/2)*Abs(r) + 1.4142135623731*focal_length*r*vec_21*(0.5*focal_length**2*vec_20**2*sin(theta/2)**2 - 0.5*focal_length**2*vec_20**2 + 0.5*focal_length**2*vec_21**2*sin(theta/2)**2 + 0.5*focal_length**2*vec_22**2*sin(theta/2)**2 + focal_length*vec_20*vec_22*x_mid + 0.5*vec_20**2*x_mid**2*sin(theta/2)**2 + 0.5*vec_21**2*x_mid**2*sin(theta/2)**2 + 0.5*vec_22**2*x_mid**2*sin(theta/2)**2 - 0.5*vec_22**2*x_mid**2)**0.5 + focal_length*vec_20*x_mid*(vec_20**2 + vec_21**2 + vec_22**2)**0.5*cos(theta/2)*Abs(r) - t3*(focal_length**2*vec_21**2 + focal_length**2*vec_22**2 + 2.0*focal_length*vec_20*vec_22*x_mid + vec_20**2*x_mid**2 + vec_21**2*x_mid**2)*Abs(sin(theta/2)))*(focal_length**2*vec_21**2 + focal_length**2*vec_22**2 + 2.0*focal_length*vec_20*vec_22*x_mid + vec_20**2*x_mid**2 + vec_21**2*x_mid**2)*sin(theta/2)**2 - 2.0*(focal_length**2 + x_mid**2)*(0.707106781186547*focal_length**2*vec_22*(vec_20**2 + vec_21**2 + vec_22**2)**0.5*cos(theta/2)*Abs(r) + focal_length*r*vec_21*(0.5*focal_length**2*vec_20**2*sin(theta/2)**2 - 0.5*focal_length**2*vec_20**2 + 0.5*focal_length**2*vec_21**2*sin(theta/2)**2 + 0.5*focal_length**2*vec_22**2*sin(theta/2)**2 + focal_length*vec_20*vec_22*x_mid + 0.5*vec_20**2*x_mid**2*sin(theta/2)**2 + 0.5*vec_21**2*x_mid**2*sin(theta/2)**2 + 0.5*vec_22**2*x_mid**2*sin(theta/2)**2 - 0.5*vec_22**2*x_mid**2)**0.5 + 0.707106781186547*focal_length*vec_20*x_mid*(vec_20**2 + vec_21**2 + vec_22**2)**0.5*cos(theta/2)*Abs(r) - 0.707106781186547*t3*(focal_length**2*vec_21**2 + focal_length**2*vec_22**2 + 2.0*focal_length*vec_20*vec_22*x_mid + vec_20**2*x_mid**2 + vec_21**2*x_mid**2)*Abs(sin(theta/2)))**2*Abs(sin(theta/2)) + 4.0*(focal_length**2*r**2 - focal_length**2*t3**2*sin(theta/2)**2 - t3**2*x_mid**2*sin(theta/2)**2)*(0.5*focal_length**2*vec_21**2 + 0.5*focal_length**2*vec_22**2 + focal_length*vec_20*vec_22*x_mid + 0.5*vec_20**2*x_mid**2 + 0.5*vec_21**2*x_mid**2)**2*Abs(sin(theta/2)))/Abs(sin(theta/2)))**0.5)/(focal_length*sin(theta/2)*Abs(focal_length**2*vec_21**2 + focal_length**2*vec_22**2 + 2*focal_length*vec_20*vec_22*x_mid + vec_20**2*x_mid**2 + vec_21**2*x_mid**2)))/((focal_length**2*vec_22*(vec_20**2 + vec_21**2 + vec_22**2)**0.5*cos(theta/2)*Abs(r) + 1.4142135623731*focal_length*r*vec_21*(0.5*focal_length**2*vec_20**2*sin(theta/2)**2 - 0.5*focal_length**2*vec_20**2 + 0.5*focal_length**2*vec_21**2*sin(theta/2)**2 + 0.5*focal_length**2*vec_22**2*sin(theta/2)**2 + focal_length*vec_20*vec_22*x_mid + 0.5*vec_20**2*x_mid**2*sin(theta/2)**2 + 0.5*vec_21**2*x_mid**2*sin(theta/2)**2 + 0.5*vec_22**2*x_mid**2*sin(theta/2)**2 - 0.5*vec_22**2*x_mid**2)**0.5 + focal_length*vec_20*x_mid*(vec_20**2 + vec_21**2 + vec_22**2)**0.5*cos(theta/2)*Abs(r) - t3*(focal_length**2*vec_21**2 + focal_length**2*vec_22**2 + 2.0*focal_length*vec_20*vec_22*x_mid + vec_20**2*x_mid**2 + vec_21**2*x_mid**2)*Abs(sin(theta/2)))/((focal_length**2*vec_21**2 + focal_length**2*vec_22**2 + 2.0*focal_length*vec_20*vec_22*x_mid + vec_20**2*x_mid**2 + vec_21**2*x_mid**2)*Abs(sin(theta/2))) + 23.578)
x2D is:  5000*(0.477802 - (-focal_length**2*t1*vec_21**2 - focal_length**2*t1*vec_22**2 - 2.0*focal_length*t1*vec_20*vec_22*x_mid + focal_length*vec_22*x_mid*(vec_20**2 + vec_21**2 + vec_22**2)**0.5*cos(theta/2)*Abs(r)/Abs(sin(theta/2)) + 1.4142135623731*r*vec_21*x_mid*(0.5*focal_length**2*vec_20**2*sin(theta/2)**2 - 0.5*focal_length**2*vec_20**2 + 0.5*focal_length**2*vec_21**2*sin(theta/2)**2 + 0.5*focal_length**2*vec_22**2*sin(theta/2)**2 + focal_length*vec_20*vec_22*x_mid + 0.5*vec_20**2*x_mid**2*sin(theta/2)**2 + 0.5*vec_21**2*x_mid**2*sin(theta/2)**2 + 0.5*vec_22**2*x_mid**2*sin(theta/2)**2 - 0.5*vec_22**2*x_mid**2)**0.5/Abs(sin(theta/2)) - t1*vec_20**2*x_mid**2 - t1*vec_21**2*x_mid**2 + vec_20*x_mid**2*(vec_20**2 + vec_21**2 + vec_22**2)**0.5*cos(theta/2)*Abs(r)/Abs(sin(theta/2)))/(focal_length**2*vec_21**2 + focal_length**2*vec_22**2 + 2.0*focal_length*vec_20*vec_22*x_mid + vec_20**2*x_mid**2 + vec_21**2*x_mid**2))/((focal_length**2*vec_22*(vec_20**2 + vec_21**2 + vec_22**2)**0.5*cos(theta/2)*Abs(r) + 1.4142135623731*focal_length*r*vec_21*(0.5*focal_length**2*vec_20**2*sin(theta/2)**2 - 0.5*focal_length**2*vec_20**2 + 0.5*focal_length**2*vec_21**2*sin(theta/2)**2 + 0.5*focal_length**2*vec_22**2*sin(theta/2)**2 + focal_length*vec_20*vec_22*x_mid + 0.5*vec_20**2*x_mid**2*sin(theta/2)**2 + 0.5*vec_21**2*x_mid**2*sin(theta/2)**2 + 0.5*vec_22**2*x_mid**2*sin(theta/2)**2 - 0.5*vec_22**2*x_mid**2)**0.5 + focal_length*vec_20*x_mid*(vec_20**2 + vec_21**2 + vec_22**2)**0.5*cos(theta/2)*Abs(r) - t3*(focal_length**2*vec_21**2 + focal_length**2*vec_22**2 + 2.0*focal_length*vec_20*vec_22*x_mid + vec_20**2*x_mid**2 + vec_21**2*x_mid**2)*Abs(sin(theta/2)))/((focal_length**2*vec_21**2 + focal_length**2*vec_22**2 + 2.0*focal_length*vec_20*vec_22*x_mid + vec_20**2*x_mid**2 + vec_21**2*x_mid**2)*Abs(sin(theta/2))) + 23.578)
line 259: ansz is:  (focal_length**2*vec_22*(vec_20**2 + vec_21**2 + vec_22**2)**0.5*cos(theta/2)*Abs(r) + 1.4142135623731*focal_length*r*vec_21*(0.5*focal_length**2*vec_20**2*sin(theta/2)**2 - 0.5*focal_length**2*vec_20**2 + 0.5*focal_length**2*vec_21**2*sin(theta/2)**2 + 0.5*focal_length**2*vec_22**2*sin(theta/2)**2 + focal_length*vec_20*vec_22*x_mid + 0.5*vec_20**2*x_mid**2*sin(theta/2)**2 + 0.5*vec_21**2*x_mid**2*sin(theta/2)**2 + 0.5*vec_22**2*x_mid**2*sin(theta/2)**2 - 0.5*vec_22**2*x_mid**2)**0.5 + focal_length*vec_20*x_mid*(vec_20**2 + vec_21**2 + vec_22**2)**0.5*cos(theta/2)*Abs(r) - t3*(focal_length**2*vec_21**2 + focal_length**2*vec_22**2 + 2.0*focal_length*vec_20*vec_22*x_mid + vec_20**2*x_mid**2 + vec_21**2*x_mid**2)*Abs(sin(theta/2)))/((focal_length**2*vec_21**2 + focal_length**2*vec_22**2 + 2.0*focal_length*vec_20*vec_22*x_mid + vec_20**2*x_mid**2 + vec_21**2*x_mid**2)*Abs(sin(theta/2)))
maxz is:  0.47865486
minz is:  -0.43096042
Traceback (most recent call last):
  File "test.py", line 32, in <module>
    otri, _   = get_param(result, hbox, obox, htri, img, radius, gamma_min, gamma_max)
  File "/home/mona/research/code/DJ-RN/script/generate_utils.py", line 261, in get_param
    if (ansz > maxz or  ansz < minz):          
  File "/home/mona/anaconda3/lib/python3.8/site-packages/sympy/core/relational.py", line 384, in __nonzero__
    raise TypeError("cannot determine truth value of Relational")
TypeError: cannot determine truth value of Relational

As you see x2D and y2D (and respectively ansz) have lots of free parameters. I am not sure why they are not getting values and how to go after debugging this issue.

Here is the script that throws the error: test.py https://pastebin.com/raw/tnqK44az

and here's the code that the error is rising from:https://pastebin.com/raw/fyjpEdES

Here's the git discussion I created regarding this problem I am facing: https://github.com/sympy/sympy/discussions/20690

Here's the full log of running $ python test.py: https://pastebin.com/raw/g4xSbPAe


Solution

  • It's say that

    (((y2D >= obox[1]) and (y2D <= obox[3])) or ((y2D <= obox[1]) and (y2D >= obox[3])))
    

    or

    (((y2D >= obox[1]) & (y2D <= obox[3])) | ((y2D <= obox[1]) & (y2D >= obox[3])))
    

    cannot be used as a condition for an if statement. An if requires a simple True or False. numpy uses often have problems like this because a conditional on an array produces a boolean array, e.g. np.array([True,False,True]), and they get an Ambiguity error. This appears to be the sympy equivalent.

    The and/or in the first first also has this problem because they implicitly have an if test as part of their evaluation.

    I'd suggest understanding exactly what these conditions are doing (or supposed to be doing). You may have to examine the pieces (y2D >= obox[1]) etc.

    You may also need to raise the issue with the original repo github. And double check that your set up matches the original. Trying out-of-the-box code with your own data or variables can be tricky, especially if you don't have much experience with the underlying language (such as Python and sympy). Any little deviation for the source's intentions can lead to hard to understand errors.

    In an isympy sessionI have a symbolx`:

    In [31]: x
    Out[31]: x
    
    In [32]: x>0              # this is a relational
    Out[32]: x > 0
    
    In [33]: if x>0: print('yes')
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-33-cea59247e99a> in <module>
    ----> 1 if x>0: print('yes')
    
    /usr/local/lib/python3.8/dist-packages/sympy/core/relational.py in __bool__(self)
        393 
        394     def __bool__(self):
    --> 395         raise TypeError("cannot determine truth value of Relational")
        396 
        397     def _eval_as_set(self):
    
    TypeError: cannot determine truth value of Relational
    

    If I do a subs to replace the variable with a numeric value, the if works:

    In [35]: x.subs({x:1})
    Out[35]: 1
    
    In [36]: if x.subs({x:1})>0: print('yes')
    yes