Calculating Derivatives
May 5, 2017
This is easy in a language that supports higher-order functions, and either difficult or impossible in one that doesn’t. Here’s a Python solution:
Python 2.7.10 (default, Jun 1 2015, 18:05:38) [GCC 4.9.2] on cygwin Type "help", "copyright", "credits" or "license" for more information. >>> def deriv(f): ... dx = 0.0001 ... return lambda x : (f(x+dx) - f(x)) / dx ... >>> def cube(x): ... return x*x*x ... >>> cube_deriv = deriv(cube) >>> print(cube_deriv(2)) 12.00060001 >>> print(cube_deriv(3)) 27.0009000101 >>> print(cube_deriv(4)) 48.0012000099
You can run the program in Scheme or Python.
The real point of this exercise is to get you to look at Joe Marshall’s paean to Scheme. If your language doesn’t make this as easy as Scheme, maybe you need a new language.
Using C11 and function pointers:
#include <stdio.h>
#include <stdlib.h>
double deriv(double (*f)(double), double x);
double cube(double x);
int main(int argc, char **argv) {
printf("%f\n", deriv(cube, 2));
printf("%f\n", deriv(cube, 3));
printf("%f\n", deriv(cube, 4));
exit(0);
}
double deriv(double (*f)(double), double x) {
const double dx = 0.0000001;
const double dy = f(x + dx) - f(x);
return dy / dx;
}
double cube(double x) {
return x * x * x;
}
Using a slightly different formula.
import sys import math EPS = sys.float_info.epsilon EPS3 = EPS ** (1/3) def der(f, x): h = EPS3 * abs(x) if x != 0 else EPS3 xm, xp = x - h, x + h return (f(xp) - f(xm)) / (xp - xm)Results using the same example as Rutger:
Haskell
dx = 0.0000001 derive f = let f' x = (f (x + dx) - f (x)) / dx in f' cube x = x * x * x test = do print (derive cube 2) print (derive cube 3) print (derive cube 4)Gforth
: cube ( F: f -- f^3) fdup fdup f* f* ; : f' ( xt --) ( F: f -- f'-of-x) dup fdup 1e-7 f+ execute fswap execute f- 1e-7 f/ ; : test 10 0 DO ['] cube I s>d d>f fdup f. ." => " f' f. CR LOOP ; test byePrints
Here’s another Haskell version, similar to Josef’s. This example shows that you can use it with various numeric types. For example, using the “constructive reals” (CReal) from the “numbers” package we can specify an arbitrary precision. (Also, note that ^3 is shorthand for the cube function, \x -> x^3.)
MUMPS V1:
EXTR ; Test of calculating derivatives
N I
F I=0:1:9 W !,I,” –> “,$$DERIV(“CUBE”,I,.0000001)
Q
;
CUBE (N) ; Cube a number
Q N*N*N
;
DERIV (FUNC,VAL,DX) ;
Q @(“$$”_FUNC_”(VAL+DX)”)-@(“$$”_FUNC_”(VAL)”)/DX
MCL> D ^EXTR
0 –> 0
1 –> 3.0000003
2 –> 12.0000006
3 –> 27.0000009
4 –> 48.0000012
5 –> 75.0000015
6 –> 108.0000018
7 –> 147.0000021
8 –> 192.0000024
9 –> 243.0000027