Differentiation With wxMaxima
1 Basic Introduction
The command to differentiate any expression in Maxima is diff() and it has the following syntax:
diff(expression, variable, [order-of-derivative (only if greater than 1)])
So let's say we want to take the first three derivatives of an 3 sin(x):
--> | diff(3*sin(x),x); |
--> | diff(3*sin(x),x,2); |
--> | diff(3*sin(x),x,3); |
If we have already defined a function f(x), then we can differentiate using the f(x) symbol:
(%i5) |
f(x):=3*sin(x)$ diff(f(x),x); diff(f(x),x,2); diff(f(x),x,3); |
NOTE: We cannot omit the (x) in the expression f(x), since:
(%i6) | diff(f,x); |
Maxima thinks that you want the derivative of the symbolic expression f, which has no x dependence,
and therefore yields 0 upon differentiation.
The ev(,nouns) trick works with diff() too:
(%i9) |
f(x):=3*x^2*tan(5*x^2)$ D:'diff(f(x),x,2)$ D=ev(D,nouns); |
2 Catching the Output in a New Function
Let's say we want to differentiate a function and then find where its derivative is zero, and also we want to calculate some values of the derivative. We need to be able to "catch" the derivative of that function as a new function. Here's how we do that:
(%i10) | f(x):= sqrt(x)*exp(x^2+2*x); |
(%i11) | define(fp(x),diff(f(x),x)); |
While this is a little ungainly, most all CASes (like Mathematica and Maple) do this.
So why can't we just define g(x) := diff(f(x),x)? Let's try it:
(%i13) | f(x); g(x):=diff(f(x),x); |
(%i14) | g(x); |
Wait... that looks pretty good. Infact, there doesn't seem to be anything wrong, until we ask a very simple question:
(%i15) | g(1); |
Ahk! What happend is that with g(x):=diff(f(x),x) when we ask for g(1)
Maxima interprets this as: diff(f(1),1) and since the second argument of the diff() command must be a variable,
the request fails. So, the correct syntax is:
(%i19) | define(g(x),diff(f(x),x))$ g(1); |
3 Graphing derivatives
Now that we can catch derivatives in their own functions, we can do all the usual things we would like to with them.
For example, we could graph them along side their functions:
(%i22) | f(x):=sin(x);define(g(x),diff(f(x),x)); define(h(x),diff(f(x),x,2)); |
(%i23) | wxplot2d([f(x),g(x),h(x)],[x,0,2*%pi],[legend,"sin(x)","Derivative", "Second Derivative"]); |
(%i24) | kill(all); |
Let's try another example in which we plot the first three derivatives of:
(%i2) | f(x):=sqrt(cos(x)+2); |
(%i7) | define(g(x),diff(f(x),x)); define(h(x),diff(f(x),x,2));define(i(x),diff(f(x),x,3)); |
(%i8) |
wxplot2d([f(x),g(x),h(x),i(x)], [x,-%pi,%pi], [legend,"Function","d1","d2","d3"], [title, "Three Derivatives of A Function"]); |
(%i9) | kill(all); |
3.1 A Streamlined Way to Get Higher Order Derivatives
A different way to get higher order derivatives is built on exploiting a feature of
the programming language that Maxima is built on. Lisp (the programming language) allows
a user to define an array (or list of objects) based on a rule or algorithm. This is
miles away from C/C++, but it allows us a tremendous amount of flexibility. We'll start an empty list:
(%i37) | f=[]; |
Now, at the 0th position, we'll put the function we want to differentiate:
(%i38) | f[0](x):=x*cos(exp(x+1)); |
O.k., so here's the magic, we will define the nth element of the list to be the nth derivative of the
0th element!
(%i39) | define(f[n](x),diff(f[0](x),x,n)); |
Now, let's do some differentiating!
(%i43) | f[0](x);f[1](x);f[2](x);f[3](x); |
Wait! Stop! While symbolically that's right, that's not very useful! We want the actual expanded out expressions! Let's get one using the ev() command. The issue is that the recursion in the definition is at the symbolic level, and we need to force
the evaluation of the diff operator!
(%i44) | ev(f[1](x),diff); |
(%i45) | ev(f[2](x),diff); |
There's no reason to go in order!
(%i47) | ev(f[6](x),diff); |
We are still stuck with the issue of not having an easy to use function for, say, the 4th or 8th derivative. Here is where define() comes to the rescue!
(%i54) |
define(g[4](x),ev(f[4](x),diff))$ define(g[10](x),ev(f[10](x),diff))$ |
And now we can compute away!
(%i52) | ratsimp(g[4](log(%pi)-1)); |
(%i55) | ratsimp(g[10](log(%pi)-1)); |
(%i56) | kill(all); |
4 Getting Numerical Values
What if you want a decimal approximation for your derivatives? We simply wrap the exact value in a float() command:
(%i1) | f(x):=3*cos(3*x^2 - exp(sqrt(x))); |
(%i2) | define(g(x),diff(f(x),x)); |
(%i3) | g(2); |
(%i4) | float(g(2)); |
If you are only going to be asking for one value from the derivative, then it may be faster to simply substitute it
directly as a float value:
(%i5) | f(x):=(x-1)*exp(-x/2); |
(%i7) | subst(x=2, diff(f(x),x));subst(x=2.0,diff(f(x),x)); |
If you are going to be asking for alot of decimal output from your functions, it might be a good
idea to force the float() command into the definition:
(%i8) | f(x); |
(%i9) | define(g(x),float(diff(f(x),x))); |
(%i12) | g(1);g(2);g(3/2); |