2017-05-18 4 views
1

spicy.itegrate.odeintを使用して微分方程式のシステムを統合しようとしています。パラメータと初期値の辞書をscipy.integrate.odeintに渡します。

まず、パラメータと初期条件をサンプリングし、2つの辞書(x0p)で返します。その後、モデルを作成し、(ダミーの式で)次のように大まかに見て、ファイルへの関数として記述されています

def model(x, t, p): 
    xdot = [ 
     x['rate1'], p["a"] 
     x['rate2'], p["b"] * x["state1"] - p["c"] * x["state2"] 
     x['rate3'], p["c"] * x["state2"] 
     x["state4"], x["rate1"] + x["rate2"] 
     x["state5"], - x["rate2"] + x["rate3"] 
     ] 
    return xdot 

これは私が簡単な入力からの異なるモデルを生成することができるようです。したがって、通常ハードコーディングされた変数は、対応する値を持つ辞書のキーになります。変数を動的に割り当てることは悪い習慣とみなされるので、私はこれを行います。

私は

sol = odeint(model, x0, t, args=(p,), 
       atol=1.0e-8, rtol=1.0e-6) 

次のように、odeintを使用してシステムを統合しようとすると、このように、x0は、初期条件の辞書、およびパラメータのp(とt floatのリスト)です。私は次のエラーを取得する:

明らか
TypeError: float() argument must be a string or a number, not 'dict' 

、scipyのダウンロードは私のモデルをパラメータ化し、初期化するための辞書を渡すために私の試みに満足していないです。質問は、私がこれを解決する方法があるかどうか、または辞書のすべての値を、対応するキーの名前を変数に割り当てるよう強制されているかどうかです。後者は、状態とパラメータの両方が異なるため、すべてのモデルに同じ初期条件とパラメータのセットを渡すことはできません。したがって、パラメータがモデル内にあるかどうかにかかわらず、すべてのモデルに同じパラメータセットを渡したいと考えています。

+0

あなたは数字の1次元シーケンスに初期条件を入れてあります。

この例では、アイデアを伝える必要があります。 'model(x、t、p)'への 'x'引数は浮動小数点値の1次元の数値配列です。 'model(x、t、p)'は1次元の配列(すなわちリストまたはnumpy配列)を返さなければなりません。それがあなたと協力しなければならないことです。辞書を使ってパラメータを保持したい場合は、それを追加の引数にすることができます(すでに 'p'引数で行っています)。 –

答えて

2

性能上の理由から、odeintのようなscipyの機能は、各パラメータが固定位置に関連付けられている配列で動作します。

パラメータに名前でアクセスするソリューションは、名前と位置の両方を与えるnamedtupleに変換することです。ただし、odeintは、numpy.arrayというパラメータをモデル関数に渡すため、変換は関数内で実行する必要があります。

from scipy.integrate import odeint 
from collections import namedtuple 

params = namedtuple('params', ['a', 'b', 'c', 'd']) 

def model(x, t0): 
    x = params(*x) 
    xdot = [1, 
      x.a + x.b, 
      x.c/x.a, 
      1/x.d**2] # whatever 
    return xdot 


x0 = params(a=1, b=0, c=2, d=0.5) 

t = [0, 0.5, 1] 

sol = odeint(model, x0, t) 
関連する問題