繁体   English   中英

Python LMFIT限制适合参数

[英]Python LMFIT restriction fit parameters

我正在尝试使用针对非线性函数的LMFIT库使函数适合Python中的某些数据。 这很容易,但是我想知道是否有办法限制拟合值的某些属性。

例如,在下面的代码中,我适合我的数据以优化值A,B和C。但是我还希望A与B的比率为pi / 4某个整数的倍。 有没有办法施加这种限制?

from lmfit import  Model
import numpy
from numpy import cos, sin, pi, linspace

上传数据:

data = numpy.genfromtxt('data')
axis = numpy.genfromtxt('axis')

定义功能:

def func(x, A, B, C):
return (A*cos(x)*cos(x) + B*sin(x)*sin(x) + 2*C*sin(x)*cos(x))**2

我必须对我的参数进行初步猜测:

a = 0.009 
b = 0.3 
c = 0.3 

然后创建一个适合我功能的模型:

func_model = Model(func)

使用初始猜测值将函数拟合为输入数据(A = a,B = b,C = c):

result = func_model.fit(data, x=axis, A = a, B = b, C = c) 
fitted_vals = result.best_values #dictionary structure
Afit = fitted_vals['A']
Bfit = fitted_vals['B']
Cfit = fitted_vals['C']

如何确定Afit与Bfit的比率是某个整数的pi / 4倍?

如果不可能,是否有人知道具有此功能的软件?

标准拟合的问题是雅可比估计。 如果参数是离散的,则几乎在任何地方导数均为零。 一种解决方法可能是使用带有自定义残差函数的leastsq并另外提供导数。 可以在残差函数中设置参数离散,但在导数中使其连续。 我并不是说这是解决此类问题的常规方法,但是在使用OP功能的情况下,它的工作效果还不错。

编辑-代码为:

# -*- 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

数据和拟合

我认为答案是否定的。scipy.optimize中的求解器优化lmfit换行不支持离散变量,仅支持连续变量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM