samer@0
|
1 /*
|
samer@0
|
2 * Copyright (c) 2000, Samer Abdallah, King's College London.
|
samer@0
|
3 * All rights reserved.
|
samer@0
|
4 *
|
samer@0
|
5 * This software is provided AS iS and WITHOUT ANY WARRANTY;
|
samer@0
|
6 * without even the implied warranty of MERCHANTABILITY or
|
samer@0
|
7 * FITNESS FOR A PARTICULAR PURPOSE.
|
samer@0
|
8 */
|
samer@0
|
9
|
samer@0
|
10 package samer.maths.opt;
|
samer@0
|
11 import samer.maths.*;
|
samer@0
|
12 import samer.core.*;
|
samer@0
|
13
|
samer@0
|
14 public class GillMurray
|
samer@0
|
15 {
|
samer@0
|
16 public Matrix hessin;
|
samer@0
|
17 Jama.Matrix H0;
|
samer@0
|
18 double[][] H; // approximate inverse Hessian
|
samer@0
|
19 double[] u, v, Hv; // used in updating hessian
|
samer@0
|
20 double uv;
|
samer@0
|
21 State S;
|
samer@0
|
22 boolean uvc;
|
samer@0
|
23
|
samer@0
|
24 public GillMurray(State s)
|
samer@0
|
25 {
|
samer@0
|
26 S = s;
|
samer@0
|
27 hessin = new Matrix("H",s.n,s.n);
|
samer@0
|
28 H = hessin.getArray();
|
samer@0
|
29 u = new double[s.n];
|
samer@0
|
30 v = new double[s.n];
|
samer@0
|
31 Hv= new double[s.n];
|
samer@0
|
32 uv= 0;
|
samer@0
|
33
|
samer@0
|
34 H0=Matrix.identity(new Jama.Matrix(s.n,s.n));
|
samer@0
|
35 resetHessian();
|
samer@0
|
36 }
|
samer@0
|
37
|
samer@0
|
38 public void dispose() {
|
samer@0
|
39 H=null;
|
samer@0
|
40 u=v=Hv=null;
|
samer@0
|
41 hessin.dispose();
|
samer@0
|
42 S=null;
|
samer@0
|
43 }
|
samer@0
|
44
|
samer@0
|
45 public void setInitialHessian(Jama.Matrix H0) { this.H0=H0; }
|
samer@0
|
46 public void resetHessian() { hessin.assign(H0); }
|
samer@0
|
47 public void init() { computeHg(S.P1.g); }
|
samer@0
|
48
|
samer@0
|
49 public void steepest() {
|
samer@0
|
50 Mathx.negate(S.P1.g,S.h);
|
samer@0
|
51 S.normh = Util.maxabs(S.h);
|
samer@0
|
52 }
|
samer@0
|
53
|
samer@0
|
54 public void computeHg(double [] g) {
|
samer@0
|
55 Mathx.mul(S.h,H,g);
|
samer@0
|
56 Mathx.negate(S.h);
|
samer@0
|
57 S.normh = Util.maxabs(S.h);
|
samer@0
|
58 }
|
samer@0
|
59
|
samer@0
|
60 protected boolean uvCheck( double uv, double uu, double vv) {
|
samer@0
|
61 return uvc = (uv>1e-6*Math.sqrt(uu*vv));
|
samer@0
|
62 }
|
samer@0
|
63
|
samer@0
|
64 public void update()
|
samer@0
|
65 {
|
samer@0
|
66 // calculate new hessian
|
samer@0
|
67 Mathx.sub(v,S.P2.g,S.P1.g);
|
samer@0
|
68 Mathx.sub(u,S.P2.x,S.P1.x);
|
samer@0
|
69 double uv=Mathx.dot(u,v);
|
samer@0
|
70
|
samer@0
|
71 if (uvCheck(uv,Mathx.norm2(u),Mathx.norm2(v))) {
|
samer@0
|
72
|
samer@0
|
73 Mathx.mul(Hv,H,v);
|
samer@0
|
74 double a = 1/uv;
|
samer@0
|
75 double b = a*(1+a*Mathx.dot(v,Hv));
|
samer@0
|
76
|
samer@0
|
77 for (int i=0; i<S.n; i++) {
|
samer@0
|
78 for (int j=0; j<i; j++) {
|
samer@0
|
79 H[i][j] = H[i][j] - a*(Hv[i]*u[j]+u[i]*Hv[j]) + b*u[i]*u[j];
|
samer@0
|
80 H[j][i] = H[i][j];
|
samer@0
|
81 }
|
samer@0
|
82 H[i][i] = H[i][i] - a*(2*Hv[i]*u[i]) + b*u[i]*u[i];
|
samer@0
|
83 }
|
samer@0
|
84 }
|
samer@0
|
85 computeHg(S.P2.g);
|
samer@0
|
86 S.setSlope2(Mathx.dot(S.P2.g,S.h));
|
samer@0
|
87 }
|
samer@0
|
88 }
|