This is LaPlace.m in view mode; [Download] [Up]
(* :Title: Forward Laplace Transform Package *)
(* :Authors: Brian Evans, James McClellan *)
(* :Summary: *)
(* :Context: SignalProcessing`Analog`LaPlace` *)
(* :PackageVersion: 2.6 *)
(*
:Copyright: Copyright 1990-1991 by Brian L. Evans
Georgia Tech Research Corporation
Permission to use, copy, modify, and distribute this software
and its documentation for any purpose and without fee is
hereby granted, provided that the above copyright notice
appear in all copies and that both that copyright notice and
this permission notice appear in supporting documentation,
and that the name of the Georgia Tech Research Corporation,
Georgia Tech, or Georgia Institute of Technology not be used
in advertising or publicity pertaining to distribution of the
software without specific, written prior permission. Georgia
Tech makes no representations about the suitability of this
software for any purpose. It is provided "as is" without
express or implied warranty.
*)
(*
:History: began -- February, 1990 (adapted from "ZTransform.m")
added Dialogue ability -- February, 1991
*)
(* :Keywords: *)
(*
:Source: Muth, E. J. {Transform Methods}. 1977.
Franklin, G. F. {Feedback Control of Dynamic Systems}. 1986.
Bracewell. {The Fourier Transform and Its Applications}. 1978.
Nilsson, J. W. {Electric Circuits}
Churchill, R. {Operational Mathematics}. 1958.
Oberhettinger, F., and Badii, L. {Tables of Laplace
Transforms}, 1973.
*)
(*
:Warning: Keep conditional clauses (code following /;) on the same line;
breaking a clause into lines separated by RETURNS will
confuse Mathematica (e.g., the active context for this
package will not be reset to Global).
*)
(* :Mathematica Version: 1.2 or 2.0 *)
(* :Limitation: *)
(*
:Discussion: All new functions have usage information.
The 1-D rule base has a total of 102 rules:
I. multidimensional hooks 3 rules
II. rational transform pairs 13 rules
III. non-rational transform pairs 40 rules
IV. transform properties 23 rules *
V. transforms of SP structures 14 rules **
VI. transform strategies 9 rules
* one rule has been commented out
** two rules have been commented out
The only purpose to the multidimensional hook rules is to track
the region of convergence for non-separable functions. Without
these rules, the z-transform rule base would still properly
compute the z-transform function. Otherwise, the CTFTransform
would not work properly for functions like Exp[-(6/7)^t1]
Exp[-(9/10)^t2] Delta[t1 - t2] CStep[t1, t2] with respect to
variables t1 and t2.
At each step in the Laplace rule base, the current expression
has a local state associated with it. This state consists of
a list of six boolean values. Each boolean value is associated
with a strategy. If an element is True, then that strategy has
not been tried yet; if False, then that strategy has already
been tried, and it will not be tried again. Thus, local state
is used to prevent infinite loops which would be caused by the
repetitive application of certain strategy rules. See the
section S T A T E D E F I N I T I O N below and section VI
of the rules.
MyLaPlace[ f[t], t, s, state, tlist, slist ] is one-dimensional
Laplace transform rule base. It returns the transform of f[t]
as a three-element list: { F(s), Rminus, Rplus }. The "time"
variable being transform is t, and s is the Laplace variable.
The complete collection of time variables is in tlist and
Laplace variables in slist. Note that LaPlace drives the rule
base defined by MyLaPlace when computing the forward LaPlace
transform.
*)
(* :Functions: LaPlace *)
If [ TrueQ[ $VersionNumber >= 2.0 ],
Off[ General::spell ];
Off[ General::spell1 ] ];
(* B E G I N P A C K A G E *)
BeginPackage[ "SignalProcessing`Analog`LaPlace`",
"SignalProcessing`Analog`LSupport`",
"SignalProcessing`Support`TransSupport`",
"SignalProcessing`Support`ROC`",
"SignalProcessing`Support`SigProc`",
"SignalProcessing`Support`SupCode`",
"SignalProcessing`Support`FilterSupport`" ]
(* U S A G E I N F O R M A T I O N *)
LaPlace::usage =
"LaPlace[e, t] or LaPlace[e, t, s] gives the two-sided Laplace \
transform of the expression e, which is a function of t, by \
returning an object of four slots tagged by LTransData: \
<transform>, <rminus>, <rplus>, <laplace_variables>. \
The Region of Convergence (ROC) is defined as \
<rminus> < Re{s} < <rplus>. \
Note that the returned ROC is either the actual ROC or a subset \
of the actual ROC. \
In two dimensions, LaPlace[e, {t1, t2}, {s1, s2}] \
is the same as LaPlace [ LaPlace[e, t1, s1], t2, s2 ]. \
This notation extends naturally to higher dimensions. \
Note that the right-sided transform is specified by \
multiplying the expression by CStep[t]. \
Also, LaPlaceTransform is an alias for LaPlace."
(* E N D U S A G E I N F O R M A T I O N *)
Begin["`Private`"]
(* U S E R I N T E R F A C E *)
(* L operator *)
Unprotect[L]
L/: TheFunction[ L[t_, s_][f_] ] := LaPlace[f, t, s]
Protect[L]
(* LaPlace *)
LaPlace/: Options[ LaPlace ] :=
{ Definition -> False, Dialogue -> True,
Simplify -> True, TransformLookup -> {} }
LaPlace[e_] :=
laplacedriver[ Options[LaPlace], e ]
LaPlace[e_, t_] :=
laplacedriver[ Options[LaPlace], e, t ]
LaPlace[e_, t_, s_] :=
laplacedriver[ Options[LaPlace], e, t, s ]
LaPlace[e_, t_, s_, op__] :=
laplacedriver[ ToList[op] ~Join~ Options[LaPlace], e, t, s ]
(* Interface support for LaPlace *)
laplacedriver[op_, f_, args__] :=
cleanup [ laplace[op, ToContinuous[f], args],
Replace[Dialogue, op],
TrueQ[Replace[Simplify, op]] ]
laplace[op_, f_, args___] :=
Block [ {},
Replace [ ltrans[op, f, args], LaPlaceInterfaceRules ] ]
LaPlaceInterfaceRules = {
ltrans[op_, e_] :>
Message[Transform::novariables, "t (time)", GetVariables[e]],
ltrans[op_, e_, t_] :> e /; LTransformQ[e],
ltrans[op_, e_, t_] :>
laplace[op, e, t, DummyVariables[Length[t], Global`s] ] /;
validvarQ[t],
ltrans[op_, e_, t_, rest___] :>
Message[ Transform::badvar, "time", LaPlace, t ] /;
! validvarQ[t],
ltrans[op_, e_, t_, s_, rest___] :>
Message[ Transform::badvar, "s", LaPlace, s ] /;
! validvarQ[s],
ltrans[op_, e_, t_List, sl_] :>
MultiDTransform[ MakeLObject, laplace,
LTransformQ, e, t, s, sl, op ],
ltrans[op_, e_, t_Symbol, s_Symbol] :>
laplace[op, e, t, s, {t}, {s}],
ltrans[op_, e_, t_Symbol, s_Symbol, tlist_, slist_] :>
If [ SameQ[ToList[LVariables[e]], slist],
e,
LMultiDROC[laplace[op, TheFunction[e], t, s, tlist, slist],
e] ] /;
LTransformQ[e],
ltrans[op_, e_, t_Symbol, s_Symbol, tlist_, slist_] :>
MakeLObject [ MyLaPlace [ e, t, s, initLstate[],
tlist, slist, op ],
s ] /;
! LTransformQ[e]
}
cleanup[ Null, dialogue_, simplify_ ] := Null
cleanup[trans_, dialogue_, simplify_ ] :=
Block [ {dialflag, retval},
retval = trans;
dialflag = SameQ[dialogue, All];
If [ simplify,
Off[Replace::rep];
retval = SPSimplify[trans, Dialogue -> dialflag];
On[Replace::rep] ];
If [ dialogue || dialflag,
Scan[explain, retval, Infinity] ];
retval ]
explain[ mylaplace[ f_, t_, rest__ ] ] :=
Message[ Transform::incomplete, "forward Laplace transform", f, t ]
validvarQ[ x_Symbol ] := True
validvarQ[ x_List ] := Apply[And, Map[VariableQ, x]]
validvarQ[ x_ ] := False
(* S U P P O R T I N G R O U T I N E S F O R R U L E B A S E *)
absDialogue[f_, t_, options_] :=
Block [ {dialogue, result},
dialogue = InformUserQ[ options ];
result = (f /. Abs[a_. t] :> Abs[a] t) CStep[t] +
(f /. Abs[b_. t] :> - Abs[b] t) CStep[-t];
If [ dialogue,
Print[ "( after rewriting the two-sided expression" ];
Print[ " ", f ];
Print[ " as a left-sided plus a right-sided function:"];
Print[ " ", result, " . )" ] ];
result ]
addL[trans1_, trans2_] := AddT[LForm, trans1, trans2, -Infinity]
antiCausalL[trans_, s_] :=
Transform[ TheFunction[trans] /. s -> -s,
-GetRPlus[trans], -GetRMinus[trans] ] /;
LForm[trans]
conjL[trans_, s_] := ConjT[LForm, trans, s]
convolveL[convop_, trans1_, trans2_] :=
ConvolveT[LForm, convop, trans1, trans2]
definitionDialogue[ oldexpr_, trans_, operator_, options_ ] :=
Block [ {},
If [ InformUserQ[options],
Print[ "( after using ", operator,
" to apply the definition to" ];
Print[ " ", oldexpr ];
Print[ " to find its transform"];
Print[ " ", trans, " )" ] ];
trans ]
integrateL[trans_, s_] := IntegrateT[LForm, trans, s, s, Infinity]
lDerivative[trans_, s_, m_] := scaleL[DerivativeT[LForm, trans, s, m], (-1)^m]
lineImpulseMDL[trans_, s_, slist_, sleft_] :=
LineImpulsemDT[LForm, trans, s, slist, sleft, Plus]
lMultiplyByExp[trans_, s_, a_] :=
Block [ {newrm, newrp, transform},
newrm = GetRMinus[trans] - Re[a];
newrp = GetRPlus[trans] - Re[a];
transform = Transform[ TheFunction[trans], newrm, newrp ];
substituteForL[transform, s, s+a] ] /;
LForm[trans]
multL[trans1_, trans2_] := MultT[LForm, trans1, trans2, -Infinity]
scaleL[trans_, c_] := ScaleT[LForm, trans, c]
similarityL[x_, s_, scale_] :=
Block [ {adjrm, adjrp, newx},
adjrm = GetRMinus[x];
If [ ! InfinityQ[adjrm], adjrm *= scale ];
adjrp = GetRPlus[x];
If [ ! InfinityQ[adjrp], adjrp *= scale ];
newx = Transform[ TheFunction[x],
Min[adjrm, adjrp],
Max[adjrm, adjrp] ];
scaleL[ substituteForL[ newx, s, s/scale ], 1/Abs[scale] ] ] /;
LForm[x]
similarityQ[f_, t_] :=
Block [ {scale},
scale = ScalingFactor[f, t];
(! SameQ[scale, 1]) && (! SameQ[scale, 0]) ]
subL[trans1_, trans2_] := SubT[LForm, trans1, trans2, -Infinity]
substituteForL[trans_, s_, news_] := SubstituteForT[LForm, trans, s, news]
summationL[trans_, op_ ] :=
Block [ {fun, rm, rp},
fun = TheFunction[trans];
rm = GetRMinus[trans];
rp = GetRPlus[trans];
Transform[ op[fun], rm, rp ] ] /;
LForm[trans]
(* one-sided function *)
timeDerivative[x_, s_, m_, f_, t_] :=
Block [ {curderivative, i, result, rm, rp, xfun},
rm = Max[0, GetRMinus[x]];
rp = GetRPlus[x];
xfun = TheFunction[x];
result = s^m xfun - s^(m-1) Limit[f, t -> 0];
curderivative = f;
For [ i = 2, i <= m, i++,
curderivative = D[curderivative, t];
result -= s^(m-i) Limit[curderivative, t -> 0] ];
Transform[result, rm, rp] ] /;
LForm[x] && IntegerQ[m]
(* S T A T E D E F I N T I O N *)
(* In order of appearance in rule base *)
polyfactorfield = 1 (* factor denominator if denom. is rat. poly *)
partialfractionsfield = 2 (* partial fractions if denom. is rat. poly. *)
expandfield = 3 (* apply Expand[] to expression *)
expandallfield = 4 (* apply ExpandAll[] to expression *)
collectallfield = 5 (* apply Collect to every level of expression *)
stepfield = 6 (* multiply by (CStep[t] + CStep[-t]) *)
thefunfield = 7 (* apply TheFunction[] to expression *)
definitionfield = 8 (* apply definition of Laplace transform *)
statevariables = 8
initLstate[] := Table[True, {statevariables}]
nullLstate[] := Table[False, {statevariables}]
(* Driver for one-dimensional rule base *)
(* First, convert all z /(z - a) forms to 1/(1 - a z^-1) *)
(* since the rule base favors terms with z^-1 terms *)
(* Loop until the expression to be inverted does not change. *)
(* Use fixUp to remove the TransformLookup option before *)
(* the options are passed on to the rule base; otherwise, *)
(* the rule base could loop indefinitely. *)
MyLaPlace[ f_, t_, s_, st_, tlist_, slist_, op_ ] :=
Block [ {laste = Null, newe, newf, newlrules, trace},
(* generate the forward Laplace transform rules *)
newlrules = TransformFixUp[ t, s, op, mylaplace, True,
LaPlace, -Infinity, Infinity ];
LaPlaceRules = Join[ newlrules, OriginalLaPlaceRules ];
(* determine the level of dialogue *)
trace = SameQ[ Replace[Dialogue, op], All ];
(* separate Sqrt[b t] forms into Sqrt[b] Sqrt[t] forms *)
newf = f /. ( Sqrt[b_ t] :> Sqrt[b] Sqrt[t] /; FreeQ[b, t] );
(* take the 1-D Laplace transform *)
newe = mylaplace[newf, t, s, st, tlist, slist, fixUp[op]];
While [ ! SameQ[ laste, newe ],
If [ trace, Print[ newe ]; Print[ "which becomes" ] ];
laste = newe;
newe = MapAll[transform, laste] ];
If [ trace, Print[ newe ] ];
newe ]
(* fixUp -- remove redundant options and the option TransformLookup *)
fixUp[ op_ ] := { Definition -> Replace[Definition, op],
Dialogue -> Replace[Dialogue, op],
Simplify -> Replace[Simplify, op] }
transform[ expr_ ] :=
If [ SameQ[Head[expr], mylaplace],
Replace [ expr, LaPlaceRules ],
expr ]
(* Format intermediate forms so that output from Dialogue -> All is readable *)
Format[ mylaplace[ x_, t_, s_, st_, tlist_, slist_, op_ ] ] :=
SequenceForm[ ColumnForm[{"L",
" " ~StringJoin~ ToString[t]}],
{ x } ]
Format[ antiCausalL[trans_, s_] ] :=
SequenceForm[ {trans}, Subscript[s -> -s], Subscript[" and flip ROC "] ]
Format[ lMultiplyByExp[trans_, s_, a_] ] :=
SequenceForm[ {trans},
Subscript[s -> s + a],
Subscript[" and shift ROC "] ]
Format[ similarityL[trans_, s_, scale_] ] :=
SequenceForm[ {trans},
Subscript[s -> s/scale],
Subscript[" and scale transform & ROC "] ]
tdfmt = "`` - Summation[i, 0, ``, 1][`` Limit[ D[``, {``, i}], `` -> 0 ] ]"
Format[ timeDerivative[x_, s_, m_, f_, t_] ] :=
ToString[ StringForm[ tdfmt, s^m x, m - 1, s^(m - "i"), f, t, t ] ]
(* B E G I N R U L E B A S E *)
LaPlaceRules = {}
OriginalLaPlaceRules = {
(* I. M U L T I D I M E N S I O N A L H O O K S *)
(* A. Region of convergence specification for dimension given *)
(* by the variable n. Allows multi-dimensional LaPlace *)
(* transforms like a^t1 Delta[t1 - t2] CStep[t1,t2] to be *)
(* taken -- see Line impulses *)
mylaplace[ SignalProcessing`ROCinfo[t_, rm_:-Infinity , rp_:Infinity], t_, s_,
st_, tlist_, slist_, options_ ] :>
Transform[ 1, rm, rp ],
(* B. Multidimensional line Deltas become LineImpulses. *)
mylaplace[ f_. Delta[k_. t1_Symbol + l_. t2_Symbol], t_, s_,
st_, tlist_, slist_, options_ ] :>
mylaplace[ f LineImpulse[{t1,t2}, {k,-l}], t, s,
st, tlist, slist, options ] /;
SubsetQ[{t1, t2}, tlist] && MemberQ[{t1, t2}, t],
(* C. Line impulses. *)
mylaplace[ f_. LineImpulse[varlist_, coefflist_], t_, s_,
st_, tlist_, slist_, options_ ] :>
Block [ {functionoft, slistmD},
functionoft = f /. ReplaceWith[varlist, t / coefflist];
slistmD = AssociateItem[varlist, tlist, slist];
lineImpulseMDL [ mylaplace [ functionoft, t, s,
st, tlist, slist, options ],
s, slistmD, Complement[varlist,{t}]] ] /;
FreeQ[f, LineImpulse[a__]],
(* II. R A T I O N A L L A P L A C E T R A N S F O R M S *)
(* A. Lookup rules for the zero, step, and impulse functions. *)
mylaplace[ 0, t_, s_, st_, tlist_, slist_, options_ ] :>
Transform[ 0, -Infinity, Infinity ],
mylaplace[ CStep[t_], t_, s_, st_, tlist_, slist_, options_ ] :>
Transform[ 1/s, 0, Infinity ],
mylaplace[ f_. Delta[a_. t_ + t0_.], t_, s_, st_, tlist_, slist_, options_ ] :>
Transform[ (f /. t -> -t0/a) Exp[s t0/a] / Abs[a],
-Infinity, Infinity ] /;
FreeQ[{a,t0}, t],
mylaplace[ Unit[n_][t_ + t0_.], t_, s_, st_, tlist_, slist_, options_ ] :>
Transform[ s^n Exp[s t0], -Infinity, Infinity ] /;
IntegerQ[n] && n > 0 && FreeQ[t0, t],
mylaplace[ t_^n_. CStep[t_], t_, s_, st_, tlist_, slist_, options_ ] :>
Block [ {dialogue},
dialogue = SameQ[Replace[Dialogue, options], All];
Assuming[ n > 0, dialogue ];
If [ dialogue && ! IntegerQ[n],
Print[ "and that ", n, " is an integer" ] ];
Transform[ n! / s^(n+1), 0, Infinity ] ] /;
Implies[ NumberQ[n], IntegerQ[n] && n > 0 ],
(* B. Sinusoidal functions -- note that cross terms like *)
(* cos(at) cos(bt) are handled by properties *)
mylaplace[ Sin[b_. + w_. t_] CStep[t_], t_, s_,
st_, tlist_, slist_, options_ ] :>
Transform[ (s Sin[b] + w Cos[b]) / (s^2 + w^2), 0, Infinity ] /;
FreeQ[{b,w}, t], (* Modified from [Franklin, 591] *)
mylaplace[ Cos[b_. + w_. t_] CStep[t_], t_, s_,
st_, tlist_, slist_, options_ ] :>
Transform[ (s Cos[b] - w Sin[b]) / (s^2 + w^2), 0, Infinity ] /;
FreeQ[{b,w}, t], (* Modified from [Franklin, 591] *)
mylaplace[ a_. Sinh[b_. + w_. t_] CStep[t_], t_, s_,
st_, tlist_, slist_, options_ ] :>
Transform[a (s Sinh[b] + w Cosh[b]) / (s^2 - w^2), Abs[w], Infinity] /;
FreeQ[{a,b,w}, t], (* Modified from [Franklin, 591] *)
mylaplace[ a_. Cosh[b_. + w_. t_] CStep[t_], t_, s_,
st_, tlist_, slist_, options_ ] :>
Transform[a (s Cosh[b] - w Sinh[b]) / (s^2 - w^2), Abs[w], Infinity] /;
FreeQ[{a,b,w}, t], (* Modified from [Franklin, 591] *)
mylaplace[ Sin[a_. t_]^2 CStep[t_], t_, s_,
st_, tlist_, slist_, options_ ] :>
Transform[ 2 a^2 / ( s (s^2 + 4 a^2) ), 2 Abs[Im[a]], Infinity ] /;
FreeQ[a, t], (* [O & B, Formula 7.38] *)
mylaplace[ Cos[a_. t_]^2 CStep[t_], t_, s_, st_, tlist_, slist_, options_ ] :>
Transform[ (s^2 + 2 a^2)/(s (s^2 + 4 a^2)), 2 Abs[Im[a]], Infinity ] /;
FreeQ[a, t], (* [O & B, Formula 7.39] *)
(* C. Constant function *)
mylaplace[ a_, t_, s_, st_, tlist_, slist_, options_ ] :>
Transform[ a Delta[s], 0, 0 ] /;
FreeQ[a, t],
(* D. LaGuerre polynomials *)
mylaplace[ LaguerreL[n_, t_ + b_.] CStep[t_], t_, s_,
st_, tlist_, slist_, options_ ] :>
Transform[ Exp[b s] ((s - 1)/s)^n / s, 0, Infinity ] /;
FreeQ[{b,n}, t],
(* E. Other rational transform pairs *)
mylaplace[ t_^j_. BesselJ[j_, a_. t_] CStep[t_], t_, s_,
st_, tlist_, slist_, options_ ] :>
Transform[ (2 a)^j Gamma[j + 1/2] / ( Sqrt[Pi] (s^2 + a^2)^(j + 1/2) ),
0, Infinity ] /;
FreeQ[{a,j}, t],
(* III. N O N - R A T I O N A L L A P L A C E T R A N S F O R M S *)
(* A. "Time" functions whose denominators are rational polys *)
(* 1. Put functions with rational polynomial denominators *)
(* in standard form (factor denominator, expand numer.) *)
mylaplace[ p_, t_, s_, st_, tlist_, slist_, options_ ] :>
mylaplace [ Expand[Numerator[p]] / ( Factor[Denominator[p]] ), t, s,
SetStateField[st, polyfactorfield, False],
tlist, slist, options ] /;
GetStateField[st, polyfactorfield] &&
PolynomialQ[Denominator[p], t] && RationalFunctionQ[p, t],
(* 2. Normalize the factors of the denominator *)
(* a. for numeric k, numeric j *)
mylaplace[ ((a_ + b_ t_^j_.)^k_) x_., t_, s_,
st_, tlist_, slist_, options_ ] :>
b^k mylaplace[ x ( a/b + t^j )^k, t, s, st, tlist, slist, options ] /;
FreeQ[{a,b},t] && IntegerQ[k] && (k < 0) && IntegerQ[j] && (j > 0),
(* b. for symbolic k, numeric j *)
mylaplace[ x_. / ((a_ + b_ t_^j_.)^k_.), t_, s_,
st_, tlist_, slist_, options_ ] :>
b^(- k) mylaplace[x / (a/b + t^j)^k, t, s, st, tlist, slist, options] /;
FreeQ[{a,b,k},t] && IntegerQ[j] && (j > 0),
(* 3. Partial fractions decomposition *)
mylaplace[ p_, t_, s_, st_, tlist_, slist_, options_ ] :>
mylaplace [ Apart[p, t], t, s,
SetStateField[st, partialfractionsfield, False],
tlist, slist, options ] /;
GetStateField[st, partialfractionsfield] &&
PolynomialQ[Denominator[p], t] && RationalFunctionQ[p, t],
(* 4. Denominator sections *)
mylaplace[ CStep[t_] / ( t_ + a_ ), t_, s_, st_, tlist_, slist_, options_ ] :>
Transform[ - Exp[a s] ExpIntegralEi[- a s], 0, Infinity ] /;
FreeQ[a, t], (* [O & B, Formula 2.9] *)
mylaplace[ CStep[t_] / ( t_ + a_ )^2, t_, s_,
st_, tlist_, slist_, options_ ] :>
Transform[ 1 / a + s Exp[a s] ExpIntegralEi[- a s], 0, Infinity ] /;
FreeQ[a, t],
mylaplace[ CStep[t_] / ( t_^2 + b_ ), t_, s_,
st_, tlist_, slist_, options_ ] :>
Block [ {a, trans},
a = Sqrt[b];
trans = CosIntegral[a s] Sin[a s] / a -
SinIntegral[a s] Cos[a s] / a;
Transform[trans, 0, Infinity] ] /;
FreeQ[b, t] && Positive[b], (* [O & B, Formula 2.16] *)
mylaplace[ CStep[t_] / ( t_^2 + b_ ), t_, s_,
st_, tlist_, slist_, options_ ] :>
Block [ {g, trans},
a = Sqrt[- b];
trans = ExpIntegralEi[- a s] Exp[a s] / ( 2 a ) -
(I Pi + ExpIntegralEi[a s] Exp[- a s] ) / ( 2 a );
Transform[trans, 0, Infinity] ] /;
FreeQ[{a,b}, t] && Negative[b], (* [O & B, Formula 2.21] *)
mylaplace[ (a_. t_ + b_.) CStep[t_] / (t_^2 + d_), t_, s_,
st_, tlist_, slist_, options_ ] :>
Block [ {c, trans},
c = Sqrt[d];
trans = - CosIntegral[c s] (a Cos[c s] - b Sin[c s] / c) -
SinIntegral[c s] (a Sin[c s] + b Cos[c s] / c);
Transform[trans, 0, Infinity] ] /;
FreeQ[{a,b,c,d}, t] && Positive[d], (* [O & B, Formula 2.19] *)
mylaplace[ (a_. t_ + b_.) CStep[t_] / (t_^2 + d_), t_, s_,
st_, tlist_, slist_, options_ ] :>
Block [ {c, trans},
c = Sqrt[- d];
trans = - ExpIntegralEi[- c s] Exp[c s] (a - b/c) / (2 f) -
ExpIntegralEi[c s] Exp[- c s] (a + b/c) / (2 f );
Transform[trans, 0, Infinity] ] /;
FreeQ[{a,b,d}, t] && Negative[d], (* [O & B, Formula 2.23] *)
mylaplace[ CStep[t_] / t_, t_, s_, st_, tlist_, slist_, options_ ] :>
Transform[ - Log[s], 0, Infinity ], (* [Churchill, 324] *)
mylaplace[ (t_ + b_.)^k_. CStep[t_ + b_.], t_, s_,
st_, tlist_, slist_, options_ ] :>
Block [ {},
Assuming[ Positive[k + 1], options];
Transform[ Exp[b s] Gamma[k+1] / s^(k+1), 0, Infinity ] ] /;
FreeQ[b, t] && Implies[NumberQ[N[k]], N[k > -1]],
(* [O & B, Formula 3.3] *)
(* B. "Time" functions whose denominators contains powers of t *)
mylaplace[ CPulse[l_, t_ + k_.] / Sqrt[ t_ ( t_ + l_ ) ],
t_, s_, st_, tlist_, slist_, options_ ] :>
Transform[ -I Pi Exp[s k] Exp[l s / 2] BesselI[0, l s / 2],
-Infinity, Infinity ] /;
FreeQ[{k,l}, t], (* [Churchill, 323 & 331] *)
mylaplace[ t_ CPulse[l_, t_ + k_.] / Sqrt[ t_ ( t_ + l_ ) ], t_, s_,
st_, tlist_, slist_, options_ ] :>
Transform[ I Pi l Exp[s k] Exp[l s / 2] BesselI[0, l s / 2] -
I Pi l Exp[l s / 2] BesselI[1, l s / 2],
-Infinity, Infinity ] /;
FreeQ[{k,l}, t], (* [Churchill, 323 & 331] *)
(* C. Gaussian function *)
mylaplace[ Exp[a_. t_^2] CStep[t_], t_, s_, st_, tlist_, slist_, options_ ] :>
Transform[ Sqrt[Pi / -a] Exp[- s^2 / (4 a)] *
( 1 - Erf[s / (2 Sqrt[-a])] ), -Infinity, Infinity ] /;
FreeQ[a, t], (* [O & B, Formula 5.41] *)
(* D. Common waves *)
(* 1. square waves *)
mylaplace[ SquareWave[c_, t_] CStep[t_], t_, s_,
st_, tlist_, slist_, options_ ] :>
Transform[Tanh[c s / 2] / s, 0, Infinity] /;
FreeQ[c, t], (* [Churchill, 54] *)
(* 2. full-wave rectified sinusoids *)
mylaplace[ Abs[Sin[a_. t_]] CStep[t_], t_, s_,
st_, tlist_, slist_, options_ ] :>
Transform[a Coth[Pi s / (2 a)] / (s^2 + a^2), Abs[Im[a]], Infinity] /;
FreeQ[a, t], (* [O & B, Formula 7.3] *)
mylaplace[ Abs[Cos[a_. t_]] CStep[t_], t_, s_,
st_, tlist_, slist_, options_ ] :>
Transform[ ( s + a Csch[Pi s / (2 a)] ) / (s^2 + a^2),
Abs[Im[a]], Infinity ] /;
FreeQ[a, t], (* [O & B, Formula 7.4] *)
(* E. Bessel functions *)
(* Bessel functions [Churchill, 327] and [O & B, Formulas 14.1/15.1] *)
(* Note that formula 14.1 in O & B has a typo in it: -v should be v *)
mylaplace[ BesselI[v_, a_. t_] CStep[t_], t_, s_,
st_, tlist_, slist_, options_ ] :>
Block [ {},
Assuming[ Positive[Re[v] + 1], options ];
Transform[ (s - Sqrt[s^2 - a^2])^v / (a^v Sqrt[s^2 - a^2]),
Abs[Re[a]], Infinity ] ] /;
FreeQ[{a,v}, t] && Implies[NumberQ[N[v]], N[Re[v] > -1]],
mylaplace[ BesselJ[v_, a_. t_] CStep[t_], t_, s_,
st_, tlist_, slist_, options_ ] :>
Block [ {},
Assuming[ Positive[Re[v] + 1], options];
Transform[ (Sqrt[s^2 + a^2] - s)^v / (a^v Sqrt[s^2 + a^2]),
Abs[Im[a]], Infinity ] ] /;
FreeQ[{a,v}, t] && Implies[NumberQ[N[v]], N[Re[v] > -1]],
mylaplace[ BesselJ[v_, a_. t_] CStep[t_] / t_, t_, s_,
st_, tlist_, slist_, options_ ] :>
Block [ {},
Assuming[ Positive[Re[v]], options ];
Transform[ ( Sqrt[s^2 + a^2] - s )^v / ( v a^v ),
Abs[Im[a]], Infinity ] ] /;
FreeQ[{a,v}, t] && Implies[NumberQ[N[v]], Re[N[v]] > 0],
mylaplace[ BesselK[0, j_. Sqrt[t_]] CStep[t_] / Sqrt[t_], t_, s_,
st_, tlist_, slist_, options_ ] :>
Transform[ Sqrt[Pi] Exp[j^2 / (8 s)] BesselK[0, j^2 / (8 s)] /
(2 Sqrt[s]), 0, Infinity ] /;
FreeQ[j, t],
(* F. Exponential forms *)
(* 1. exponential integral [Churchill, 329] *)
mylaplace[ ExpIntegralEi[a_. t_] CStep[t_], t_, s_,
st_, tlist_, slist_, options_ ] :>
Block [ {},
Assuming[ Negative[a], options ];
Transform[ - Log[ 1 - s / a ] / s, 0, Infinity ] ] /;
FreeQ[a, t] && Implies[NumberQ[N[a]], N[a < 0]],
(* [Churchill, 329] *)
(* 2. error functions, erf *)
mylaplace[ Erf[a_. Sqrt[t_]] CStep[t_], t_, s_,
st_, tlist_, slist_, options_ ] :>
Transform[ a / ( s Sqrt[s + a^2] ), 0, Infinity ] /;
FreeQ[a, t], (* Modified [Churchill, 326] *)
mylaplace[ Erf[a_. t_ + b_.] CStep[t_], t_, s_,
st_, tlist_, slist_, options_ ] :>
Transform[ ( Exp[s^2 / (4 a^2) + s b / a] ( 1 - Erf[b + s / (2 a)] ) +
Erf[b] ) / s, 0, Infinity ] /;
FreeQ[{a,b}, t], (* [O & B, Formula 17.59] *)
mylaplace[ Exp[a_/t_] CStep[t_], t_, s_,
st_, tlist_, slist_, options_ ] :>
Transform[ -2 I Sqrt[a] BesselK[-1, -2 I Sqrt[a] Sqrt[s]] / Sqrt[s],
0, Infinity ] /;
FreeQ[a, t], (* from Mathematica's Integrate command *)
mylaplace[ Exp[a_/t_] CStep[t_] / Sqrt[t_], t_, s_,
st_, tlist_, slist_, options_ ] :>
Transform[ Exp[2 I Sqrt[a] Sqrt[s]] Sqrt[Pi] / Sqrt[s], 0, Infinity ] /;
FreeQ[a, t], (* from Mathematica's Integrate command *)
(* G. Trigonometric functions *)
(* 1. sinc-like forms *)
mylaplace[ Sin[a_. t_] CStep[t_] / t_, t_, s_,
st_, tlist_, slist_, options_ ] :>
Transform[ ArcTan[ a / s ], Abs[Im[a]], Infinity ] /;
FreeQ[a, t], (* [O & B, Formula 7.5] *)
mylaplace[ Sin[k_. Sqrt[t_]] CStep[t_] / t_, t_, s_,
st_, tlist_, slist_, options_ ] :>
Transform[ Pi Erf[ k / ( 2 Sqrt[s] ) ], -Infinity, Infinity ] /;
FreeQ[k, t], (* [Churchill, 330] *)
(* 2. sine integral Si *)
mylaplace[ SinIntegral[a_. t_ + b_.] CStep[t_], t_, s_,
st_, tlist_, slist_, options_ ] :>
Transform[ Exp[b s / a] ArcTan[a / s] / s, 0, Infinity ] /;
FreeQ[{a,b}, t], (* [Churchill, 330] *)
(* 3. cosine integral Ci *)
mylaplace[ CosIntegral[a_. t_] CStep[t_], t_, s_,
st_, tlist_, slist_, options_ ] :>
Transform[ ( 2 Log[a] - Log[s^2 + a^2] ) / ( 2 s ), 0, Infinity ] /;
Positive[a], (* [Churchill, 330] *)
mylaplace[ CosIntegral[a_. t_] CStep[t_], t_, s_,
st_, tlist_, slist_, options_ ] :>
Transform[ - Log[1 + s^2/a^2] / (2 s), 0, Infinity ] /;
FreeQ[a, t], (* [Churchill, 330] *)
(* 4. inverse trigonometric functions *)
mylaplace[ ArcTan[a_. t_] CStep[t_], t_, s_, st_, tlist_, slist_, options_ ] :>
Transform[ (CosIntegral[s/a] Sin[s/a] - SinIntegral[s/a] Cos[s/a]) / s,
0, Infinity ] /;
FreeQ[a, t], (* [O & B, Formula 8.4] *)
mylaplace[ ArcCot[a_. t_] CStep[t_], t_, s_, st_, tlist_, slist_, options_ ] :>
Transform[ ( Pi/2 - CosIntegral[s/a] Sin[s/a] -
SinIntegral[s/a] Cos[s/a] ) / s, 0, Infinity ] /;
FreeQ[a, t], (* [O & B, Formula 8.5] *)
(* H. Logarithmic forms *)
mylaplace[ Log[a_. t_] CStep[t_], t_, s_, st_, tlist_, slist_, options_ ] :>
Transform[ - a ( EulerGamma + Log[s / a] ) / s, 0, Infinity ] /;
FreeQ[a, t], (* Modified [O & B, Formula 6.1] *)
mylaplace[ Log[a_. t_]^2 CStep[t_], t_, s_, st_, tlist_, slist_, options_ ] :>
Transform[ a ( Pi^2 / 6 + ( EulerGamma + Log[s / a] )^2 ) / s,
0, Infinity ] /;
FreeQ[a, t], (* [O & B, Formula 6.2] *)
mylaplace[ Log[a_ + b_. t_] CStep[t_], t_, s_,
st_, tlist_, slist_, options_ ] :>
Block [ {},
Assuming[ Negative[ Abs[Arg[b/a]] - Pi ], options ];
Transform[ (Log[a] - Exp[a s / b] ExpIntegralEi[- a s / b]) / s,
0, Infinity ] ] /;
FreeQ[{a,b},t] && Implies[NumberQ[N[a]] && NumberQ[N[b]], N[Abs[Arg[b/a]] < Pi]], (* [O & B, Formula 6.7] *)
mylaplace[ Log[t_^2 + b_] CStep[t_], t_, s_, st_, tlist_, slist_, options_ ] :>
Block [ {a, trans},
Assuming[ Positive[b], options];
a = Sqrt[b];
trans = 2 ( Log[a] - CosIntegral[a s] Cos[a s] -
SinIntegral[a s] Sin[a s] ) / s;
Transform[trans, 0, Infinity] ] /;
FreeQ[b, t] && Implies[ NumberQ[N[b]], Positive[b] ],
(* [O & B, Formula 6.11] *)
mylaplace[ Log[1 + b_. t_^2] CStep[t_] / t_, t_, s_,
st_, tlist_, slist_, options_ ] :>
Block [ {a, trans},
a = Sqrt[b];
trans = CosIntegral[s/a]^2 + SinIntegral[s/a]^2;
Transform[trans, 0, Infinity] ] /;
FreeQ[b, t], (* [O & B, Formula 6.15] *)
(* IV. T R A N S F O R M P R O P E R T I E S *)
(* A. pick off constants *)
mylaplace[ c_ x_, t_, s_, st_, tlist_, slist_, options_ ] :>
scaleL[mylaplace[x, t, s, st, tlist, slist, options], c] /;
FreeQ[c, t] && ! FreeQ[x, t],
(* B. additivity -- resulting ROC is intersection of two ROC's *)
mylaplace[ (x_ + y_) CStep[t_], t_, s_, st_, tlist_, slist_, options_ ] :>
addL[mylaplace[x CStep[t], t, s, st, tlist, slist, options],
mylaplace[y CStep[t], t, s, st, tlist, slist, options]],
mylaplace[ x_ + y_, t_, s_, st_, tlist_, slist_, options_ ] :>
addL[mylaplace[x, t, s, st, tlist, slist, options],
mylaplace[y, t, s, st, tlist, slist, options]],
mylaplace[ (x_ + y_) CStep[t_] / c_, t_, s_, st_, tlist_, slist_, options_ ] :>
addL[mylaplace[x CStep[t] / c, t, s, st, tlist, slist, options],
mylaplace[y CStep[t] / c, t, s, st, tlist, slist, options]],
mylaplace[ (x_ + y_) / c_, t_, s_, st_, tlist_, slist_, options_ ] :>
addL[mylaplace[x / c, t, s, st, tlist, slist, options],
mylaplace[y / c, t, s, st, tlist, slist, options]],
(* C. Time reversal *)
mylaplace[ x_. CStep[-t_], t_, s_, st_, tlist_, slist_, options_ ] :>
antiCausalL [ mylaplace [ (x /. t -> - t) CStep[t], t, s,
st, tlist, slist, options ],
s ],
(* D. Shift and delays -- every continuous function should *)
(* be a function times either a CStep or an Delta, and *)
(* the rule base already handles the Delta case. *)
mylaplace[ f_. CStep[a_ t_ + b_.], t_, s_, st_, tlist_, slist_, options_ ] :>
mylaplace[ f CStep[t + b/a] CStep[a] + f CStep[-t - b/a] CStep[-a],
t, s, st, tlist, slist, options ] /;
FreeQ[{a, b}, t], (* [Bracewell, 67] *)
mylaplace[ f_. CStep[t_ + m_], t_, s_, st_, tlist_, slist_, options_ ] :>
scaleL [ mylaplace [ (f /. t -> t - m) CStep[t], t, s,
st, tlist, slist, options ],
Exp[m s] ] /;
FreeQ[m, t],
mylaplace[ f_. CStep[m_ - t_], t_, s_, st_, tlist_, slist_, options_ ] :>
scaleL [ mylaplace [ (f /. t -> t + m) CStep[-t], t, s,
st, tlist, slist, options ],
Exp[- m s] ] /;
FreeQ[m, t],
mylaplace[ f_[t_ + b_], t_, s_, st_, tlist_, slist_, options_ ] :>
scaleL[ mylaplace[ f[t], t, s, st, tlist, slist, options],
Exp[b s] ] /;
FreeQ[b, t],
(*
mylaplace[ f_[t_ + b_] CStep[t_], t_, s_, st_, tlist_, slist_, options_ ] :>
scaleL[ mylaplace[ f[t] CStep[t], t, s, st, tlist, slist, options],
Exp[b s] ] /;
FreeQ[b, t],
*)
(* E. Multiplication by c^(at+b) -- covers exponential case, *)
(* b can be a function of t *)
mylaplace[ c_^(b_. + a_. t_) x_., t_, s_, st_, tlist_, slist_, options_ ] :>
lMultiplyByExp [ mylaplace[c^b x, t, s, st, tlist, slist, options],
s, -a Log[c] ] /;
FreeQ[{a,c}, t], (* Modified [Franklin, 590] *)
(* F. Multiplication by t^m [Franklin, 590] *)
mylaplace[ t_^m_. x_., t_, s_, st_, tlist_, slist_, options_ ] :>
lDerivative[ mylaplace[x, t, s, st, tlist, slist, options], s, m ] /;
IntegerQ[m] && m > 0,
(* G. Modulation *)
(* 1. multiplication by a cosine function [Bracewell, 224] *)
mylaplace[ Cos[b_ + w_. t_] f_, t_, s_, st_, tlist_, slist_, options_ ] :>
mylaplace [ Cos[b] Cos[w t] f - Sin[b] Sin[w t] f, t, s,
st, tlist, slist, options ],
mylaplace[ Cos[w_. t_] f_. CStep[t_], t_, s_, st_, tlist_, slist_, options_ ] :>
Block [ {trans},
trans = mylaplace[f CStep[t], t, s, st, tlist, slist, options];
scaleL[addL[substituteForL[trans, s, s + I w],
substituteForL[trans, s, s - I w] ],
1/2] ] /;
FreeQ[w, t],
(* 2. multiplication by a sine function [Bracewell, 224] *)
mylaplace[ Sin[b_ + w_. t_] f_, t_, s_, st_, tlist_, slist_, options_ ] :>
mylaplace [ Sin[b] Cos[w t] f + Cos[b] Sin[w t] f, t,
s, st, tlist, slist, options ],
mylaplace[ Sin[w_. t_] f_. CStep[t_], t_, s_, st_, tlist_, slist_, options_ ] :>
Block [ {trans},
trans = mylaplace[f CStep[t], t, s, st, tlist, slist, options];
scaleL[subL[substituteForL[trans, s, s + I w],
substituteForL[trans, s, s - I w] ],
I/2] ] /;
FreeQ[w, t],
(* H. Derivative *)
mylaplace[ Derivative[m_][f_][t_],
t_, s_, st_, tlist_, slist_, options_ ] :>
Block [ {dialogue},
dialogue = SameQ[ Replace[Dialogue, options], All ];
Assuming[ m > 0, dialogue ];
If [ dialogue && ! IntegerQ[m],
Print[ "and that ", m, " is an integer" ] ];
scaleL[ mylaplace[f[t], t, s, st, tlist, slist, options],
s^m ] ] /;
Implies[NumberQ[m], IntegerQ[m] && m > 0], (* [Bracewell, 224] *)
mylaplace[ Derivative[m_][f_][t_] CStep[t_],
t_, s_, st_, tlist_, slist_, options_ ] :>
Block [ {dialogue},
dialogue = SameQ[ Replace[Dialogue, options], All ];
Assuming[ m > 0, dialogue ];
If [ dialogue && ! IntegerQ[m],
Print[ "and that ", m, " is an integer" ] ];
timeDerivative[mylaplace[f[t], t, s, st, tlist, slist, options],
s, m, f[t], t] ] /;
Implies[NumberQ[m], IntegerQ[m] && m > 0], (* [Bracewell, 224] *)
(* I. Integral with time as upper limit *)
mylaplace[ Integrate[f_, terms1___, {a_, 0, t_}, terms2___],
t_, s_, st_, tlist_, slist_, options_ ] :>
Block [ {leftover, trans},
leftover = ToCollection[ terms1, terms2 ];
trans = mylaplace[f /. a -> t, t, s, st, tlist, slist, options];
If [ SameQ[{leftover}, {}],
scaleL [ trans, 1/s ],
scaleL [ trans, 1/s Integrate[f, leftover] ] ] ],
(* [Churchill, 323] *)
mylaplace[ Integrate[f_, terms1___, t_, terms2___],
t_, s_, st_, tlist_, slist_, options_ ] :>
Block [ {leftover, trans},
leftover = ToCollection[ terms1, terms2 ];
trans = mylaplace[f, t, s, st, tlist, slist, options];
If [ SameQ[{leftover}, {}],
scaleL [ trans, 1/s ],
scaleL [ trans, 1/s Integrate[f, leftover] ] ] ],
(* [Churchill, 323] *)
(* J. Divide by powers of t *)
mylaplace[ f_. t_^m_, t_, s_, st_, tlist_, slist_, options_ ] :>
integrateL[mylaplace[f t^(m+1), t, s, st, tlist, slist, options], s] /;
IntegerQ[m] && m < 0, (* [Nilsson, 516] *)
(* K. Conjugation: L{ Conj f[-t] } --> Conj F(s) *)
mylaplace[ Conjugate[x_], t_, s_, st_, tlist_, slist_, options_ ] :>
conjL[mylaplace[x /. t -> -t, t, s, st, tlist, slist, options], s],
(* [Bracewell, 122] *)
(* L. Convert forms with Abs[a t] into two-sided transforms *)
mylaplace[ f_, t_, s_, st_, tlist_, slist_, options_ ] :>
mylaplace[ absDialogue[f, t, options],
t, s, st, tlist, slist, options ] /;
! FreeQ[ f, Abs[c_. t] ],
(* V. S T R U C T U R E S *)
(* A. Convolution *)
mylaplace[ CConvolve[t_][x1_, x2_, rest__], t_, s_,
st_, tlist_, slist_, op_ ] :>
multL[mylaplace[x1, t, s, st, tlist, slist, op],
mylaplace[CConvolve[t][x2, rest], t, s,
st, tlist, slist, op]],
mylaplace[ CConvolve[t_][x1_, x2_], t_, s_, st_, tlist_, slist_, op_ ] :>
multL[mylaplace[x1, t, s, st, tlist, slist, op],
mylaplace[x2, t, s, st, tlist, slist, op]],
mylaplace[ CConvolve[tconv_][x1_, x2_], t_, s_, st_, tlist_, slist_, op_ ] :>
convolveL[ CConvolve[Complement[tconv, {t}]],
mylaplace[x1, t, s, st, tlist, slist, op],
mylaplace[x2, t, s, st, tlist, slist, op]] /;
ListQ[tconv] && MemberQ[tconv, t],
(* B. Continuous FIR filters. *)
mylaplace[ CFIR[t_, h_List, Roots -> r_], t_, s_,
st_, tlist_, slist_, options_ ] :>
Block [ {i, numzeroes},
If [ Length[h] != Length[r] + 1,
Message[ CFIR::invalid ] ];
numzeroes = Length[r];
Transform[ Product[(s - r[[i]]), {i, 1, numzeroes}],
-Infinity, Infinity ] ] /;
Length[Dimensions[h]] == 1,
mylaplace[ CFIR[t_, h_, rest___], t_, s_, st_, tlist_, slist_, options_ ] :>
Transform[ h . Table[s^k, {k, 0, Length[h] - 1}], -Infinity, Infinity ],
mylaplace[ CFIR[all__] [ x__ ], t_, s_, st_, tlist_, slist_, options_ ] :>
multL[mylaplace[CFIR[all], t, s, st, tlist, slist, options],
mylaplace[x, t, s, st, tlist, slist, options]],
(* C. One-dimensional analog IIR filters. *)
(* Region of convergence is incorrect *)
mylaplace[ CIIR[t_, a_List, Roots -> r_], t_, s_,
st_, tlist_, slist_, options_ ] :>
Block [ {i, numpoles},
If [ Length[a] != Length[r] + 1,
Message[ CIIR::invalid ] ];
numpoles = Length[r];
rminus = Max[Re[r]];
If [ ListQ[rminus], rminus = N[rminus] ];
Transform[ 1 / Product[(s - r[[i]]), {i, 1, numpoles}],
rminus, Infinity ] ] /;
Length[Dimensions[a]] == 1,
mylaplace[ CIIR[t_, a_List], t_, s_, st_, tlist_, slist_, options_ ] :>
Block [ {alist, denom, index, rminus, len},
alist = ToList[a];
len = Length[alist];
denom = a[[1]] +
Sum[ alist[[index]] s^(index - 1), {index, 2, len} ];
rminus = Max[ Re[ GetRootList[denom, s] ] ];
Transform[ 1 / denom, rminus, Infinity ] ] /;
Length[Dimensions[a]] == 1,
mylaplace[ CIIR[all__] [x__], t_, s_, st_, tlist_, slist_, options_ ] :>
multL[mylaplace[CIIR[all], t, s, st, tlist, slist, options],
mylaplace[x, t, s, st, tlist, slist, options]],
(* D. Imaginary part of a sequence *)
mylaplace[ Im[x_], t_, s_, st_, tlist_, slist_, options_ ] :>
Block [ {trans},
trans = mylaplace[x, t, s, st, tlist, slist, options];
scaleL[ subL [ trans,
conjL[substituteForL[trans, s, -s], s] ],
1/2 ] ],
(* E. Periodic sequence with period k *)
mylaplace[ Periodic[a_, t_][f_] CStep[t_], t_, s_,
st_, tlist_, slist_, options_ ] :>
scaleL[mylaplace[f CPulse[a, t], t, s, st, tlist, slist, options],
1 / ( 1 - Exp[- a s] ) ] /;
FreeQ[a, t],
(* F. Real part of a function *)
mylaplace[ Re[x_], t_, s_, st_, tlist_, slist_, options_ ] :>
Block [ {trans},
trans = mylaplace[x, t, s, st, tlist, slist, options];
scaleL [ addL [ trans,
conjL[substituteForL[trans, s, -s], s] ],
1/2] ],
(* G. Reverse operator *)
mylaplace[ Rev[t_][x_], t_, s_, st_, tlist_, slist_, options_ ] :>
antiCausalL[ mylaplace[ x, t, s, st, tlist, slist, options ], s ],
(* H. Shift operator *)
mylaplace[ Shift[m_, t_][x_], t_, s_, st_, tlist_, slist_, options_ ] :>
scaleL[mylaplace[x, t, s, st, tlist, slist, options], Exp[- m s]] /;
FreeQ[m, t],
(* I. Summation operator *)
mylaplace[ a_. Summation[i_, ib_, ie_, inc_][x_], t_, s_,
st_, tlist_, slist_, options_ ] :>
summationL[ mylaplace[a x, t, s, st, tlist, slist, options],
Summation[i, ib, ie, inc] ],
(* VI. S T R A T E G I E S *)
(* A. Similarity -- f(at) <--> F(s/a) / |a| [Bracewell, 224] *)
(* only perform this if a is neither 1 nor 0 *)
(* must be done after operator rules because the *)
(* substitution t -> t/scale messes up operators *)
mylaplace[ f_ CStep[t_], t_, s_, st_, tlist_, slist_, options_ ] :>
Block [ {newf, scale},
scale = ScalingFactor[f, t];
newf = ( f /. t -> t/scale ) CStep[t];
similarityL[ mylaplace[newf, t, s, st, tlist, slist, options],
s,
scale ] ] /;
similarityQ[f, t],
mylaplace[ f_, t_, s_, st_, tlist_, slist_, options_ ] :>
Block [ {newf, scale},
scale = ScalingFactor[f, t];
newf = ( f /. t -> t/scale );
similarityL[ mylaplace[newf, t, s, st, tlist, slist, options],
s,
scale ] ] /;
similarityQ[f, t],
(* B. Place sub-expressions over a common denominator *)
mylaplace[ f_. a_^(v_. t_ + k_.) / b_^(u_. t_ + l_.), t_, s_,
st_, tlist_, slist_, options_ ] :>
mylaplace[ (a^v/b^u)^t f a^k/b^l, t, s, st, tlist, slist, options ],
(* C. Expand out products like (t + 1) (t + 2) ... *)
mylaplace[ x_, t_, s_, st_, tlist_, slist_, options_ ] :>
mylaplace[ Distribute[x], t, s, st, tlist, slist, options ] /;
SameQ[Head[x], Times] && ! SameQ[Distribute[x], x],
(* D. Expands out all numerator in the expression *)
mylaplace[ x_, t_, s_, st_, tlist_, slist_, options_ ] :>
mylaplace [ Expand[x], t, s,
SetStateField[st, expandfield, False],
tlist, slist, options ] /;
GetStateField[st, expandfield] && ! SameQ[x, Expand[x]],
(* E. Expands out all numerators and denominators in expression *)
mylaplace[ x_, t_, s_, st_, tlist_, slist_, options_ ] :>
mylaplace[ ExpandAll[x], t, s,
SetStateField[st, expandallfield, False],
tlist, slist, options ] /;
GetStateField[st, expandallfield] && ! SameQ[x, ExpandAll[x]],
(* F. Collect all terms in expression *)
mylaplace[ x_, t_, s_, st_, tlist_, slist_, options_ ] :>
mylaplace[ MyCollectAll[x, t], t, s,
SetStateField[st, collectallfield, False],
tlist, slist, options ] /;
GetStateField[st, collectallfield],
(* G. Reduces all signal processing operations to their *)
(* mathematical forms *)
mylaplace[ x_, t_, s_, st_, tlist_, slist_, options_ ] :>
Block [ {newx},
newx = ToContinuous[ TheFunction[x] ];
state = If [ SameQ[newx, x], st, initLstate[] ];
state = SetStateField[state, thefunfield, False];
mylaplace[ newx, t, s, state, tlist, slist, options ] ] /;
GetStateField[st, thefunfield],
(* H. Apply definition if flag is set *)
mylaplace[ x_, t_, s_, st_, tlist_, slist_, options_ ] :>
Block [ {state, trans},
state = SetStateField[st, definitionfield, False];
trans = Integrate[x Exp[- s t], {t, -Infinity, Infinity}];
If [ SameQ[Head[trans], Integrate],
mylaplace[x, t, s, state, tlist, slist, options],
definitionDialogue[ x CStep[t],
Transform[ trans, 0, Infinity ],
Integrate, options ] ] ] /;
GetStateField[st, definitionfield] && Replace[Definition, options],
(* I. Two-sided transform if all else fails *)
mylaplace[ x_, t_, s_, st_, tlist_, slist_, options_ ] :>
Block [ {trans},
trans = MyLaPlace[ x CStep[t] + x CStep[-t], t, s,
nullLstate[], tlist, slist, options ];
If [ TrueQ[LForm[trans] && TheFunction[trans] != 0],
MyMessage[Transform::twosided, trans, x],
mylaplace[x, t, s, state, tlist, slist, options] ] ] /;
GetStateField[st, stepfield]
}
(* E N D P A C K A G E *)
End[]
EndPackage[]
If [ TrueQ[ $VersionNumber >= 2.0 ],
On[ General::spell ];
On[ General::spell1 ] ];
(* A L I A S E S *)
Unprotect[ LaPlaceTransform ]
LaPlaceTransform = LaPlace
LaPlaceTransform::usage = LaPlace::usage
Protect[ LaPlaceTransform ]
(* H E L P I N F O R M A T I O N *)
Combine[ SPfunctions, { LaPlace } ]
Protect[ LaPlace ]
(* E N D M E S S A G E *)
Print["The forward Laplace transform rule base LaPlace has been loaded."]
Null
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.