%-*-EMaxima-*-

%Definitions to help mactex output look better.

\beginmaximanoshow
texput(%hbar,"\\hbar")$
texput(%me,"m_e")$
texput(%mp,"m_p")$
texput(%c,"c")$
texput(%%e,"e")$
texput(%mue,"\\mu_e")$
texput(%mup,"\\mu_p")$
texput(%g,"G")$
texput(LAMBDA,"\\lambda")$
linenum : 0$
\maximaoutput




















\endmaximanoshow

\noindent Author: 

   Barton Willis 
   
   University of Nebraska at Kearney 
   
   Kearney Nebraska

\vspace{2ex}

\noindent Documentation adapted for the Maxima Book by CY

\subsection*{Introduction}

\noindent  Working with derivatives of unknown functions\footnote{By
{\em unknown  function\/}, we mean a function that isn't bound to a formula and
that has a derivative that isn't known to Maxima.} can be  cumbersome in Maxima.
If we want, for example, the first order  Taylor polynomial of 
$f(x + x^2)$ about $x = 1$, we get

\beginmaximasession
taylor(f(x + x^2),x,1,1);
\maximatexsession
\C1.  taylor(f(x + x^2),x,1,1); \\
\D1.  f\left(2\right)+\left(\left.\frac{d}{d\*x}\*f\left(x^{2}+x\right)\right|_{x=1}\right)\*\left(x-1\right)+\cdots \\
\endmaximasession

\noindent To ``simplify'' the Taylor polynomial, we must assign a gradient to $f$ 

\beginmaximasession
gradef(f(x),df(x))$
taylor(f(x+x^2),x,1,1);
\maximatexsession
\C2.  gradef(f(x),df(x))$ \\
\C3.  taylor(f(x+x^2),x,1,1); \\
\D3.  f\left(2\right)+3\*\mathrm{df}\left(2\right)\*\left(x-1\right)+\cdots \\
\endmaximasession

This method works well for simple problems, but it 
is tedious for functions of several variables or high order
derivatives. The positional derivative package {\tt pdiff} gives 
an alternative to using {\tt gradef} when working with derivatives 
of unknown functions.

\subsection*{Usage}

To use the positional derivative package, you must load it from
a Maxima prompt.  Assuming {\tt pdiff.lisp} is in a directory that 
Maxima can find, this is done with the command

\beginmaximasession
kill(all)$
load("pdiff.lisp")$
\maximatexsession
\C4.  kill(all)$ \\
\C1.  load("pdiff.lisp")$ \\
\endmaximasession

\noindent Use the full pathname if Maxima can't find the file. Note that
the {\tt kill(all)} is needed because the gradef definition will
conflict with the proper functioning of the diff commands. Loading 
{\tt pdiff.lisp} sets the option variable {\tt use\_pdiff} to true; 
when {\tt use\_diff} is true, Maxima will 
indicate derivatives of  unknown functions positionally. To illustrate, 
the first three  derivatives of $f$ are

\beginmaximasession
[diff(f(x),x),
  diff(f(x),x,2),
  diff(f(x),x,3)];
\maximatexsession
\C2.  [diff(f(x),x),
  diff(f(x),x,2),
  diff(f(x),x,3)]; \\
\D2.  \left[ f_{\left(1\right)}(x),f_{\left(2\right)}(x),f_{\left(3\right)}(x) \right] \\
\endmaximasession

The subscript indicates the order of the derivative;  since $f$ is a function of 
one variable, the subscript has only one index.  When a function has more 
than one variable, the subscript has an index for each variable

\beginmaximasession
[diff(f(x,y),x,0,y,1), diff(f(y,x),x,0,y,1)];
\maximatexsession
\C3.  [diff(f(x,y),x,0,y,1), diff(f(y,x),x,0,y,1)]; \\
\D3.  \left[ f_{\left(0,1\right)}(x,y),f_{\left(1,0\right)}(y,x) \right] \\
\endmaximasession

\noindent Setting {\tt use\_pdiff} to false  (either locally or globally) inhibits derivatives from begin computed positionally

\beginmaximasession
diff(f(x,x^2),x), use_pdiff : false;
diff(f(x,x^2),x), use_pdiff : true;
\maximatexsession
\C4.  diff(f(x,x^2),x), use_pdiff : false; \\
\D4.  {{d}\over{d\,x}}\,f\left(x,x^2\right) \\
\C5.  diff(f(x,x^2),x), use_pdiff : true; \\
\D5.  f_{\left(1,0\right)}(x,x^2)+2\,x\,f_{\left(0,1\right)}(x,x^2) \\
\endmaximasession

Taylor polynomials of unknown functions can be found without using
{\tt gradef}. An example

\beginmaximasession
taylor(f(x+x^2),x,1,2);
\maximatexsession
\C6.  taylor(f(x+x^2),x,1,2); \\
\D6.  f\left(2\right)+3\,f_{\left(1\right)}(2)\,\left(x-1\right)+{{\left(2\,f_{\left(1\right)}(2)+9\,f_{\left(2\right)}(2)\right)\,\left(x-1\right)^2}\over{2}}+\cdots \\
\endmaximasession

\noindent Additionally, we can verify that $ y = f(x-c \, t) + g(x+c \,t)$ is
a solution to a wave equation without using {\tt gradef}

\beginmaximasession
y : f(x-c*t) + g(x+c*t)$
ratsimp(diff(y,t,2) - c^2 * diff(y,x,2));
remvalue(y)$
\maximatexsession
\C7.  y : f(x-c*t) + g(x+c*t)$ \\
\C8.  ratsimp(diff(y,t,2) - c^2 * diff(y,x,2)); \\
\D8.  0 \\
\C9.  remvalue(y)$ \\
\endmaximasession

\noindent Expressions involving  positional derivatives can be differentiated

\beginmaximasession
e : diff(f(x,y),x);
diff(e,y);
\maximatexsession
\C10.  e : diff(f(x,y),x); \\
\D10.  f_{\left(1,0\right)}(x,y) \\
\C11.  diff(e,y); \\
\D11.  f_{\left(1,1\right)}(x,y) \\
\endmaximasession

\noindent The chain rule is applied when needed

\beginmaximasession
[diff(f(x^2),x), diff(f(g(x)),x)];
\maximatexsession
\C12.  [diff(f(x^2),x), diff(f(g(x)),x)]; \\
\D12.  \left[ 2\,x\,f_{\left(1\right)}(x^2),g_{\left(1\right)}(x)\,f_{\left(1\right)}(g\left(x\right)) \right] \\
\endmaximasession

The positional derivative package doesn't alter the way known functions
are differentiated

\beginmaximasession
diff(exp(-x^2),x);
\maximatexsession
\C13.  diff(exp(-x^2),x); \\
\D13.  -2\,x\,e^ {- x^2 } \\
\endmaximasession

\noindent To convert positional derivatives to standard Maxima derivatives,
use {\tt convert\_to\_diff}

\beginmaximasession
e : [diff(f(x),x), diff(f(x,y),x,1,y,1)];
e : convert_to_diff(e);
\maximatexsession
\C14.  e : [diff(f(x),x), diff(f(x,y),x,1,y,1)]; \\
\D14.  \left[ f_{\left(1\right)}(x),f_{\left(1,1\right)}(x,y) \right] \\
\C15.  e : convert_to_diff(e); \\
\D15.  \left[ {{d}\over{d\,x}}\,f\left(x\right),{{d^2}\over{d\,y\,d\,x}}\,f\left(x,y\right) \right] \\
\endmaximasession

\noindent To convert back to a positional derivative, use {\tt ev} with {\tt diff} as an argument

\beginmaximasession
ev(e,diff);
\maximatexsession
\C16.  ev(e,diff); \\
\D16.  \left[ f_{\left(1\right)}(x),f_{\left(1,1\right)}(x,y) \right] \\
\endmaximasession

\noindent Conversion to standard derivatives  sometimes requires the 
introduction of  a dummy variable. Here's an example

\beginmaximasession
e : diff(f(x,y),x,1,y,1);
e : subst(p(s),y,e);
e : convert_to_diff(e);
\maximatexsession
\C17.  e : diff(f(x,y),x,1,y,1); \\
\D17.  f_{\left(1,1\right)}(x,y) \\
\C18.  e : subst(p(s),y,e); \\
\D18.  f_{\left(1,1\right)}(x,p\left(s\right)) \\
\C19.  e : convert_to_diff(e); \\
\D19.  \left.{{d^2}\over{d\,%x_0\,d\,x}}\,f\left(x,%x_0\right)\right|_{\left[ %x_0=p\left(s\right) \right] } \\
\endmaximasession

Dummy variables have the form ci, where i=0,1,2\dots and c is the 
value of the option variable {\tt dummy\_char}. The default value
for {\tt dummy\_char} is {\tt \%x}. If a user variable conflicts with a 
dummy variable,  the conversion process can give an 
incorrect value. To convert the previous expression back to a positional derivative, use {\tt ev} with {\tt diff} and {\tt at} as arguments

\beginmaximasession
ev(e,diff,at);
\maximatexsession
\C20.  ev(e,diff,at); \\
\D20.  f_{\left(1,1\right)}(x,p\left(s\right)) \\
\endmaximasession

Maxima correctly evaluates expressions involving positional derivatives 
if a formula is  later given to the function.  (Thus converting an unknown 
function into a known one.)  Here is an example;  let

\beginmaximasession
e : diff(f(x^2),x);
\maximatexsession
\C21.  e : diff(f(x^2),x); \\
\D21.  2\,x\,f_{\left(1\right)}(x^2) \\
\endmaximasession

\noindent Now, give $f$ a formula

\beginmaximasession
f(x) := x^5;
\maximatexsession
\C22.  f(x) := x^5; \\
\D22.  f\left(x\right):=x^5 \\
\endmaximasession

\noindent and evaluate {\tt e}

\beginmaximasession
ev(e);
\maximatexsession
\C23.  ev(e); \\
\D23.  10\,x^9 \\
\endmaximasession

\noindent This result is the same as  

\beginmaximasession
diff(f(x^2),x);
\maximatexsession
\C24.  diff(f(x^2),x); \\
\D24.  10\,x^9 \\
\endmaximasession

\noindent In this calculation, Maxima first evaluates $f(x)$ to $x^{10}$ and then does the derivative.  Additionally, we can substitute a value for $x$ 
before evaluating

\beginmaximasession
ev(subst(2,x,e));
\maximatexsession
\C25.  ev(subst(2,x,e)); \\
\D25.  5120 \\
\endmaximasession

\noindent We can duplicate this with

\beginmaximasession
subst(2,x,diff(f(x^2),x));
remfunction(f);
\maximatexsession
\C26.  subst(2,x,diff(f(x^2),x)); \\
\D26.  5120 \\
\C27.  remfunction(f); \\
\D27.  \left[ f \right] \\
\endmaximasession

\noindent We can also evaluate a positional derivative using a local 
function definition

\beginmaximasession
e : diff(g(x),x);
e, g(x) := sqrt(x);
e, g = sqrt; 
e, g = h; 
e, g = lambda([t],t^2);
\maximatexsession
\C28.  e : diff(g(x),x); \\
\D28.  g_{\left(1\right)}(x) \\
\C29.  e, g(x) := sqrt(x); \\
\D29.  {{1}\over{2\,\sqrt{x}}} \\
\C30.  e, g = sqrt; \\
\D30.  {{1}\over{2\,\sqrt{x}}} \\
\C31.  e, g = h; \\
\D31.  h_{\left(1\right)}(x) \\
\C32.  e, g = lambda([t],t^2); \\
\D32.  2\,x \\
\endmaximasession

\subsection*{The {\tt pderivop} function}

If $F$ is an atom and $i_1, i_2, \dots i_n$ are nonnegative
integers, then $ \mbox{pderivop}(F,i_1,i_2, \dots i_n)$, is the 
function that has the formula 
\[
   \frac{\partial^{i_1 + i_2 + \cdots + i_n}}{\partial x_1^{i_1} 
     \partial x_2^{i_2}  \cdots \partial x_n^{i_n}} F(x_1,x_2, \dots x_n). 
\]
If any of the derivative arguments are not nonnegative integers,
we'll get an error

\beginmaximasession
pderivop(f,2,-1);
\maximatexsession
\C33.  pderivop(f,2,-1); \\
\p
Each derivative order must be a nonnegative integer
 -- an error.  Quitting.  To debug this try DEBUGMODE(TRUE);) \\
\endmaximasession

\noindent The {\tt pderivop} function can be composed with itself

\beginmaximasession
pderivop(pderivop(f,3,4),1,2);
\maximatexsession
\C34.  pderivop(pderivop(f,3,4),1,2); \\
\D34.  f_{\left(4,6\right)} \\
\endmaximasession

\noindent If the number of derivative arguments between two calls 
to {\tt pderivop} isn't the same, Maxima gives an error

\beginmaximasession
pderivop(pderivop(f,3,4),1);
\maximatexsession
\C35.  pderivop(pderivop(f,3,4),1); \\
\p
The function f expected 2 derivative argument(s), but it received 1
 -- an error.  Quitting.  To debug this try DEBUGMODE(TRUE);) \\
\endmaximasession

When {\tt pderivop} is applied to a known function, the result is
a lambda form\footnote{If you repeat theses calculations, you 
may get a different prefix for the {\tt gensym} variables.}

\beginmaximasession
f(x) := x^2;
df : pderivop(f,1);
apply(df,[z]);
ddf : pderivop(f,2);
apply(ddf,[10]);
remfunction(f);
\maximatexsession
\C36.  f(x) := x^2; \\
\D36.  f\left(x\right):=x^2 \\
\C37.  df : pderivop(f,1); \\
\D37.  \lambda\left(\left[ G_{2491} \right] ,2\,G_{2491}\right) \\
\C38.  apply(df,[z]); \\
\D38.  2\,z \\
\C39.  ddf : pderivop(f,2); \\
\D39.  \lambda\left(\left[ G_{2492} \right] ,2\right) \\
\C40.  apply(ddf,[10]); \\
\D40.  2 \\
\C41.  remfunction(f); \\
\D41.  \left[ f \right] \\
\endmaximasession

If the first argument to {\tt pderivop} is a lambda form, the
result is another lambda form

\beginmaximasession
f : pderivop(lambda([x],x^2),1);
apply(f,[a]);
f : pderivop(lambda([x],x^2),2);
apply(f,[a]);
f : pderivop(lambda([x],x^2),3);
apply(f,[a]);
remvalue(f)$
\maximatexsession
\C42.  f : pderivop(lambda([x],x^2),1); \\
\D42.  \lambda\left(\left[ G_{2493} \right] ,2\,G_{2493}\right) \\
\C43.  apply(f,[a]); \\
\D43.  2\,a \\
\C44.  f : pderivop(lambda([x],x^2),2); \\
\D44.  \lambda\left(\left[ G_{2494} \right] ,2\right) \\
\C45.  apply(f,[a]); \\
\D45.  2 \\
\C46.  f : pderivop(lambda([x],x^2),3); \\
\D46.  \lambda\left(\left[ G_{2495} \right] ,0\right) \\
\C47.  apply(f,[a]); \\
\D47.  0 \\
\C48.  remvalue(f)$ \\
\endmaximasession

If the first argument to {\tt pderivop} isn't an atom or
a lambda form, Maxima will signal an error 

\beginmaximasession
pderivop(f+g,1);
\maximatexsession
\C49.  pderivop(f+g,1); \\
\p
Non-atom g+f used as a function
 -- an error.  Quitting.  To debug this try DEBUGMODE(TRUE);) \\
\endmaximasession

You may use {\tt tellsimpafter} together with {\tt pderivop} to 
give a value to a derivative of a function at a point; an
example

\beginmaximasession
tellsimpafter(pderivop(f,1)(1),1)$
tellsimpafter(pderivop(f,2)(1),2)$
diff(f(x),x,2) + diff(f(x),x)$
subst(1,x,%);
\maximatexsession
\C50.  tellsimpafter(pderivop(f,1)(1),1)$ \\
\C51.  tellsimpafter(pderivop(f,2)(1),2)$ \\
\C52.  diff(f(x),x,2) + diff(f(x),x)$ \\
\C53.  subst(1,x,%); \\
\D53.  3 \\
\endmaximasession

This technique works for functions of several variables as well

\beginmaximasession
kill(rules)$
tellsimpafter(pderivop(f,1,0)(0,0),a)$
tellsimpafter(pderivop(f,0,1)(0,0),b)$
sublis([x = 0, y = 0], diff(f(x,y),x) + diff(f(x,y),y));
\maximatexsession
\C54.  kill(rules)$ \\
\C55.  tellsimpafter(pderivop(f,1,0)(0,0),a)$ \\
\C56.  tellsimpafter(pderivop(f,0,1)(0,0),b)$ \\
\C57.  sublis([x = 0, y = 0], diff(f(x,y),x) + diff(f(x,y),y)); \\
\D57.  b+a \\
\endmaximasession

\subsection*{\TeX{}-ing positional derivatives}

Several option variables control how positional derivatives
are converted to \TeX{}. When the option variable
{\tt tex\_uses\_prime\_for\_derivatives} is true (default false), 
makes functions of one variable \TeX{} as superscripted primes

\beginmaximasession
tex_uses_prime_for_derivatives : true$
tex(makelist(diff(f(x),x,i),i,1,3))$
tex(makelist(pderivop(f,i),i,1,3))$
\maximatexsession
\C58.  tex_uses_prime_for_derivatives : true$ \\
\C59.  tex(makelist(diff(f(x),x,i),i,1,3))$ \\
$$\left[ f^{\prime}(x),f^{\prime\prime}(x),f^{\prime\prime\prime}(x)
  \right] $$
\C60.  tex(makelist(pderivop(f,i),i,1,3))$ \\
$$\left[ f^{\prime},f^{\prime\prime},f^{\prime\prime\prime} \right] $$
\endmaximasession

When the derivative order exceeds the value of the option
variable {\tt tex\_prime\_limit}, (default 3) 
derivatives are indicated with parenthesis delimited superscripts

\beginmaximasession
tex(makelist(pderivop(f,i),i,1,5)), tex_prime_limit : 0$
tex(makelist(pderivop(f,i),i,1,5)), tex_prime_limit : 5$
\maximatexsession
\C61.  tex(makelist(pderivop(f,i),i,1,5)), tex_prime_limit : 0$ \\
$$\left[ f^{(1)},f^{(2)},f^{(3)},f^{(4)},f^{(5)} \right] $$
\C62.  tex(makelist(pderivop(f,i),i,1,5)), tex_prime_limit : 5$ \\
$$\left[ f^{\prime},f^{\prime\prime},f^{\prime\prime\prime},f^{\prime
 \prime\prime\prime},f^{\prime\prime\prime\prime\prime} \right] $$
\endmaximasession

The value of {\tt tex\_uses\_prime\_for\_derivatives} doesn't change the way 
functions of two or more variables are converted to \TeX{}.

\beginmaximasession
tex(pderivop(f,2,1))$
\maximatexsession
\C63.  tex(pderivop(f,2,1))$ \\
$$f_{\left(2,1\right)}$$
\endmaximasession

When the option variable {\tt tex\_uses\_named\_subscripts\_for\_derivatives}
(default false) is true, a derivative with respect to the i-th argument is 
indicated by a subscript that is the i-th element of the option variable
{\tt tex\_diff\_var\_names}.  An example is the clearest way to 
describe this.

\beginmaximasession
tex_uses_named_subscripts_for_derivatives : true$
tex_diff_var_names;
tex([pderivop(f,1,0), pderivop(f,0,1), pderivop(f,1,1), pderivop(f,2,0)])$
tex_diff_var_names : [a,b];
tex([pderivop(f,1,0), pderivop(f,0,1), pderivop(f,1,1), pderivop(f,2,0)])$
tex_diff_var_names : [x,y,z];
tex([diff(f(x,y),x), diff(f(y,x),y)])$
\maximatexsession
\C64.  tex_uses_named_subscripts_for_derivatives : true$ \\
\C65.  tex_diff_var_names; \\
\D65.  \left[ x,y,z \right] \\
\C66.  tex([pderivop(f,1,0), pderivop(f,0,1), pderivop(f,1,1), pderivop(f,2,0)])$ \\
$$\left[ f_{x},f_{y},f_{xy},f_{xx} \right] $$
\C67.  tex_diff_var_names : [a,b]; \\
\D67.  \left[ a,b \right] \\
\C68.  tex([pderivop(f,1,0), pderivop(f,0,1), pderivop(f,1,1), pderivop(f,2,0)])$ \\
$$\left[ f_{a},f_{b},f_{ab},f_{aa} \right] $$
\C69.  tex_diff_var_names : [x,y,z]; \\
\D69.  \left[ x,y,z \right] \\
\C70.  tex([diff(f(x,y),x), diff(f(y,x),y)])$ \\
$$\left[ f_{x}(x,y),f_{x}(y,x) \right] $$
\endmaximasession

When the derivative order exceeds {tt tex\_prime\_limit}, revert to the default
method for converting to \TeX{}

\beginmaximasession
tex(diff(f(x,y,z),x,1,y,1,z,1)), tex_prime_limit : 4$
tex(diff(f(x,y,z),x,1,y,1,z,1)), tex_prime_limit : 1$
\maximatexsession
\C71.  tex(diff(f(x,y,z),x,1,y,1,z,1)), tex_prime_limit : 4$ \\
$$f_{xyz}(x,y,z)$$
\C72.  tex(diff(f(x,y,z),x,1,y,1,z,1)), tex_prime_limit : 1$ \\
$$f_{\left(1,1,1\right)}(x,y,z)$$
\endmaximasession

\subsection*{A longer example}

We'll use the positional derivative package to change the independent
variable of the differential equation

\beginmaximasession
de :  4*x^2*'DIFF(y,x,2) + 4*x*'DIFF(y,x,1) + (x-1)*y = 0;
\maximatexsession
\C73.  de :  4*x^2*'DIFF(y,x,2) + 4*x*'DIFF(y,x,1) + (x-1)*y = 0; \\
\D73.  4\,x^2\,\left({{d^2}\over{d\,x^2}}\,y\right)+4\,x\,\left({{d}\over{d\,x}}\,y\right)+\left(x-1\right)\,y=0 \\
\endmaximasession

With malice aforethought, we'll assume a solution of the form
$ y = g(x^n)$, where $n$ is a number.  Substituting $y \rightarrow g(x^n)$
in the  differential equation  gives

\beginmaximasession
de : subst(g(x^n),y,de);
de : ev(de, diff);
\maximatexsession
\C74.  de : subst(g(x^n),y,de); \\
\D74.  4\,x^2\,\left({{d^2}\over{d\,x^2}}\,g\left(x^{n}\right)\right)+4\,x\,\left({{d}\over{d\,x}}\,g\left(x^{n}\right)\right)+\left(x-1\right)\,g\left(x^{n}\right)=0 \\
\C75.  de : ev(de, diff); \\
\D75.  4\,x^2\,\left(n^2\,x^{2\,n-2}\,g^{\prime\prime}(x^{n})+\left(n-1\right)\,n\,x^{n-2}\,g^{\prime}(x^{n})\right)+4\,n\,x^{n}\,g^{\prime}(x^{n})+\left(x-1\right)\,g\left(x^{n}\right)=0 \\
\endmaximasession

Now let $x \rightarrow t^{1/n}$

\beginmaximasession
de : radcan(subst(x^(1/n),x, de));
\maximatexsession
\C76.  de : radcan(subst(x^(1/n),x, de)); \\
\D76.  4\,n^2\,x^2\,g^{\prime\prime}(x)+4\,n^2\,x\,g^{\prime}(x)+\left(x^{{{1}\over{n}}}-1\right)\,g\left(x\right)=0 \\
\endmaximasession

Setting $n \rightarrow 1/2$, we recognize that $g$ is the order 1 Bessel
equation

\beginmaximasession
subst(1/2,n, de);
\maximatexsession
\C77.  subst(1/2,n, de); \\
\D77.  x^2\,g^{\prime\prime}(x)+x\,g^{\prime}(x)+\left(x^2-1\right)\,g\left(x\right)=0 \\
\endmaximasession

\subsection*{Limitations}

\begin{itemize}
  \item Positional derivatives of subscripted functions are not allowed.

  \item Derivatives of unknown functions with symbolic orders are not 
   computed positionally.

  \item The {\tt pdiff.lisp} code alters the Maxima functions {\tt mqapply}
   and {\tt sdiffgrad} Although the author is unaware  of any problems associated with these altered functions, there may be some.  Setting {\tt use\_pdiff} to
   false should restore {\tt mqapply} and {\tt sdiffgrad} to their
   original functioning.

\end{itemize}
