annotate src/samer/maths/opt/ConstrainedMinimiser.java @ 8:5e3cbbf173aa tip

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