Calculating Derivatives
May 5, 2017
I’ve seen this before, and when I ran across it again a few days ago decided to share it with all of you. This is why I like Scheme so much:
In mathematics, the derivative of a function f(x) is . Here’s a simple implementation in Scheme, with an example:
Petite Chez Scheme Version 8.4
Copyright (c) 1985-2011 Cadence Research Systems
> (define dx 0.0000001)
> (define (deriv f)
(define (f-prime x)
(/ (- (f (+ x dx)) (f x))
dx))
f-prime)
> (define (cube x) (* x x x))
> ((deriv cube) 2)
12.000000584322379
> ((deriv cube) 3)
27.000000848431682
> ((deriv cube) 4)
48.00000141358396
Those results are reasonably close to the actual derivative of . The code is identical to the math.
Your task is to write a function to calculate derivatives in your favorite language. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution in the comments below.
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