Linear Algebraic Equations


This tutorial is made solely for the purpose of education and it is designed for students taking Applied Math 0340. It is primarily for students who have some experience using Mathematica. If you have never used Mathematica before and would like to learn more of the basics for this computer algebra system, it is strongly recommended looking at the APMA 0330 tutorial. As a friendly reminder, don't forget to clear variables in use and/or the kernel.

Finally, the commands in this tutorial are all written in bold black font, while Mathematica output is in normal font. This means that you can copy and paste all commands into Mathematica, change the parameters and run them. You, as the user, are free to use the scripts for your needs to learn the Mathematica program, and have the right to distribute this tutorial and refer to this tutorial as long as this tutorial is accredited appropriately.

Return to computing page for the first course APMA0330
Return to computing page for the second course APMA0340
Return to Mathematica tutorial for the first course APMA0330
Return to Mathematica tutorial for the second course APMA0340
Return to the main page for the course APMA0340
Return to the main page for the course APMA0330

This chapter is devoted to methods for solving linear algebraic equations. While they originated in the early nineteen century (by the work of Gauss), the field has seen an explosion of activity spurred by demand due to extraordinary technological advances in engineering and sciences. The reviews of the methods could be found in

http://www-users.cs.umn.edu/~saad/PDF/umsi-99-152.pdf


Vector Space


We recall the definition of vector space. A vector space is a set \( V \) together with an inner operation called addition (a rule for adding two elements of \( V \) to obtain a third element of \( V \) ) and another outer operation called scalar multiplication (a rule for multiplying a real or complex number times an element of \( V \) to obtain a second element of \( V \) ) on which the following properties hold:

  1. \( {\bf x} + {\bf y} = {\bf y} + {\bf x} \)
  2. \( {\bf x} + ({\bf y} + {\bf z}) = ({\bf x} + {\bf y}) + {\bf z} \)
  3. There is an element 0 of V so that \( {\bf 0} + {\bf y} = {\bf y} + {\bf 0} = {\bf y}\) for every \( {\bf y} \in V \)
  4. There is an element \( -{\bf x} \) in V such that \( {\bf x} - {\bf x} = -{\bf x} + {\bf x} = {\bf 0}\)
  5. \( a({\bf x} + {\bf y}) = a{\bf y} + a{\bf x} \)
  6. \( (a+b)\,{\bf x} = a\,{\bf x} + b\,{\bf x} \)
  7. \( (ab){\bf x} = a(b {\bf x} )\)
  8. \( 1\,{\bf x} = {\bf x} \)
The elements of a vector space V are called vectors. It is a custom to denote vectors by lower case letter in bold font, while scalars/numbers by regular letters. Later on, when a system of coordinates (or basis) is introduced, vectors will be identified by ordered n-tuples written in either column form or row form. For the former, we will use the same notation as for vectors in general, but the later will be identified by an arrow above the vector ( \( \vec{x} \) ).

 

 

 

2.4.2. Euler's Algorithms


Euler method for systems of differential equations

euler[F_, a_, Y0_, b_, Steps_] :=
Module[{t, Y, h = (b - a)/Steps//N, i},
t[0] = a; Y[0] = Y0;
Do[
t[i] = a + i h;
Y[i] = Y[i - 1] + h F[t[i - 1], Y[i - 1]],
{i, 1, n}
];
Table[{t[i], Y[i]}, {i, 0, n}]
]

Using for simplicity the initial point to be the origin. we present another way to implement the Euler rule:

h = .1;                (* step size *)
TimeMax = 3.5;
maxN = TimeMax/h;
plotmax = 5;
plotmin = -5;
fx[x_, y_] = y + x
Out[8]= x+y
fy[x_, y_] = -2 x + 3 y
Out[9]= -2 x + 3 y
xxo = -1.5;
yyo = -0.5;
xx[0] := xxo
yy[0] := yyo
xx[n_] := xx[n] = xx[n - 1] + h*fx[xx[n - 1], yy[n - 1]]
yy[n_] := yy[n] = yy[n - 1] + h*fy[xx[n - 1], yy[n - 1]]
MatrixForm[Table[{h*n, xx[n], yy[n]}, {n, 0, maxN}]]
Out[15]//MatrixForm=

We can make several different types of plots. Here we plot on the phase plane using dots and then using line segments

eulerdotplot =
ListPlot[Table[{xx[n], yy[n]}, {n, 0, maxN}],
PlotStyle -> {PointSize[Large], Red}]
eulerlineplot =
ListLinePlot[Table[{xx[n], yy[n]}, {n, 0, maxN}],
PlotStyle -> {Thick, Green}]

Here we create the associated streamplot

streamplot =
StreamPlot[{fx[x, y], fy[x, y]}, {x, plotmin, plotmax}, {y, plotmin,
plotmax}]

 

We plot x-component versus t

xPlot = ListLinePlot[Table[{h*n, xx[n]}, {n, 0, maxN}],
PlotStyle -> {Thick, Blue}]

We plot y-component versus t

yPlot = ListLinePlot[Table[{h*n, yy[n]}, {n, 0, maxN}],
PlotStyle -> {Thick, Green}]

Finally, we mash them all together

Show[streamplot, eulerlineplot]




 

 


II. Basic Properties of Matrices


2.4.3. LU Factorization


 

The matrix A is a global variable and elements are changed when the LUfactor subroutine is executed. Hence, it is important to save a copy of A in the variable A0. Use one of the following two versions of the LUfactor subroutine and the SolveLU subroutine. The first version of LUfactor uses parallel programming and "row operations" instead of loops.
LUfactor[n_] := Module[ {i,j,k,p,Z},
r = Table[j, {j,n}];
For[ p=1, p<= n-1, p++ ,
For[ j=p+1 , j<= n, j++ ,
If Abs[ A[[ r[[j]] , p ]] ] > Abs[ A[[ r[[p]] , p ]] ] ,
r[[{j,p}]] = r[[{p,j}]] ]; ];
For[ k=p+1, k<=n, k++,
A[[ r[[k]] , p ]] = A[[ r[[k]] , p ]] / A[[ r[[p]] , p ]] ;
A[[ r[[k]] , Range[p+1,n] ]] = A[[ r[[k]] , Range[p+1,n] ]] - A[[ r[[k]] , p ]] A[[ r[[p]] , Range[p+1,n] ]] ;];];
L = P = IdentityMatrix[n];
Z = Table[0, {j,n}];
P = P[[r]];
U = A[[r]];
For[ i = 1, i <=n, i++,
L[[ i, Range[1, i-1] ]] = A[[ r[[i]] , Range[1, i-1] ]] ;
U[[ i, Range[1, i-1] ]] = Z[[ Range[1, i-1] ]] ; ];
This is the second version of LUfactor and it uses more loops and traditional programming.
LUfactor[n_] := Module[ {i,j,k,p},
r = Table[j, {j,n}];
For[ p=1, p<= n-1, p++ ,
For[ j=p+1 , j<= n, j++ ,
If Abs[ A[[ r[[j]] , p ]] ] > Abs[ A[[ r[[p]] , p ]] ] ,
r[[{j,p}]] = r[[{p,j}]] ]; ];
For[ k=p+1, k<=n, k++,
A[[ r[[k]] , p ]] = A[[ r[[k]] , p ]] / A[[ r[[p]] , p ]] ;
For[ c =p+1, c <= n, c++ ,
A[[ r[[k]], c ]] = A[[ r[[k]], c ]] - A[[ r[[k]], p ]] A[[ r[[p]], c ]] ;];];]; L = P = IdentityMatrix[n];
Z = Table[0, {j,n}];
P = P[[r]];
U = A[[r]];
For[ i = 1, i <=n, i++,
For[ j = 1, j <=i-1, j++,
L[[ i, j ]] = A[[ r[[i]] , j ]] ;
U[[ i, j ]] = 0 ; ];];];
Use the subroutine SolveLU which is similar to the forward substitution and back substitution subroutines.
SolvLU[n_]:=
Module[ {k}, X = Y = Table[0, {n}] ;
For[ k=1, k<=n, k++ ,
Y[[k]] = (B[[ r[[k]] ]] - Sum[A[[ r[[k]], j ]] Y[[j]], {j, 1, k-1}]);];
For[ k =n, 1 <= k, k-- ,
X[[k]] = (Y[[k]] - Sum[A[[r[[k]], j]] X[[j]] , {j,k+1, n }])/ A[[r[[k]], k]] ];];

 

 

2.4.4. Runge-Kutta Methods


 

 

 

2.4.5. Multistep Methods

 

 

 

IV. Solving Systems of Non-linear Differential Equations



F[x_, y_] := -y^3;
G[x_, y_] := x^3;
sol = NDSolve[{x'[t] == F[x[t], y[t]], y'[t] == G[x[t], y[t]],
x[0] == 1, y[0] == 0}, {x, y}, {t, 0, 3*Pi},
WorkingPrecision -> 20]
ParametricPlot[Evaluate[{x[t], y[t]}] /. sol, {t, 0, 3*Pi}]

X[t_] := Evaluate[x[t] /. sol]
Y[t_] := Evaluate[y[t] /. sol]
fns[t_] := {X[t], Y[t]};
len := Length[fns[t]];
Plot[Evaluate[fns[t]], {t, 0, 3*Pi}]

 

 

V. van der Pol Equation


vdot[t_] = mu (1 - x[t]^2)*x'[t] - x[t]
Out[1]= -x[t] + mu (1 - x[t]^2) Derivative[1][x][t]
M = {{0, 1}, {D[vdot[t], x[t]], D[vdot[t], x'[t]]}}
Out[2]= {{0, 1}, {-1 - 2 mu x[t] Derivative[1][x][t], mu (1 - x[t]^2)}}
MO = M /. {x[t] -> 0, x'[t] -> 0}
Out[3]= {{0, 1}, {-1, mu}}
Eigenvalues[MO]
Out[3]= {1/2 (mu - Sqrt[-4 + mu^2]), 1/2 (mu + Sqrt[-4 + mu^2])}
MO // MatrixForm
Out[4]=
{"0", "1"},
{"1, "mu"}

vdot05[t_] = vdot[t] /. mu -> 0.5
Out[6]= -x[t] + 0.5 (1 - x[t]^2) Derivative[1][x][t]
Orbit1 = NDSolve[{v'[t] == vdot05[t], x'[t] == v[t], x[0] == 0.01,  v[0] == 0}, {x, v}, {t, 0, 40}]
Out[7]= {{x->InterpolatingFunction[{0.,40.}},<>],
v->InterpolatingFunction[{0.,40.}},<>]}}

plot05 = ParametricPlot[{x[t] /. Orbit1[[1]],
v[t] /. Orbit1[[1]]}, {t, 0, 40}, Frame -> True,
PlotLabel -> "van der Pol solution for mu =0.5"]

Out[6]=

Orbit2 = NDSolve[{v'[t] == vdot05[t], x'[t] == v[t], x[0] == 4.0, v[0] == 0}, {x, v}, {t, 0, 40}]
plot054 =
ParametricPlot[{x[t] /. Orbit2[[1]], v[t] /. Orbit2[[1]]}, {t, 0, 40}]
Out[8]=
Show[{plot05, plot054}, Frame -> True]

vdot3[t_] = vdot[t] /. mu -> 3.0
Orbit3 = NDSolve[{v'[t] == vdot3[t], x'[t] == v[t], x[0] == 0.01,
v[0] == 0}, {x, v}, {t, 0, 40}]
plot305 =

ParametricPlot[{x[t] /. Orbit3[[1]], v[t] /. Orbit3[[1]]}, {t, 0,
40}, Frame -> True, AspectRatio -> 1.0, PlotRange -> 5.1,
PlotLabel -> "van der Pol solution for mu =3"]
Out[11]=

plot305 =
ParametricPlot[{x[t] /. Orbit3[[1]], v[t] /. Orbit3[[1]]}, {t, 0,
40}, Frame -> True, AspectRatio -> 1.0, PlotRange -> 5.1,
PlotLabel -> "van der Pol solution for mu =3"]

Orbit33 =
NDSolve[{v'[t] == vdot3[t], x'[t] == v[t], x[0] == 3.0,
v[0] == 0}, {x, v}, {t, 0, 40}]
plot33 = ParametricPlot[{x[t] /. Orbit33[[1]],
v[t] /. Orbit33[[1]]}, {t, 0, 40}, Frame -> True,
AspectRatio -> 1.0, PlotRange -> 5.1,
PlotLabel -> "van der Pol solution for mu =3"]
Out[13]=

ParametricPlot[
Evaluate[Table[{x[t], x'[t]} /.
NDSolve[{x''[t] - 3 (1 - (x[t])^2) x'[t] + x[t] == 0, x[0] == c,
x'[0] == 0}, {x[t], x'[t]}, {t, 0, 50}], {c, -1, 1, 0.1}]], {t,
0, 50}, PlotRange -> {{-3, 3}, {-5.1, 5.1}}, PlotStyle -> Purple]

 

Plot with colors (Orlando):

Show[Table[
ParametricPlot[
Evaluate[{x[t], x'[t]} /.
NDSolve[{x''[t] - 3 (1 - (x[t])^2) x'[t] + x[t] == 0, x[0] == c,
x'[0] == 0}, {x[t], x'[t]}, {t, 0, 50}]], {t, 0, 50},
PlotRange -> {{-3, 3}, {-5.1, 5.1}},
PlotStyle -> Hue[(c + 1)/2]], {c, -1, 1, 0.1}]]

with two colors:

black = ParametricPlot[
Evaluate[Table[{x[t], x'[t]} /.
NDSolve[{x''[t] - 3 (1 - (x[t])^2) x'[t] + x[t] == 0, x[0] == c,
x'[0] == 0}, {x[t], x'[t]}, {t, 0, 50}], {c, -1, 0, 0.1}]], {t,
0, 50}, PlotRange -> {{-2.5, 2.5}, {-5.1, 5.1}},
PlotStyle -> Black]

blue = ParametricPlot[
Evaluate[Table[{x[t], x'[t]} /.
NDSolve[{x''[t] - 3 (1 - (x[t])^2) x'[t] + x[t] == 0, x[0] == c,
x'[0] == 0}, {x[t], x'[t]}, {t, 0, 50}], {c, 0, 1, 0.1}]], {t,
0, 50}, PlotRange -> {{-2.5, 2.5}, {-5.1, 5.1}}, PlotStyle -> Blue]

Show[black, blue]

With direction field:

field = VectorPlot[{y, 1*(1 - x^2)*y - x}, {x, -4.2, 4.2}, {y, -4.2,
4.2}, VectorScale -> {Small, 1}]

de1 = x'[t] == y[t];
de2 = y'[t] == 4*(1 - (x[t])^2)*y[t] - x[t];
soln1 = NDSolve[{de1, de2, x[0] == 0.5, y[0] == 0}, {x, y}, {t, 0,
40}]
soln2 = NDSolve[{de1, de2, x[0] == 2.5, y[0] == 0}, {x, y}, {t, 0,
40}]
plot1 = ParametricPlot[Evaluate[{x[t], y[t]} /. soln1], {t, 0, 40},
PlotStyle -> {RGBColor[0, 0, 1], Thickness[0.005]},
DisplayFunction -> Identity, PlotRange -> 6.6]
plot2 = ParametricPlot[Evaluate[{x[t], y[t]} /. soln2], {t, 0, 40},
PlotStyle -> {Black, Thickness[0.006]}, DisplayFunction -> Identity]
Show[plot1, plot2, field,
PlotLabel -> "Van der Pol System with mu = 4",
AxesLabel -> {"x", "y"}, DisplayFunction -> $DisplayFunction]

Kplot = Plot[Evaluate[x[t] /. soln2[[1]][[1]]], {t, 0, 40},
PlotStyle -> RGBColor[0, 0, 1], DisplayFunction -> Identity]

Vplot = Plot[Evaluate[y[t] /. soln2[[1]][[2]]], {t, 0, 40},
PlotStyle -> Black, DisplayFunction -> Identity]

Show[Kplot, Vplot, PlotLabel -> "Current (x) and Voltage (y)",
AxesLabel -> {"t", "x,y"}, DisplayFunction -> $DisplayFunction]

Instead of Vectorplot, sometimes StreamPlot presents the solution better:

StreamPlot[{y, 1*(1 - x^2)*y - x}, {x, -4.2, 4.2}, {y, -4.2, 4.2},
VectorScale -> {Small, 1}]

 

 

 

 

2. Solving Euler Systems of Equations


Euler systems of equation are of the form: x y' = A y
where y=y[x] is unknown vector column
A is a square matrix