Передача больших зависящих от времени данных для решения дифференциального уравнения в python, - PullRequest
0 голосов
/ 27 апреля 2020

Рассмотрим это простое дифференциальное уравнение первого порядка:

text

, где k - это константа со значением 0,5, а text - это переменная, которая изменяется со временем.

Я использовал следующий код для ввода значений y_bar в разное время, что прекрасно работает.

import numpy as np
from scipy.integrate import odeint
from matplotlib import pyplot as plt
def get_y_bar(t):
    if t>=0 and t<=1:
        return 0.0
    elif t<=2:
        return 1.0
    elif t<=3:
        return 2.0
    elif t<=4:
        return 3.0
    elif t<=5:
        return 4.0
    else:
        return 5.0
def ode(y,t):
    k=0.5
    y_bar=get_y_bar(t)
    dy=k*(y_bar-y)
    return dy
y0=0.0
t0=np.linspace(0,10,100)
sol=odeint(ode,y0,t0)
plt.plot(t0,sol)
plt.show() 

Но этот метод осуществим только тогда, когда у меня есть небольшие данные и я могу их ввести используя if .. elif..else l oop вручную. Что я могу сделать, если у меня большие значения y_bar с меньшими временными шагами (например, t = 0,01, 0,025, 0,03, ..., 5,0) ??

У меня есть данные в формате CSV, и я попытался выполнить цикл через данные, но застрял! Есть ли простой способ сделать это ??

def get_y_bar(t):
    data=np.genfromtxt('data.csv',delimiter=',')
    time=data[:,0]
    y_bar=data[:,1]
    for i in range(len(time)):
        if t>=time[i] and t<=time[i=1]:
            return y_bar[i]
        else:

Ответы [ 2 ]

0 голосов
/ 27 апреля 2020

При таком подходе вы будете загружать файл каждый раз, когда odeint вызывает вашу функцию ode, что будет крайне неэффективно.

Более удобный способ решить вашу проблему - это заменить вашу get_y_bar функция с использованием scipy.interpolate.interp1d вместо kind = zero, то есть постоянная интерполяция . Вы должны выполнить эту интерполяцию вне вашей функции ode, так что вы делаете это только один раз.

0 голосов
/ 27 апреля 2020

Я не уверен, что полностью понял ваш вопрос. Но если вы хотите заменить многочисленные циклы elif в get_y_bar, попробуйте следующее:

import math

def get_y_bar(t):
    return math.floor(t)

То есть math.floor(4.2) вернет 4, что является наибольшим целым числом, меньшим 4.2

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...