-
Notifications
You must be signed in to change notification settings - Fork 77
/
Copy pathfinite_difference.jl
85 lines (65 loc) · 3.68 KB
/
finite_difference.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#
# Derivatives of f: R -> R
#
@test norm(Calculus.finite_difference(x -> x^2, 1.0, :forward) - 2.0) < 10e-4
@test norm(Calculus.finite_difference(x -> x^2, 1.0, :central) - 2.0) < 10e-4
@test norm(Calculus.finite_difference(x -> x^2, 1.0) - 2.0) < 10e-4
@test norm(Calculus.finite_difference(x -> sin(x), 1.0, :forward) - cos(1.0)) < 10e-4
@test norm(Calculus.finite_difference(x -> sin(x), 1.0, :central) - cos(1.0)) < 10e-4
@test norm(Calculus.finite_difference(x -> sin(x), 1.0) - cos(1.0)) < 10e-4
@test norm(Calculus.finite_difference(x -> exp(-x), 1.0, :forward) - (-exp(-1.0))) < 10e-4
@test norm(Calculus.finite_difference(x -> exp(-x), 1.0, :central) - (-exp(-1.0))) < 10e-4
@test norm(Calculus.finite_difference(x -> exp(-x), 1.0) - (-exp(-1.0))) < 10e-4
#
# Gradients of f: R^n -> R
#
@test norm(Calculus.finite_difference(x -> x[1]^2, [1.0], :forward) - [2.0]) < 10e-4
@test norm(Calculus.finite_difference(x -> x[1]^2, [1.0], :central) - [2.0]) < 10e-4
@test norm(Calculus.finite_difference(x -> x[1]^2, [1.0]) - [2.0]) < 10e-4
@test norm(Calculus.finite_difference(x -> sin(x[1]), [1.0], :forward) - [cos(1.0)]) < 10e-4
@test norm(Calculus.finite_difference(x -> sin(x[1]), [1.0], :central) - [cos(1.0)]) < 10e-4
@test norm(Calculus.finite_difference(x -> sin(x[1]), [1.0]) - [cos(1.0)]) < 10e-4
@test norm(Calculus.finite_difference(x -> exp(-x[1]), [1.0], :forward) - [-exp(-1.0)]) < 10e-4
@test norm(Calculus.finite_difference(x -> exp(-x[1]), [1.0], :central) - [-exp(-1.0)]) < 10e-4
@test norm(Calculus.finite_difference(x -> exp(-x[1]), [1.0]) - [-exp(-1.0)]) < 10e-4
# Gradients of f when x is a SubArrays
@test norm(Calculus.finite_difference(x -> exp(-x[1]), sub([1.0],:), :forward) - [-exp(-1.0)]) < 10e-4
@test norm(Calculus.finite_difference(x -> exp(-x[1]), sub([1.0],:), :central) - [-exp(-1.0)]) < 10e-4
@test norm(Calculus.finite_difference(x -> exp(-x[1]), sub([1.0],:)) - [-exp(-1.0)]) < 10e-4
#
# Second derivatives of f: R -> R
#
@test norm(Calculus.finite_difference_hessian(x -> x^2, x -> 2 * x, 1.0) - 2.0) < 10e-4
@test norm(Calculus.finite_difference_hessian(x -> x^2, x -> 2 * x, 10.0) - 2.0) < 10e-4
@test norm(Calculus.finite_difference_hessian(x -> x^2, x -> 2 * x, 100.0) - 2.0) < 10e-4
@test norm(Calculus.finite_difference_hessian(x -> x^2, 1.0) - 2.0) < 10e-4
@test norm(Calculus.finite_difference_hessian(x -> x^2, 10.0) - 2.0) < 10e-4
@test norm(Calculus.finite_difference_hessian(x -> x^2, 100.0) - 2.0) < 10e-4
#
# Hessians of f: R^n -> R
#
fx(x) = sin(x[1]) + cos(x[2])
gx = Calculus.gradient(fx)
@test norm(gx([0.0, 0.0]) - [cos(0.0), -sin(0.0)]) < 10e-4
@test norm(Calculus.finite_difference_hessian(fx, gx, [0.0, 0.0], :central) - [-sin(0.0) 0.0; 0.0 -cos(0.0)]) < 10e-4
@test norm(Calculus.finite_difference_hessian(fx, [0.0, 0.0]) - [-sin(0.0) 0.0; 0.0 -cos(0.0)]) < 10e-4
@test norm(gx(sub([0.0, 0.0],:)) - [cos(0.0), -sin(0.0)]) < 10e-4
@test norm(Calculus.finite_difference_hessian(fx, gx, sub([0.0, 0.0],:), :central) - [-sin(0.0) 0.0; 0.0 -cos(0.0)]) < 10e-4
@test norm(Calculus.finite_difference_hessian(fx, sub([0.0, 0.0],:)) - [-sin(0.0) 0.0; 0.0 -cos(0.0)]) < 10e-4
#
# Taylor Series first derivatives
#
@test norm(Calculus.taylor_finite_difference(x -> x^2, 1.0, :forward) - 2.0) < 10e-4
@test norm(Calculus.taylor_finite_difference(x -> x^2, 1.0, :central) - 2.0) < 10e-4
#
# Taylor Series second derivatives
#
# TODO: Fill this in
#
# Speed comparisons
#
@elapsed Calculus.finite_difference(x -> x^2, 1.0, :forward)
@elapsed Calculus.finite_difference(x -> x^2, 1.0, :central)
@elapsed Calculus.finite_difference(x -> x^2, 1.0)
@elapsed Calculus.taylor_finite_difference(x -> x^2, 1.0, :forward, 10e-4)
@elapsed Calculus.taylor_finite_difference(x -> x^2, 1.0, :central, 10e-4)