Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/352.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/amazon-web-services/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从CSV文件写入微分方程(与solve_ivp一起使用)_Python_Csv_Differential Equations - Fatal编程技术网

Python 从CSV文件写入微分方程(与solve_ivp一起使用)

Python 从CSV文件写入微分方程(与solve_ivp一起使用),python,csv,differential-equations,Python,Csv,Differential Equations,我正在尝试使用solve\u ivp求解一个大型微分方程组 from scipy import integrate sol = integrate.solve_ivp(func_system, (0,100), initial_value_array, t_eval) func_系统是一个微分方程系统,必须从CSV文件中推断,其示例如下: From,To,Rate Blood,Other_3,3.0000E+02 Blood,Blood_5,7.0000E+02 Blood_5

我正在尝试使用
solve\u ivp
求解一个大型微分方程组

    from scipy import integrate
    sol = integrate.solve_ivp(func_system, (0,100), initial_value_array, t_eval)
func_系统
是一个微分方程系统,必须从CSV文件中推断,其示例如下:

From,To,Rate
Blood,Other_3,3.0000E+02
Blood,Blood_5,7.0000E+02
Blood_5,Liver_1,4.6200E-01
Blood_5,C-bone-S,8.7780E-02
Blood_5,C-bone-V,4.6200E-03
Blood_5,T-bone-S,1.2474E-01
Blood_5,T-bone-V,1.3860E-02
Blood_5,UB-cont,1.5400E-02
Blood_5,Kidneys_1,7.7000E-03
Blood_5,Kidneys_2,3.8500E-04
Blood_5,RC-cont,1.1550E-02
Blood_5,Testes,2.6950E-04
Blood_5,Ovaries,8.4700E-05
Blood_5,Other_4,1.8511E-02
Blood_5,Other_5,2.3100E-02
Other_3,Blood_5,9.9000E-02
Blood_4,UB-cont,3.5000E+00
Blood_4,Blood_5,6.7550E+01
Blood_4,Other_3,2.8950E+01
Kidneys_1,UB-cont,1.7329E-02
Kidneys_2,Blood_4,1.2660E-04
Other_4,Blood_4,1.3860E-03
Other_5,Blood_4,1.2660E-04
Liver_1,SI-cont,9.2420E-04
Liver_1,Liver_2,4.5286E-02
[...]
from jitcode import jitcode,y
import numpy as np
from pandas import read_csv

# Dictionary describing the RHS of the ODE:
f = {}
def add_to_equation(dynvar,to_be_added):
    try:
        f[dynvar] += to_be_added
    except KeyError:
        f[dynvar]  = to_be_added

# Dictionary mapping identifiers to JiTCODE’s dynamic variables
dynvars = {}
def get_dynvar(name):
    try:
        return dynvars[name]
    except KeyError:
        new_dynvar = y(len(dynvars))
        dynvars[name] = new_dynvar
        return new_dynvar

# Parsing the file
for source_name,target_name,rate in read_csv("flows.csv").values:
    rate = float(rate)
    source = get_dynvar(source_name)
    target = get_dynvar(target_name)

    add_to_equation(target, rate*source)
    add_to_equation(source,-rate*source)

initial_condition = np.random.random(len(dynvars))

# Your test case:
Liver_1 = get_dynvar("Liver_1")
Blood_5 = get_dynvar("Blood_5")
assert f[Liver_1] == 0.462*Blood_5-0.0009242*Liver_1-0.045286*Liver_1

# Setup integrator
ODE = jitcode(f)
ODE.set_integrator("dopri5")
ODE.set_initial_value(initial_condition,0.0)

# Actual integration
times = np.linspace(0,100,50)
for time in times:
    print(ODE.integrate(time))
微分方程,例如,隔室
肝1
,将为:

dLiver_1/dt = 0.462*Blood_5 - 0.000924*Liver_1 - 0.045286*Liver_1
必须在
func_系统中写入

dLiver_1_dt = 0.462*Blood_5 - 0.000924*Liver_1 - 0.045286*Liver_1
其中,0.462是从
血液_5
肝脏_1
的比率,0.000924和0.045286是远离
肝脏_1
的比率

有没有一种方法可以创建所有这些方程(我总共有150多个),而不必实际编写它们?
我可以使用矩阵方法,但我还需要添加另一个非线性微分方程组。

我不确定.solve_ivp()是如何工作的,但如果您只需要方程的字符串表示,我会执行以下操作

import pandas as pd

df = pd.read_csv("test.csv")  # create DataFrame

def get_dt(some_variable):
    equation = ["d{}/dt =".format(some_variable)]  # store str representation of our eqn in a list
    variables = []
    for index, row in df.iterrows():  # iterate over all rows to check for a match
        if (row["From"] == some_variable) or (row["To"] == some_variable):  # if variable is found in row
            if len(variables):
                variables.append("- {}*{}".format(row["Rate"], row["From"]))  # add it to our equation
            else:
                variables.append("{}*{}".format(row["Rate"], row["From"]))  # the first number is positive for some reason
    equation.extend(variables)  # combine left and right hand sides into one list
    return " ".join(equation)  # combine our list or strings and return a nicely formatted single string

eqn = get_dt("Liver_1")
print(eqn)
输出

D肝脏1/dt=0.462*血液5-0.0009242*肝脏1-0.045286*肝脏1

另外,如果你想一次得到所有的方程式

all_vars = set(df["From"])  # make a "list" of the From variables that doesn't contain duplicates
all_vars.update(set(df["To"]))  # add in all To variables still without duplicates
for var in all_vars:
    eqn = get_dt(var)
    print(eqn)
这给了我们输出

dT-bone-S/dt = 0.12474*Blood_5
dT-bone-V/dt = 0.013859999999999999*Blood_5
dUB-cont/dt = 0.0154*Blood_5 - 3.5*Blood_4 - 0.017329*Kidneys_1
dRC-cont/dt = 0.01155*Blood_5
dSI-cont/dt = 0.0009242*Liver_1
dOther_3/dt = 300.0*Blood - 0.099*Other_3 - 28.95*Blood_4
dLiver_2/dt = 0.045286*Liver_1
dOther_5/dt = 0.0231*Blood_5 - 0.0001266*Other_5
dLiver_1/dt = 0.462*Blood_5 - 0.0009242*Liver_1 - 0.045286*Liver_1
dOvaries/dt = 8.47e-05*Blood_5
dKidneys_1/dt = 0.0077*Blood_5 - 0.017329*Kidneys_1
dKidneys_2/dt = 0.000385*Blood_5 - 0.0001266*Kidneys_2
dBlood/dt = 300.0*Blood - 700.0*Blood
dOther_4/dt = 0.018511*Blood_5 - 0.0013859999999999999*Other_4
dBlood_5/dt = 700.0*Blood - 0.462*Blood_5 - 0.08778*Blood_5 - 0.00462*Blood_5 - 0.12474*Blood_5 - 0.013859999999999999*Blood_5 - 0.0154*Blood_5 - 0.0077*Blood_5 - 0.000385*Blood_5 - 0.01155*Blood_5 - 0.0002695*Blood_5 - 8.47e-05*Blood_5 - 0.018511*Blood_5 - 0.0231*Blood_5 - 0.099*Other_3 - 67.55*Blood_4
dBlood_4/dt = 3.5*Blood_4 - 67.55*Blood_4 - 28.95*Blood_4 - 0.0001266*Kidneys_2 - 0.0013859999999999999*Other_4 - 0.0001266*Other_5
dTestes/dt = 0.0002695*Blood_5
dC-bone-S/dt = 0.08778*Blood_5
dC-bone-V/dt = 0.00462*Blood_5
我认为这足以让你走,这样你就可以找到它,但它可能不完全是你想要的,因为奇怪的线条,如:

D血液/dt=300.0*血液-700.0*血液

这对我来说似乎没有多大意义。

我编写了一个名为的模块,它允许您以符号形式指定微分方程。这对您来说很方便,因为它主要负责将您的方程转换为函数。此外,在实际积分过程中,函数求值将非常有效,因为它是用C硬编码的。如果你有150个方程,这可能很重要

针对您的具体问题,我会这样做:

From,To,Rate
Blood,Other_3,3.0000E+02
Blood,Blood_5,7.0000E+02
Blood_5,Liver_1,4.6200E-01
Blood_5,C-bone-S,8.7780E-02
Blood_5,C-bone-V,4.6200E-03
Blood_5,T-bone-S,1.2474E-01
Blood_5,T-bone-V,1.3860E-02
Blood_5,UB-cont,1.5400E-02
Blood_5,Kidneys_1,7.7000E-03
Blood_5,Kidneys_2,3.8500E-04
Blood_5,RC-cont,1.1550E-02
Blood_5,Testes,2.6950E-04
Blood_5,Ovaries,8.4700E-05
Blood_5,Other_4,1.8511E-02
Blood_5,Other_5,2.3100E-02
Other_3,Blood_5,9.9000E-02
Blood_4,UB-cont,3.5000E+00
Blood_4,Blood_5,6.7550E+01
Blood_4,Other_3,2.8950E+01
Kidneys_1,UB-cont,1.7329E-02
Kidneys_2,Blood_4,1.2660E-04
Other_4,Blood_4,1.3860E-03
Other_5,Blood_4,1.2660E-04
Liver_1,SI-cont,9.2420E-04
Liver_1,Liver_2,4.5286E-02
[...]
from jitcode import jitcode,y
import numpy as np
from pandas import read_csv

# Dictionary describing the RHS of the ODE:
f = {}
def add_to_equation(dynvar,to_be_added):
    try:
        f[dynvar] += to_be_added
    except KeyError:
        f[dynvar]  = to_be_added

# Dictionary mapping identifiers to JiTCODE’s dynamic variables
dynvars = {}
def get_dynvar(name):
    try:
        return dynvars[name]
    except KeyError:
        new_dynvar = y(len(dynvars))
        dynvars[name] = new_dynvar
        return new_dynvar

# Parsing the file
for source_name,target_name,rate in read_csv("flows.csv").values:
    rate = float(rate)
    source = get_dynvar(source_name)
    target = get_dynvar(target_name)

    add_to_equation(target, rate*source)
    add_to_equation(source,-rate*source)

initial_condition = np.random.random(len(dynvars))

# Your test case:
Liver_1 = get_dynvar("Liver_1")
Blood_5 = get_dynvar("Blood_5")
assert f[Liver_1] == 0.462*Blood_5-0.0009242*Liver_1-0.045286*Liver_1

# Setup integrator
ODE = jitcode(f)
ODE.set_integrator("dopri5")
ODE.set_initial_value(initial_condition,0.0)

# Actual integration
times = np.linspace(0,100,50)
for time in times:
    print(ODE.integrate(time))
一些注意事项:

  • 包括不同的非线性组件应该很简单

  • 我在这里打印输出,但您可以用不同的方式存储和处理输出

  • 您还可以使用标识符(通过
    dynvars
    )作为字典访问解决方案。这样,您就不需要直接处理动态变量的编号

  • 基本的简化如

    -0.000924*Liver_1 - 0.045286*Liver_1 = -0.04621*Liver_1
    
    将由SymEngine(象征性主干)在引擎盖下动态完成

  • JiTCODE在引擎盖下使用
    scipy.integrate.ode
    solve\u ivp


所以你没有csv?为什么不能通过编程实现呢?也许我不明白这个问题。@JeffTilton,我有csv文件。我正在寻找一种使用csv文件制作微分方程的方法,这样它们就可以与solve_ivp一起使用。谢谢。为了详细说明提问者的问题:他们不希望有方程串,而是希望有一个实现这些方程的函数传递给
solve\u ivp