To get started, we load the MTH229
package and a plotting package:
using MTH229
using Plots
plotly()
┌ Info: For saving to png with the Plotly backend PlotlyBase has to be installed. └ @ Plots /Users/verzani/.julia/packages/Plots/1KWPG/src/backends.jl:318
Plots.PlotlyBackend()
Read about this material here: Approximate derivatives in julia.
For the impatient, A secant line connecting points on the graph of $f(x)$ between $x=c$ and $x = c+h$ has slope:
The slope of the tangent line to the graph of $f(x)$ at the point $(c,f(c))$ is given by taking the limit as $h$ goes to $0$:
The notation for this - when the limit exists - is $f'(c)$.
In general the derivative of a function $f(x)$ is the function $f'(x)$, which returns the slope of the tangent line for each $x$ where it is defined. For many functions, finding the derivative is straightforward, though may be complicated enough to seek alternatives. At times approximating the value is desirable.
We can approximate the slope of the tangent line several ways. The forward difference quotient takes a small value of $h$ and uses the value $(f(x+h) - f(x))/h$ as an approximation.
For example, to estimate the derivative of $x^{\ln(x)}$ at $c=2$ with h=1e-6
we could have
f(x) = x^log(x)
c, h = 2, 1e-6
(f(c+h) - f(c))/h
1.120685498845475
The above pattern finds the approximate derivative at the point $c$. Though this can be pushed to return a function giving the derivative at any point, we will use the more convenient solution described next for finding the derivative as a function, when applicable.
In mathematics we use the notation $f'(x)$ to refer to the function that computes the derivative of $f(x)$ at a given $x$. The MTH229
package provides the same notation in Julia
. In the background, this uses automatic differentiation, as provided by the ForwardDiff
package, to compute the derivative. Automatic differentiation is a tad slower than using a hand-computed derivative, but as accurate as that, and much easier and more accurate than using an approximate derivative.
The MTH229
package, using ForwardDiff.derivative
, overloads the default meaning of '
allowing the usual notation for a derivative to be used:
f(x) = sin(x)
f'(pi), f''(pi)
(-1.0, -1.2246467991473532e-16)
(The math notation is followed by Julia
, in that f'
itself returns a function which evaluates the derivative, and f'(pi)
first computes the derivative and then evaluates that function at pi
.)
Automatic differentiation gives accurate numeric values for first, second, and even higher-order derivatives. It does not however, return the expression one would get were these computed by hand. The diff
function from SymPy
will find symbolic derivatives, similar to what is achieved when differentiating "by hand," though for many problems the effort will be much less.
The diff
function can be called with a symbolic expression and a variable to differentiate in:
f(x) = exp(x^2) * sin(sqrt(x))
@syms x
diff(f(x), x)
Symbolic expressions can be generated by passing x
into the function, as illustrated, or written directly, as in diff(exp(x^2)*sin(sqrt(x)), x)
.
The tangent line to the graph of $f(x)$ at $x=c$ is given by $y=f(c)+f'(c)(x-c)$. It is fairly easy to plot both the function and its tangent line - we just need a function to compute the tangent line. Such a function, tangent(f,c)
is found in the MTH229
package. This function consumes a function (f
) and a point (c
) and returns a function of x
returning the y
values of the tangent line.
Here we see how to use it and the related secant(f,a,b)
function:
f(x) = x^x
a,b = 1/2, 2
c = 1
plot(f, 1/4, 2.5, legend=false)
plot!(secant(f, a, b))
plot!(tangent(f, c))
Higher-order derivatives can be computed as well:
Automatic derivatives can be computed using the usual notation, e.g., f''
to find $f''(x)$.
Higher-order symbolic derivatives can be computed by passing the order to diff
as a second argument, as in diff(f(x), x, n)
.
For example, consider $f(x) = e^x \sin(x)$. We have:
f(x) = exp(x) * sin(x)
f''(3)
-39.769061688293974
As compared to the symbolic answer:
@syms x
fpp = diff(f(x), x, 2) # or diff(f(x), x, x)
and its numeric value at 3
:
N(fpp(3)) # make numeric
-39.76906168829397773129798975944675106812894879110228655084531523121728543571319