Sympy和Numpy解算器之间的差异

Sympy和Numpy解算器之间的差异,numpy,scipy,sympy,Numpy,Scipy,Sympy,我在nsolve中遇到一些问题,很难找到一些函数的解决方案来进行一些初步猜测。然后我想尝试numpy/scipy解算器 下面是一个使用Symphy的程序,它可以很好地解决这个问题:[0.0,-9.05567e-72,9.42477,3.14159] from sympy import * # Symbols theta = Symbol('theta') phi = Symbol('phi') phi0 = Symbol('phi0') H0 = Symbol('H0') # Constant

我在
nsolve
中遇到一些问题,很难找到一些函数的解决方案来进行一些初步猜测。然后我想尝试numpy/scipy解算器

下面是一个使用Symphy的程序,它可以很好地解决这个问题:
[0.0,-9.05567e-72,9.42477,3.14159]

from sympy import *

# Symbols
theta = Symbol('theta')
phi = Symbol('phi')
phi0 = Symbol('phi0')
H0 = Symbol('H0')
# Constants
phi0 = 60*pi.evalf()/180
a = 0.05
t = 100*1e-9
b = 0.05**2/(8*pi.evalf()*1e-7)
c = 0.001/(4*pi.evalf()*1e-7) 

def m(theta,phi):
    return Matrix([[sin(theta)*cos(phi),sin(theta)*cos(phi),cos(phi)]])
def h(phi0):
    return Matrix([[cos(phi0),sin(phi0),0]])
def k(theta,phi,phi0):
    return m(theta,phi).dot(h(phi0))
def F(theta,phi,phi0,H0): 
    return -(t*a*H0)*k(theta,phi,phi0)+b*t*(cos(theta)**2)+c*t*(sin(2*theta)**2)+t*sin(theta)**4*sin(2*phi)**2
def F_phi(theta,phi,phi0,H0):
    return diff(F(theta,phi,phi0,H0),phi)
def G(phi):
    return F_phi(theta,phi,phi0,H0).subs(theta,pi/2)

H0 = -0.03/(4*pi.evalf()*1e-7)
sol = []
for i in range(5):
    x0=i*pi.evalf()/4
    solution = float(nsolve(G(phi),x0))
    sol.append(solution)
sol = list(set(sol)) # remove duplicate values
print sol
这是同一个程序,但使用numpy兼容的函数:

from numpy import *
from scipy.optimize import fsolve
# Constants
phi0 = 60*pi/180
a = 0.05
t = 100*1e-9
b = 0.05**2/(8*pi*1e-7)
c = 0.001/(4*pi*1e-7)

def m(theta,phi):
    return array([sin(theta)*cos(phi),sin(theta)*cos(phi),cos(phi)])
def h(phi0):
    return array([cos(phi0),sin(phi0),0])
def k(theta,phi,phi0):
    return dot(m(theta,phi).T,h(phi0))
def F(theta,phi,phi0,H0): 
    return -(t*a*H0)*k(theta,phi,phi0)+b*t*(cos(theta)**2)+c*t*(sin(2*theta)**2)+t*sin(theta)**4*sin(2*phi)**2
def F_phi(theta,phi,phi0,H0):
    return diff(F(theta,phi,phi0,H0),phi)
def G(phi):
    return F_phi(pi/2,phi,phi0,H0)

H0 = -0.03/(4*pi*1e-7)
sol = []
for i in range(5):
    x0=array([i*pi/4]) # x0 as ndarray argument for fsolve
    solution = float(fsolve(G,x0))
    sol.append(solution)
sol = list(set(sol)) # remove duplicate values
print sol
但当我运行程序时:

Traceback (most recent call last):
File "Test4.py", line 27, in <module>
solution = float(fsolve(G,x0))
File "/usr/lib64/python2.7/site-packages/scipy/optimize/minpack.py", line 127, in fsolve
res = _root_hybr(func, x0, args, jac=fprime, **options)
File "/usr/lib64/python2.7/site-packages/scipy/optimize/minpack.py", line 224, in _root_hybr
raise errors[status][1](errors[status][0])
TypeError: Improper input parameters were entered.
回溯(最近一次呼叫最后一次):
文件“Test4.py”,第27行,在
溶液=浮点数(fsolve(G,x0))
fsolve中的文件“/usr/lib64/python2.7/site packages/scipy/optimize/minpack.py”,第127行
res=\u root\u hybr(func,x0,args,jac=fprime,**选项)
文件“/usr/lib64/python2.7/site packages/scipy/optimize/minpack.py”,第224行,在_root_hybr中
引发错误[状态][1](错误[状态][0])
类型错误:输入的输入参数不正确。

我试着给x0赋值0,第二个程序(使用numpy)给出了一个接近0的数值,但从pi/4开始,它给出了错误消息。我在numpy中遗漏了什么吗?

在numpy版本函数中
G(数组([pi/4])
返回一个空数组:

>> G(array([pi/4]))  
array([], dtype=float64)
问题在于:

return diff(F(theta,phi,phi0,H0),phi)
numpy.diff
计算数组中连续元素之间的差异,而
sympy.diff
计算导数。您可以修改自己的
F_phi
函数,以返回分析计算的导数(如果您知道解)或数值计算的导数。对于数值解,您可以使用:

def F_phi(theta,phi,phi0,H0, eps=1e-12):
    return (F(theta,phi+eps,phi0,H0) - F(theta,phi,phi0,H0))/eps
和分析溶液(用sympy计算):


请记住,数值解不会像解析解那样精确。因此,sympy(分析)和numpy(数值)方法之间可能仍然存在差异。

是的,问题来自
diff
函数,我认为这两个库中的函数相同。事实上,numpy的解似乎与sympy的解不同(尽管在最后一种情况下,解是使用
nsolve
进行数值计算的,还是我误解了此函数的范围?)。此外,根据eps的值,我有不同的解决方案:根据您给我的值,我有一个相对于RuntimeWarning的警告,但是对于
epsI添加的分析解决方案,解决方案集似乎是稳定的,这可能更精确。您还可以计算
solution%(2*pi)
,因为
phi
是周期性的。通过这些修改,
sympy
numpy
解决方案非常接近!是的,只要可能,交响乐将是象征性的。NumPy永远不会是象征性的。请不要忘记接受为您的问题提供解决方案的答案(使用答案旁边的勾号)。
def F_phi(theta, phi, phi0, H0):
    return -H0*a*t*(-sin(phi)*sin(phi0)*sin(theta) - sin(phi)*sin(theta)*cos(phi0)) + 4*t*sin(2*phi)*sin(theta)**4*cos(2*phi)