Нахождение комплексных корней из системы нелинейных уравнений в 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.

Большое Вам спасибо


person rmsrms1987    schedule 17.02.2014    source источник


Ответы (2)


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

person amd    schedule 17.02.2014

Здесь можно использовать методы 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
person Abdelsalam H. M. Abdelaziz    schedule 04.04.2020