2014-08-31 2 views
2

Я хочу свести обыкновенное дифференциальное уравнение n-порядка в систему уравнений первого порядка. Это готовится для численного анализа. Я использую как Sympy, так и Sagemath для компьютерной алгебры, но я не нашел в них каких-либо функций для этого типа сокращения. Я не был уверен, что кто-нибудь еще может указать, существует ли эта функциональность внутри Sympy или Sagemath., уменьшающее дифференциальное уравнение n-порядка до системы уравнений первого порядка с использованием либо sagemath, либо sympy

Примером этого может быть уменьшение уравнения:

x''' - 2x'' + x' = 0 

к системе уравнений первого порядка:

[0 1 0 
0 0 1 
0 -1 2] 
+0

попробуйте найти преобразования Лапласа или Z, которые обычно используются для этой цели. – Spektre

+0

@Spektre Спасибо за примечание. Я не уверен, что здесь правильная идея преобразования Лапласа. Поэтому я хочу сказать, что дифференциальное уравнение второго или третьего порядка и преобразовать его в систему первого порядка. Я действительно хочу использовать инструмент компьютерной алгебры, такой как Sympy или Sage, чтобы я мог проверить свою собственную алгебру за ошибки. Использование преобразования Лапласа будет работать как метод решения уравнения, но я не уверен, что он преобразует однородное дифференциальное уравнение третьего порядка в систему дифференциальных уравнений первого порядка. Возможно, вы могли бы объяснить, что вы имеете в виду. – krishnab

+0

добавлен ответ (это комментарий действительно, но в комментариях он будет нечитаемым) – Spektre

ответ

1

Я не использую SymPy или Sagemath. но ищите преобразования Лапласа или Z внутри их документов API.

  • если найден, то у вас есть меньше работы
  • если вы не придется искать Lib или код его самостоятельно

решения дифференциальной системы с использованием Лапласа

  • Я долгое время не использовал это, поэтому проверяю все на некоторые математические книги !!!
  • в любом случае, если я помню правильно
  • преобразование Лапласа преобразования интегральной функции линейной функции (временная область, чтобы ей домен)
  • ваших дифференциальных функций просто должно иметь непрерывные Дифференцирования/интегралы, чтобы сделать эту работу
  • чтобы решить вашу проблему это сделать:

    1. конвертирована все дифференциалы к интегральному интегрированию всего этого
    2. применить преобразование Лапласа
      • это преобразует дифференциальную систему в полиномиальной системе
      • wiki example
    3. решить полиномиальное систему уравнений
    4. применить обратное преобразование Лапласа
      • это будет преобразовывать частичные результаты в результате вашего решения в
    5. решить интеграцию c onstants краевыми случаев определяется вашим probem
  • также посмотреть here еще примеры

  • есть тонны материала по этой теме только Google

решить дифференциальную систему Z

  • никогда не делал этого, но должен быть схожим, если не то же самое, что решение с помощью преобразования Лапласа
3

Вопрос в том, как бы вы кодировали дифференциальное уравнение как строку в первую очередь. Потому что кодирование уже более сложное, чем запись системы первого порядка.

Общая ручная процедура является установка х1 = х, х2 = х», х3 = х„“, а затем заметить, что

x1'=x'=x2 
x2'=x''=x3 
x3'=x'''= 2*x'' - x' = 2*x3 - x2 

, а затем преобразовать полученную систему в матричной форме.

См. Также матрицу компаньонов для многочленов, это (с точностью до транспонирования) также общий вид, который вы получаете для системной матрицы для линейного дифференциального уравнения более высокого порядка.

+1

Не нужно кодировать строки.В этом весь смысл использования SymPy или Sage, которые могут представлять собой символические объекты напрямую. – asmeurer

+0

Вам необходимо закодировать ODE как некоторый объект кода, как входной, в форме, которая может быть проанализирована и интерпретирована CAS. I: передайте уравнение из бумаги в компьютер. Даже если это тривиально, в зависимости от метода, усилия будут сопоставимы с ручной установкой системы первого порядка. – LutzL

5

Насколько я знаю, SymPy не имеет функции, которая делает это напрямую, но это просто сделать вручную.

Я предполагаю, что вы всегда хотите, чтобы ваши два дополнительных уравнения имели форму y = x' и z = y'.

Во-первых, давайте создадим ODE (в SymPy выражения автоматически принимаются равными нулю, поэтому для упрощения вещей не будем беспокоиться о части = 0). Я возьму вашу независимую переменную t.

In [4]: t = symbols('t') 

In [7]: x, y, z = symbols('x y z', cls=Function) 

In [6]: ode = x(t).diff(t, t) - 2*x(t).diff(t) + x(t) 

In [13]: ode = x(t).diff(t, 3) - 2*x(t).diff(t, t) + x(t).diff(t) 

In [14]: ode 
Out[14]: 
       2   3 
d    d   d 
──(x(t)) - 2⋅───(x(t)) + ───(x(t)) 
dt    2   3 
      dt   dt 

Теперь, если мы заменим x' с y,

In [15]: ode.subs(x(t).diff(t), y(t)) 
Out[15]: 
         2 
     d   d 
y(t) - 2⋅──(y(t)) + ───(y(t)) 
     dt   2 
        dt 

мы видим, что он также заменяет x'' с y'. Так что давайте подставим y' с z:

In [16]: ode = ode.subs(x(t).diff(t), y(t)).subs(y(t).diff(t), z(t)) 

In [17]: ode 
Out[17]: 
       d 
y(t) - 2⋅z(t) + ──(z(t)) 
       dt 

Теперь наша система [x' y' z'] является

In [20]: Matrix([y(t), z(t), solve(ode, z(t).diff(t))[0]]) 
Out[20]: 
⎡  y(t)  ⎤ 
⎢    ⎥ 
⎢  z(t)  ⎥ 
⎢    ⎥ 
⎣-y(t) + 2⋅z(t)⎦ 

Обратите внимание, что мы уже знаем, что x' = y и y' = z, поэтому мы используем только те, кто непосредственно, но мы используем solve(), чтобы получить наш замещенного ОДУ в количестве z'.

Если вы хотите коэффициенты, простой фокус в том, чтобы взять якобиан:

In [23]: M = Matrix([y(t), z(t), solve(ode, z(t).diff(t))[0]]).jacobian([x(t), y(t), z(t)]) 

In [24]: M 
Out[24]: 
⎡0 1 0⎤ 
⎢  ⎥ 
⎢0 0 1⎥ 
⎢  ⎥ 
⎣0 -1 2⎦ 

Я оставил задачу оборачивать это в единую функцию ode_to_system(ode, [x(t), y(t), z(t)]) в качестве упражнения для читателя.

3

Я написал экспериментальную библиотеку для решения систем обыкновенных дифференциальных уравнений:

https://github.com/bjodah/symodesys

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

from sympy import * 
from symodesys.odesys import AnyOrderODESystem 

t = Symbol('t') 
x = Function('x')(t) 

D1x = x.diff(t) 
D2x = x.diff(t, 2) 
D3x = x.diff(t, 3) 

expr = Eq(D3x, 2*D2x - D1x) 

odesys = AnyOrderODESystem.from_list_of_eqs([expr]) 
print(odesys.all_depv) 
redsys = odesys.reduce_to_sys_of_first_order() 
print(redsys.all_depv) 
print(redsys.f) 

Каких выходы:

[x(t)] 
[x(t), x_h1(t), x_h2(t)] 
OrderedDict([(x(t), x_h1(t)), (x_h1(t), x_h2(t)), (x_h2(t), -x_h1(t) + 2*x_h2(t))]) 

добавив несколько дополнительных линий дает графический интерфейс для экспериментов с начальной задачей (см кривые решения как функция начального значения)

from symodesys.gui import get_chaco_viewer 
from collections import defaultdict 
y0 = defaultdict(int) 
y0[redsys['x']] = 3.14 
params = {} 
t0, tend, N = 0, 10, 100 
viewer = get_chaco_viewer(redsys, y0, params, t0, tend, N) 
viewer.configure_traits() 
viewer.clean_up() 

, который дает вам:

symodesys gui

Это немного сложно установить некоторые из зависимостей, добавьте комментарий, если вам нужна помощь!

 Смежные вопросы

  • Нет связанных вопросов^_^