scipy.optimize可以完全最小化复杂变量的功能吗?

时间:2018-07-06 13:03:30

标签: python scipy mathematical-optimization

我正在尝试使用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指定所有可能的方法(根据需要提供Jacobian和Hessian),但是没有一个方法能达到正确的结果。它们中的大多数会导致ComplexWarning: Casting complex values to real discards the imaginary part,表明它们无法正确处理复数。

使用scipy.optimize完全可以吗?

如果是这样,如果有人可以告诉我我做错了,我将不胜感激。

如果没有,您是否可能对允许这样做的替代优化工具(针对Python)提出建议?

1 个答案:

答案 0 :(得分:6)

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]

您提到了Jacobian和Hessian ...,但是最小化仅对实值函数有意义,而对于复杂变量则永远不可区分。无论如何,都必须在R 2n 上计算Jacobian和Hessian,将实部和虚部视为单独​​的变量。