Mercurial > hg > jslab
view 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 |
line wrap: on
line source
/* * Copyright (c) 2000, Samer Abdallah, King's College London. * All rights reserved. * * This software is provided AS iS and WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. */ package samer.maths.opt; import samer.maths.*; import samer.core.*; import samer.core.types.*; import samer.core.util.heavy.*; /** Constrained minimiser. - ConjugateGradient - OR Quasi-newton (using GillMurray uydates) - Safeguarded cubic interpolation line search using gradients We expect a Class object to be in object Space to tell us what kind of constraints to create */ public class ConstrainedMinimiser extends MinimiserBase implements Agent { ConstrainedGillMurray dir; // ConstrainedConjGrad dir; Constraints cons; // handles line search VDouble percentage; boolean toggle=false; /** expected stack top: Vec, Functionx, Class */ public ConstrainedMinimiser(Vec v, Functionx f, Constraints.Factory constraintFactory) { super(v,f); cons = constraintFactory.build(this); init(); } public ConstrainedMinimiser(Vec v, Functionx f, Class conscl) { super(v,f); if (conscl==ZeroCrossingSparsity.class) { cons = new ZeroCrossingSparsity(this); } else if (conscl==Positivity.class) { cons = new Positivity(this); } else { throw new Error("Unrecognised constrain class: "+conscl); } init(); } private void init() { dir = new ConstrainedGillMurray(this,cons); // dir = new ConstrainedConjGrad(this,cons); percentage=new VDouble("releaseFactor",0.01); // add( dir.hessin.viewable()); add( percentage); cons.activateAll(); } public void setHessian(Jama.Matrix H) { dir.setInitialHessian(H); } public void getCommands(Agent.Registry r) { super.getCommands(r); r.add("all").add("run"); r.add("report").add("release").add("resetHess"); } public void execute(String cmd, Environment env) throws Exception { if (cmd.equals("run")) run(); else if (cmd.equals("report")) cons.report(); else if (cmd.equals("release")) releaseDimensions(P1); else if (cmd.equals("all")) { toggle = X._bool(env.datum(),!toggle); if (toggle) cons.activateAll(); else cons.deactivateAll(); } else if (cmd.equals("resetHess")) { dir.resetHessian(); } else super.execute(cmd,env); } private boolean releaseDimensions(Datum P) { if (cons.release(P)) { dir.resetDimension(cons.getReleasedDimension()); int p=cons.getReleasableDimensions()-1; // going to release a percentage of releasable dims? // or absolute number? p=(int)(percentage.value*p); // if (p>1) p=1; for (; p>0; p--) { cons.release(P); dir.resetDimension(cons.getReleasedDimension()); } return true; } return false; } public void run() { double beta; int i, maxiter=getMaxiter(); boolean triedSteepest=false; // we start from the current state instead. // cons.initialise should set up the constraints // to reflect the current state. cons.initialise(); evaluate(); releaseDimensions(P1); if (cons.activeCount()==0) { iters.next(0); sig3.off(); return; } sig1.off(); // must reset hessian for active dimensions cons.zeroInactive(P2.x); dir.resetHessian(); dir.hessin.changed(); dir.init(); setSlope(); beta = initialStep(); // beta = beta.value; ?? for (i=0; i<maxiter; i++) { // constrained line search with initial step beta0 lstest.init(); cons.lineSearch(lstest,ls,beta); lsiters.next(lstest.count); steplength.next(alpha); if (lstest.tiny && (P2.f>=P1.f)) { // tiny step was no good sig1.on(); sig2.off(); if (gconv.isSatisfied(P1.g,cons)) break; if (triedSteepest) break; sig2.on(); beta = this.beta.value; dir.update(); // ?? if (dir.uvc) dir.init(); else dir.steepest(); setSlope(); triedSteepest=true; continue; } // check gradients at P2 if (!releaseDimensions(P2)) { // don't quit if any dimensions released if (cons.activeCount()==0) break; if (xfconv.isSatisfied(this)) { if (gconv.isSatisfied(P2.g,cons)) break; } } // beta = beta.value; beta = nextStep(); dir.update(); move(); perIteration(); } perOptimisation(i); dir.hessin.changed(); } }