10

Scipy & Numpy を使用して MATLAB コードを Python に変換する際に問題が発生しています。ODE のシステムが 10 個の観測データ ポイントに適合するように最適なパラメーター値 (k0 と k1) を見つける方法に行き詰まっています。現在、k0 と k1 の最初の推測があります。MATLAB では、「fminsearch」と呼ばれるものを使用できます。これは、ODE 系、観測されたデータ ポイント、および ODE 系の初期値を取得する関数です。次に、観測データに適合する新しいパラメーター k0 と k1 のペアを計算します。データに適合する最適なパラメータ値 k0 と k1 を見つけるために、ある種の「fminsearch」を実装するのに役立つかどうかを確認するために、コードを含めました。これを行うコードを lsqtest.py ファイルに追加したいと思います。

ode.py、lsq.py、および lsqtest.py の 3 つの .py ファイルがあります。

ode.py:

def f(y, t, k): 
return (-k[0]*y[0],
      k[0]*y[0]-k[1]*y[1],
      k[1]*y[1])

lsq.py:

import pylab as py
import numpy as np
from scipy import integrate
from scipy import optimize
import ode
def lsq(teta,y0,data):
    #INPUT teta, the unknowns k0,k1
    # data, observed 
    # y0 initial values needed by the ODE
    #OUTPUT lsq value

    t = np.linspace(0,9,10)
    y_obs = data #data points
    k = [0,0]
    k[0] = teta[0]
    k[1] = teta[1]

    #call the ODE solver to get the states:
    r = integrate.odeint(ode.f,y0,t,args=(k,))


    #the ODE system in ode.py
    #at each row (time point), y_cal has
    #the values of the components [A,B,C]
    y_cal = r[:,1] #separate the measured B
    #compute the expression to be minimized:
    return sum((y_obs-y_cal)**2)

lsqtest.py:

import pylab as py
import numpy as np
from scipy import integrate
from scipy import optimize
import lsq


if __name__ == '__main__':

    teta = [0.2,0.3] #guess for parameter values k0 and k1
    y0 = [1,0,0] #initial conditions for system
    y = [0.000,0.416,0.489,0.595,0.506,0.493,0.458,0.394,0.335,0.309] #observed data points
    data = y
    resid = lsq.lsq(teta,y0,data)
    print resid
4

4 に答える 4

5

以下は私のために働いた:

import pylab as pp
import numpy as np
from scipy import integrate, interpolate
from scipy import optimize

##initialize the data
x_data = np.linspace(0,9,10)
y_data = np.array([0.000,0.416,0.489,0.595,0.506,0.493,0.458,0.394,0.335,0.309])


def f(y, t, k): 
    """define the ODE system in terms of 
        dependent variable y,
        independent variable t, and
        optinal parmaeters, in this case a single variable k """
    return (-k[0]*y[0],
          k[0]*y[0]-k[1]*y[1],
          k[1]*y[1])

def my_ls_func(x,teta):
    """definition of function for LS fit
        x gives evaluation points,
        teta is an array of parameters to be varied for fit"""
    # create an alias to f which passes the optional params    
    f2 = lambda y,t: f(y, t, teta)
    # calculate ode solution, retuen values for each entry of "x"
    r = integrate.odeint(f2,y0,x)
    #in this case, we only need one of the dependent variable values
    return r[:,1]

def f_resid(p):
    """ function to pass to optimize.leastsq
        The routine will square and sum the values returned by 
        this function""" 
    return y_data-my_ls_func(x_data,p)
#solve the system - the solution is in variable c
guess = [0.2,0.3] #initial guess for params
y0 = [1,0,0] #inital conditions for ODEs
(c,kvg) = optimize.leastsq(f_resid, guess) #get params

print "parameter values are ",c

# fit ODE results to interpolating spline just for fun
xeval=np.linspace(min(x_data), max(x_data),30) 
gls = interpolate.UnivariateSpline(xeval, my_ls_func(xeval,c), k=3, s=0)

#pick a few more points for a very smooth curve, then plot 
#   data and curve fit
xeval=np.linspace(min(x_data), max(x_data),200)
#Plot of the data as red dots and fit as blue line
pp.plot(x_data, y_data,'.r',xeval,gls(xeval),'-b')
pp.xlabel('xlabel',{"fontsize":16})
pp.ylabel("ylabel",{"fontsize":16})
pp.legend(('data','fit'),loc=0)
pp.show()
于 2012-12-19T14:42:04.830 に答える
1
    # cleaned up a bit to get my head around it - thanks for sharing 
    import pylab as pp
    import numpy as np
    from scipy import integrate, optimize

    class Parameterize_ODE():
        def __init__(self):
            self.X = np.linspace(0,9,10)
            self.y = np.array([0.000,0.416,0.489,0.595,0.506,0.493,0.458,0.394,0.335,0.309])
            self.y0 = [1,0,0] # inital conditions ODEs
        def ode(self, y, X, p):
            return (-p[0]*y[0],
                     p[0]*y[0]-p[1]*y[1],
                               p[1]*y[1])
        def model(self, X, p):
            return integrate.odeint(self.ode, self.y0, X, args=(p,))
        def f_resid(self, p):
            return self.y - self.model(self.X, p)[:,1]
        def optim(self, p_quess):
            return optimize.leastsq(self.f_resid, p_guess) # fit params

    po = Parameterize_ODE(); p_guess = [0.2, 0.3] 
    c, kvg = po.optim(p_guess)

    # --- show ---
    print "parameter values are ", c, kvg
    x = np.linspace(min(po.X), max(po.X), 2000)
    pp.plot(po.X, po.y,'.r',x, po.model(x, c)[:,1],'-b')
    pp.xlabel('X',{"fontsize":16}); pp.ylabel("y",{"fontsize":16}); pp.legend(('data','fit'),loc=0); pp.show()
于 2017-03-05T10:39:34.987 に答える
0

scipy.optimize モジュールを見てください。このminimize関数は とよく似てfminsearchおり、どちらも基本的に最適化にシンプレックス アルゴリズムを使用していると思います。

于 2012-07-01T01:12:04.127 に答える