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