我怎样才能拟合一个不是函数的方程

时间:2017-11-05 00:19:57

标签: python scipy curve-fitting ellipse

给定xy平面中的数据点,我想使用scipy.optimize.leastsq来查找椭圆的拟合参数(不能将其写为x和y的函数)。我尝试将整个等式设置为零,然后拟合此函数,但拟合无法与误差输出收敛

“两次连续迭代之间的相对误差最多为0.000000。”

代码如下所示,以及输出。钳工显然没有找到任何合理的参数。我的问题是这是否是scipy.optimize.leastsq的一个问题,或者设置函数的“技巧”是否等于零,而是拟合无效。

from scipy.optimize import leastsq, curve_fit
import numpy as np

import matplotlib.pyplot as plt

def function(x,y,theta,smaj,smin):
    xp = np.cos(theta)*x - np.sin(theta)*y
    yp = np.sin(theta)*x + np.cos(theta)*y

    z = ((xp)**2)/smaj**2 + ((yp)**2)/smin**2

    return z

def g(x,y,smaj,smin):
    return x*x/smaj**2 + y*y/smin**2


def window(array,alt,arange):
        arr = [array[i] for i,a in enumerate(alt) if a > arange[0] and a < arange[1]]
        return np.asarray(arr)

def fitter(p0,x,y,func,errfunc,err):
# the fitter function   
    out = leastsq(errfunc,p0,args=(x,y,func,err),full_output=1)
    pfinal = out[0]
    covar  = out[1]
    mydict = out[2]
    mesg   = out[3]
    ier    = out[4]
    resids = mydict['fvec']
    chisq  = np.sum(resids**2)
    degs_frdm     = len(x)-len(pfinal) 
    reduced_chisq = chisq/degs_frdm
    ls = [pfinal,covar,mydict,mesg,ier,resids,chisq,degs_frdm,reduced_chisq]
    print('fitter status: ', ier, '-- aka -- ', mesg)
    i = 0
    if covar is not None: 
        if (ier == 1 or ier == 2 or ier == 3 or ier == 4):
            for u in pfinal:
                print ('Param', i+1, ': ',u, ' +/- ', np.sqrt(covar[i,i])) 
                i = i + 1
            print ('reduced chisq',reduced_chisq)

        else:
            print('fitter failed')

    return ls

def func(x,y,p):
    x = x-p[3]
    y = y-p[4]
    xp = np.cos(p[0])*(x) - np.sin(p[0])*(y)
    yp = np.sin(p[0])*(x) + np.cos(p[0])*(y)
    z = ((xp)**2)/p[1]**2 + ((yp)**2)/p[2]**2 - 1

    return z

def errfunc(p,x,y,func,err):

    return (y-func(x,y,p))/err    


t = np.linspace(0,2*np.pi,100)
xx = 5*np.cos(t); yy = np.sin(t)


p0 = [0,5,1,0,0]
sigma = np.ones(len(xx))
fit = fitter(p0,xx,yy,func,errfunc,sigma)

params     = fit[0]
covariance = fit[1]
residuals  = fit[5]    
t = np.linspace(0,2*np.pi,100)
xx = 5*np.cos(t); yy = np.sin(t)
plt.plot(xx,yy,'bx',ms = 4)



xx = np.linspace(-10,10, 1000)
yy = np.linspace(-5, 5, 1000)
newx = []
newy = []
for x in xx:
    for y in yy:
        if 0.99 < func(x,y,params) < 1.01:
          #if g(x,y,5,1) == 1:
            newx.append(x)
            newy.append(y)


plt.plot(newx,newy,'kx',ms = 1)
plt.show()        

enter image description here 蓝色十字架是实际数据,黑色线条是拟合人员对参数的猜测。

0 个答案:

没有答案