0

I'm writing a short program which should find value for which real and imaginary part of function are both zero. I don't understand why I get "can't convert expression to float" after running program. (Please forgive my messiness while writing the code!) I cut-off definitions of symbols a11-a88, to save you reading, but all of them are type Acmath.exp(bx), A1*cmath.exp(1.0j*b1*x) or 1.0j*A2*cmath.exp(1.0j*b2*x). I consistently use the cmath function instead of math (cmath.exp not exp, and cmath.sqrt not sqrt).

import sys
import math
from scipy import *
from numpy.linalg import *
from sympy import *
import numpy
from sympy.solvers import solve
import cmath
from scipy import optimize

plik=open('solution_e-.txt','w')

#I cut-off definitions of symbols a11-a88.

Det =((a77*a88+(-1.0)*a78*a87)*(a44*a55*a66+a45*a56*a64)+(a76*a88+(-1.0)*a78*a86)*(a44*a57*a65+a45*a54*a67))*(a11*(a22*a33+(-1.0)*a23*a32)+a21*(a13*a32+(-1.0)*a12*a33))+((a77*a88+(-1.0)*a78*a87)*(a34*a56*a65+a35*a54*a66)+(a76*a88+(-1.0)*a78*a86)*(a34*a55*a67+a35*a57*a64))*(a11*(a22*a43+(-1.0)*a23*a42)+a21*(a13*a42+(-1.0)*a12*a43))+((a77*a88+(-1.0)*a78*a87)*(a44*a56*a65+a45*a54*a66)+(a76*a88+(-1.0)*a78*a86)*(a44*a55*a67+a45*a57*a64))*(a11*(a23*a32+(-1.0)*a22*a33)+a21*(a12*a33+(-1.0)*a13*a32))+((a77*a88+(-1.0)*a78*a87)*(a34*a55*a66+a35*a56*a64)+(a76*a88+(-1.0)*a78*a86)*(a34*a57*a65+a35*a54*a67))*(a11*(a23*a42+(-1.0)*a22*a43)+a21*(a12*a43+(-1.0)*a13*a42))

equat = Det.real + Det.imag


for i in range (76500,76550,1):
    n=i/100000.0

    equat_lam = lambdify(x,equat)
    Solut = optimize.fsolve(equat_lam, n)
    plik.write(str(float(Solut))+'\n')
    print n



plik.close()

Edit: full traceback of the error

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
C:\Anaconda\lib\site-packages\IPython\utils\py3compat.pyc in execfile(fname, glob, loc)
    195             else:
    196                 filename = fname
--> 197             exec compile(scripttext, filename, 'exec') in glob, loc
    198     else:
    199         def execfile(fname, *where):

C:\Users\Melania\Documents\doktorat\2017\analiza\Próbka I\poziomy_en\rozwiazanie_elektrony.py in <module>()
     33 print 'I defined other symbols'
     34 
---> 35 k1=(cmath.sqrt(2.0*(V1-x)*m))/hkr
     36 k2=(cmath.sqrt(2.0*(V2-x)*m))/hkr
     37 k3=(cmath.sqrt(2.0*x*m))/hkr

C:\Anaconda\lib\site-packages\sympy\core\expr.pyc in __complex__(self)
    210         result = self.evalf()
    211         re, im = result.as_real_imag()
--> 212         return complex(float(re), float(im))
    213 
    214     @_sympifyit('other', False)  # sympy >  other

C:\Anaconda\lib\site-packages\sympy\core\expr.pyc in __float__(self)
    205         if result.is_number and result.as_real_imag()[1]:
    206             raise TypeError("can't convert complex to float")
--> 207         raise TypeError("can't convert expression to float")
    208 
    209     def __complex__(self):

TypeError: can't convert expression to float
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459

1 Answers1

0

The trace starts with

C:\Users\...
k1=(cmath.sqrt(2.0*(V1-x)*m))/hkr

and at the end you see a

TypeError: can't convert expression to float

raised by Sympy's expr.__float__ that was called by expr.__complex__ so one can deduce that the expression 2.0*(V1-x)*m cannot be converted to a complex number — typically this happens because it contains a free symbol.

If you want to compute numerically the square root you must substitute a numerical value for all the symbols that constitute the argument of cmath.sqrt where every term, say e.g. V1, can be a symbolic expression containing a large number of symbols.

That said, if you want to "find value for which real and imaginary part of function are both zero" apparently you shouldn't write equat = Det.real + Det.imag

gboffi
  • 22,939
  • 8
  • 54
  • 85