summaryrefslogtreecommitdiff
path: root/examples/minimize.hs
blob: 11643c94fffa25b5793b2e5b6e8ffc8f5b773964 (plain)
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
-- the multidimensional minimization example in the GSL manual
import Numeric.GSL
import Numeric.LinearAlgebra
import Graphics.Plot
import Text.Printf(printf)

-- the function to be minimized 
f [x,y] = 10*(x-1)^2 + 20*(y-2)^2 + 30

-- its gradient
df [x,y] = [20*(x-1), 40*(y-2)]

-- the conjugate gradient method
minimizeCG = minimizeConjugateGradient 1E-2 1E-4 1E-3 30

-- the BFGS2 method
minimizeBFGS2 = minimizeVectorBFGS2 1E-2 1E-2 1E-3 30

-- a minimization algorithm which does not require the gradient
minimizeS f xi = minimizeNMSimplex f xi (replicate (length xi) 1) 1E-2 100

-- Numerical estimation of the gradient
gradient f v = [partialDerivative k f v | k <- [0 .. length v -1]]

partialDerivative n f v = fst (derivCentral 0.01 g (v!!n)) where
    g x = f (concat [a,x:b])
    (a,_:b) = splitAt n v

main = do
    putStrLn "BFGS2 with true gradient"
    let (s,p) = minimizeBFGS2 f df [5,7]
    print s -- solution
    disp p -- evolution of the algorithm
    let [x,y] = drop 2 (toColumns p)
    mplot [x,y]  -- path from the starting point to the solution

    putStrLn "conjugate gradient with true gradient"
    let (s,p) = minimizeCG f df [5,7]
    print s
    disp p
    let [x,y] = drop 2 (toColumns p)
    mplot [x,y]

    putStrLn "conjugate gradient with estimated gradient"
    let (s,p) = minimizeCG f (gradient f) [5,7]
    print s
    disp p
    mplot $ drop 2 (toColumns p)

    putStrLn "without gradient, using the NM Simplex method"
    let (s,p) = minimizeS f [5,7]
    print s
    disp p
    mplot $ drop 3 (toColumns p)

    putStrLn "-------------------------"
    mapM_ test [NMSimplex,NMSimplex2]
    mapM_ testd [ConjugateFR .. SteepestDescent]

disp = putStrLn . format "  " (printf "%.3f")

test method = do
    print method
    let (s,p) = minimize method 1E-2 30 [1,1] f [5,7]
    print s
    disp p

testd method = do
    print method
    let (s,p) = minimizeD method 1E-3 30 1E-2 1E-4 f df [5,7]
    print s
    disp p