sympy / sympy

A computer algebra system written in pure Python
https://sympy.org/
Other
13k stars 4.44k forks source link

laplace_transform(Sum((-1)**n*Heaviside(t - n*a), (n, 1, oo)), t, s) not calculated #7177

Open ppuedom opened 11 years ago

ppuedom commented 11 years ago
t = symbols('t', real=True, positive=True)
a = symbols('a', real=True)
s = symbols('s')
laplace_transform(1 + 2*Sum((-1)**n*Heaviside(t - n*a), (n, 1, oo)), t, s)

returns:
(2*LaplaceTransform(Sum((-1)**n*Heaviside(-a*n + t), (n, 1, oo)), t, s) + 1/s,
 0,
 True)

Expected result should be:
1/s + 2*Sum( (-1)**n*exp(-s*n*a)/s, (n, 1, oo))

Original issue for #7177: http://code.google.com/p/sympy/issues/detail?id=4078 Original author: https://code.google.com/u/118279007905392951376/

asmeurer commented 11 years ago
So it just commutes with the sum?

Original comment: http://code.google.com/p/sympy/issues/detail?id=4078#c1 Original author: https://code.google.com/u/asmeurer@gmail.com/

smichr commented 9 years ago

It now gives

>>> t = symbols('t', real=True, positive=True)
>>> a = symbols('a', real=True)
>>> s = symbols('s')
>>> laplace_transform(1 + 2*Sum((-1)**n*Heaviside(t - n*a), (n, 1, oo)), t, s)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "sympy\integrals\transforms.py", line 1119, in laplace_transform
    return LaplaceTransform(f, t, s).doit(**hints)
  File "sympy\integrals\transforms.py", line 118, in doit
    self.function_variable, self.transform_variable, **hints)
  File "sympy\integrals\transforms.py", line 1065, in _compute_transform
    return _laplace_transform(f, t, s, **hints)
  File "sympy\integrals\transforms.py", line 196, in wrapper
    res = func(*args, **kwargs)
  File "sympy\integrals\transforms.py", line 960, in _laplace_transform
    F = integrate(exp(-s*t) * f, (t, 0, oo))
  File "sympy\utilities\decorator.py", line 35, in threaded_func
    return func(expr, *args, **kwargs)
  File "sympy\integrals\integrals.py", line 1254, in integrate
    risch=risch, manual=manual)
  File "sympy\integrals\integrals.py", line 485, in doit
    conds=conds)
  File "sympy\integrals\integrals.py", line 885, in _eval_integral
    result = manualintegrate(g, x)
  File "sympy\integrals\manualintegrate.py", line 1144, in manualintegrate
    return _manualintegrate(integral_steps(f, var))
  File "sympy\integrals\manualintegrate.py", line 1096, in _manualintegrate
    return evaluator(*rule)
  File "sympy\integrals\manualintegrate.py", line 1028, in eval_rewrite
    return _manualintegrate(substep)
  File "sympy\integrals\manualintegrate.py", line 1096, in _manualintegrate
    return evaluator(*rule)
  File "sympy\integrals\manualintegrate.py", line 967, in eval_add
    return sum(map(_manualintegrate, substeps))
  File "sympy\integrals\manualintegrate.py", line 1096, in _manualintegrate
    return evaluator(*rule)
  File "sympy\integrals\manualintegrate.py", line 955, in eval_constanttimes
    return constant * _manualintegrate(substep)
  File "sympy\integrals\manualintegrate.py", line 1096, in _manualintegrate
    return evaluator(*rule)
  File "sympy\integrals\manualintegrate.py", line 1040, in eval_trigsubstitution

    assert len(trig_function) == 1
AssertionError
oscargus commented 5 years ago

So it just commutes with the sum?

Yes. Wasn't there a general method to change order of integrals and summations? (Or at least a PR?)

Edit: btw, it is back to "normal". No AssertionError, but does not evaluate.

oscarbenjamin commented 5 years ago

Do we not need conditions to guarantee that the integrals and sums converge?

I feel like I've seen examples where swapping the sum and integral means that one or both don't converge any more.

oscargus commented 5 years ago

You are probably right that there may be some corner cases where this is not correct. Although for most practical cases it is. On the other hand, does this only hold for infinite summations or are the cases where one cannot separate an integral of an addition into addition of integral? That is, can it always be applied to finite summations (which isn't the case here anyway)? I am working on a problem where that is needed (the whole reason I got into sympy a few months ago...) and I have a finite summation (and I know that there are no convergence problems etc). Different question though.

I assume it is the same reason that Integral(diff(... does not work either, that for some special cases (non-differentiable functions I assume) it cannot be simplified.

oscarbenjamin commented 5 years ago

I think in some way you can derive the conditions from Fubini's theorem by treating the sum as a particular kind of integral.

For a finite sum it would hold if all the integrals converge. Otherwise there can be cases like:

In [180]: integrate(1/x, (x, 0, 1)) - integrate(1/x, (x, 0, 1))                                                                                               
Out[180]: nan

In [181]: integrate(1/x-1/x, (x, 0, 1))                                                                                                                       
Out[181]: 0

In [182]: Integral(1/x, (x, 0, 1)) - Integral(1/x, (x, 0, 1))                                                                                                 
Out[182]: 0
jksuom commented 5 years ago

Fubini can be used but absolute convergence is needed. In this case, it means that it should be possible to do the same computations without (-1)**n. Then the sum of the Heavisides would not be bounded but growing of order t. However, that will still work for the Laplace transform because of the exponential decay of exp(-s*t) for s > 0.

oscargus commented 5 years ago

I note that Wester thinks using linearity is a good thing: http://www.math.unm.edu/~wester/cas/book/Wester.pdf (see Table 1.2 where he, more or less, advocates that integrals, derivatives and Laplace transforms should move in or out of summations).

I would be more convinced with an actual example of an actual problem.

I mean, consider this:

from sympy import Symbol
x = Symbol('x')
a = 1/x
b = a.subs(x, 0)
print(a - a)
print(b - b)

So sympy is already making certain assumptions.