用一组点解方程 [英] Solve equation with a set of points

查看:65
本文介绍了用一组点解方程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有几点要点.基本上,我有P = f(t).

I have a set of points. Basically, I have P = f(t).

我有50个测量值. P的50个值,时间的函数.这些价值观遵循既定的法律.

I have, let's say, 50 measurements. 50 values of P, function of the time. And these values follow an established law.

我要做的就是找到定律中参数的值,仅此而已.基本上,我必须用最佳曲线拟合这些点.这是法律:

What I have to do is to find the values of the parameters in the law, that's all. Basically, I have to fit the points with the best curve. Here is the law:

P = V.t - ((V - W)(1 - exp(-k.t)) / k)

我需要做的是找到V,W和k的数值.我有P和P.您对如何做到这一点有想法吗?

What I need to do is to find a numeric value for V, W and k. I have t and P. Do you have an idea about how to do that?

以下是我想要获取的屏幕截图:

Here is a screenshot of what I want to obtain:

在图片上:

  • V是Vs
  • W是Vi
  • k是k

这就是我在reptilicus的帮助下获得的:

And that's what I obtained with reptilicus's help:

http://i.imgur.com/f59Eo29.png

import numpy as np
from scipy.optimize import curve_fit
from matplotlib.pyplot import *
import xlrd

def myFunc(t, V, W, k):

    y = V * t - ((V - W) * (1 - np.exp(-k * t)) / k)

    return y

classeur = xlrd.open_workbook(path)
names_sheets = classeur.sheet_names()

sheet = classeur.sheet_by_name(names_sheets[0])

row_start = 2

time = sheet.col_values(0, row_start)
fluo = feuille.col_values(4, row_start)

time = [ index for index in time if index ]
fluo = [ index for index in fluo if index ]

# this generates some fake data to fit. For youm just read in the 
# data in CSV or whatever you've
x = np.array(time)
y = np.array(fluo)

#fit the data, return the best fit parameters and the covariance matrix
#popt, pcov = curve_fit(myFunc, x, yn)
popt, pcov = curve_fit(myFunc, x, y)
print(popt)
print(pcov)

#plot the data
clf() #matplotlib
plot(x, y, "rs")
#overplot the best fit curve
plot(x, myFunc(x, popt[0], popt[1], popt[2]))
grid(True)
show()

不错.我设法提取了我的excel工作簿的数据,并对其进行了绘制.但是正如您所看到的,我得到了线性回归,这是我不想要的.我的目标不是重现他们与Origin 8的契合度.

Not bad. I managed to extract the data of my excel workbook, and plotted it. But as you can see, I got a linear regression, what I don't want. My goal is t reproduce the fit they got with Origin 8.

我有一些消息.我团队中最后一个做到这一点的人告诉我他如何使用Origin.实际上,他们也使用最小二乘法,但是他们使用chi 2最小化来找到参数.该软件会进行一些迭代,并优化参数.

I have some news. The last guy who did that in my team told me how he did with Origin. In fact, they use the least square way as well, but they find the parameters with a chi 2 minimization. The software does some iterations, and optimizes the parameters.

因为我花了很长时间才弄清楚,所以我在这里分享了我的研究结果.我面临的主要问题是我的价值观太小".实际上,我的y值约为10 ^ -7.如此处所述拟合曲线:为什么小数是更好吗?,数量级为1的数字更合适.

Because it took me so long to figure it out, I share here the results of my researches. The main problem I was facing was the fact my values were "too small". Indeed, my y values were of the order of 10^-7. As explained here Fitting curve: why small numbers are better?, numbers of the order of 1 are better for the fit.

此外,至少在我的情况下,因为我的数据是这个顺序,所以我不需要给出一些初始参数(默认情况下,它们设置为1).因此,我只是标准化"了我的价值观.例如,我将时间值从秒转换为小时,然后乘以10 ^ 7我的y值,这是10 ^ -7的数量级. 然后,我将获得的参数转换回以使其具有所需的单位.这是我的代码:

Moreover, in my case at least, as my data were of this order, I didn't need to give some initial parameters (by default, they are set to 1). So I just "normalized" my values. For example, I transformed the time values from seconds to hour, and I multiplicated by 10^7 my y values, which were of the order of 10^-7. Then, I transformed back the obtained parameters to get them in the desired unities. Here is my code:

import numpy as np
from scipy.optimize import curve_fit, leastsq
from matplotlib.pyplot import *

def myFunc(t, Vs, Vi, k):

    y = Vs * t - ((Vs - Vi) * (1 - np.exp(-k * t)) / k)

    return y

raw_x = some_input 
raw_y = some_input 

# scaling data
time = [ index /3600 for index in raw_x if index or index==0 ]
fluo = [ index*10**7 for index in raw_y if index or index==0 ]

x = np.array(temps)
y = np.array(fluo)

popt, pcov = curve_fit(myFunc, x, y, maxfev=3000)

# Good unities
popt2 = list()
popt2 = [ popt[0] / 3600 * 10**-7, popt[1] / 3600 * 10**-7, popt[2] / 3600 ]

#plot the data
clf() #matplotlib
plot(raw_x, raw_y, "rp")
plot(raw_x, myFunc(raw_x, popt2[0], popt2[1], popt2[2]), 'b')
grid(True)
show()

下面是说明区别的图片:

And here is a picture illustrating the difference:

http://i.imgur.com/YXkJG5j.png

蓝色图是使用单位缩放后获得的参数的拟合曲线(并以良好的单位转换回去).绿色的是通过拟合原始单位获得的曲线.

The blue plot is the fitting curve using the parameters obtained with the units rescaling (and transformed back in the good unities). The green one is the curve obtained by fitting in the original unities.

感谢大家的帮助.

推荐答案

只需在scipy.optimize中使用curve_fit:

import numpy as np
from scipy.optimize import curve_fit
from pylab import *

def myFunc(t, V, W, k):
    y = V * t - ((V - W) * (1 - np.exp(-k * t)) / k)
    return y

# this generates some fake data to fit. For youm just read in the 
# data in CSV or whatever you've
x = np.linspace(0,4,50)
y = myFunc(x, 2.5, 1.3, 0.5)
# add some noise to the fake data to make it more realistic. . .
yn = y + 0.2*np.random.normal(size=len(x))

#fit the data, return the best fit parameters and the covariance matrix
popt, pcov = curve_fit(myFunc, x, yn)
print popt
print pcov

#plot the data
clf()
plot(x, yn, "rs")
#overplot the best fit curve
plot(x, myFunc(x, popt[0], popt[1], popt[2]))
grid(True)
show()

这给出了类似下面的图.红点是(嘈杂的)数据,蓝线是最佳拟合曲线,其特定数据的最佳拟合参数为:

This gives something like the plot below. The red points are the (noisy) data, and the blue line is the best fit curve, with the best fitting parameters for that particular data of:

[ 2.32751132, 1.27686053, 0.65986596]

这与预期的参数2.5、1.3、0.5非常接近.差异是由于我添加到虚假数据中的噪声造成的.

Which is pretty close to the expected parameters of 2.5, 1.3, 0.5. The difference is due to the noise that I added in to the fake data.

这篇关于用一组点解方程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆