|
This worksheet is designed to accompany Chapter 6 of Introduction to Scientific Programming: Computational Problem Solving Using Maple and C by Joseph L. Zachary. In it we will explore the idea of symbolic computing further.
Chapter 6 only hints at the support for symbolic mathematics provided by Maple. In this worksheet, we will explore this support in somewhat more depth. The material that we will be covering requires varying levels of mathematical expertise. Feel free to skip over examples if you don't have the necessary background.
Maple'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);
Be aware that Maple will sometimes make unstated assumptions when doing simplification. For example, compare
> 16^(3/2);
and
> simplify(16^(3/2));
in which Maple has assumed that you want the positive square root.
Maple provides two general-purpose functions for solving equations, "solve" and "fsolve". "solve" works symbolically much as you do when solving equations; "fsolve" works numerically by repeatedly guessing at a solution until it finds one that works. "solve" is exact, "fsolve" is approximate. For complicated equations, "solve" can be much slower than "fsolve". In fact, there are plenty of equations where "solve" fails but "fsolve" 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);
Maple can also solve simultaneous linear equations. Notice how set 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});
Maple tries to keep the answer simple by using the RootOf notation. If we had used floating-point coefficients
> solve({3.*x^2 + y = 7., 5.*x + 3.*y = 11}, {x,y});
this wouldn't have been necessary.
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, fsolve can solve more equations and is generally faster.
> fsolve(3*cos(x) = x, x);
Of course, if you forget and pose a symbolic equation
> fsolve(a*cos(x) = x, x);
you'll get an error message.
Maple is also handy for doing calculus. The "diff" function does symbolic differentiation
> diff(cos(sin(x)), x);
whereas the "int" function does symbolic integration
> int(-sin(sin(x))*cos(x), x);
You can also do definite integration by providing bounds
> int(-sin(sin(x))*cos(x), x=0..Pi/2.);
It is not difficult to stump Maple.
> int(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.
> int(cos(sin(x)), x=0..Pi/2.);
In this case, if you wrap a call to "evalf" around the call to int, Maple 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.
> evalf(int(cos(sin(x)), x=0..Pi/2));
It is possible to supply infinity and -infinity as bounds. Thus
> int(1/x, x=0..infinity);
gives us an answer of infinity, whereas
> int(1/exp(x), x=0..infinity);
gives us a finite answer.
Another handy feature of Maple is the ability to perform substitutions. Let's suppose that we define an equation
> eqn := cos(x) = x;
which we then solve numerically.
> soln := fsolve(eqn, x);
We can substitute the value of soln for x in the original equation by doing
> evalf(subs(x=soln, eqn));
This works for any kind of expression-not just for equations. For example, suppose we differentiate
> res := diff(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
> evalf(subs(x=1.2, res));
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. Maple will do all of the standard operations upon them. The first step is to make the linear algebra functions visible with
> with(linalg);
Now we can define a vector with
> v := vector([1,2,3]);
and a 3x3 matrix with
> m := matrix(3, 3, [1,2,3,4,5,4,3,2,1]);
Let's do some operations on them. We can do addition,
> matadd(v, v);
> matadd(m, m);
multiplication,
> multiply(m, m);
> multiply(m, v);
and dot product.
> dotprod(v, v);
We can transpose
> transpose(m);
or invert.
> minverse := inverse(m);
> multiply(m, minverse);
Much more is possible. Do
> ?linalg
for pointers.