Mercurial > hg > jslab
comparison src/samer/maths/opt/ConstrainedMinimiser.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 import samer.core.types.*; | |
14 import samer.core.util.heavy.*; | |
15 | |
16 /** | |
17 Constrained minimiser. | |
18 | |
19 - ConjugateGradient | |
20 - OR Quasi-newton (using GillMurray uydates) | |
21 - Safeguarded cubic interpolation line search using gradients | |
22 | |
23 We expect a Class object to be in object Space | |
24 to tell us what kind of constraints to create | |
25 */ | |
26 | |
27 | |
28 public class ConstrainedMinimiser extends MinimiserBase implements Agent | |
29 { | |
30 ConstrainedGillMurray dir; | |
31 // ConstrainedConjGrad dir; | |
32 Constraints cons; // handles line search | |
33 VDouble percentage; | |
34 boolean toggle=false; | |
35 | |
36 /** expected stack top: Vec, Functionx, Class */ | |
37 public ConstrainedMinimiser(Vec v, Functionx f, Constraints.Factory constraintFactory) | |
38 { | |
39 super(v,f); | |
40 cons = constraintFactory.build(this); | |
41 init(); | |
42 } | |
43 | |
44 public ConstrainedMinimiser(Vec v, Functionx f, Class conscl) | |
45 { | |
46 super(v,f); | |
47 | |
48 if (conscl==ZeroCrossingSparsity.class) { | |
49 cons = new ZeroCrossingSparsity(this); | |
50 } else if (conscl==Positivity.class) { | |
51 cons = new Positivity(this); | |
52 } else { | |
53 throw new Error("Unrecognised constrain class: "+conscl); | |
54 } | |
55 init(); | |
56 } | |
57 | |
58 private void init() { | |
59 dir = new ConstrainedGillMurray(this,cons); | |
60 // dir = new ConstrainedConjGrad(this,cons); | |
61 percentage=new VDouble("releaseFactor",0.01); | |
62 | |
63 // add( dir.hessin.viewable()); | |
64 add( percentage); | |
65 cons.activateAll(); | |
66 } | |
67 | |
68 public void setHessian(Jama.Matrix H) { dir.setInitialHessian(H); } | |
69 | |
70 public void getCommands(Agent.Registry r) { | |
71 super.getCommands(r); | |
72 r.add("all").add("run"); | |
73 r.add("report").add("release").add("resetHess"); | |
74 } | |
75 | |
76 public void execute(String cmd, Environment env) throws Exception | |
77 { | |
78 if (cmd.equals("run")) run(); | |
79 else if (cmd.equals("report")) cons.report(); | |
80 else if (cmd.equals("release")) releaseDimensions(P1); | |
81 else if (cmd.equals("all")) { | |
82 toggle = X._bool(env.datum(),!toggle); | |
83 if (toggle) cons.activateAll(); | |
84 else cons.deactivateAll(); | |
85 } else if (cmd.equals("resetHess")) { | |
86 dir.resetHessian(); | |
87 } else super.execute(cmd,env); | |
88 } | |
89 | |
90 private boolean releaseDimensions(Datum P) | |
91 { | |
92 if (cons.release(P)) { | |
93 dir.resetDimension(cons.getReleasedDimension()); | |
94 | |
95 int p=cons.getReleasableDimensions()-1; | |
96 | |
97 // going to release a percentage of releasable dims? | |
98 // or absolute number? | |
99 p=(int)(percentage.value*p); | |
100 // if (p>1) p=1; | |
101 for (; p>0; p--) { | |
102 cons.release(P); | |
103 dir.resetDimension(cons.getReleasedDimension()); | |
104 } | |
105 | |
106 return true; | |
107 } | |
108 return false; | |
109 } | |
110 | |
111 public void run() | |
112 { | |
113 double beta; | |
114 int i, maxiter=getMaxiter(); | |
115 boolean triedSteepest=false; | |
116 | |
117 // we start from the current state instead. | |
118 // cons.initialise should set up the constraints | |
119 // to reflect the current state. | |
120 cons.initialise(); | |
121 | |
122 evaluate(); | |
123 releaseDimensions(P1); | |
124 | |
125 if (cons.activeCount()==0) { | |
126 iters.next(0); | |
127 sig3.off(); | |
128 return; | |
129 } | |
130 | |
131 | |
132 sig1.off(); | |
133 | |
134 // must reset hessian for active dimensions | |
135 cons.zeroInactive(P2.x); | |
136 dir.resetHessian(); | |
137 dir.hessin.changed(); | |
138 dir.init(); | |
139 setSlope(); | |
140 beta = initialStep(); | |
141 // beta = beta.value; ?? | |
142 | |
143 for (i=0; i<maxiter; i++) { | |
144 | |
145 // constrained line search with initial step beta0 | |
146 lstest.init(); | |
147 cons.lineSearch(lstest,ls,beta); | |
148 lsiters.next(lstest.count); | |
149 steplength.next(alpha); | |
150 | |
151 if (lstest.tiny && (P2.f>=P1.f)) { | |
152 // tiny step was no good | |
153 sig1.on(); | |
154 sig2.off(); | |
155 if (gconv.isSatisfied(P1.g,cons)) break; | |
156 if (triedSteepest) break; | |
157 sig2.on(); | |
158 | |
159 beta = this.beta.value; | |
160 dir.update(); // ?? | |
161 if (dir.uvc) dir.init(); | |
162 else dir.steepest(); | |
163 setSlope(); | |
164 triedSteepest=true; | |
165 continue; | |
166 } | |
167 | |
168 | |
169 // check gradients at P2 | |
170 if (!releaseDimensions(P2)) { | |
171 // don't quit if any dimensions released | |
172 if (cons.activeCount()==0) break; | |
173 if (xfconv.isSatisfied(this)) { | |
174 if (gconv.isSatisfied(P2.g,cons)) break; | |
175 } | |
176 } | |
177 | |
178 // beta = beta.value; | |
179 beta = nextStep(); | |
180 dir.update(); | |
181 move(); | |
182 perIteration(); | |
183 } | |
184 | |
185 perOptimisation(i); | |
186 dir.hessin.changed(); | |
187 } | |
188 } | |
189 | |
190 | |
191 | |
192 |