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.