Get derivative of a function

I want to write a macro, which takes a mathematical function as argument and returns a plot using pgfplots of the function and of its derivative.

I guess that this isn't possible using just LaTeX; however, for example, pgfplots can use the external program gnuplot to plot functions or there is LuaTeX...

So is there any way to get the derivative of a mathematical function do do this?

-
You need to do it automatically? – R. M. Sep 24 '12 at 20:00

Within reason (i.e. for not too nonlinear functions), you can numerically differentiate your functions right within PGFPlots, using the approach f'(x)=(f(x+dx)-f(x))/dx:

\documentclass{article}
\usepackage{pgfplots}

\begin{document}
\begin{tikzpicture}
\begin{axis}[no markers, legend pos=south east, legend entries={Original function, Analytical derivative, Numerical derivative}]
\end{axis}
\end{tikzpicture}

\begin{tikzpicture}
\begin{axis}[no markers, samples=500]
\end{axis}
\end{tikzpicture}

\end{document}

-
Nice! Is it possible to make a command \diff which takes the function as an argument and returns the differential quotient (with suitable small dx), then one would write for example: \addplot [black] {\diff{sin(x)}} which expands to \addplot [black] {(sin(deg(x+0.01))-sin(deg(x)))/0.01}; – student Sep 25 '12 at 7:54
I have added a feature request to add this to pgfmath: sourceforge.net/p/pgf/feature-requests/99 – student Jun 21 at 11:28

To derive a function analytically LaTeX is not really equipped with a linear algebra package. Instead you can use sympy, a python library for symbolic mathematics. An example session in python looks like this:

>>> from sympy import *
>>> x = Symbol('x')
>>> diff(sin(x), x)
cos(x)


Thanks to the great pythontex package this can easily be integrated into a LaTeX document. Have a look at the examples, which contain several derivatives of functions and plots using matplotlib. It is no problem though to adapt the output to pgfplots.

-
Wow, that's pretty nice! – Jake Sep 24 '12 at 18:47

the first 15 derivations of

f(x)=1-x^2/2+x^4/24-x^6/720+x^8/40320-x^10/3628800+x^12/479001600-x^14/87178291200


which is

\PassOptionsToPackage{dvipsnames,svgnames}{pstricks}
\documentclass[pstricks]{standalone}
\begin{document}

\psset{unit=2cm}
\def\getColor#1{\ifcase#1 Tan\or RedOrange\or magenta\or yellow\or green%
\or Orange\or blue\or DarkOrchid\or BrickRed\or Rhodamine\or OliveGreen%
\or Goldenrod\or Mahogany\or OrangeRed\or CarnationPink\or RoyalPurple\or Lavender\fi}
\begin{pspicture}[showgrid](-0.2,-1.2)(7,1.5)
\psclip{\psframe[linestyle=none](-0.2,-1.1)(7,1.1)}
\multido{\in=0+1}{16}{%
\psplot[linewidth=1pt,algebraic=true,linecolor=\getColor{\in}]{0}{7}
{Derive(\in,1-x^2/2+x^4/24-x^6/720+x^8/40320-x^10/3628800+
x^12/479001600-x^14/87178291200)}}
\endpsclip
\end{pspicture}

\end{document}


and the first 2 of sin(x)*cos(x)

-
Can we use pst-tools.pro's /factorial to define the function to be simpler? – kiss my armpit Sep 24 '12 at 20:20
sure, but not with the algebraic mode, because /factorial is a PS function – Herbert Sep 24 '12 at 20:23
\psPolynomial[coeff=0 0 1,Derivation=1]{-2}{4} from package pst-func – Herbert Feb 20 '13 at 15:24
not possible by automatic. If you want to plot it, then let it be calculated by \psTangentLine or use x dup add – Herbert Feb 20 '13 at 15:29
Is there a way to get the nodes (c,f(c)) in which f'(c)=0? – kiss my armpit Feb 20 '13 at 15:35

Here's a PythonTeX version of @Jake's answer that uses pgfplots. This required a reasonable bit of code to try to translate back and forth between Python and pgfplots syntax. It might be simpler to use a Python plotting solution like matplotlib, though that might also require a little translation from SymPy.

\documentclass{article}
\usepackage{pgfplots}
\usepackage{pythontex}

\begin{document}

\begin{sympycode}
import re
x = Symbol('x')
def deriv(tikz_args, expr):
expr = eval(expr.replace('^', '**'))
expr_deriv = str(diff(expr, x)).replace('**', '^')
expr = str(expr).replace('**', '^')
for f in ['sin', 'cos', 'tan']:
if f in expr:
fpattern = f + r'$$(.+)$$'
expr = re.sub(fpattern, f + r'(deg(\1))', expr)
if f in expr_deriv:
fpattern = f + r'$$(.+)$$'
expr_deriv = re.sub(fpattern, f + r'(deg(\1))', expr_deriv)
func = r'\addplot [blue] {' + expr + r'};'
func_deriv = r'\addplot [red] {' + expr_deriv + r'};'
tikz = r'''
\begin{tikzpicture}
\begin{axis}[tikz_args]
\end{axis}
\end{tikzpicture}'''
tikz = tikz.replace('tikz_args', tikz_args)
print(tikz)
\end{sympycode}

\newcommand{\plotderiv}[2][]{\sympyc{deriv("#1", "#2")}}

\plotderiv[no markers, legend pos=south east, legend entries={Function, Derivative}]{x^3}

\plotderiv[no markers, legend pos=south east, legend entries={Function, Derivative}, samples=500]{sin(x)}

\end{document}


-
I get: ERROR: Undefined control sequence. --- TeX said --- l.115 \ProcessPgfPackageOptions {/PYTX/pkgopt} – student Sep 25 '12 at 8:10
@student That sounds like you may need to install the pgfopts package. – G. Poore Sep 25 '12 at 11:31
Now it compiles without output but without error. Do I need special compile options for this? – student Sep 25 '12 at 11:46
@student With pythontex, you have to compile, then run a Python script, then compile again to bring in the Python results. You need to install pythontex on your system according to the manual (see the section on installation and compiling). You may want to create a shortcut in your TeX editor for running the Python script. – G. Poore Sep 25 '12 at 12:12