Reputation: 3
I'm new to sympy and I'm trying to perform some convolution with it. I'm working on Jupyter Notebook.
My convolution includes two exponentials (f1, f2) with two different tau values (tau1, tau2). When solving the convolution, sympy returns a Piecewise function with two parts:
import sympy as sp
from sympy.plotting import plot
def convolve(f, g, t, lim_low, lim_up):
tau = sp.symbols('tau', real=True, positive=True)
h = sp.integrate(f.subs(t, tau) * g.subs(t, t - tau),
(tau, lim_low, lim_up))
return h
tau_1, tau_2, tau_3 = sp.symbols('tau_1, tau_2, tau_3', real=True, positive=True)
t = sp.symbols('t', real=True)
f1 = sp.exp( -t/tau_1 )
f2 = sp.exp( -t/tau_2 )
f3 = sp.exp( -t/tau_3 )
h12 = convolve(f1, f2, t, lim_low=0, lim_up=t).simplify()
print('First convolution:')
display(h12)
In my case, I know that tau1 and tau2 are not equal, so I wish to put that constraint before calculating the convolution - but I could not find how to do so.
Is there a way to do it?
I've tried getting the part of the calculation where tau1 != tau2 like this:
h12_TausNotEqaul = h12.args[0][0]
But when I use this in a second convolution with f3 I'm pacing with the same problem, where I only care for the case of tau1 != tau2 != tau3.
h123_TausNotEqaul = convolve(h12_TausNotEqaul, f3, t, lim_low=0, lim_up=t).simplify()
display(h123_TausNotEqaul)
Thanks.
Upvotes: 0
Views: 161
Reputation: 18979
To resolve simple Eq
cases like Eq(x, y)
when I know that x
and y
are not the same, I prefer to just do two substitutions to resolve them:
>>> from sympy import Eq, Dummy
>>> from sympy.abc import x, y
>>> d = Dummy(positive=True)
>>> Eq(y,x).subs(y,x+d).subs(d,y-x)
False
>>> Eq(y,x/y).subs(y,x+d).subs(d,y-x) # doesn't help (as expected) here
Eq(y, x/y)
If you have several variables in Eq
to handle, an automated way of indicating those symbols are distinct from one another might be:
def distinct(e, *v):
d = Dummy(positive=1)
for i in range(len(v)):
for j in range(i + 1, len(v)):
e = e.subs(v[j],v[i]+d).subs(d,v[j]-v[i])
return e
>>> distinct(h123_TausNotEqaul, tau_1,tau_2,tau_3).is_Piecewise
False
Upvotes: 0
Reputation: 14480
You can use refine
to choose the cases that you want:
In [15]: h123_TausNotEqaul
Out[15]:
⎧ ⎛ t t t t ⎞ t t
⎪ ⎜ ── ── ── ──⎟ - ── - ──
⎪ ⎜ τ₂ τ₂ τ₂ τ₃⎟ τ₃ τ₂
⎪ τ₂⋅τ₃⋅⎝- t⋅τ₂⋅ℯ + t⋅τ₃⋅ℯ - τ₂⋅τ₃⋅ℯ + τ₂⋅τ₃⋅ℯ ⎠⋅ℯ
⎪ ──────────────────────────────────────────────────────────────── for τ₁ = τ₃ ∧ (τ₁ = τ₃ ∨ τ₂ = τ₃)
⎪ 2 2
⎪ τ₂ - 2⋅τ₂⋅τ₃ + τ₃
⎪
⎪ ⎛ t t t t ⎞ t t
⎪ ⎜ ── ── ── ──⎟ - ── - ──
⎪ ⎜ τ₁ τ₁ τ₁ τ₃⎟ τ₃ τ₁
⎨ τ₁⋅τ₃⋅⎝- t⋅τ₁⋅ℯ + t⋅τ₃⋅ℯ - τ₁⋅τ₃⋅ℯ + τ₁⋅τ₃⋅ℯ ⎠⋅ℯ
⎪ ──────────────────────────────────────────────────────────────── for τ₂ = τ₃
⎪ 2 2
⎪ τ₁ - 2⋅τ₁⋅τ₃ + τ₃
⎪
⎪ ⎛ t⋅(τ₁ + τ₂) ⎛ t t t t ⎞ t ⎞ t t t
⎪ ⎜ ─────────── ⎜ ── ── ── ──⎟ ──⎟ - ── - ── - ──
⎪ ⎜ τ₁⋅τ₂ ⎜ τ₁ τ₂ τ₂ τ₁⎟ τ₃⎟ τ₃ τ₂ τ₁
⎪τ₁⋅τ₂⋅τ₃⋅⎝τ₃⋅(τ₁ - τ₂)⋅ℯ + ⎝- τ₁⋅τ₂⋅ℯ + τ₁⋅τ₂⋅ℯ - τ₁⋅τ₃⋅ℯ + τ₂⋅τ₃⋅ℯ ⎠⋅ℯ ⎠⋅ℯ
⎪──────────────────────────────────────────────────────────────────────────────────────────────────────────── otherwise
⎪ 2 2 2 2 2 2
⎩ τ₁ ⋅τ₂ - τ₁ ⋅τ₃ - τ₁⋅τ₂ + τ₁⋅τ₃ + τ₂ ⋅τ₃ - τ₂⋅τ₃
In [16]: refine(h123_TausNotEqaul, Ne(tau_2, tau_3) & Ne(tau_1, tau_3) & Ne(tau_1, tau_2))
Out[16]:
⎛ t⋅(τ₁ + τ₂) ⎛ t t t t ⎞ t ⎞ t t t
⎜ ─────────── ⎜ ── ── ── ──⎟ ──⎟ - ── - ── - ──
⎜ τ₁⋅τ₂ ⎜ τ₁ τ₂ τ₂ τ₁⎟ τ₃⎟ τ₃ τ₂ τ₁
τ₁⋅τ₂⋅τ₃⋅⎝τ₃⋅(τ₁ - τ₂)⋅ℯ + ⎝- τ₁⋅τ₂⋅ℯ + τ₁⋅τ₂⋅ℯ - τ₁⋅τ₃⋅ℯ + τ₂⋅τ₃⋅ℯ ⎠⋅ℯ ⎠⋅ℯ
────────────────────────────────────────────────────────────────────────────────────────────────────────────
2 2 2 2 2 2
τ₁ ⋅τ₂ - τ₁ ⋅τ₃ - τ₁⋅τ₂ + τ₁⋅τ₃ + τ₂ ⋅τ₃ - τ₂⋅τ₃
Upvotes: 1