Проблема со стандартным соответствием - оценка якобиана.Если параметр дискретный, то производная равна нулю почти везде.Обходной путь может заключаться в том, что каждый использует leastsq
с самостоятельно определенной функцией невязки и дополнительно предоставляет производные.Можно задать параметр дискретный в функции невязки, но пусть он будет непрерывным в производной.Я не говорю, что это общее решение проблемы такого типа, но в случае функции ОП она работает вполне нормально.
Правка - Код будет:
# -*- coding: utf-8 -*-
import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import leastsq
def f0( x, A, B, C ):
return ( A * np.cos( x )**2 + B * np.sin( x )**2 + 2 * C * np.sin( x ) * np.cos( x ) )
def func(x, A, B, C):
return f0( x, A, B, C )**2
a = 0.009
b = 0.3
c = 0.4
xList = np.linspace( -1, 6, 500 )
yList = np.fromiter( ( func( x, a, b, c ) for x in xList ), np.float )
def residuals( p, x, y ):
return func(x, p[0], int(p[1]) * np.pi / 2. * p[0], p[2] ) - y
def dfunc( p, x, y ): #Derivative
return [
f0( x, p[0], int( p[1] ) * np.pi / 2. * p[0] , p[2] ) * ( np.cos( x )**2 + p[1] * np.pi / 2. * np.sin( x )**2 ),
f0( x, p[0], int( p[1] ) * np.pi / 2. * p[0] , p[2] ) * ( p[0] * np.pi / 2.* np.sin( x )**2 ),
f0( x, p[0], int( p[1] ) * np.pi / 2. * p[0] , p[2] ) * ( 2 * np.sin( x ) * np.cos( x ) ),
]
plsq, cov, infodict, mesg, ier = leastsq( residuals, [ 0.009, .3/.01, .4 ], args=( xList, yList ), Dfun=dfunc, col_deriv=1, full_output=True )
fit = func(xList, plsq[0], int( plsq[1] ) * np.pi / 2. * plsq[0], plsq[2] )
print plsq
print int( plsq[1] )
fig1 = plt.figure( 1, figsize=( 6, 4 ), dpi=80 )
ax = fig1.add_subplot( 1, 1, 1 )
ax.plot( xList, yList )
ax.plot( xList, fit, ls='--')
plt.show()
Предоставление:
>>[8.68421935e-03 2.22248626e+01 4.00032135e-01]
>>22