
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.
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.
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]
Mathematica provides two generalpurpose 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 floatingpoint coefficients, we get floatingpoint 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.
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.
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 lefthandside 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 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,
StyleBox[{MatrixForm[v + v], MatrixForm[m + m]}, ShowStringCharacters > True]
matrix multiplication,
StyleBox[{MatrixForm[m . m], MatrixForm[m . v]}, ShowStringCharacters > True]
and dot product
MatrixForm[v . v]
We can transpose
MatrixForm[Transpose[m]]
or invert
StyleBox[{minverse = Inverse[m], MatrixForm[m . minverse]}, ShowStringCharacters > True]
Much more is possible. Consult the online documentation for pointers.