优化功能 - 使用数组作为输入

时间:2014-02-07 14:42:45

标签: python scipy least-squares

我今天正在玩SciPy,我想测试最小二乘拟合。函数malo(time)在返回计算浓度时非常有效,如果我把它放在一个遍历时间步长数组的循环中(在代码“time”中)。

现在我想将我的计算浓度与我测量的浓度进行比较。我创建了一个残差函数,用于计算测量浓度(在脚本中称为conc的数组)与使用malo(时间)建模的浓度之间的差异。

使用optimize.leastsq我希望拟合参数PD以尽可能地拟合两条曲线。我没有看到我的代码中的错误,malo(时间)表现良好,但每当我想运行optimize.leastsq命令时,Python说“只有长度为1的数组可以转换为Python标量”。如果我将timedt数组设置为单个值,则代码运行时不会出现任何错误。

你认为有没有机会说服Python在循环中使用我的时间步长数组?

import pylab as p
import math as m
import numpy as np
from scipy import optimize


Q = 0.02114
M = 7500.0
dt = 30.0
PD = 0.020242215
tom  = 26.0 #Minuten
tos = tom * 60.0 #Sekunden
timedt = np.array([30.,60.,90])
conc= np.array([ 2.7096,  2.258 ,  1.3548,  0.9032,  0.9032])


def malo(time):
     M1 = M/Q
     M2 = 1/(tos*m.sqrt(4*m.pi*PD*((time/tos)**3)))
     M3a = (1 - time/tos)**2
     M3b = 4*PD*(time/tos)
     M3 = m.exp(-1*(M3a/M3b))

     out = M1 * M2 * M3
     return out

def residuals(p,y,time):
    PD = p
    err = y - malo(timedt)
    return err

p0 = 0.05

p1 = optimize.leastsq(residuals,p0,args=(conc,timedt))

1 个答案:

答案 0 :(得分:3)

请注意,您正在使用NumPy模块中定义的数组。例如

timedt = np.array([30.,60.,90])
conc= np.array([ 2.7096,  2.258 ,  1.3548,  0.9032,  0.9032])

现在,这些数组不是标准Python(这是一种通用语言)的一部分。问题是你正在使用math模块中的常规操作来混合数组, 是标准Python的一部分,而且只适用于标量。

所以,例如:

M2 = 1/(tos*m.sqrt(4*m.pi*PD*((time/tos)**3)))
如果您使用np.sqrt代替,那么

将会起作用,它可用于数组:

M2 = 1/(tos*np.sqrt(4*m.pi*PD*((time/tos)**3)))

等等。

注意:SciPy和其他用于数字/科学编程的模块都知道NumPy并且是建立在它之上的,因此这些函数应该都在数组上工作。使用它们时不要使用math。 NumPy附带了所有这些函数的副本(sqrtcosexp,...)以使用您的数组。