我正在尝试使用 Python 来查找与函数最小值相对应的向量 z 的值。 z 可以是矩形,z = a+b*j 或极坐标形式,z = 幅度,相位。我尝试通过几种方式输入它,目前在下面的代码块中将其设置为 z = complex(cwx,cwy) 。我使用网格网格试图创建可能的向量空间来评估函数。
该函数包含 z 和其他复数(我将其转换为矩形的极坐标形式的向量)。该函数计算结果为标量,因此应该存在一些导致最小值的向量。希望有人能给我指出正确的方向,因为我是优化新手,到目前为止还陷入困境:|是否有可以很好地处理复数的优化函数?
from math import radians
from cmath import rect
import numpy as np
import scipy.optimize as opt
# input variables, to be obtained via GUI
w1 = 0.5
w2 = 0.5
a1m = 53
a1p = 280
a2m = 46
a2p = 245
s11m = 1.8
s11p = 338
s21m = 1.1
s21p = 332
cwm_max = 500
f = lambda z: (w1*abs(rect(a1m,radians(a1p)) + complex(cwx,cwy) / rect(s11m,radians(s11p))) +
w2*abs(rect(a2m,radians(a2p)) + complex(cwx,cwy) / rect(s21m,radians(s21p))))
# create a grid of potential vectors wrapping from 0 to 360 degress with max amplitude = cwm_max:
cwx, cwy = np.meshgrid(np.linspace(-cwm_max,cwm_max,200),np.linspace(-cwm_max,cwm_max,200))
# opt.minimze requires a guess argument
guess = np.array([0, 200])
sol = opt.minimize(f, guess)
print(sol)
它不喜欢我在函数中使用complex(cwx,cwy)。我想输入一个标量吗?
f = lambda z: (w1*abs(rect(a1m,radians(a1p)) + complex(cwx,cwy) / rect(s11m,radians(s11p))) +
^^^^^^^^^^^^^^^^
TypeError: only length-1 arrays can be converted to Python scalars
并且 opt.minimize() 看起来并不是完成这项工作的最佳工具,因为这会引发各种回溯问题。
使用嵌套循环的强力替代方案可以解决问题:
cwm_max = 500
dim = 1200
mag_sum = 1000*np.ones((dim,dim))
cwx = np.linspace(-cwm_max,cwm_max,dim)
cwy = np.linspace(-cwm_max,cwm_max,dim)
for p in range(dim):
for q in range(dim):
mag_sum[p,q] = (w1 * abs(rect(a1m, radians(a1p)) + complex(cwx[p],cwy[q]) / rect(s11m, radians(s11p)))+ w2 * abs(rect(a2m, radians(a2p)) + complex(cwx[p],cwy[q]) / rect(s21m, radians(s21p))))
# rectangular to polar
def polar_deg(z):
"""expects a single complex number in cartesian form (a+bj),
returns mag & phase (degrees, 0 to 360)"""
mag, phase_r = cmath.polar(z)
phase_d = math.degrees(phase_r)
if phase_d < 0:
phase_d += 360
return mag, phase_d
a,b = np.unravel_index(mag_sum.argmin(), mag_sum.shape)
cwz = complex(cwx[a],cwy[b])
cwm, cwp = polar_deg(cwz)
使用嵌套循环的强力替代方案可以解决问题:
cwm_max = 500
dim = 1200
mag_sum = 1000*np.ones((dim,dim))
cwx = np.linspace(-cwm_max,cwm_max,dim)
cwy = np.linspace(-cwm_max,cwm_max,dim)
for p in range(dim):
for q in range(dim):
mag_sum[p,q] = (w1 * abs(rect(a1m, radians(a1p)) + complex(cwx[p],cwy[q]) / rect(s11m, radians(s11p)))+ w2 * abs(rect(a2m, radians(a2p)) + complex(cwx[p],cwy[q]) / rect(s21m, radians(s21p))))
# rectangular to polar
def polar_deg(z):
"""expects a single complex number in cartesian form (a+bj),
returns mag & phase (degrees, 0 to 360)"""
mag, phase_r = cmath.polar(z)
phase_d = math.degrees(phase_r)
if phase_d < 0:
phase_d += 360
return mag, phase_d
a,b = np.unravel_index(mag_sum.argmin(), mag_sum.shape)
cwz = complex(cwx[a],cwy[b])
cwm, cwp = polar_deg(cwz)