sin(y) 导致 "can't convert expression to float" 错误
sin(y) results in "can't convert expression to float" error
我创建了一个非常简单的 MWE 来说明我的问题。当我键入 y**(2)
时,程序运行。但是当我键入 sin(y)
或 cos(y)
时,它会导致错误 TypeError: can't convert expression to float
。我在下面讨论修复此错误的尝试。
from vpython import *
from scipy.optimize import fsolve
import math
import numpy as np
import sympy as sp
from sympy import Eq, Symbol, solve
import matplotlib.pyplot as plt
y = Symbol('y')
i = input()
i = ''.join(i).split(',')
for x in range(0, len(i)):
i[x] = i[x].strip()
userMediums = i
def refIndexSize(medium):
def refractiveProfile(y):
return eval(medium, {'y': y, 'np': np})
lowerProfile = Eq(eval(medium), 1)
upperProfile = Eq(eval(medium), 1.6)
bounds = [abs(round(float(solve(lowerProfile)[0]),5)),
abs(round(float(solve(upperProfile)[0]),5))]
lowerBound = np.amin(bounds)
upperBound = np.amax(bounds)
return lowerProfile
refIndexSize(userMediums[0])
错误:
sin(y)+1
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/tmp/ipykernel_48/825631216.py in <module>
29 return lowerProfile
30
---> 31 refIndexSize(userMediums[0])
/tmp/ipykernel_48/825631216.py in refIndexSize(medium)
20 return eval(medium, {'y': y, 'np': np})
21
---> 22 lowerProfile = eval(medium)
23 upperProfile = Eq(eval(medium), 1.6)
24 bounds = [abs(round(float(solve(lowerProfile)[0]),5)),
<string> in <module>
/srv/conda/envs/notebook/lib/python3.7/site-packages/sympy/core/expr.py in __float__(self)
357 if result.is_number and result.as_real_imag()[1]:
358 raise TypeError("can't convert complex to float")
--> 359 raise TypeError("can't convert expression to float")
360
361 def __complex__(self):
TypeError: can't convert expression to float
我查看了有关 TypeError: can't convert expression to float
的其他问题,例如 and this。因此,我尝试更改导入的顺序,尽管我无法更改通配符 from vpython import *
,因为这是导入 vpython 的唯一方法(据我所知),但这没有用。在查看了不同的 SO 答案后,我也尝试输入 sp.sin(y)
,但这也无济于事。再次感谢任何提示或帮助。
你的问题出在这一行:
bounds = [abs(round(float(solve(lowerProfile)[0]),5)),
abs(round(float(solve(upperProfile)[0]),5))]
具体这部分:
abs(round(float(solve(upperProfile)[0]),5))
此处solve()
函数returns列表中的复解。
看到这个:
[1.5707963267949 - 1.04696791500319*I, 1.5707963267949 + 1.04696791500319*I]
因此,当您选择 0 索引时,它将是一个复杂的结果,如下所示:
1.5707963267949 - 1.04696791500319*I
因此,您试图将 float()
强制转换为导致错误的解决方案。相反,您可以通过使用 try-except
块来删除具有复杂结果的解决方案的界限,如下所示:
try:
bounds = [abs(round(float(solve(lowerProfile)[0]),5)),
abs(round(float(solve(upperProfile)[0]),5))]
lowerBound = np.amin(bounds)
upperBound = np.amax(bounds)
except:
print("The solutions are complex. Cant find a result")
也像这样导入:
from vpython import *
from scipy.optimize import fsolve
import math
import numpy as np
import sympy as sp
from sympy import *
import matplotlib.pyplot as plt
在 ipython
会话中,最相关的导入:
In [1]: import numpy as np
...: import sympy as sp
...: from sympy import Eq, Symbol, solve
将您的函数也修改为 return bounds
。
In [2]: def refIndexSize(medium):
...:
...: def refractiveProfile(y):
...: return eval(medium, {'y': y, 'np': np})
...:
...: lowerProfile = Eq(eval(medium), 1)
...: upperProfile = Eq(eval(medium), 1.6)
...: bounds = [abs(round(float(solve(lowerProfile)[0]),5)),
...: abs(round(float(solve(upperProfile)[0]),5))]
...: lowerBound = np.amin(bounds)
...: upperBound = np.amax(bounds)
...:
...: return lowerProfile, bounds
...:
定义符号,用字符串调用函数。在交互式会话中,我不需要经历 input
并发症。
In [3]: y = sp.Symbol('y')
y**2
给出您在评论中声明的界限:
In [4]: refIndexSize("y**(2)")
Out[4]: (Eq(y**2, 1), [1.0, 1.26491])
由于 sin
定义而导致的错误
使用 sin
表达式给出 NameError
。 sin
尚未导入或定义。
In [5]: refIndexSize("sin(y)+1")
Traceback (most recent call last):
File "<ipython-input-5-30c99485bce7>", line 1, in <module>
refIndexSize("sin(y)+1")
File "<ipython-input-2-6fea36c332b7>", line 6, in refIndexSize
lowerProfile = Eq(eval(medium), 1)
File "<string>", line 1, in <module>
NameError: name 'sin' is not defined
从 math
导入 sin
给出了您的错误:
In [6]: from math import sin
In [7]: refIndexSize("sin(y)+1")
Traceback (most recent call last):
File "<ipython-input-7-30c99485bce7>", line 1, in <module>
refIndexSize("sin(y)+1")
File "<ipython-input-2-6fea36c332b7>", line 6, in refIndexSize
lowerProfile = Eq(eval(medium), 1)
File "<string>", line 1, in <module>
File "/usr/local/lib/python3.8/dist-packages/sympy/core/expr.py", line 359, in __float__
raise TypeError("can't convert expression to float")
TypeError: can't convert expression to float
math.sin
需要一个浮点值,因此不适用于符号 y
.
但是从 sympy
导入 sin
,它起作用了:
In [8]: from sympy import sin
In [9]: refIndexSize("sin(y)+1")
Out[9]: (Eq(sin(y) + 1, 1), [0.0, 0.6435])
复杂值导致的错误
最初你的问题显示了 sin(y)
的使用,它给出了 @Prakash 讨论的 complex
错误
In [10]: refIndexSize("sin(y)")
Traceback (most recent call last):
File "<ipython-input-10-d470e7448a68>", line 1, in <module>
refIndexSize("sin(y)")
File "<ipython-input-2-6fea36c332b7>", line 9, in refIndexSize
abs(round(float(solve(upperProfile)[0]),5))]
File "/usr/local/lib/python3.8/dist-packages/sympy/core/expr.py", line 358, in __float__
raise TypeError("can't convert complex to float")
TypeError: can't convert complex to float
让我们简化您的函数以摆脱似乎有问题的 float
调用
In [11]: def refIndexSize(medium):
...: lowerProfile = Eq(eval(medium), 1)
...: upperProfile = Eq(eval(medium), 1.6)
...: bounds = [solve(lowerProfile),
...: solve(upperProfile)]
...: return lowerProfile, bounds
...:
运行 在 sin(y)+1)
上,我们像以前一样得到 [0.0, 0.6435]
值:
In [12]: refIndexSize("sin(y)+1")
Out[12]: (Eq(sin(y) + 1, 1), [[0, pi], [0.643501108793284, 2.49809154479651]])
运行 在 sin(y)
上,我们看到 'raw' 边界包括复数值:
In [13]: refIndexSize("sin(y)")
Out[13]:
(Eq(sin(y), 1),
[[pi/2],
[1.5707963267949 - 1.04696791500319*I,
1.5707963267949 + 1.04696791500319*I]])
如果你真的需要这样一个答案的四舍五入的浮点数,你需要先提取 real
部分,或者先使用 abs
:
In [15]: bounds = _[1][1]
In [17]: abs(bounds[0])
Out[17]: 1.88773486361789
我创建了一个非常简单的 MWE 来说明我的问题。当我键入 y**(2)
时,程序运行。但是当我键入 sin(y)
或 cos(y)
时,它会导致错误 TypeError: can't convert expression to float
。我在下面讨论修复此错误的尝试。
from vpython import *
from scipy.optimize import fsolve
import math
import numpy as np
import sympy as sp
from sympy import Eq, Symbol, solve
import matplotlib.pyplot as plt
y = Symbol('y')
i = input()
i = ''.join(i).split(',')
for x in range(0, len(i)):
i[x] = i[x].strip()
userMediums = i
def refIndexSize(medium):
def refractiveProfile(y):
return eval(medium, {'y': y, 'np': np})
lowerProfile = Eq(eval(medium), 1)
upperProfile = Eq(eval(medium), 1.6)
bounds = [abs(round(float(solve(lowerProfile)[0]),5)),
abs(round(float(solve(upperProfile)[0]),5))]
lowerBound = np.amin(bounds)
upperBound = np.amax(bounds)
return lowerProfile
refIndexSize(userMediums[0])
错误:
sin(y)+1
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/tmp/ipykernel_48/825631216.py in <module>
29 return lowerProfile
30
---> 31 refIndexSize(userMediums[0])
/tmp/ipykernel_48/825631216.py in refIndexSize(medium)
20 return eval(medium, {'y': y, 'np': np})
21
---> 22 lowerProfile = eval(medium)
23 upperProfile = Eq(eval(medium), 1.6)
24 bounds = [abs(round(float(solve(lowerProfile)[0]),5)),
<string> in <module>
/srv/conda/envs/notebook/lib/python3.7/site-packages/sympy/core/expr.py in __float__(self)
357 if result.is_number and result.as_real_imag()[1]:
358 raise TypeError("can't convert complex to float")
--> 359 raise TypeError("can't convert expression to float")
360
361 def __complex__(self):
TypeError: can't convert expression to float
我查看了有关 TypeError: can't convert expression to float
的其他问题,例如 from vpython import *
,因为这是导入 vpython 的唯一方法(据我所知),但这没有用。在查看了不同的 SO 答案后,我也尝试输入 sp.sin(y)
,但这也无济于事。再次感谢任何提示或帮助。
你的问题出在这一行:
bounds = [abs(round(float(solve(lowerProfile)[0]),5)),
abs(round(float(solve(upperProfile)[0]),5))]
具体这部分:
abs(round(float(solve(upperProfile)[0]),5))
此处solve()
函数returns列表中的复解。
看到这个:
[1.5707963267949 - 1.04696791500319*I, 1.5707963267949 + 1.04696791500319*I]
因此,当您选择 0 索引时,它将是一个复杂的结果,如下所示:
1.5707963267949 - 1.04696791500319*I
因此,您试图将 float()
强制转换为导致错误的解决方案。相反,您可以通过使用 try-except
块来删除具有复杂结果的解决方案的界限,如下所示:
try:
bounds = [abs(round(float(solve(lowerProfile)[0]),5)),
abs(round(float(solve(upperProfile)[0]),5))]
lowerBound = np.amin(bounds)
upperBound = np.amax(bounds)
except:
print("The solutions are complex. Cant find a result")
也像这样导入:
from vpython import *
from scipy.optimize import fsolve
import math
import numpy as np
import sympy as sp
from sympy import *
import matplotlib.pyplot as plt
在 ipython
会话中,最相关的导入:
In [1]: import numpy as np
...: import sympy as sp
...: from sympy import Eq, Symbol, solve
将您的函数也修改为 return bounds
。
In [2]: def refIndexSize(medium):
...:
...: def refractiveProfile(y):
...: return eval(medium, {'y': y, 'np': np})
...:
...: lowerProfile = Eq(eval(medium), 1)
...: upperProfile = Eq(eval(medium), 1.6)
...: bounds = [abs(round(float(solve(lowerProfile)[0]),5)),
...: abs(round(float(solve(upperProfile)[0]),5))]
...: lowerBound = np.amin(bounds)
...: upperBound = np.amax(bounds)
...:
...: return lowerProfile, bounds
...:
定义符号,用字符串调用函数。在交互式会话中,我不需要经历 input
并发症。
In [3]: y = sp.Symbol('y')
y**2
给出您在评论中声明的界限:
In [4]: refIndexSize("y**(2)")
Out[4]: (Eq(y**2, 1), [1.0, 1.26491])
由于 sin
定义而导致的错误
使用 sin
表达式给出 NameError
。 sin
尚未导入或定义。
In [5]: refIndexSize("sin(y)+1")
Traceback (most recent call last):
File "<ipython-input-5-30c99485bce7>", line 1, in <module>
refIndexSize("sin(y)+1")
File "<ipython-input-2-6fea36c332b7>", line 6, in refIndexSize
lowerProfile = Eq(eval(medium), 1)
File "<string>", line 1, in <module>
NameError: name 'sin' is not defined
从 math
导入 sin
给出了您的错误:
In [6]: from math import sin
In [7]: refIndexSize("sin(y)+1")
Traceback (most recent call last):
File "<ipython-input-7-30c99485bce7>", line 1, in <module>
refIndexSize("sin(y)+1")
File "<ipython-input-2-6fea36c332b7>", line 6, in refIndexSize
lowerProfile = Eq(eval(medium), 1)
File "<string>", line 1, in <module>
File "/usr/local/lib/python3.8/dist-packages/sympy/core/expr.py", line 359, in __float__
raise TypeError("can't convert expression to float")
TypeError: can't convert expression to float
math.sin
需要一个浮点值,因此不适用于符号 y
.
但是从 sympy
导入 sin
,它起作用了:
In [8]: from sympy import sin
In [9]: refIndexSize("sin(y)+1")
Out[9]: (Eq(sin(y) + 1, 1), [0.0, 0.6435])
复杂值导致的错误
最初你的问题显示了 sin(y)
的使用,它给出了 @Prakash 讨论的 complex
错误
In [10]: refIndexSize("sin(y)")
Traceback (most recent call last):
File "<ipython-input-10-d470e7448a68>", line 1, in <module>
refIndexSize("sin(y)")
File "<ipython-input-2-6fea36c332b7>", line 9, in refIndexSize
abs(round(float(solve(upperProfile)[0]),5))]
File "/usr/local/lib/python3.8/dist-packages/sympy/core/expr.py", line 358, in __float__
raise TypeError("can't convert complex to float")
TypeError: can't convert complex to float
让我们简化您的函数以摆脱似乎有问题的 float
调用
In [11]: def refIndexSize(medium):
...: lowerProfile = Eq(eval(medium), 1)
...: upperProfile = Eq(eval(medium), 1.6)
...: bounds = [solve(lowerProfile),
...: solve(upperProfile)]
...: return lowerProfile, bounds
...:
运行 在 sin(y)+1)
上,我们像以前一样得到 [0.0, 0.6435]
值:
In [12]: refIndexSize("sin(y)+1")
Out[12]: (Eq(sin(y) + 1, 1), [[0, pi], [0.643501108793284, 2.49809154479651]])
运行 在 sin(y)
上,我们看到 'raw' 边界包括复数值:
In [13]: refIndexSize("sin(y)")
Out[13]:
(Eq(sin(y), 1),
[[pi/2],
[1.5707963267949 - 1.04696791500319*I,
1.5707963267949 + 1.04696791500319*I]])
如果你真的需要这样一个答案的四舍五入的浮点数,你需要先提取 real
部分,或者先使用 abs
:
In [15]: bounds = _[1][1]
In [17]: abs(bounds[0])
Out[17]: 1.88773486361789