1 回答
TA贡献1934条经验 获得超2个赞
共享对象函数的基本思想很好。我并没有真正深入探讨 OP 尝试的细节,因为这可能会产生误导。该过程是定义可用于最小二乘拟合的适当残差函数。Python 有多种可能性可以做到这一点。我将展示scipy.optimize.leastsq与此密切相关的scipy.optimize.least_squares。
import numpy as np
from scipy.optimize import least_squares ## allows bounds and has given loss functions but provides only Jacobian
from scipy.optimize import leastsq ## provides scaled covariance matrix
"""
some arbitrary test function taking two inputs and providing
two correlated outputs with shared parameters - only three for testing.
"""
def test_function( time, temp, x0, x1, x2 ):
s = np.sqrt( time/x0 ) * np.log( ( temp - x1 ) / x2 )
t = np.exp( - time/x0 ) * np.sqrt( (time/x0)**2 + ( ( temp - x1 ) / x2 )**2 )
return s, t
### make some data with noise
indata = list()
for _ in range( 60 ):
a = 50 * np.random.random()
b = 10 + 25 * np.random.random()
indata.append( [a,b] )
outdata = list()
for a,b in indata:
s,t = test_function( a, b, 3.78, 5.33, 12.88 )
noise1 = np.random.normal( scale=0.01 )
noise2 = np.random.normal( scale=0.01 )
outdata.append( [s + noise1, t + noise2 ] )
indata = np.array( indata)
outdata = np.array( outdata)
#########################################################################
### define the residuals function for fitting This is the important part!
#########################################################################
def residuals( params, xdata, ydata, weightA=1, weightB=1 ):
x0, x1, x2 = params
diff = list()
for ab, st in zip( indata, outdata ):
a, b = ab
s, t = st
sf, tf = test_function( a, b, x0,x1, x2 )
diff.append( weightA * ( s - sf ) )
diff.append( weightB * ( t - tf ) )
return diff
### Fit
solx, cov, info, msg, ier = leastsq(
residuals, [ 3.8, 5.0, 12.5],
args=( indata, outdata ), full_output=True
)
print solx
print cov
sol = least_squares( residuals, [ 3.8, 5.0, 12.5 ], args=( indata, outdata ))
print sol.x
根据OP的需要修改它应该很容易。
添加回答
举报