Mercurial > hg > jslab
comparison src/samer/maths/opt/State.java @ 0:bf79fb79ee13
Initial Mercurial check in.
author | samer |
---|---|
date | Tue, 17 Jan 2012 17:50:20 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:bf79fb79ee13 |
---|---|
1 /* | |
2 * Copyright (c) 2000, Samer Abdallah, King's College London. | |
3 * All rights reserved. | |
4 * | |
5 * This software is provided AS iS and WITHOUT ANY WARRANTY; | |
6 * without even the implied warranty of MERCHANTABILITY or | |
7 * FITNESS FOR A PARTICULAR PURPOSE. | |
8 */ | |
9 | |
10 package samer.maths.opt; | |
11 import samer.maths.*; | |
12 import samer.core.*; | |
13 | |
14 public class State | |
15 { | |
16 public Functionx func; // function | |
17 public int n; // number of dimensions | |
18 public double[] h; // search direction | |
19 public Datum P1, P2; // two bracket points and a new point | |
20 public double alpha; // step length | |
21 public double normh; // some norm of h | |
22 | |
23 /** x must have an accessible array */ | |
24 public State( Vec x, Functionx func) | |
25 { | |
26 this.n = x.size(); | |
27 this.func = func; | |
28 P1 = new Datum(n,x.array()); | |
29 P2 = new Datum(n); | |
30 h = new double[n]; | |
31 } | |
32 | |
33 public void dispose() | |
34 { | |
35 func.dispose(); | |
36 P1.dispose(); | |
37 P2.dispose(); | |
38 h=null; | |
39 } | |
40 | |
41 /** estimated step to minimum using cubic interpolation of current state */ | |
42 public final double cubic() { return Util.cubici(P1.f,P1.s,P2.f,P2.s,alpha); } | |
43 | |
44 /** evaluate at P1 */ | |
45 public final void evaluate() { func.evaluate(P1); } | |
46 | |
47 /** move P1 to where P2 is now */ | |
48 public final void move() { P1.copy(P2); } // assert that P1.s<0 ? | |
49 | |
50 /** take step of length lambda from | |
51 P1 in direction of h, evaluate and store in P2 */ | |
52 public void step(double lambda) | |
53 { | |
54 for (int i=0; i<n; i++) { | |
55 P2.x[i] = P1.x[i] + lambda*h[i]; | |
56 } | |
57 | |
58 func.evaluate(P2); | |
59 P2.s = Mathx.dot(P2.g,h); | |
60 alpha=lambda; | |
61 } | |
62 | |
63 /** evaluate at P2 */ | |
64 public final void eval2() | |
65 { | |
66 func.evaluate(P2); | |
67 P2.s = Mathx.dot(P2.g,h); | |
68 } | |
69 | |
70 /** evaluate slope at P1 using gradient at P1 */ | |
71 public final void setSlope() { | |
72 double s1 = Mathx.dot(P1.g,h); | |
73 if (Double.isNaN(s1)) throw new Error( "slope 1 is NaN"); | |
74 if (s1>0) { | |
75 Shell.trace(toString()); | |
76 Shell.trace("bad new slope="+s1); | |
77 } | |
78 P1.s = s1; | |
79 } | |
80 | |
81 /** set slope at P2, assert new slope is negative */ | |
82 public final void setSlope2(double s2) | |
83 { | |
84 if (Double.isNaN(s2)) throw new Error( "slope 2 is NaN"); | |
85 | |
86 if (s2>0) { | |
87 Shell.trace(" ***** BAD DIRECTION UPDATE **** "); | |
88 Shell.trace(toString()); | |
89 Shell.trace("-- slope = "+s2); | |
90 } | |
91 | |
92 P2.s=s2; | |
93 } | |
94 | |
95 public String toString() { | |
96 return append(new StringBuffer()).toString(); | |
97 } | |
98 | |
99 public double initialStep() { | |
100 double step=2*Math.abs(P1.f/P1.s); | |
101 if (Double.isNaN(step)) return 1; | |
102 return Util.clip(0.01,step,1); | |
103 } | |
104 | |
105 /** estimate initial step for line search after turn */ | |
106 public double nextStep() | |
107 { | |
108 double beta; | |
109 | |
110 if (P2.s<=P1.s) return 1; | |
111 if (P2.s>0) { | |
112 // signal: 'overshoot, updhess' | |
113 // expect beta between 0 and 1 | |
114 if (alpha<0.9) beta=alpha; | |
115 else beta=cubic(); | |
116 if (Double.isNaN(beta) || Double.isInfinite(beta)) beta=1; | |
117 } else { | |
118 // signal: 'undershoot, updhess' | |
119 double gamma=1.5*alpha; if (gamma<2) gamma=2; | |
120 double delta=alpha*(P2.s-P1.s)-P2.s+(alpha>1?alpha:1); | |
121 // double delta=uv-P2.s+(alpha>1?alpha:1); | |
122 beta=cubic(); | |
123 if (Double.isNaN(beta) || Double.isInfinite(beta) || beta<alpha) beta=2*alpha+1e-5; | |
124 beta*=1.2; | |
125 if (gamma<beta) beta=gamma; | |
126 if (delta<beta) beta=delta; | |
127 } | |
128 | |
129 return beta; | |
130 } | |
131 | |
132 public StringBuffer append(StringBuffer info) | |
133 { | |
134 info.append(DoubleFormat.format(P1.f,4)) | |
135 .append(", ") | |
136 .append(DoubleFormat.format(P1.s,4)) | |
137 .append("\t") | |
138 .append(DoubleFormat.format(alpha,4)) | |
139 .append("\t") | |
140 .append(DoubleFormat.format(P2.f,4)) | |
141 .append(", ") | |
142 .append(DoubleFormat.format(P2.s,4)) | |
143 .append(" : "); // .append(this.info); | |
144 return info; | |
145 } | |
146 } |