Может ли scipy.optimize минимизировать функции сложных переменных вообще и как? - PullRequest
0 голосов
/ 06 июля 2018

Я пытаюсь минимизировать функцию сложной (векторной) переменной, используя scipy.optimize. Мои результаты показывают, что это невозможно. Чтобы исследовать проблему, я реализовал простой пример - минимизировать 2-норму комплексного вектора со смещением:

import numpy as np
from scipy.optimize import fmin

def fun(x):
    return np.linalg.norm(x - 1j * np.ones(2), 2)

sol = fmin(fun, x0=np.ones(2) + 0j)

Выход

Optimization terminated successfully.
         Current function value: 2.000000
         Iterations: 38
         Function evaluations: 69

>>> sol
array([-2.10235293e-05,  2.54845649e-05])

Ясно, что решение должно быть

array([0.+1.j, 0.+1.j])

Разочарованный этим результатом, я также пытался scipy.optimize.minimize:

from scipy.optimize import minimize

def fun(x):
    return np.linalg.norm(x - 1j * np.ones(2), 1)

sol = minimize(fun, x0=np.ones(2) + 0j)

Выход

>>> sol
      fun: 2.0
 hess_inv: array([[ 9.99997339e-01, -2.66135332e-06],
       [-2.66135332e-06,  9.99997339e-01]])
      jac: array([0., 0.])
  message: 'Optimization terminated successfully.'
     nfev: 24
      nit: 5
     njev: 6
   status: 0
  success: True
        x: array([6.18479071e-09+0.j, 6.18479071e-09+0.j])

Не очень хорошо. Я попытался указать все возможные методы для minimize (при необходимости предоставляя якобиан и гессиан), но ни один из них не достиг правильного результата. Большинство из них вызывают ComplexWarning: Casting complex values to real discards the imaginary part, указывая на то, что они не могут правильно обрабатывать комплексные числа.

Возможно ли это вообще с помощью scipy.optimize?

Если это так, я был бы очень признателен, если бы кто-нибудь сказал мне, что я делаю неправильно.

Если нет, то можете ли вы предложить альтернативные инструменты оптимизации (для Python), которые позволяют это?

1 Ответ

0 голосов
/ 06 июля 2018

Методы минимизации SciPy работают только с реальными аргументами. Но минимизация на комплексном пространстве C n равносильна минимизации на R 2n , алгебра комплексных чисел никогда не входит в рассмотрение. Таким образом, добавив две оболочки для преобразования из C n в R 2n и обратно, вы можете оптимизировать комплексные числа.

def real_to_complex(z):      # real vector of length 2n -> complex of length n
    return z[:len(z)//2] + 1j * z[len(z)//2:]

def complex_to_real(z):      # complex vector of length n -> real of length 2n
    return np.concatenate((np.real(z), np.imag(z)))

sol = minimize(lambda z: fun(real_to_complex(z)), x0=complex_to_real(np.ones(2) + 0j))
print(real_to_complex(sol.x))   # [-7.40376620e-09+1.j -8.77719406e-09+1.j]

Вы упоминаете Якобиана и Гессиана ... но минимизация имеет смысл только для вещественных функций, и они никогда не дифференцируемы по отношению к комплексным переменным. В любом случае якобиан и гессиан должны быть вычислены по R 2n , обрабатывая действительные и мнимые части как отдельные переменные.

...