【问题标题】:Finding complex roots from set of non-linear equations in python从python中的一组非线性方程中找到复根
【发布时间】:2014-03-17 01:35:49
【问题描述】:

我一直在测试一种已发表在文献中的算法,该算法涉及在 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 中正确求解复杂的非线性方程。

非常感谢

【问题讨论】:

    标签: python matlab numerical-methods complex-numbers nonlinear-functions


    【解决方案1】:

    当我遇到这类问题时,我会尝试将我的函数重写为实部和虚部的数组。例如,如果 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:同时求解函数的实部和虚部,将输入参数的实部和虚部视为独立的。

    【讨论】:

      【解决方案2】:

      这里可以使用 append() 和 extend() 方法使其自动并轻松扩展到 N 个变量

      def real_eqns(y1):
      y=[]
      for i in range(N):
          y.append(y1[2*i+0]+1j*y1[2*i+1])
      real_eqns1 = eqns(y)
      real_eqns=[]
      for i in range(N):
          real_eqns.extend([real_eqns1[i].real,real_eqns1[i].imag])
      return real_eqns
      

      【讨论】:

        猜你喜欢
        • 2012-10-14
        • 2017-04-22
        • 2022-08-04
        • 1970-01-01
        • 1970-01-01
        • 2013-02-19
        • 1970-01-01
        • 2019-10-05
        • 2017-07-11
        相关资源
        最近更新 更多