Using Mathematica to Solve Differential Equations

NOTE: I have a lot of difficulty with Mathematica solving differential equations. Frequently I find that if I make a typo in entering the equation that it is NOT enough to fix the typo, but rather I need to save the file, close Mathematica, and then reload!

In these notes we solve various types of differential equations: with and without initial conditions, systems of differential equations, .... We also solve difference equations.

(* NOTE: Anything between parentheses star and star parentheses is a comment *)
(* To compile a line type shift-enter *)
(* YOU DO NOT NEED TO CLEAR A VARIABLE BEFORE USING IT, BUT IT'S OFTEN A GOOD IDEA SO MATHEMATICA DOESN'T USE AN OLD VALUE *)

Print["If you want to see my template for Mathematica, you can go to the following address (you can just click it below and your browser will open it!): "Hyperlink["http://www.williams.edu/go/math/sjmiller/public_html/math/LaTexMathematica/MathematicaIntroVer6.nb"]];
Print["In case that link doesn't let you download the code but rather opens the code in the browswer window, just go to: ", Hyperlink["http://www.williams.edu/go/math/sjmiller/public_html/math/handouts/latex.htm"]];

(* THESE LINES SOLVE A LINEAR DIFFERENTIAL EQUATION. THE FIRST DOESN'T HAVE ANY INITIAL CONDITIONS AND THUS GENERATES ALL SOLUTIONS; THE SECOND HAS AN INITIAL CONDITION. *)
Clear[y];
DSolve[y'[x] + y[x] == x, y[x], x]
DSolve[{y'[x] + y[x] == x, y[0] == 1}, y[x], x]

(* IT'S NOT ALWAYS EASY TO PULL FUNCTIONS OFF OF MATHEMATICA WHEN IT SOLVES SOMETHING. SOMETIMES THE EASIEST WAY IS TO JUST CUT AND PASTE, WHICH WE DO BELOW. TO DEFINE A FUNCTION, WE HAVE AN UNDERSCORE AFTER EACH VARIABLE AND A COLON BEFORE THE EQUAL SIGN. *)
(* IF YOU HAVE A SEMICOLON AFTER A LINE IT SUPPRESSES THE OUTPUT; HOWEVER, IT ALWAYS SUPPRESSES OUTPUT WHEN DEFINING A FUNCTION. *)
solution[x_] := (E^(-x)) (2-(E^x)+(E^x) x)

(* SOMETIMES WHEN IT SOLVES AN EQUATION, THE RESULT IS NOT SIMPLIFIED. YOU CAN FIX THIS BY USING EXPAND OR SIMPLIFY. *)
Expand[solution[x]]
Simplify[solution[x]]

(* The commands below allow you to plot the solution *)
Plot[solution[x], {x,-2,5}]

(* ONE OF THE NICE NEW FEATURES IN VERSIONS 6 AND 7 IS MANIPULATE. HERE WE SHOW HOW WE CAN MANIPULATE THE PLOT OF THE SOLUTION WITH TWO FREE PARAMETERS *)
(* IMAGINE THE SOLUTION TO A DIFFERENTIAL EQUATION IS THE FOLLOWING *)
solution[x_,c1_,c2_] := c1 (x^2 - 2x + 1) + c2 Exp[-x/5];
Manipulate[Plot[solution[x,c1,c2], {x,xcenter-xrange,xcenter+xrange}], {xcenter,-100,100},{xrange,.01,100},{c1,-2,2},{c2,-2,2}]

(* HERE WE SOLVE A SECOND ORDER DIFFERENTIAL EQUATION, FIRST WITH AND THEN WITHOUT INITIAL CONDITIONS. NOTE THE SYNTAX -- WE HAVE THE DIFFERENTIAL EQUATION AND THE INITIAL CONDITIONS IN {}, AND WE USE == AND NOT = ALWAYS. *)
Clear[y];
DSolve[y''[x] + y[x] == 0, y[x], x]
Clear[y];
DSolve[{y''[x] + y[x] == 0, y[0] == 2, y'[0] == 1}, y[x], x]

(* ONE OF THE NICE NEW FEATURES IN VERSIONS 6 AND 7 IS MANIPULATE. HERE IS SOME CODE TO SHOW HOW ADDITIONAL TERMS IN THE TAYLOR SERIES EXPANSION OF SIN(X) GIVE A BETTER AND BETTER FIT. *)
(* Note that once we have 51 or so terms, Mathematica is no longer evaluating things properly. The reason is we are now raising large numbers to large powers and then dividing by large factorials -- if we don't group the terms carefully, there will easily be overflow problems. *)
Manipulate[Plot[{Sin[x],Sum[(-1.)^(n+1) x^(2n-1) / ((2n - 1)!),{n,1,Floor[num]}]}, {x,0,xrange 2 Pi}, PlotRange -> {-yrange,yrange}], {num,1,80}, {xrange, 1, 10}, {yrange,1.25,20}]

(* HERE IS AN EXAMPLE OF A SYSTEM OF DIFFERENTIAL EQUATIONS, WITH AND WITHOUT INITIAL CONDITIONS. *)
Clear[x]; Clear[y];
DSolve[{x'[t] == 2 x[t] + 3 y[t], y'[t] == 3 x[t] + 2 y[t]}, {y, x}, t]
Clear[x]; Clear[y];
DSolve[{x'[t] == 2 x[t] + 3 y[t], y'[t] == 3 x[t] + 2 y[t], x[0] == 4, y[0] == 2}, {y, x}, t]

(* THIS EXAMPLE IS TYPICAL OF WHAT HAPPENS, NAMELY THAT MOST OF THESE EQUATIONS ARE TOO HARD TO BE SOLVED EXACTLY. HERE IS AN EXAMPLE, WHERE K[1] IS A DUMMY VARIABLE OF INTEGRATION. IF WE CHANTE t^2 TO t THEN WE CAN SOLVE IT IN TERMS OF SPECIAL FUNCTIONS, OR IF WE CHANGE THE NON-HOMOGENOUS TERM. *)
DSolve[y'[t] + t^2 y[t] == Exp[t], y[t], t]
DSolve[y'[t] + t y[t] == Exp[t], y[t], t]
DSolve[y'[t] + t^2 y[t] == 1, y[t], t]

(* WHEN WE DO GET SOLUTIONS LIKE THE ABOVE, IT CAN INVOLVE FUNCTIONS YOU HAVEN'T SEEN, SUCH AS ERFI. TO FIND OUT MORE ABOUT THAT, EITHER GO TO FIND SELECTED FUNCTION, OR TYPE QUESTION MARK ERFI AT THE NEXT COMMAND LINE. YOU CAN THEN CLICK ON THE >> FOR MORE INFO. *)
? Erfi

(* You can also use Mathematica to solve difference equations, which it calls recurrence equations. *)
(* Does the last solution mean anything to you??? *)
RSolve[a[n+2] - a[n+1] - a[n] == 0, a[n],n]
RSolve[a[n+2] - 3 a[n+1]  - 10 a[n] == 0, a[n],n]
RSolve[{a[n+2] - 3 a[n+1]  - 10 a[n] == 0, a[0] == 1, a[1] == 2}, a[n],n]
RSolve[a[n+2] - 6 a[n+1]  + 9 a[n] == 0, a[n],n]
RSolve[a[n+2] - 6 n a[n+1]  + 6  a[n] == 0, a[n],n]

?  Hypergeometric0F1Regularized

(* The following examples illustrate how powerful the symbolic algorithms in Mathematica are. We proved in one of the Green Chicken problem sessions that the sequence below has limit equal to log(2); Mathematica is able to see this! *)

RSolve[{a[n+1] ==  (a[n]  + n  a[n-1]) / (n+1), a[0] == 0, a[1] ==1}, a[n],n]

? LerchPhi

Limit[-(((-1))^n) LerchPhi[-1,1,1+n]+Log[2],n  ->  Infinity]

(* the following is a slight generalization of our original sequence. It isn't hard to show that if the first equals log(2) then this equals x + (y-x) log(2); Mathematica sees this as well! *)
RSolve[{a[n+1] ==  (a[n]  + n  a[n-1]) / (n+1), a[0] ==x, a[1] ==y}, a[n],n]

Limit[x+(((-1))^n) x LerchPhi[-1,1,1+n]-(((-1))^n) y LerchPhi[-1,1,1+n]-x Log[2]+y Log[2], n -> Infinity]