scipy.optimize能最小化复变量的函数吗?如何最小化?

pftdvrlh  于 2022-11-10  发布在  其他
关注(0)|答案(2)|浏览(231)

我正在尝试使用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)的建议?

deikduxw

deikduxw1#

SciPy的最小化方法只适用于真实的参数。但在复数空间Cn上的最小化相当于在R2n上的最小化,复数代数从未进入考虑范围。因此,添加两个 Package 器用于从Cn到R2n和从R2n到Cn的转换,您可以对复数进行优化。

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]

你提到了雅可比行列式和海森行列式......但最小化只对实值函数有意义,而实值函数对于复变量是永远不可微的。无论如何,雅可比行列式和海森行列式都必须在R2n上计算,将实部和虚部视为单独的变量。

hsvhsicv

hsvhsicv2#

我需要在真实的域上最小化复值模型函数对复值参数的偏离。
一个玩具例子:
定义f(x,a,B):ab =复合物(a,b);返回np.exp(x*ab)
假设我有数据DATA,x = np·arange(N),注意x是真实的。
我所做的是这样的:
定义辅助对象(x,a,B):返回绝对值(f(x,a,b)- DATA[x])
然后我可以使用curve_fit():
curve_fit(辅助对象,np.范围(N),np.零(N),p0 = [1,0])
发生的事情是这样的:通过从模型函数中减去数据,新的“理想”输出是全零,为了使curve_fit()起作用,它可以(必须)是真实的。复参数ab = a + jb已经被分解为实部和虚部。helper()函数返回模型和数据之间的差的绝对值。
一个关键的问题是curve_fit()只计算你给予它的x值,否则DATA[x]会失败。
请注意,通过使用abs(),我实现了L1拟合(或多或少)。我们也可以使用abs()**2来获得L2拟合......但为什么要使用L1或L2是另一天的主题。
你可能会担心,“假设x[]不是整数(而是真实的)?”这正是我的代码所要求的。嗯,这是可行的,只需将它们放入数组中,并对其进行索引。可能有一些聪明的黑客使用字典来解决这个问题。
很抱歉代码格式化;我还没弄清楚价格.

相关问题