Нелинейный ОДУ солвер - PullRequest
1 голос
/ 11 марта 2020

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

Вот мой код:

j, u, eps, V_0, d = sympy.symbols("j, u, eps, V_0, d")
E = sympy.Function("E_x") (x) #set up symbolic solver

Vi = sympy.Derivative(E)

ode = E*Vi+j/(u*eps)    #define the differential equation


E_sol = sympy.dsolve(ode)   #solve

print(E_sol) #print general solution

ics = {E(0):0}

C_eq = E_sol.subs(x,0).subs(ics)
C_ = sympy.solve(C_eq)

Я получаю вызываемую ошибку на ics = {E(0):0} и список ошибок на C_eq = E_sol.subs(x,0).subs(ics) Пример в моей книге (Числовой Python) решает линейное ОДУ и не получает эту ошибку. Есть ли другой способ решить нелинейный DE или определить E как вызываемый и E_sol как не список?

Ответы [ 2 ]

1 голос
/ 11 марта 2020

Проблема в том, что вы использовали

E = Function('E')(x)

Попробуйте интерактивно:

In [12]: E = Function('E')                                                                                                                                    

In [13]: E                                                                                                                                                    
Out[13]: E

In [14]: E(x)                                                                                                                                                 
Out[14]: E(x)

In [20]: E(1)                                                                                                                                                 
Out[20]: E(1)

In [15]: E(x)(1)                                                                                                                                              
...
TypeError: 'E' object is not callable

In [16]: E = Function('E')(x)                                                                                                                                 

In [17]: E                                                                                                                                                    
Out[17]: E(x)

In [18]: E(1)                                                                                                                                                 
...
TypeError: 'E' object is not callable

Обычно лучше определить E = Function('E'), а затем использовать E(x) на протяжении всего остальная часть вашего кода.

Также dsolve может обработать для вас начальные условия, помня об этом:

import sympy

j, u, eps, V_0, d = sympy.symbols("j, u, eps, V_0, d")
E = sympy.Function("E")

ode = E(x)*E(x).diff(x) + j/(u*eps)    #define the differential equation

E_sol = sympy.dsolve(ode, ics={E(0):0})   #solve with initial conditions

print(E_sol) #print particular solution

Это дает

In [25]: E_sol                                                                                                                                                
Out[25]: 
⎡               _______                _______⎤
⎢              ╱ -j⋅x                 ╱ -j⋅x  ⎥
⎢E(x) = -√2⋅  ╱  ───── , E(x) = √2⋅  ╱  ───── ⎥
⎣           ╲╱   eps⋅u             ╲╱   eps⋅u ⎦
1 голос
/ 11 марта 2020

Функция f может быть вызвана как в f(x), но вы не можете вызвать функцию, которая была вызвана как в f(x)(1) - вам нужно использовать подпрограммы. Кроме того, Python список не понимает subs, но вещи внутри списка делают. Таким образом, вы должны либо выполнить итерацию по списку и выполнить подстановку для элементов списка, которые понимают подстановку или , вы можете преобразовать свой список в контейнер SymPy, который понимает подстановку, например,

>>> [x, 1/x].subs(x, 2) # no
>>> L = [x, 1/x]
>>> [i.subs(x, 2) for i in L]  # yes
[2, 1/2]
>>> from sympy import Tuple
>>> Tuple(*L).subs(x, 2)
(2, 1/2)

Таким образом, используя эти две идеи и определяя x, ваш код дает

import sympy
x, j, u, eps, V_0, d = sympy.symbols("x, j, u, eps, V_0, d")
E = sympy.Function("E_x") (x) #set up symbolic solver
Vi = sympy.Derivative(E)
ode = E*Vi+j/(u*eps)    #define the differential equation
E_sol = sympy.dsolve(ode)   #solve
ics = {E.subs(x,0):0}
C_eq = [i.subs(x,0).subs(ics) for i in E_sol]
C_ = sympy.solve(C_eq)

>>> print(E_sol) #print general solution
[Eq(E_x(x), -sqrt(C1 - 2*j*x/(eps*u))), Eq(E_x(x), sqrt(C1 - 2*j*x/(eps*u)))]
>>> print(C_)
[{C1: 0}]
...