Symbolic Computation

This notebook is designed to accompany Chapter 6 of Introduction to Scientific Programming: Computational Problem Solving Using Mathematica and C by Joseph L. Zachary.  In it we will explore the idea of symblic computing further.

Introduction

Chapter 6 only hints at the support for symbolic mathematics provided by Mathematica.  In this notebook we will explore this support in more depth.  The material that we will be covering here requires varying levels of mathematical expertise.  Feel free to skip over examples if you don't have the necessary background.

Algebraic simplification

Mathematica's "Simplify" function expects an expression as a parameter, which it simplifies.  For example, notice the difference between

Sin[x]^2  +  Cos[x]^2

and

Simplify[Sin[x]^2  +  Cos[x]^2]

Equation solving

Mathematica provides two general-purpose functions for solving equations, Solve and FindRoot.  Solve works symbolically much as you do when solving equations; FindRoot works numerically by repeatedly guessing at a solution until it finds one that works.  Solve is exact, FindRoot is approximate.  For complicated equations, Solve can be much slower than FindRoot.  In fact, there are plenty of equations where Solve fails but FindRoot succeeds.

Solve knows all kinds of tricks for solving equations.  For example, it knows the quadratic formula

Solve[3*x^2  -  10*x  +  6  ==  0,  x]

With floating-point coefficients, we get floating-point solutions.

Solve[3.*x^2  -  10.*x  +  6.  ==  0,  x]

Complex roots are also possible

Solve[3*x^2  -  4*x  +  6  ==  0,  x]

The coefficients can be entirely symbolic.

Solve[a*x^2  +  b*x  +  c  ==  0,  x]

Mathematica can also solve simultaneous linear equations.  Notice how list notation is used here.

Solve[{3*x  +  4*y  ==  7,  5*x  +  3*y  ==  11},  {x, y}]

The equations don't have to be linear.

Solve[{3*x^2  +  y  ==  7,  5*x  +  3*y  ==  11},  {x, y}]

It is not difficult to pose an equation that solve cannot deal with.

Solve[3*Cos[x] ==  x,  x]

If you don't need an exact or a symbolic solution, FindRoot can solve more equations and is generally faster.

FindRoot[3*Cos[x]  ==  x,  {x, 0}]

Of course, if you forget and pose a symbolic equation

FindRoot[a*cos[x]  ==  x,  {x, 0}]

you'll get an error message.

Calculus

Mathematica is also handy for doing calculus.  The D function does symbolic differentiation

D[Cos[Sin[x]],  x]

whereas the Integrate function does symbolic integration

Integrate[-Sin[Sin[x]]*Cos[x],  x]

You can also do definite integration by providing bounds

Integrate[-Sin[Sin[x]]*Cos[x],  {x, 0, Pi/2.}]

It is not difficult to stump Mathematica.

Integrate[Cos[Sin[x]],  x]

and this is how it tells you that it has failed.  In situations like this, trying to do a definite integral as above may be futile as well.

Integrate[Cos[Sin[x]],  {x, 0, Pi/2.}]

In this case, if you "NIntegrate" instead, Mathematica will do a numerical integration.  This means that instead of first integration symbolically and then plugging in the bounds, it will find an approximation to the integral without first computing the definite integral.

NIntegrate[Cos[Sin[x]],  {x, 0, Pi/2.}]

It is possible to supply infinity and -infinity as bounds.  Thus

Integrate[1/x, {x, 0, Infinity}]

diverges, whereas

Integrate[1/Exp[x],  {x, 0, Infinity}]

gives us a finite answer.

Replacements

Another handy feature of Mathematica is the ability to perform substitutions.  Let's suppose that we solve an equation numerically

soln  =  FindRoot[Cos[x] == x,  {x, 0}]

We can substitute the value of soln for x in the left-hand-side of the equation by doing

ReplaceAll[Cos[x],  soln]

This works for any kind of expression.  For example, suppose we differentiate

res  =  D[Exp[Cos[x]],  x]

and we'd like to find out the value of res when x is 1.2.  We can do that with

ReplaceAll[res,  {x -> 1.2}]

When an equation has multiple solutions, it is possible to pick them out individually.  Thus

solns  =  Solve[3.15*x^2  -  24.2*x  +  15  ==  0,  x]

We can access the first of the two solutions as

solns[[1]]

and the second of the two solutions as

solns[[2]]

Vectors and matrices

Vectors and matrices are used extensively in linear algebra.  Mathematica will do all of the standard operations on them.

Now we can define a vector with

v  =  {1, 2, 3}

We can ask Mathematica to display the vector using more standard notation by using the function "MatrixForm".

MatrixForm[v]

We can define a 3x3 matrix with

m  =  {{1, 2, 3}, {4, 5, 4}, {3, 2, 1}}

and display it with

MatrixForm[m]

Let's do some operations on vectors and matrices.  We can do addition,

MatrixForm[v + v]MatrixForm[m + m]

matrix multiplication,

MatrixForm[m.m]MatrixForm[m.v]

and dot product

MatrixForm[v . v]

We can transpose

MatrixForm[Transpose[m]]

or invert

minverse  =  Inverse[m]MatrixForm[m . minverse]

Much more is possible. Consult the on-line documentation for pointers.