我用Python编写了一个脚本,该脚本使用fsolve查找相当复杂的函数的零。其工作方式如下。有一个类仅存储函数的参数。该类具有一个评估方法,该方法根据存储的参数返回一个值,而另一个方法(反转)则找到该函数获取提供的输出的参数。
反转方法会在每次迭代时更新函数的参数,并且会一直这样做,直到评估方法返回的值与提供的值之间的不匹配为零为止。
我遇到的问题是,虽然反转方法返回的值正确,但在反转方法终止后,作为对象一部分的参数始终为0。奇怪的是,如果我使用root而不是fsolve,此问题将消失。据我所知,fsolve只是根的包装器,其中包含求解器算法的某些设置以及其他需要执行的内容。
这是fsolve的已知问题,还是我在这里做些愚蠢的事情?下面的脚本演示了我在正弦函数上遇到的问题。
from scipy.optimize import fsolve, root
from math import sin, pi
class invertSin(object):
def __init__(self,x):
self.x = x
def evaluate(self):
return sin(self.x)
def arcsin_fsolve(self,y):
def errorfunc(xnew):
self.x = xnew
return self.evaluate() - y
soln = fsolve(errorfunc, 0.1)
return soln
def arcsin_root(self,y):
def errorfunc(xnew):
self.x = xnew
return self.evaluate() - y
soln = root(errorfunc, 0.1, method = 'anderson')
return soln
myobject = invertSin(pi/2)
x0 = myobject.arcsin_fsolve(0.5) #find x s.t. sin(x) = 0.5 using fsolve
print(x0) #this prints pi/6
x0obj = myobject.x
print(x0obj) #this always prints 0 no matter which function I invert
myobject2 = invertSin(pi/2)
x1 = myobject2.arcsin_root(0.5) #find x s.t. sin(x) = 0.5 using root
print(x1) #this prints pi/6
x1obj = myobject2.x
print(x1obj) #this prints pi/6
最佳答案
如果在xnew
中为errorfunc
添加打印语句,则将看到fsolve
使用一个列表(一个元素)。这意味着将以这种方式重新解释功能,而不是原始功能。退出求解器后,类型信息会以某种方式丢失,因此该列表的地址/引用将被解释为浮点数据,从而给出错误的值。
在此处设置self.x = xnew[0]
可以恢复所需的行为。