ilaplace doesn't handle tanh()

65 views (last 30 days)
marcel hendrix
marcel hendrix on 20 Sep 2025
Commented: marcel hendrix ungefär 13 timmar 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 on 25 Oct 2025 at 13:18
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 on 25 Oct 2025 at 15:20
Edited: Paul on 25 Oct 2025 at 16:37
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 on 25 Oct 2025 at 7:59
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.
  7 Comments
David Goodmanson
David Goodmanson ungefär 18 timmar ago
Hi marcel, the links sound interesting but appear to be self-referential.
marcel hendrix
marcel hendrix ungefär 13 timmar ago
Here is the IEEE Xplore reference for a good paper if you have an engineering background: Ajoy Opal, 'The Transition Matrix for Linear Circuits', IEEE Transactions on Computer-Aided Design of Integrated Circuits and Systems, Vol. 16, No 5, May 1997. But maybe The_Matrix_Exponential_via_the_Laplace_Transform is enough?

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!