Solving  Linear Systems, Existence and Uniqueness

Solving and Uniqueness

Consider the set of equations
     x + 2y +  z  +  t  = a
    -x + 4y - 2z         = b
     x + 3y + 4z + 5t = c
     x          +  z  +   t = d
We illustrate how to use a matrix representation to write these out and solve them…     

Start with the matrix of coefficients of the variables, mymatrix:

In[79]:=

mymatrix = { {1, 2, 1, 1},  {-1, 4, -2, 0},  {1, 3, 4, 5},  {1, 0, 1, 1}} ;

mymatrix//MatrixForm

Out[80]//MatrixForm=

( 1 2 1 1 - 1 4 - 2 0 1 3 4 5 1 0 1 1 )

The system of equations will only have a unique solution if the determinant of mymatrix is nonzero.

In[81]:=

Det [ mymatrix ]

Out[81]=

14

Now define vectors for x and b in A _ x = b

In[82]:=

myx = { x , y , z , t } ;

In[83]:=

myb = { a , b , c , d } ;

The left-hand side of the first equation will be

In[84]:=

( mymatrix . myx ) [ [ 1 ] ]

Out[84]=

t + x + 2 y + z

and the left-hand side of all four equations will be

In[86]:=

lhs = mymatrix . myx ;

lhs//MatrixForm

Out[87]//MatrixForm=

( t + x + 2 y + z - x + 4 y - 2 z 5 t + x + 3 y + 4 z t + x + z )

Now define an indexed variable linsys with four entries, each being one of the equations in the system of interest:

In[88]:=

linsys [ i_Integer ] := lhs [ [ i ] ] == myb [ [ i ] ]

In[89]:=

linsys [ 2 ]

Out[89]=

- x + 4 y - 2 z b

Solving the set of equations for the unknowns x

In[94]:=

linsol = Solve [ { linsys [ 1 ] , linsys [ 2 ] , linsys [ 3 ] , linsys [ 4 ] } , myx ]

Out[94]=

{ { x 1 7 ( a + b - 2 c + 9 d ) , y a - d 2 , z 1 14 ( 13 a - 8 b + 2 c - 23 d ) , t 1 14 ( - 15 a + 6 b + 2 c + 19 d ) } }

Doing the same thing a different way, using Mathematica's LinearSolve function:

In[95]:=

? LinearSolve

LinearSolve[m, b] finds an x which solves the matrix equation m.x==b. LinearSolve[m] generates a LinearSolveFunction[ ... ] which can be applied repeatedly to different b. More…

In[96]:=

LinearSolve [ mymatrix , myb ]

Out[96]=

{ 1 7 ( a + b - 2 c + 9 d ) , a - d 2 , 1 14 ( 13 a - 8 b + 2 c - 23 d ) , 1 14 ( - 15 a + 6 b + 2 c + 19 d ) }

And yet another way, based on x = A _ - 1 A _ x = A _ - 1 b

In[98]:=

Inverse [ mymatrix ] . myb // MatrixForm

Out[98]//MatrixForm=

( a 7 + b 7 - 2 c 7 + 9 d 7 a 2 - d 2 13 a 14 - 4 b 7 + c 7 - 23 d 14 - 15 a 14 + 3 b 7 + c 7 + 19 d 14 )

When determinants are zero

Create a matrix with one row as a linear combination of the others

In[99]:=

myzeromatrix =  {mymatrix[[1]], mymatrix[[2]], p * mymatrix[[1]] + q * mymatrix[[2]] + r * mymatrix[[4]], mymatrix[[4]]} ;

myzeromatrix//MatrixForm

Out[100]//MatrixForm=

( 1 2 1 1 - 1 4 - 2 0 p - q + r 2 p + 4 q p - 2 q + r p + r 1 0 1 1 )

In[101]:=

Det [ myzeromatrix ]

Out[101]=

0

In[102]:=

LinearSolve [ myzeromatrix , myb ]

LinearSolve :: nosol : Linear equation encountered which has no solution. More… "Linear equation encountered which has no solution. \\!\\(\\*ButtonBox[\\\"More\[Ellipsis]\\\", ButtonStyle->\\\"RefGuideLinkText\\\", ButtonFrame->None, ButtonData:>\\\"LinearSolve::nosol\\\"]\\)"

Out[102]=

LinearSolve [ { { 1 , 2 , 1 , 1 } , { - 1 , 4 , - 2 , 0 } , { p - q + r , 2 p + 4 q , p - 2 q + r , p + r } , { 1 , 0 , 1 , 1 } } , { a , b , c , d } ]

This was not expected to have a solution because one of four equations in the system was a linear combination of others in the system. Effectively, we were asking Mathematica to solve a system of three equations in four unknowns. The rank of a square matrix of coefficients is equal to the number of linearly independent equations in the system. The null space of the matrix will be empty when the equations are all linearly independent.

In[103]:=

MatrixRank[mymatrix]

MatrixRank[myzeromatrix]

Out[103]=

4

Out[104]=

3

In[109]:=

NullSpace[mymatrix]

NullSpace[myzeromatrix]

Out[109]=

{ }

Out[110]=

{ { - 2 , 0 , 1 , 1 } }

Try solving this inhomogeneous system of equations using Solve:

In[111]:=

zerolhs = myzeromatrix . myx

Out[111]=

{ t + x + 2 y + z , - x + 4 y - 2 z , ( p + r ) t + ( p - q + r ) x + ( 2 p + 4 q ) y + ( p - 2 q + r ) z , t + x + z }

In[112]:=

zerolinsys [ i_Integer ] := zerolhs [ [ i ] ] == myb [ [ i ] ]

In[114]:=

Table [ zerolinsys [ i ] , { i , 4 } ] // MatrixForm

Out[114]//MatrixForm=

( t + x + 2 y + z a - x + 4 y - 2 z b ( p + r ) t + ( p - q + r ) x + ( 2 p + 4 q ) y + ( p - 2 q + r ) z c t + x + z d )

In[115]:=

zerolinsol = Solve [ Table [ zerolinsys [ i ] , { i , 4 } ] , myx ]

Out[115]=

{ }

No solution, as expected,  Let's see what happens if we ask Mathematica to solve the homogeneous problem:

In[118]:=

zerolinsol = Solve [ Table [ zerolinsys [ i ] /. { a 0 , b 0 , c 0 , d 0 } , { i , 4 } ] , myx ]

Solve :: svars : Equations may not give solutions for all \"solve\" variables. More… "Equations may not give solutions for all \\\"solve\\\" variables. \\!\\(\\*ButtonBox[\\\"More\[Ellipsis]\\\", ButtonStyle->\\\"RefGuideLinkText\\\", ButtonFrame->None, ButtonData:>\\\"Solve::svars\\\"]\\)"

Out[118]=

{ { y 0 , x - 2 t , z t } }

In this case, Mathematica gives a relationship between the variables, but because there are fewer equations than variables, there is still no unique solution.

Determinants

In[119]:=

Clear [ rv ]

Start by building a routine to make vectors containing six random numbers on the interval {-1,1}:

In[120]:=

rv [ i_ ] := rv [ i ] = Table [ Random [ Real , { - 1 , 1 } ] , { j , 6 } ]

In[121]:=

rv [ 1 ]

Out[121]=

{ - 0.9938040851644031 , - 0.8133427994181586 , 0.11622561205586446 , 0.41266758086355004 , - 0.6833753149939834 , 0.11068552486666561 }

In[122]:=

rv [ 2 ]

Out[122]=

{ - 0.2846169224254458 , - 0.9539538982723608 , 0.11907194814649213 , - 0.195040702170307 , 0.9983018639811516 , - 0.9796379773985667 }

Now use rv to make a 6 x 6 matrix, then find its determinant:

In[123]:=

randmat = Table [ rv [ i ] , { i , 6 } ]

Out[123]=

{ { - 0.9938040851644031 , - 0.8133427994181586 , 0.11622561205586446 , 0.41266758086355004 , - 0.6833753149939834 , 0.11068552486666561 } , { - 0.2846169224254458 , - 0.9539538982723608 , 0.11907194814649213 , - 0.195040702170307 , 0.9983018639811516 , - 0.9796379773985667 } , { 0.804619993357784 , 0.12328338055979393 , 0.5597976331631047 , 0.10082311726214988 , 0.23687755319034087 , - 0.4444852340488643 } , { - 0.8559303815338402 , 0.10236574476922677 , - 0.5869278995683929 , - 0.3368010045707486 , 0.6963141430303932 , - 0.21268133938503675 } , { - 0.5931238144039899 , - 0.5234582051525899 , - 0.4199114690254714 , 0.3746510797514133 , - 0.9097484994100065 , 0.3658562699807444 } , { 0.8647054533999743 , 0.3286049780237741 , - 0.028820447556498596 , - 0.4391030278489485 , 0.8664035894188227 , 0.3082429554223407 } }

In[124]:=

Det [ randmat ]

Out[124]=

- 0.11257469973661695

Switching two rows changes the sign but not the magnitude of the determinant:

In[125]:=

Det [ { rv [ 2 ] , rv [ 1 ] , rv [ 3 ] , rv [ 4 ] , rv [ 5 ] , rv [ 6 ] } ]

Out[125]=

0.11257469973661705

In[127]:=

Det [ { rv [ 3 ] , rv [ 1 ] , rv [ 2 ] , rv [ 4 ] , rv [ 5 ] , rv [ 6 ] } ]

Out[127]=

- 0.11257469973661702

Multiply one row by a constant and calculate determinant:

Clear[a]

Det[{a * rv[2], rv[1], rv[3], rv[4], rv[5], rv[6]}]

Out[128]=

0.11257469973661698 a

Multiply two rows by a constant and calculate determinant:

In[129]:=

Det [ { a * rv [ 2 ] , a * rv [ 1 ] , rv [ 3 ] , rv [ 4 ] , rv [ 5 ] , rv [ 6 ] } ]

Out[129]=

0.11257469973661698 a 2

Multiply all rows by a constant and calculate determinant:

In[130]:=

Det [ a { rv [ 2 ] , rv [ 1 ] , rv [ 3 ] , rv [ 4 ] , rv [ 5 ] , rv [ 6 ] } ]

Out[130]=

0.11257469973661698 a 6

In[131]:=

Clear [ a , b , c , d , e ]

In[132]:=

lindepvec = a * rv [ 1 ] + b * rv [ 2 ] + c * rv [ 3 ] + d * rv [ 4 ] + e * rv [ 5 ]

Out[132]=

{ - 0.9938040851644031 a - 0.2846169224254458 b + 0.804619993357784 c - 0.8559303815338402 d - 0.5931238144039899 e , - 0.8133427994181586 a - 0.9539538982723608 b + 0.12328338055979393 c + 0.10236574476922677 d - 0.5234582051525899 e , 0.11622561205586446 a + 0.11907194814649213 b + 0.5597976331631047 c - 0.5869278995683929 d - 0.4199114690254714 e , 0.41266758086355004 a - 0.195040702170307 b + 0.10082311726214988 c - 0.3368010045707486 d + 0.3746510797514133 e , - 0.6833753149939834 a + 0.9983018639811516 b + 0.23687755319034087 c + 0.6963141430303932 d - 0.9097484994100065 e , 0.11068552486666561 a - 0.9796379773985667 b - 0.4444852340488643 c - 0.21268133938503675 d + 0.3658562699807444 e }

Example of numerical precision: if one row of a 6 x 6 matrix is a linear combination of the other five rows, its determinant should evaluate to zero…

In[133]:=

Det [ { rv [ 1 ] , rv [ 2 ] , rv [ 3 ] , rv [ 4 ] , rv [ 5 ] , lindepvec } ]

Out[133]=

- 5.551115123125783 × 10 - 17 a + 0. b - 1.387778780781446 × 10 - 17 c + 5.551115123125783 × 10 - 17 d - 2.775557561562891 × 10 - 17 e

In[134]:=

Chop [ Det [ { rv [ 1 ] , rv [ 2 ] , rv [ 3 ] , rv [ 4 ] , rv [ 5 ] , lindepvec } ] ]

Out[134]=

0

Showing that the determinant of a product of matrices is the product of determinants

Creating a symbolic matrix

In[135]:=

symvec = { a , a , a , c , c , c } ;

In[138]:=

permuts = Permutations[symvec]

permuts//Dimensions

Out[138]=

{ { a , a , a , c , c , c } , { a , a , c , a , c , c } , { a , a , c , c , a , c } , { a , a , c , c , c , a } , { a , c , a , a , c , c } , { a , c , a , c , a , c } , { a , c , a , c , c , a } , { a , c , c , a , a , c } , { a , c , c , a , c , a } , { a , c , c , c , a , a } , { c , a , a , a , c , c } , { c , a , a , c , a , c } , { c , a , a , c , c , a } , { c , a , c , a , a , c } , { c , a , c , a , c , a } , { c , a , c , c , a , a } , { c , c , a , a , a , c } , { c , c , a , a , c , a } , { c , c , a , c , a , a } , { c , c , c , a , a , a } }

Out[139]=

{ 20 , 6 }

In[140]:=

symbmat//MatrixForm

Out[141]//MatrixForm=

( a a a c c c c a a c a c a c a c a c c c a a c a c c a a a c a c c a c a )

In[150]:=

detsymbmat = Simplify [ Det [ symbmat ] ]

Out[150]=

3 ( a - c ) 5 ( a + c )

Creating a matrix of rational numbers

In[143]:=

randommat = Table[Table[Random[Integer, {-100, 100}]/Random[Integer, {-100, 100}], {i, 6}], {j, 6}] ;

randommat//MatrixForm

Out[144]//MatrixForm=

( 4 19 0 - 41 9 89 85 32 55 3 2 - 84 73 - 58 99 34 87 50 17 - 71 64 23 68 - 10 27 89 26 - 3 13 - 3 20 98 23 - 82 67 76 87 - 19 6 7 30 - 69 25 - 29 2 41 9 - 33 61 43 89 - 55 79 25 64 - 1 83 1 34 29 97 9 10 - 4 11 - 53 57 - 57 43 - 75 86 )

In[151]:=

detrandomat = Det [ randommat ]

Out[151]=

479143363691667875348163770188617794024261 1613994538465867953181901005266186240000

In[146]:=

checka = Det [ symbmat . randommat ] // Simplify

Out[146]=

479143363691667875348163770188617794024261 ( a - c ) 5 ( a + c ) 537998179488622651060633668422062080000

In[153]:=

detrandomat * detsymbmat == checka

Out[153]=

True

Does the determinant of a product depend on the order of multiplication?

In[154]:=

checkb = Det [ randommat . symbmat ] // Simplify

Out[154]=

479143363691667875348163770188617794024261 ( a - c ) 5 ( a + c ) 537998179488622651060633668422062080000

In[155]:=

checka checkb

Out[155]=

True

However, the product of two matrices depends on which matrix is on the left and which is on the right

In[156]:=

( randommat . symbmat - symbmat . randommat ) // Simplify // MatrixForm

Out[156]//MatrixForm=

( - 6049 a 3942 + 480032437 c 481318365 - 128461 a 48906 + 534503 c 1497870 33742222 a 20092215 + 30326 c 13035 - 2653 a 3740 - 286139 c 273600 - 102103 a 13248 + 107181609 c 5763935 44027 a 22780 - 51398498 c 6875055 5327809 a 3247884 - 789359203 c 5756883264 - 854223 a 168922 + 2284763 c 473280 8254787449 a 8075276352 + 169111 c 33660 - 86 a 85 + 2195065781 c 1692382725 - 24355721 a 5480739 + 203950601 c 11739860 9421 a 2278 - 4405720195 c 576772416 - 1134860 a 1009489 + 27674280671 c 3683961060 - 2051 a 2403 + 218506243 c 39665340 158361809 a 12755340 - 317257 c 213730 13407039 a 8383040 + 20240399 c 5668650 311269 a 118690 + 378124609 c 24891840 - 571 a 340 + 72258863 c 23605452 127291 a 26190 - 120219299 c 6345525 - 19507 a 5655 - 2724449 c 220275 - 1965543 a 103675 + 194159 c 20619 - 30317 a 3420 - 609455 c 94656 - 87061 a 14835 + 1223386267 c 381268800 - 95653 a 144050 - 545083 c 29580 - 2460637 a 2103138 + 95593847425 c 63605733952 - 1897 a 2379 - 2127120373 c 3531337920 1789282021 a 5623575360 + 444905 c 97614 413051 a 141100 - 7922184683 c 2077976895 3242693 a 323426 + 4248208 c 2452505 - 113501 a 38592 - 180305130001 c 104088414572 - 3627589 a 1563738 + 694116553 c 982287270 2017 a 582 - 57948296 c 8507421 2329292 a 713241 - 2581259 c 7684014 - 17717 a 36550 - 13620031 c 5804480 159 a 11 - 134847539639 c 29046977472 - 2389 a 342 + 382516087 c 1045169180 )

Linear Transformations

We now demonstrate the use of matrix multiplication for manipulating an object, specifically an octohedron. The Octahedron is made up of eight polygons and the initial coordinates of the vertices were set to make a regular octahedron with its main diagonals parallel to axes x,y,z. The faces of the octahedron are colored so that rotations and other transformations can be easily tracked.

In[157]:=

<< Graphics`Polyhedra`

In[158]:=

Show [ Polyhedron [ Octahedron ] ]

[Graphics:HTMLFiles/Lecture-07_19.gif]

Out[158]=

Graphics3D

In[159]:=

Show [ Polyhedron [ Octahedron ] , ViewPoint -> { - 0.007 , - 1.995 , - 0.135 } ]

[Graphics:HTMLFiles/Lecture-07_20.gif]

Out[159]=

Graphics3D

In[160]:=

Polyhedron [ Octahedron ] // InputForm

Out[160]//InputForm=

Graphics3D[{Polygon[{{0., 0., 1.4142135623730951},
    {1.4142135623730951, 0., 0.}, {0., 1.4142135623730951, 0.}}],
  Polygon[{{0., 0., 1.4142135623730951}, {0., 1.4142135623730951, 0.},
    {-1.4142135623730951, 0., 0.}}],
  Polygon[{{0., 0., 1.4142135623730951}, {-1.4142135623730951, 0., 0.},
    {0., -1.4142135623730951, 0.}}],
  Polygon[{{0., 0., 1.4142135623730951}, {0., -1.4142135623730951, 0.},
    {1.4142135623730951, 0., 0.}}],
  Polygon[{{1.4142135623730951, 0., 0.}, {0., -1.4142135623730951, 0.},
    {0., 0., -1.4142135623730951}}],
  Polygon[{{1.4142135623730951, 0., 0.}, {0., 0., -1.4142135623730951},
    {0., 1.4142135623730951, 0.}}],
  Polygon[{{0., 0., -1.4142135623730951}, {0., -1.4142135623730951, 0.},
    {-1.4142135623730951, 0., 0.}}],
  Polygon[{{0., 1.4142135623730951, 0.}, {0., 0., -1.4142135623730951},
    {-1.4142135623730951, 0., 0.}}]}, {AmbientLight -> GrayLevel[0],
  AspectRatio -> Automatic, Axes -> False, AxesEdge -> Automatic,
  AxesLabel -> None, AxesStyle -> Automatic, Background -> Automatic,
  Boxed -> True, BoxRatios -> Automatic, BoxStyle -> Automatic,
  ColorOutput -> Automatic, DefaultColor -> Automatic,
  DefaultFont :> $DefaultFont, DisplayFunction :> $DisplayFunction,
  Epilog -> {}, FaceGrids -> None, FormatType :> $FormatType,
  ImageSize -> Automatic, Lighting -> True,
  LightSources -> {{{1., 0., 1.}, RGBColor[1, 0, 0]},
    {{1., 1., 1.}, RGBColor[0, 1, 0]}, {{0., 1., 1.},
     RGBColor[0, 0, 1]}}, Plot3Matrix -> Automatic, PlotLabel -> None,
  PlotRange -> All, PlotRegion -> Automatic,
  PolygonIntersections -> True, Prolog -> {}, RenderAll -> True,
  Shading -> True, SphericalRegion -> False, TextStyle :> $TextStyle,
  Ticks -> Automatic, ViewCenter -> Automatic,
  ViewPoint -> {1.3, -2.4, 2.}, ViewVertical -> {0., 0., 1.}}]

The object coloct is defined below to draw an octahedron and it invokes the Polygon function to draw the triangular faces by connecting three points at specific numerical coordinates. Note that each triangles' three vertices are each specified by a vector.

In[161]:=

Clear[coloct] ;

Out[162]=

Graphics3D

In[163]:=

Show [ coloct , Lighting False ]

[Graphics:HTMLFiles/Lecture-07_23.gif]

Out[163]=

Graphics3D

Now a matrix tmat is defined that will operate on the coordinate vectors fed to the Polygon function in coloct. In this first example, each z coordinate will be changed to -z:

In[164]:=

Clear[tmat] ;

tmat = {{1, 0, 0}, {0, 1, 0}, {0, 0, -1}} ;

tmat//MatrixForm

Out[166]//MatrixForm=

( 1 0 0 0 1 0 0 0 - 1 )

The Replace is used to modify the coordinates fed to the Polygon function in coloct by matrix multiplication of the vertex vectors:

In[167]:=

Show [ coloct /. { Polygon [ { a_List , b_List , c_List } ] Polygon [ { tmat . a , tmat . b , tmat . c } ] } , Lighting False ]

[Graphics:HTMLFiles/Lecture-07_27.gif]

Out[167]=

Graphics3D

The program seetrans does the same thing by feeding a matrix tranmat to operate on the vertex vectors before Polygon is executed:

In[168]:=

seetrans [ tranmat_ ] := Show [ coloct /. { Polygon [ { a_List , b_List , c_List } ] Polygon [ { tranmat . a , tranmat . b , tranmat . c } ] } , Lighting False ]

When tranmat is the identity matrix, the octagon is rendered in its initial orientation.

In[169]:=

seetrans [ { { 1 , 0 , 0 } , { 0 , 1 , 0 } , { 0 , 0 , 1 } } ]

[Graphics:HTMLFiles/Lecture-07_28.gif]

Out[169]=

Graphics3D

The next command rotates the octagon by 45° about the vertical (z) axis…

In[170]:=

seetrans [ { { Cos [ Pi / 4 ] , Sin [ Pi / 4 ] , 0 } , { Sin [ - Pi / 4 ] , Cos [ Pi / 4 ] , 0 } , { 0 , 0 , 1 } } ]

[Graphics:HTMLFiles/Lecture-07_29.gif]

Out[170]=

Graphics3D

And the next command both rotates it 180° about x and y and stretches it by a factor of 5 along z.

In[171]:=

seetrans [ { { - 1 , 0 , 0 } , { 0 , - 1 , 0 } , { 0 , 0 , 5 } } ]

[Graphics:HTMLFiles/Lecture-07_30.gif]

Out[171]=

Graphics3D


Created by Mathematica  (September 23, 2005) Valid XHTML 1.1!