I am new to sympy. I am trying to integrate two times a simple piecewise function.
-
The piecewise symbolic function f(z) is firstly defined based on a list of some constants.
-
f(z) is integrated a first time in the variable z between 0 and z, resulting in a function g(z).
-
g(z)^2 is integrated again between 0 and z
Here is the code:
import numpy as np
import sympy as sym
from sympy.plotting import plot
t = np.array([60, 175, 95, 175, 95, 175, 95, 175, 95, 175, 60])
t_tot = np.sum(t)
V = np.array([1, 0, -1, 0, 1, 0, -1, 0, 1, 0, -1])
# Generate piecewise function
z = sym.symbols('z', real=True, positive=True)
pw = []
i = 0
for j in np.nditer(V):
z_i = np.sum(t[:i])
z_f = np.sum(t[:i+1])
pw.append( (V[i], ((z > z_i)&(z <= z_f))) )
i +=1
pw.append((0, True)) # pw function is null elsewhere
f = sym.Piecewise(*pw)
g = sym.integrate(f, (z, 0, z))
h = sym.integrate(g**2, (z, 0, z))
p1 = plot(g, (z, 0, t_tot))
p2 = plot(h, (z, 0, t_tot))
Apparently, in most of simple cases sympy fails to compute h, and stucks on the corresponding line.
Sometimes is just sufficient to slighty change the values of the function f
I’ve managed to get it working for less intervals, i.e., 4, but still is rather slow.
This is the traceback when hitting CTRL+C:
(python3.11_venv) user@host: ./python3.11_venv/bin/python3.11 ./sympy_piecewise_double_integral.py
Traceback (most recent call last):
File "./sympy_piecewise_double_integral.py", line 26, in <module>
h = sym.integrate(g**2, (z, 0, z))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "./python3.11_venv/lib/python3.11/site-packages/sympy/integrals/integrals.py", line 1567, in integrate
return integral.doit(**doit_flags)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "./python3.11_venv/lib/python3.11/site-packages/sympy/integrals/integrals.py", line 711, in doit
evalued_pw = piecewise_fold(Add(*piecewises))._eval_interval(x, a, b)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "./python3.11_venv/lib/python3.11/site-packages/sympy/functions/elementary/piecewise.py", line 545, in _eval_interval
ok, abei = self._intervals(x)
^^^^^^^^^^^^^^^^^^
File "./python3.11_venv/lib/python3.11/site-packages/sympy/functions/elementary/piecewise.py", line 670, in _intervals
cond = distribute_or_over_and(cond)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "./python3.11_venv/lib/python3.11/site-packages/sympy/logic/boolalg.py", line 1563, in distribute_or_over_and
return _distribute((expr, Or, And))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "./python3.11_venv/lib/python3.11/site-packages/sympy/logic/boolalg.py", line 1597, in _distribute
return info[1](*list(map(_distribute,
^^^^^^^^^^^^^^^^^^^^^
File "./python3.11_venv/lib/python3.11/site-packages/sympy/logic/boolalg.py", line 1597, in _distribute
return info[1](*list(map(_distribute,
^^^^^^^^^^^^^^^^^^^^^
File "./python3.11_venv/lib/python3.11/site-packages/sympy/logic/boolalg.py", line 1597, in _distribute
return info[1](*list(map(_distribute,
^^^^^^^^^^^^^^^^^^^^^
[Previous line repeated 29 more times]
File "./python3.11_venv/lib/python3.11/site-packages/sympy/logic/boolalg.py", line 1598, in _distribute
[(info[2](c, rest), info[1], info[2])
File "./python3.11_venv/lib/python3.11/site-packages/sympy/logic/boolalg.py", line 1598, in <listcomp>
[(info[2](c, rest), info[1], info[2])
^^^^^^^^^^^^^^^^
File "./python3.11_venv/lib/python3.11/site-packages/sympy/core/operations.py", line 513, in __new__
_args = frozenset(cls._new_args_filter(args))
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "./python3.11_venv/lib/python3.11/site-packages/sympy/logic/boolalg.py", line 606, in _new_args_filter
args = BooleanFunction.binary_check_and_simplify(*args)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "./python3.11_venv/lib/python3.11/site-packages/sympy/logic/boolalg.py", line 496, in binary_check_and_simplify
rel = set().union(*[i.atoms(Relational) for i in args])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "./python3.11_venv/lib/python3.11/site-packages/sympy/logic/boolalg.py", line 496, in <listcomp>
rel = set().union(*[i.atoms(Relational) for i in args])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
KeyboardInterrupt
Your help is appreciated.
Python 3.11, sympy 1.12
Tried to simplify expression upon calling, without success.