2015-04-14 2 views
0

Прежде всего, извините, если заголовок не совсем подходит, мне было трудно найти подходящий (что также могло бы повлиять на эффективность поиска по уже задаваемым вопросам как это :/).Избегайте жесткого кодирования большого количества связанных ODE в python

Проблема заключается в следующем. Хотя сравнительно легко решить связанные ODE в python со Scipy, мне все равно придется записывать ODE в форме явно. Например, для связанной ОДУ формы

д/дт (c_0) = а (c_0) + Ь (c_1) и г/д (c_1) = C (c_0)

Я хотел бы настроить н как:

import numpy as np 
from scipy.integrate import ode 

a=1 
b=2 
c=3 
val=[] 

def dC_dt(t, C): 
    return [a*C[0]+b*C[1], 
      c*C[0]] 

c0, t0 = [1.0,0.0], 0 
r = ode(dC_dt).set_integrator('zvode', method='bdf',with_jacobian=False) 
r.set_initial_value(c0, t0) 
t1 = 0.001 
dt = 0.000005 
while r.successful() and r.t < t1: 
    r.integrate(r.t+dt) 
val.append(r.y) 

Однако, теперь я связан ОДУ в грубой форме

д/дт (C_ {т, п}) = а (C_ {т, п}) + Ь (C_ { m + 1, n-1}) + k (c_ {m-1, n + 1})

с c_ {0,0} = 1, и я должен включать в себя порядки с m^2 + n^2 -mn меньше max v ALUE. Для небольшого максимума, что я сделал, это использование словаря использовать обозначение с двумя индексами и отобразить его на 1D список

dict_in={'0,0':0,'-1,0':2,...} 

, а затем поступил в ОДУ для каждого заказа

def dC_dt(t,C): 
    return[a*C[dict_in['0,0']]+b*C[dict_in['1,-1']]... 

Теперь я в основном должен сделать это для некоторых 100 связанных уравнений, которые я не хочу жесткого кода, поэтому я пытался выяснить способ, чтобы реализовать ODE с помощью цикла или sth. Однако я еще не мог найти пути к тому, чтобы иметь два индекса в моих коэффициентах вместе с условием включения только порядка с m^2 + n^2-mn, меньшим максимального значения. Как я бегу в некоторых крайних сроках, я решил, что пора попросить умных людей о помощи.

Спасибо, что прочитал мой вопрос!

+0

Так что c [m, n] зависит от c [m + 1, n-1], который, в свою очередь, зависит от c [m + 2, n-2] и т. Д. Для каждого c [m + k, nk], а также c [mk, n + k]. Есть ли какое-либо условие остановки, любое наибольшее k? И если да, то каково граничное условие? Является ли это всей структурой вашей проблемы, имеет ли набор координат соответственно. точки сетки с ненулевым значением c остаются неизменными во все времена? – LutzL

ответ

1

У меня была аналогичная проблема. Если вы заполняете словарь, вы можете просто повторно использовать функцию больше времени внутри цикла. Это глупый пример того, как это работает:

dict_in={'0,0':0,'-1,0':2} 

for elem in dict_in: 
    def dC_dt(t,C): 
     #return[a*C[dict_in['0,0']]+b*C[dict_in['1,-1']] 
     return dict_in[elem] 

    t, C = 0, 0 
    print(dC_dt(t,C)) 
    #r = ode(dC_dt).set_integrator('zvode', method='bdf',with_jacobian=False) 

Если вам нужно использовать больше функций, вместе вы можете использовать анонимные функции и сохранять их в памяти. Другой пример:

functions_list = list() 
for i in range(4): 
    f = lambda n = i: n 
    functions_list.append(f) 

for j in range(4): 
    print(functions_list[j]()) 

Вы также можете использовать список или генератор. Например, вы можете записать значение в txt-файле и прочитать это с помощью функции readline каждый раз.

Как указано в комментариях ниже, если вы используете функции lamda, вы должны обратить внимание на ссылки. См. Также https://docs.python.org/3/faq/programming.html#why-do-lambdas-defined-in-a-loop-with-different-values-all-return-the-same-result

+0

Спасибо за ваш ответ. Хотя я не уверен, что понял. Не будет ли постоянное переопределение функции dC_dt внутри цикла элементов привести к какой-то «разобщению» разных элементов?Поскольку я использую функцию ode только на одном dC_dt, я требую, чтобы он обновлял каждый из элементов словаря на каждом этапе интеграции, поскольку каждый элемент также зависит от разработки времени других элементов (которые не обязательно являются его соседями в списке, что добавляет еще одно осложнение). – SevD

+0

На самом деле я не уверен, что понял вашу проблему. Я думал, что вы будете использовать каждую функцию только один раз. В этом случае вы можете объявлять только одну функцию и каждый раз менять ее тело, как это было в первом примере. Если вам нужно использовать каждую функцию более одного раза, используйте другой способ и храните их в памяти, как во втором примере. – alfrenardi

+0

В своем последнем комментарии вы сказали, что вам нужно изменить элементы словаря. Зачем вам обновлять их, если они являются граничными условиями? – alfrenardi