Нахождение комплексных корней из множества нелинейных уравнений в python


Я тестировал алгоритм, опубликованный в литературе, который включает в себя решение набора нелинейных уравнений " m " как в Matlab, так и в Python. Набор нелинейных уравнений включает в себя входные переменные, содержащие комплексные числа, и поэтому полученные решения также должны быть сложными. На данный момент я смог получить довольно хорошие результаты в 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 с очень небольшим успехом, однако. Численные решатели, по-видимому, настроены совсем по-другому, и алгоритм левенбурга-Марквардта существует под корнем функции. В 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.

Большое Спасибо

1 6

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: действительная и мнимая части функции одновременно решаются для, рассматривая действительную и мнимую части входного аргумента как независимые.