python用相同的变量和参数同时拟合两条曲线

时间:2018-11-15 14:48:39

标签: python curve-fitting least-squares

我正在尝试同时弯曲两个功能的拟合。我有 xdata ,并且 mdata ndata 都是具有相同参数(r1,r2,r3,l)的xdata的功能,如码。现在,我可以相对于xdata绘制mdata和ndata的图形,以及相对于t mdata绘制ndata的图形。但结果并不理想。代码在下面

这两个功能是:

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import leastsq
from scipy.optimize import curve_fit
from scipy.optimize import differential_evolution
# from scipy.signal import medfilt
import warnings

def func(x, r1, r2, r3,l):
    # "brick wall" ensuring all parameters are positive
    if r1 < 0.0 or r2 < 0.0 or r3 < 0.0 or l < 0.0 :
        return 1.0E10 # large value gives large error, curve_fit hits a brick wall
    c = 47e-8
    w=2*np.pi*x
    m=r1+(r2*l*w)/(r2**2+l**2*w**2)+r3/(1+r3*c**2*w**2)
    return m

def gunc(x, r1, r2, r3,l):
    c = 47e-8
    w = 2 * np.pi * x
    n = (r2 ** 2 * l * w) / (r2 ** 2 + l ** 2 * w ** 2) - r3 ** 3 * c * w / (1 + r3 * c ** 2 * w ** 2)
    return n

然后定义了残差函数以最小化

def residual_two_functions(pars, x, mdata, ndata):
    r1 = pars[0]
    r2 = pars[1]
    r3 = pars[2]
    l = pars[3]
    # c = pars[4]
    diff1 = mdata - func(x, r1, r2, r3, l)
    diff2 = ndata - gunc(x, r1, r2, r3, l)
    return np.concatenate((diff1, diff2))

其余代码

def readdata(filename):
    x = filename.readlines()
    x = list(map(lambda s: s.strip(), x))
    x = list(map(float, x))
    return x

 # test data
f_x= open(r'C:\Users\Desktop\ageingmodel\simpletry\fre.txt')
xdata = readdata(f_x)

f_m= open(r'C:\Users\Desktop\ageingmodel\simpletry\real.txt')
mdata = readdata(f_m)

f_n= open(r'C:\Users\Desktop\ageingmodel\simpletry\imag.txt')
ndata = readdata(f_n)

xdata = np.array(xdata)
mdata = np.array(mdata)
ndata = np.array(ndata)

# mdata.flatten(order='C')
# medfilt(mdata)

x = xdata

# function for genetic algorithm to minimize (sum of squared error)
def sumOfSquaredError(parameterTuple):
    warnings.filterwarnings("ignore") # do not print warnings by genetic algorithm
    val = func(xdata, *parameterTuple)
    return np.sum((mdata - val) ** 2.0)


def generate_Initial_Parameters():
    # min and max used for bounds
    maxX = max(xdata)
    minX = min(xdata)
    maxY = max(mdata)
    minY = min(mdata)
    minBound = min(minX, minY)
    maxBound = max(maxX, maxY)
    parameterBounds = []
    parameterBounds.append([minBound, maxBound]) # search bounds for r1
    parameterBounds.append([minBound, maxBound]) # search bounds for r2
    parameterBounds.append([minBound, maxBound]) # search bounds for r3
    parameterBounds.append([minBound, maxBound]) # search bounds for l
    # parameterBounds.append([minBound, maxBound]) # search bounds for c

    # "seed" the numpy random number generator for repeatable results
    result = differential_evolution(sumOfSquaredError, parameterBounds, seed=3)
    return result.x

# by default, differential_evolution completes by calling curve_fit() using parameter bounds
par_init = generate_Initial_Parameters()
print (par_init)

# initial values
# par_init = np.array([0.1,10,1,10])

best, cov, info, message, ier = leastsq(residual_two_functions,
                                        par_init, args=(x, mdata, ndata),
                                        full_output=True)

print(" Best-Fit Parameters: ",  best)
# print(info)
m_fit = func(xdata, *best)
n_fit = gunc(xdata, *best)


plt.figure()
plt.plot(mdata, ndata, 'bD', label='data')
plt.plot(m_fit,n_fit, 'r-',label='fitted curve')
plt.xlabel('mdata')
plt.ylabel('ndata')
plt.legend()

plt.figure()
plt.plot(xdata, mdata, 'bD', label='mdata')
plt.plot(xdata, m_fit, 'r-',label='fitted curve')
plt.xlabel('xdata')
plt.ylabel('mdata')
plt.legend()

plt.figure()
plt.plot(xdata, ndata, 'bD', label='ndata')
plt.plot(xdata, n_fit, 'r-',label='fitted curve')
plt.xlabel('xdata')
plt.ylabel('ndata')
plt.legend()
plt.show()

拟合结果远非完美。如何优化功能? 预先感谢!

图:ndata vs mdata mdata vs xdata ndata vs xdata

数据链接:testdata_link

0 个答案:

没有答案