(* Copyright 1988 Wolfram Research Inc. *)
(*
	correction by Eran Yehudai, 
	Fri, 29 Dec 89 13:01:27 CST
	added by Sha Xin Wei Jan 2, 1990
*)

            (** Basic Laplace transforms **)

BeginPackage["Laplace`"]

Laplace::usage =
	"Laplace[expr,t,s] gives the Laplace transform of expr."

Laplace[e_] := Laplace[e, t, s]

Begin["`Private`"]

(* constants *)
Laplace[c_,t_,s_] := c/s /; FreeQ[c,t]

(* linearity *)
Laplace[a_+b_,t_,s_] := Laplace[a,t,s] + Laplace[b,t,s]

(* pick off constants *)
Laplace[c_ a_,t_,s_] := c Laplace[a,t,s] /; FreeQ[c,t]

(* powers *)
Laplace[t_^n_.,t_,s_] := n!/s^(n+1) /; 
                                (FreeQ[n,t] && n > 0)

(* products involving powers *)
Laplace[a_ t_^n_.,t_,s_] := 
      (-1)^n D[Laplace[a,t,s], {s, n}] /; 
                                (FreeQ[n,t] && n > 0)

(* negative powers *)
Laplace[a_/t_,t_,s_] := 
            Block[ { v = Unique["s"] },
                  Integrate[Laplace[a,t,v],{v,s,Infinity}]
            ]

(* exponentials *)
Laplace[a_. Exp[b_. + c_. t_],t_,s_] := 
                Laplace[a Exp[b],t,s-c] /; 
					FreeQ[{b, c},t]

(* ==== Derivatives and Integrals ===================================== *)

Laplace[Derivative[1][f_][t_], t_, s_, opt___] :=
  Block[{g = Laplace[f[t], t, s, opt]}, s g - f[0] /; FreeQ[g, Laplace]]

Laplace[Derivative[n_Integer][f_][t_], t_, s_, opt___] :=
  Block[{g = Laplace[f[t], t, s, opt]},
    s^n g - (Sum[s^i D[f[t], {t, n-1-i}] , 
                        {i, 0, n-1}] /. t->0) /;  FreeQ[g, Laplace]
  ]

Laplace[Integrate[f_, t_], t_, s_, opt___] :=
  Block[{g = Laplace[f, t, s, opt]}, g / s /; FreeQ[g, Laplace]]

(* =================================================================== 
More correctly, instead of f(0) etc., we should have Limit[f[t],t->0+]
(when we can easily take directional limits (in 1.3?)).

Also the notes should describe that, to take the Laplace transform
of e.g. f''[t], you need firstly to do something like:

        Laplace[f[t],t,s_] = g[s]
        
Also, since the Laplace transform (and its inverse) will often (usually)
be applied to solving differential equations, shouldn't they be defined
so that they distribute over lists?
*)
End[]
EndPackage[ ]

Null
