Преобразование Лапласа неизвестного интеграла (функция времени) - PullRequest
0 голосов
/ 27 октября 2018

Мне нужно вычислить преобразование Лапласа интегральной функции. Кажется, Симпи еще не может этого понять.

Предполагая следующее:

from sympy import *
s, t = symbols('s t')
I = Function('I')(t)
eq1 = integrate(I, t)
transforms.laplace_transform(eq1, t, s)

Решение должно быть: I(s) / s

Однако Симпи дает: LaplaceTransform(Integral(I(t), t), t, s)

Кажется, это открытый вопрос Выпуск 7219 . Есть ли работа вокруг?

1 Ответ

0 голосов
/ 28 октября 2018

Похоже, что проблема еще не решена.

Однако мы можем дать «дерьмовый обходной путь», основанный на «дрянной реализации» Эрика Визера, приведенной для производных. Тем не менее, обратите внимание, что исходный фрагмент, похоже, не работает и для производных, поскольку внутреннее представление производных более высокого порядка, похоже, изменилось с момента публикации фрагмента.

Вот мой «дерьмовый» обходной путь, который ловит только самые простые случаи (производные только по t, неопределенные интегралы только по t, где t - переменная, на которой действует преобразование Лапласа) :

from sympy import *

def laplace(e, t, s):
    """Hacked-up Laplace transform that handles derivatives and integrals

    Updated generalization of https://github.com/sympy/sympy/issues/7219#issuecomment-154768904
    """

    res = laplace_transform(e, t, s, noconds=True)
    wf = Wild('f')
    lw = LaplaceTransform(wf, t, s)

    for exp in res.find(lw):
        e = exp.match(lw)[wf]
        args = e.args

        if isinstance(e, Derivative):
            # for derivative check that there's only d/dt^n with n>0
            if len(args) == 2 and args[1][0] == t:
                n = args[1][1]
                if n > 0:
                    newexp = s**n * LaplaceTransform(e.args[0], t, s)
                res = res.replace(exp, newexp)

        elif isinstance(e, Integral):
            # for integral check that there's only n consecutive indefinite integrals w.r.t. t
            if all(len(arg) == 1 and arg[0] == t for arg in args[1:]):
                newexp = s**(-len(args[1:])) * LaplaceTransform(args[0], t, s)
                res = res.replace(exp, newexp)

        # otherwise don't do anything

    return res

x = Function('x')
s,t = symbols('s t')
print(laplace(Derivative(x(t), t, 3), t, s))
print(laplace(Integral(Integral(x(t), t), t), t, s))

Вышеуказанные выходы

s**3*LaplaceTransform(x(t), t, s)
LaplaceTransform(x(t), t, s)/s**2

как и ожидалось. Используя ваш конкретный пример:

I = Function('I')(t)
eq1 = integrate(I, t)
LI = laplace(eq1, t, s)
print(LI)

получаем

LaplaceTransform(I(t), t, s)/s

, что является правильным представлением "I(s)/s", которое вы ожидали.


Способ работы вышеупомянутого обходного пути заключается в том, что он соответствует аргументам LaplaceTransform и проверяет, есть ли внутри чистый Derivative или Integral. Для Derivative мы проверяем, что существует только дифференцирование по t; это то, что сделал оригинальный обходной путь Эрика, но, хотя его код, похоже, ожидал аргументы вида Derivative(x(t), t, t, t), текущее представление производных - Derivative(x(t), (t,3)). Вот почему обработку этого варианта использования пришлось изменить.

Что касается Integral s, представление аналогично исходному: Integral(x(t), t, t) - двойной интеграл. Мне все еще пришлось настроить оригинал Эрика, потому что args этого выражения содержит кортежи для каждого интеграла, а не скаляр t, чтобы вместить определенные интегралы. Поскольку мы хотим обрабатывать только случай неопределенных интегралов, я убедился, что есть только неопределенные интегралы и только в отношении t.

Если аргумент LaplaceTransform является чем-то еще, выражение оставляется в покое.

...