annotate src/samer/maths/opt/MinimiserBase.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.*;
samer@0 15 import samer.tools.*;
samer@0 16 import samer.core.util.swing.*;
samer@0 17 import java.awt.*;
samer@0 18 import java.util.*;
samer@0 19
samer@0 20 /**
samer@0 21 This is a base class for running multidimensional optimisation
samer@0 22 It requires the following objects to exist in object space
samer@0 23 (they are used by the State base class default constructor)
samer@0 24
samer@0 25 Functionx "functionx": the function to be minimised
samer@0 26 VVector "vector": the vector to work with
samer@0 27
samer@0 28 ConstrainedMinimiser also requires "constraintClass" to
samer@0 29 exist.
samer@0 30
samer@0 31 */
samer@0 32
samer@0 33
samer@0 34 public abstract class MinimiserBase extends State implements SafeTask, Agent
samer@0 35 {
samer@0 36 // private Node node;
samer@0 37
samer@0 38 protected VVector x1,x2,g1,g2,vh;
samer@0 39 protected VDouble beta; // initial step length
samer@0 40 protected CubicLineSearch ls;
samer@0 41 protected LSCondition lstest; // convergence test for line search
samer@0 42 protected AbsXFConvergence xfconv; // convergence test for optimisation
samer@0 43 protected GConvergence gconv;
samer@0 44 protected double XTOL=1e-4;
samer@0 45 protected VInteger vmaxiter;
samer@0 46 protected boolean flange; // signal vector changes every iteration
samer@0 47
samer@0 48 protected Meter lsiters, iters;
samer@0 49 protected Meter steplength;
samer@0 50 protected LED sig1, sig2, sig3;
samer@0 51
samer@0 52 private LinkedList<Viewable> viewables;
samer@0 53
samer@0 54 public MinimiserBase(Vec x, Functionx func)
samer@0 55 {
samer@0 56 super(x, func);
samer@0 57
samer@0 58 // node = new Node("Minimiser");
samer@0 59 //Shell.push(node);
samer@0 60
samer@0 61 boolean oldreg=Shell.setAutoRegister(false);
samer@0 62 viewables = new LinkedList<Viewable>();
samer@0 63
samer@0 64 x1 = new VVector("x1", P1.x); // independent view?
samer@0 65 x2 = new VVector("x2", P2.x);
samer@0 66 g1 = new VVector("g1", P1.g);
samer@0 67 g2 = new VVector("g2", P2.g);
samer@0 68 vh = new VVector("h", h);
samer@0 69 beta = new VDouble("beta",1);
samer@0 70 vmaxiter=new VInteger("maxiter",400);
samer@0 71 xfconv=new AbsXFConvergence();
samer@0 72 gconv=new GConvergence();
samer@0 73 gconv.setGTolerance(0.005);
samer@0 74 flange=Shell.getBoolean("vprogress",false);
samer@0 75 ls = new CubicLineSearch(this);
samer@0 76 ls.setSafeguardFactor(0.125);
samer@0 77 lstest = new LSCondition();
samer@0 78
samer@0 79 steplength = createMeter("step length",2,false,new Color(200,170,0));
samer@0 80 lsiters = createMeter("line search iterations",20,false,new Color(90,100,255));
samer@0 81 iters = createMeter("iterations",2*x1.size(), true, new Color(200,50,0));
samer@0 82 sig1 = new LED(new Color(240,190,20));
samer@0 83 sig2 = new LED(new Color(90,100,255));
samer@0 84 sig3 = new LED(new Color(250,60,20));
samer@0 85 sig1.setToolTipText("Tiny line search step");
samer@0 86 sig2.setToolTipText("Resetting Hessian, trying steepest descent");
samer@0 87 sig3.setToolTipText("Maximum iterations reached");
samer@0 88
samer@0 89
samer@0 90 // register some viewables locally
samer@0 91 // add(x1); add(x2); add(g1); add(g2); add(vh);
samer@0 92 add(beta);
samer@0 93 add(vmaxiter);
samer@0 94
samer@0 95 add(new VParameter("xtol", new Parameter() {
samer@0 96 public void setParameter(double t) {
samer@0 97 xfconv.setXTolerance(t);
samer@0 98 XTOL=t;
samer@0 99 }
samer@0 100 } )
samer@0 101 );
samer@0 102
samer@0 103 add(new VParameter("ftol", new Parameter() {
samer@0 104 public void setParameter(double t) {
samer@0 105 xfconv.setFTolerance(t);
samer@0 106 }
samer@0 107 } )
samer@0 108 );
samer@0 109
samer@0 110 add(new VParameter("gtol", new Parameter() {
samer@0 111 public void setParameter(double t) {
samer@0 112 gconv.setGTolerance(t);
samer@0 113 }
samer@0 114 } )
samer@0 115 );
samer@0 116
samer@0 117 add(new VParameter("ZETA", new Parameter() {
samer@0 118 public void setParameter(double t) {
samer@0 119 ls.setSafeguardFactor(t);
samer@0 120 }
samer@0 121 } )
samer@0 122 );
samer@0 123 Shell.setAutoRegister(oldreg);
samer@0 124 // Shell.pop();
samer@0 125 }
samer@0 126
samer@0 127 public Viewer getViewer() {
samer@0 128 return new VPanel() {
samer@0 129 {
samer@0 130 setLayout( new StackLayout());
samer@0 131 // add(Shell.createButtonsFor(MinimiserBase.this));
samer@0 132
samer@0 133 // set default border for meterbox and signal box?
samer@0 134 VPanel meterbox = new VPanel();
samer@0 135 //meterbox.setChildBorder(BorderFactory.createLoweredBevelBorder());
samer@0 136 meterbox.setLayout( new StackLayout(8));
samer@0 137 meterbox.add(steplength);
samer@0 138 meterbox.add(iters);
samer@0 139 meterbox.add(lsiters);
samer@0 140
samer@0 141 VPanel signalbox = new VPanel();
samer@0 142 //signalbox.setChildBorder(BorderFactory.createLoweredBevelBorder());
samer@0 143 signalbox.setLayout( new FlowLayout(FlowLayout.LEFT));
samer@0 144 signalbox.add(sig1);
samer@0 145 signalbox.add(sig2);
samer@0 146 signalbox.add(sig3);
samer@0 147
samer@0 148 add(meterbox);
samer@0 149 add(signalbox);
samer@0 150
samer@0 151 add(x1); add(x2); add(g1); add(g2); add(vh);
samer@0 152 for (Iterator<Viewable> it=viewables.iterator(); it.hasNext();) {
samer@0 153 add(it.next());
samer@0 154 }
samer@0 155 // now add all other viewables
samer@0 156 }
samer@0 157 };
samer@0 158 }
samer@0 159
samer@0 160 public void dispose() { super.dispose(); }
samer@0 161
samer@0 162 public void add(Viewable vbl) { viewables.add(vbl); }
samer@0 163 public Viewable[] getViewables() { return viewables.toArray(new Viewable[0]); }
samer@0 164
samer@0 165 public int getMaxiter() { return vmaxiter.value; }
samer@0 166 protected void perIteration() { if (flange) x1.changed(); }
samer@0 167 protected void perOptimisation(int i) {
samer@0 168 if (P2.f<=P1.f) {
samer@0 169 move();
samer@0 170 if (flange) x1.changed();
samer@0 171 }
samer@0 172
samer@0 173 iters.next(i);
samer@0 174 if (i<vmaxiter.value) sig3.off();
samer@0 175 else sig3.on();
samer@0 176 }
samer@0 177
samer@0 178 public void starting() {}
samer@0 179 public void stopping() {}
samer@0 180
samer@0 181 public void getCommands(Agent.Registry r) {
samer@0 182 r.add("eval").add("step").add("move").add("turn").add("info");
samer@0 183 }
samer@0 184
samer@0 185 public void execute(String cmd, Environment env) throws Exception
samer@0 186 {
samer@0 187 if (cmd.equals("step")) {
samer@0 188 step(beta.value);
samer@0 189 g2.changed();
samer@0 190 x2.changed();
samer@0 191 } else if (cmd.equals("info")) Shell.print(toString());
samer@0 192 else if (cmd.equals("move")) {
samer@0 193 steplength.next(alpha);
samer@0 194 move();
samer@0 195 x1.changed();
samer@0 196 g1.changed();
samer@0 197 } else if (cmd.equals("eval")) {
samer@0 198 evaluate();
samer@0 199 x1.changed();
samer@0 200 g1.changed();
samer@0 201 setSlope();
samer@0 202 } else if (cmd.equals("turn")) {
samer@0 203 Mathx.negate(P1.g,h);
samer@0 204 setSlope();
samer@0 205 vh.changed();
samer@0 206 }
samer@0 207 }
samer@0 208
samer@0 209 class LSCondition implements Condition
samer@0 210 {
samer@0 211 double MU=1e-4; // ensure function decreases enough
samer@0 212 double ETA=0.1; // ensure gradient is smaller than last
samer@0 213 int count;
samer@0 214 boolean tiny;
samer@0 215
samer@0 216 LSCondition()
samer@0 217 {
samer@0 218 add(new VParameter("ETA",new DoubleModel() {
samer@0 219 public double get() { return ETA; }
samer@0 220 public void set(double t) { ETA=t; }
samer@0 221 } )
samer@0 222 );
samer@0 223 }
samer@0 224
samer@0 225 public void init() { tiny=false; count=0; }
samer@0 226 public boolean test()
samer@0 227 {
samer@0 228 if (count++>96) {
samer@0 229 Shell.trace("\n**** LINE SEARCH OVERRUN ****\n");
samer@0 230 return true;
samer@0 231 }
samer@0 232 if (alpha*normh<XTOL) { tiny=true; return true; }
samer@0 233 return (P2.f<P1.f+MU*alpha*P1.s) && (Math.abs(P2.s)<-ETA*P1.s);
samer@0 234 }
samer@0 235 }
samer@0 236
samer@0 237 private static Meter createMeter(String label, double max, boolean reinit, Color color) {
samer@0 238 Shell.push(label);
samer@0 239 Meter m=new Meter();
samer@0 240 m.setForeground(color);
samer@0 241 m.setBackground(color.darker().darker());
samer@0 242 m.getMap().setDomain(0,max);
samer@0 243 m.setToolTipText(label);
samer@0 244 m.exposeMap(reinit);
samer@0 245 Shell.pop();
samer@0 246 return m;
samer@0 247 }
samer@0 248 }