samer@0: /* samer@0: * Copyright (c) 2000, Samer Abdallah, King's College London. samer@0: * All rights reserved. samer@0: * samer@0: * This software is provided AS iS and WITHOUT ANY WARRANTY; samer@0: * without even the implied warranty of MERCHANTABILITY or samer@0: * FITNESS FOR A PARTICULAR PURPOSE. samer@0: */ samer@0: samer@0: package samer.maths.opt; samer@0: import samer.maths.*; samer@0: import samer.core.*; samer@0: import samer.core.types.*; samer@0: import samer.core.util.*; samer@0: import samer.tools.*; samer@0: import samer.core.util.swing.*; samer@0: import java.awt.*; samer@0: import java.util.*; samer@0: samer@0: /** samer@0: This is a base class for running multidimensional optimisation samer@0: It requires the following objects to exist in object space samer@0: (they are used by the State base class default constructor) samer@0: samer@0: Functionx "functionx": the function to be minimised samer@0: VVector "vector": the vector to work with samer@0: samer@0: ConstrainedMinimiser also requires "constraintClass" to samer@0: exist. samer@0: samer@0: */ samer@0: samer@0: samer@0: public abstract class MinimiserBase extends State implements SafeTask, Agent samer@0: { samer@0: // private Node node; samer@0: samer@0: protected VVector x1,x2,g1,g2,vh; samer@0: protected VDouble beta; // initial step length samer@0: protected CubicLineSearch ls; samer@0: protected LSCondition lstest; // convergence test for line search samer@0: protected AbsXFConvergence xfconv; // convergence test for optimisation samer@0: protected GConvergence gconv; samer@0: protected double XTOL=1e-4; samer@0: protected VInteger vmaxiter; samer@0: protected boolean flange; // signal vector changes every iteration samer@0: samer@0: protected Meter lsiters, iters; samer@0: protected Meter steplength; samer@0: protected LED sig1, sig2, sig3; samer@0: samer@0: private LinkedList viewables; samer@0: samer@0: public MinimiserBase(Vec x, Functionx func) samer@0: { samer@0: super(x, func); samer@0: samer@0: // node = new Node("Minimiser"); samer@0: //Shell.push(node); samer@0: samer@0: boolean oldreg=Shell.setAutoRegister(false); samer@0: viewables = new LinkedList(); samer@0: samer@0: x1 = new VVector("x1", P1.x); // independent view? samer@0: x2 = new VVector("x2", P2.x); samer@0: g1 = new VVector("g1", P1.g); samer@0: g2 = new VVector("g2", P2.g); samer@0: vh = new VVector("h", h); samer@0: beta = new VDouble("beta",1); samer@0: vmaxiter=new VInteger("maxiter",400); samer@0: xfconv=new AbsXFConvergence(); samer@0: gconv=new GConvergence(); samer@0: gconv.setGTolerance(0.005); samer@0: flange=Shell.getBoolean("vprogress",false); samer@0: ls = new CubicLineSearch(this); samer@0: ls.setSafeguardFactor(0.125); samer@0: lstest = new LSCondition(); samer@0: samer@0: steplength = createMeter("step length",2,false,new Color(200,170,0)); samer@0: lsiters = createMeter("line search iterations",20,false,new Color(90,100,255)); samer@0: iters = createMeter("iterations",2*x1.size(), true, new Color(200,50,0)); samer@0: sig1 = new LED(new Color(240,190,20)); samer@0: sig2 = new LED(new Color(90,100,255)); samer@0: sig3 = new LED(new Color(250,60,20)); samer@0: sig1.setToolTipText("Tiny line search step"); samer@0: sig2.setToolTipText("Resetting Hessian, trying steepest descent"); samer@0: sig3.setToolTipText("Maximum iterations reached"); samer@0: samer@0: samer@0: // register some viewables locally samer@0: // add(x1); add(x2); add(g1); add(g2); add(vh); samer@0: add(beta); samer@0: add(vmaxiter); samer@0: samer@0: add(new VParameter("xtol", new Parameter() { samer@0: public void setParameter(double t) { samer@0: xfconv.setXTolerance(t); samer@0: XTOL=t; samer@0: } samer@0: } ) samer@0: ); samer@0: samer@0: add(new VParameter("ftol", new Parameter() { samer@0: public void setParameter(double t) { samer@0: xfconv.setFTolerance(t); samer@0: } samer@0: } ) samer@0: ); samer@0: samer@0: add(new VParameter("gtol", new Parameter() { samer@0: public void setParameter(double t) { samer@0: gconv.setGTolerance(t); samer@0: } samer@0: } ) samer@0: ); samer@0: samer@0: add(new VParameter("ZETA", new Parameter() { samer@0: public void setParameter(double t) { samer@0: ls.setSafeguardFactor(t); samer@0: } samer@0: } ) samer@0: ); samer@0: Shell.setAutoRegister(oldreg); samer@0: // Shell.pop(); samer@0: } samer@0: samer@0: public Viewer getViewer() { samer@0: return new VPanel() { samer@0: { samer@0: setLayout( new StackLayout()); samer@0: // add(Shell.createButtonsFor(MinimiserBase.this)); samer@0: samer@0: // set default border for meterbox and signal box? samer@0: VPanel meterbox = new VPanel(); samer@0: //meterbox.setChildBorder(BorderFactory.createLoweredBevelBorder()); samer@0: meterbox.setLayout( new StackLayout(8)); samer@0: meterbox.add(steplength); samer@0: meterbox.add(iters); samer@0: meterbox.add(lsiters); samer@0: samer@0: VPanel signalbox = new VPanel(); samer@0: //signalbox.setChildBorder(BorderFactory.createLoweredBevelBorder()); samer@0: signalbox.setLayout( new FlowLayout(FlowLayout.LEFT)); samer@0: signalbox.add(sig1); samer@0: signalbox.add(sig2); samer@0: signalbox.add(sig3); samer@0: samer@0: add(meterbox); samer@0: add(signalbox); samer@0: samer@0: add(x1); add(x2); add(g1); add(g2); add(vh); samer@0: for (Iterator it=viewables.iterator(); it.hasNext();) { samer@0: add(it.next()); samer@0: } samer@0: // now add all other viewables samer@0: } samer@0: }; samer@0: } samer@0: samer@0: public void dispose() { super.dispose(); } samer@0: samer@0: public void add(Viewable vbl) { viewables.add(vbl); } samer@0: public Viewable[] getViewables() { return viewables.toArray(new Viewable[0]); } samer@0: samer@0: public int getMaxiter() { return vmaxiter.value; } samer@0: protected void perIteration() { if (flange) x1.changed(); } samer@0: protected void perOptimisation(int i) { samer@0: if (P2.f<=P1.f) { samer@0: move(); samer@0: if (flange) x1.changed(); samer@0: } samer@0: samer@0: iters.next(i); samer@0: if (i96) { samer@0: Shell.trace("\n**** LINE SEARCH OVERRUN ****\n"); samer@0: return true; samer@0: } samer@0: if (alpha*normh