这是我的问题的最小例子 - 用scipy.optimize.leastsq解决
from scipy.optimize import leastsq
from numpy import array, exp, sin, cos
def MatrixFun(x, *par):
a, b, c, d = par
m11 = a*sin(x[0])+b*cos(x[1])
m12 = c*cos(x[0])*sin(x[1])
m21 = c*sin(x[0])/cos(x[1])
m22 = d*exp(x[0]*x[1])
M = array([[m11, m12], [m21, m22]])
return M
def Residualvector(x, parameters):
MatrixAim = MatrixFun([-1 , 1], *parameters)
return (MatrixFun(x, *parameters)-MatrixAim).flatten()
parameters = [1, 2, 3, 4]
start = [0, 0]
print(leastsq(Residualvector, start, args=parameters))
问题:
- 需要良好的起点
- 使用我的真实系统不会收敛到所需的值
- 我需要x
的约束
这是针对示例问题的强力解决方案
from numpy import ones, array, arange, exp, sin, cos, sum, abs, argmin
from itertools import product as iterprod
def MatrixFun(x, *par):
a, b, c, d = par
m11 = a*sin(x[0])+b*cos(x[1])
m12 = c*cos(x[0])*sin(x[1])
m21 = c*sin(x[0])/cos(x[1])
m22 = d*exp(x[0]*x[1])
M = array([[m11, m12], [m21, m22]])
return M
def ResidualMatrix(x, parameters):
MatrixAim = MatrixFun([-1 , 1], *parameters)
return MatrixFun(x, *parameters)-MatrixAim
def MyBruteMatrixMinimizer(ResidualMatrix, ranges, args=()):
pathongrid = list(iterprod(*ranges))
pathlength = len(pathongrid)
MatSum = ones(pathlength)
for i in range(pathlength):
MatSum[i] = sum(abs(ResidualMatrix(pathongrid[i], args)))
pathgoal = pathongrid[argmin(MatSum)]
return pathgoal
parameters = [1, 2, 3, 4]
ranges = [arange(-2,0,1e-2), arange(0,2,1e-2)]
print(MyBruteMatrixMinimizer(ResidualMatrix, ranges, args=parameters))
问题:
- 慢
- 稳定性不明确
我宁愿使用scipy.optimize.brute或scipy.optimize.basinhopping,这两者都会导致错误TypeError: fsolve: there is a mismatch between the input and output shape of the 'func' argument 'F'
。这很清楚,因为我的矩阵有更多的方程而不是变量(超定)
到目前为止,我唯一的想法是总结必要的方程式的绝对值,以减小输出形状的大小 - 但我绝对不满意。
我非常感谢备选或改进的解决方案或任何其他建议。