我有几个函数来自sympy.lambdify:
f_1 = sym.lambdify((z, m_1, m_2, s_1, s_2), expression_1, modules=['numpy', 'sympy'])
f_2 = sym.lambdify((z, m_1, m_2, s_1, s_2), expression_2, modules=['numpy', 'sympy'])
f_3 = sym.lambdify((z, m_1, m_2, s_1, s_2), expression_3, modules=['numpy', 'sympy'])
f_4 = sym.lambdify((z, m_1, m_2, s_1, s_2), expression_4, modules=['numpy', 'sympy'])
其中m_1
,m_2
,s_1
,s_2
是标量,z
是已知的1D数组(对于每个{{1},不必相同}})。每个f_i
的输出都是标量。
我想(数字地)找到f_i
,m_1
,m_2
,s_1
这样,
s_2
总和在i。
使用scipy.optimize,我不知道如何实现它(使用fsolve或root)。
答案 0 :(得分:0)
将4个功能F1,F2,F3,F4全部驱动为0, 最小化平方和F1 ^ 2 + F2 ^ 2 + F3 ^ 2 + F4 ^ 2: 如果总和很小,每个F也必须很小。 (例如,总和<0.000001⇒每个| F | <0.001。) 使用scipy.optimize.least_squares 这样做:
import numpy as np
from scipy.optimize import least_squares
# http://docs.scipy.org/doc/scipy/reference/tutorial/optimize.html#least-squares-minimization-least-squares
# http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.least_squares.html
# minimize F1**2 + F2**2 + F3**2 + F4**2 --
starting_guess = ...
ret = least_squares( [F1, F2, F3, F4], x0=starting_guess, max_nfev=20, verbose=2 )
xmin = ret.x
(不要将F s平方 - least_squares
为你做那个。)
在您的情况下,您希望将金额移到lambdify
之外:
f1 = sym.lambdify((z, m1, m2, s1, s2) ... ))
Z1 = numpy array whose rows are all the z_i for f1
def F1( m1, m2, s1, s2 ):
sum = np.sum([ f( z, m1, m2, s1, s2 ) for z in Z1 ])
print "F1: %-10.3g at %-10.3g %-10.3g %-10.3g %-10.3g" % (sum, m1, m2, s1, s2)
return sum
# check a few values in ipython --
F1( 0, 0, 0, 0 )
for x in np.eye( 4 ):
F1( *x )
当它起作用时,F2 F3 F4是相似的。检查一下。然后优化:
starting_guess = ...
ret = least_squares( [F1, F2, F3, F4], x0=starting_guess, max_nfev=10, verbose=2 )
xmin = ret.x
或更多次迭代,或使用xtol
ftol
least_squares
有很多选项,请参阅
full doc。
对于任何数量的功能,有更好的方法可以执行上述操作,而不仅仅是4, 任意数量的变量:更一般,更模糊。
(优化的虚拟建议: