ilaplace doesn't handle tanh()

37 views (last 30 days)
marcel hendrix
marcel hendrix on 20 Sep 2025
Edited: Paul about 4 hours ago
While doing convolutions, I wanted to convolve a function f() with a square wave. There are two Laplace transformations of a square wave that I tried, as shown below. The problem occurs when I do the inverse Laplace on the Laplace of the original square wave, or more precisely when I attempt to plot that result. (In the code below I only show the inverse laplace of the laplace transformed squarewave, not the convolution.)
% P1 = ilaplace( 1/s*(1-2/(exp(T/2*s)+1)) );
P2 = ilaplace( 1/s*tanh(s*T/4) );
% Unfortunately, both don't work with the symbolic toolbox.
assume(P2,'real')
Tsteps = 0.1:0.5:20;
num = vpa(subs(P2,t,Tsteps),6)';
stairs(Tsteps(:),num(:,1))
When I inspect the contents of num, the (voluminous!) contents are largely symbolic:
[conj(subs(diff(floor(s), s), s, -400))*(35.334851093590259552001953125 + 0.00000000023283064365386962890625i) + conj(s ...
My program works with 'simpler' functions, like sinewaves, and then plots OK.
The stairs function faults in the (undocumented) getRealData().
Do I have to assume() something on the arguments of laplace(), ilaplace(), subs() or vpa()?
% getRealData returns the real components of ARGS. If ARGS contains any
% complex data, a warning is displayed. If any of ARGS are not numeric
% and cannot be converted to a double, an error is thrown.
  1 Comment
marcel hendrix
marcel hendrix on 21 Sep 2025
My apologies. T is a simple constant to scale the period of the square wave, e.g., 10 (seconds) is a good value.
Sorry for not mentioning this in the original question.

Sign in to comment.

Answers (3)

Torsten
Torsten on 20 Sep 2025
Moved: Torsten on 20 Sep 2025
You mean
syms s T
P2 = ilaplace( 1/s*(exp(s*T/4)-exp(-s*T/4))/(exp(s*T/4)+exp(s*T/4)) ,s);
Tsteps = 0.1:0.5:20;
num = vpa(subs(P2,T,Tsteps),6)'
num = 
?
  2 Comments
Paul
Paul on 20 Sep 2025
Hi Torsten,
With only two arguments, ilaplace uses the second as the transformation variable. So it should be
syms s T t
%P2 = ilaplace( 1/s*(exp(s*T/4)-exp(-s*T/4))/(exp(s*T/4)+exp(s*T/4)) ,s);
P2 = ilaplace( 1/s*(exp(s*T/4)-exp(-s*T/4))/(exp(s*T/4)+exp(s*T/4)) ,t)
P2 = 
assume(T,'positive')
P2 = simplify(P2,10)
P2 = 
But that's not a square wave. Why is P2 defined that way?
Torsten
Torsten on 20 Sep 2025
I forgot a minus sign:
syms s T
P2 = ilaplace( 1/s*(exp(s*T/4)-exp(-s*T/4))/(exp(s*T/4)+exp(-s*T/4)) ,s)
P2 = 

Sign in to comment.


Paul
Paul on 20 Sep 2025
Edited: Paul on 20 Sep 2025
Hi Marcel,
I attempted to recreate the example with the information provided, but got a different result.
syms s
syms T positive
syms t real
P2 = ilaplace( 1/s*tanh(s*T/4),s,t)
P2 = 
% Unfortunately, both don't work with the symbolic toolbox.
assume(P2,'real')
Tsteps = 0.1:0.5:20;
Assume T = 1, for example
num = vpa(subs(subs(P2,T,1),t,Tsteps),6)';
num
num = 
stairs(Tsteps(:),num(:,1))
Error using stairs (line 106)
Unable to convert symbolic expression to double array because it contains symbolic function that does not evaluate to number. Input expression must evaluate to number.
I think the fundamental problem is that ilaplace doesn't yield a closed form expression. The only way it could, I believe, is if the symbolic engine actually had a Laplace transform pair defined for a square wave. But the toolbox doesn't have a "square" function like, for example, rectangularPulse, so it's not surprising the toolbox doesn't have a Laplace transform for a function that can't be expressed by the user.
Also, the toolbox doesn't compute the inverse Laplace transform numerically, so I wouldn't expect vpa to work on an unresolved ilaplace expression.
  10 Comments
marcel hendrix
marcel hendrix 41 minutes ago
Your post covers my top-level problem pretty well. My concern was that I wasn't using the toolbox right, and that that was the reason of the failure to plot. The answer that I will go with is that the toolbox simply does not (yet) have the 'function vocabulary' needed for my problem. I have since that time found numerical ilaplace functions on MATLAB Central that fit my problem very well with quite simple code and no need for the symbolic toolbox.
Sorry that I got carried away and obfuscated the problem by mentioning and using the rectangularPulse function with only five terms (because I needed to plot only between 0 and 5*T). Indeed using only 5 terms makes the infinite sum different from a function with only 5 terms, and some 'endeffects' could be expected. However, it seems to work without such artifacts.
Paul
Paul about 4 hours ago
Edited: Paul about 2 hours ago
Here's an example of the second option I mentioned in this comment regarding a closed form solution expressed as a perodic summation, demonstrated with the example problem of @David Goodmanson so we can compare solutions.
Laplace transform of the current across the resistor
syms R L C U(s) V(s)
eqn = (s*L + R + 1/(s*C))* U(s) == V(s)
eqn = 
eqn = isolate(eqn,U)
eqn = 
Laplace transform of the voltage across the resistor
syms V_r(s)
eqn = V_r(s) == R*rhs(eqn)
eqn = 
[num,den]=numden(rhs(eqn));
eqn = lhs(eqn) == num/den
eqn = 
Define the input voltage, square wave of amplitude V_sq, period T = 2*a
syms a positive
syms V_sq real
eqn = lhs(eqn) == subs(rhs(eqn),V,V_sq*tanh(a*s/2)/s)
eqn = 
Sub in the values of the constants from David's example
eqn = subs(eqn,[V_sq,L,R,C,a],[10,1,20,6e-5,1/2])
eqn = 
V_r is the of the form tanh(b*s)*Z(s)
Stating w/o proof that v_r(t) is then
syms t b real
syms z(t) v_r(t)
syms n integer
try
v_r(t) = z(t) - 2*symsum((-1)^n*heaviside(t - 2*b - 2*b*n)*z(t - 2*b - 2*b*n), n, 0, inf)
catch ME
ME.message
end
ans = 'Recursive definition: Reached maximal depth for nested procedure calls.'
Not sure why there is an error here, I was expecting to see an unevaluated symbolic expression.
Proceeding ...
b = 1/sym(4);
Inverse transform of Z(s)
z(t) = ilaplace(rhs(eqn)/tanh(s/4),s,t)
z(t) = 
We only need a finite upper bound of the periodic summation to represent v_r(t) for a finite time. For example, choosing an upper bound of n = 20
v_r(t) = z(t) - 2*symsum((-1)^n*heaviside(t - 2*b - 2*b*n)*z(t - 2*b - 2*b*n), n, 0, 20);
And evaluating to t = 4
figure
fplot(v_r(t),[0,4]);
ylim([-3,3]),grid

Sign in to comment.


David Goodmanson
David Goodmanson about 6 hours ago
Hi marcel,
There seems to be some uncertainty about the question, but this answer is for the voltage across the resistor, for a series RLC circuit driven by a square wave voltage about zero, amplitude V. In what follows the square wave period is 2a rather than T, so each half of the wave has length a, which I think is a bit easier for derivation. It's easy enough to replace a by T/2 in the result. Here are a couple of examples from the code below:
T = 1; V = 10; L = 1; R = 80; C = .2
Here the values are such that a not speedy rise time is evident and there is some droop across the top of the wave. If you were to use, say L = 1 R = 1000 C = 1e6 you get basically a perfect square wave since the resistor has all the impdance.
For
T = 1; V = 10; L = 1; R = 20; C = 6e-5
you get an underdamped circuit with a lot of ringdown.
Details:
As has been noted, ilaplace does not work for the function tanh(sT/4)/s = tanh(sa/2)/s, but when tanh is written out, you get
syms s t a b
f = (exp(a*s/2)-exp(-a*s/2))/(exp(a*s/2)+exp(-a*s/2)); % = tanh(a*s/2)
g0 = ilaplace(f/s,s,t)
g0 = (-1)^floor(t/a)/2 - (-1)^floor(-t/a)/2
which works. Using
floor(x) + floor(-x) = -1 % x not an exact integer
the two terms are identical, so you get
g0 = (-1)^floor(t/a) % square wave, period 2a
Another ilaplace that will be needed is the same thing with the denominator = (s+b) instead of s:
gb = ilaplace(f/(s+b),s,t)
gb = (exp(-b*t)*((-exp(a*b))^floor(t/a) - 1))/(exp(-a*b) + 1) ...
- (exp(-b*t)*((-exp(-a*b))^floor(-t/a) - 1))/(exp(a*b) + 1)
I was suprised that syms was able to come up with this, but it did. In this case the two terms are not identical but you can define
n = floor(t/a)
and combine them to get
gb = ((1-exp(a*b))/(1+exp(a*b)))*exp(-b*t) + (2/(1+exp(a*b)))*(-1)^n*exp(a*b*(n+1))*exp(-b*t)
(This can be derived using a delta function pulse train).
The second term has a problem that exp(a*b*(n+1)) is rapidly increasing with t so the calc will bomb out for large enough t before the exp(-b*t) factor can bring it back down. The way out is to define
t = a*floor(t/a)+tbar = a*n+tbar with 0<= tbar <a (tbar is local to each interval)
and then
gb = ((1-exp(a*b))/(1+exp(a*b)))*exp(-b*t) + (2*exp(a*b)/(1+exp(a*b)))*(-1)^n*exp(-b*tbar) (1)
For the circuit aspect, (current = u since cap I shows up badly in this font)
(sL + R + 1/(sC)) u(s) = V(s) = Vf(s)/s % f = tanh(a*s/2)
and
Vres(s) = (VR/L) f(s) / (s^2 + (R/L) s + 1/(LC) )
Now factor the polynomial into its roots, (change their sign since we need s+b1 not s-b1 etc.) and use partial fractions
1/(s+b1)(s+b2) = (1/(s+b1) -1/(s+b2)) / (b2-b1)
so
Vres(s) = (VR/L)/(b2-b1) (f(s)/(s+b1) - f(s)/(s+b2))
the ilaplace of this is known, so going back to the time domain, the expression (1) for gb will be evaluated for b=b1 and b=b2:
V = 10;
L = 1;
% R = 80; C = .2;
R = 20; C = 6e-5;
T = 1;
a = T/2;
t = 0:.001:4;
n = floor(t/a);
tbar = t-n*a;
gb = @(a,b,t,n,bar) ((1-exp(a*b))/(1+exp(a*b)))*exp(-b*t) ...
+ (2*exp(a*b)/(1+exp(a*b)))*(-1).^n.*exp(-b*tbar);
b =-roots([L R 1/C])
g = (V*R/(L*diff(b)))*(gb(a,b(1),t,n,tbar)-gb(a,b(2),t,n,tbar));
figure(1)
plot(t,g)
grid on
To this solution can be added any linear combination of the homogeneous solutions exp(-b1*t) and exp(-b2*t). This will change the boundary conditions at t=0. However, the solution as is gives the right boundary conditions for a quiescent circuit before the square wave is applied.
  1 Comment
marcel hendrix
marcel hendrix 24 minutes ago
Thank you for this thoughtful post. I will remark that using laplace and ilaplace in pairs for solving ODE's automatically handles initial conditions, inconsistent state variables, and the need to laboriously piece zero-state and zero-input solutions together. Those features alone make it very useful for my work. Being able to do this symbolically is in most cases only a party-trick. It is nice to impress colleagues and infrequently it adds unique features, but in general it is not very practical to carry along page-long equations and numerical inversion is fine.

Sign in to comment.

Products


Release

R2023b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!