我一直在测试一种已发表在文献中的算法,该算法涉及在Matlab和Python中求解一组'm'非线性方程。非线性方程组涉及包含复数的输入变量,因此所得的解也应是复数。到目前为止,通过使用以下代码行,我已经在Matlab中获得了不错的效果:
lambdas0 = ones(1,m)*1e-5;
options = optimset('Algorithm','levenberg-marquardt',...
'MaxFunEvals',1000000,'MaxIter',10000,'TolX',1e-20,...
'TolFun',1e-20);
Eq = @(lambda)maxentfun(lambda,m,h,g);
[lambdasf] = fsolve(Eq,lambdas0,options);
其中h和g分别是复数矩阵和向量。对于广泛的初始值,该解决方案收敛很好。
但是,我一直试图在Python中模仿这些结果,但收效甚微。数值求解器的设置似乎大不相同,并且'levenburg-marquardt'算法存在于函数根下。在python中,该算法无法处理复杂的根,并且当我运行以下行时:
lambdas0 = np.ones(m)*1e-5
sol = root(maxentfun, lambdas0, args = (m,h,g), method='lm', tol = 1e-20, options = {'maxiter':10000, 'xtol':1e-20})
lambdasf = sol.x
我收到以下错误:
minpack.error: Result from function call is not a proper array of floats.
我曾尝试使用其他一些算法,例如'broyden2'和'anderson',但它们远不及Matlab,只能在考虑初始条件后才能给出好的结果。函数“ fsolve”也不能处理复杂的变量。
我想知道我是否在应用某些错误的东西,是否有人对如何正确地在Python中求解复杂的非线性方程式有想法。
非常感谢
当我遇到这类问题时,我尝试将我的函数重写为实部和虚部的数组。例如,如果f
是使用复杂输入数组x
的函数(为简单起见,假设x
的大小为2)
from numpy import *
def f(x):
# Takes a complex-valued vector of size 2 and outputs a complex-valued vector of size 2
return [x[0]-3*x[1]+1j+2, x[0]+x[1]] # <-- for example
def real_f(x1):
# converts a real-valued vector of size 4 to a complex-valued vector of size 2
# outputs a real-valued vector of size 4
x = [x1[0]+1j*x1[1],x1[2]+1j*x1[3]]
actual_f = f(x)
return [real(actual_f[0]),imag(actual_f[0]),real(actual_f[1]),imag(actual_f[1])]
[新函数real_f
可在fsolve
中使用:同时求解函数的实部和虚部,将输入自变量的实部和虚部视为独立的。
这里的append()方法可用于使其自动且易于扩展为任意数量的变量
y=[]
for i in range(2):
y.append(y1[2*i+0]+1j*y1[2*i+1])
real_eqns = eqns(y)
return real_eqns[0].real,real_eqns[0].imag,real_eqns[1].real,real_eqns[1].imag