annotate src/samer/maths/opt/Positivity.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
samer@0 15 /**
samer@0 16 Cubic line search with positivity constraints
samer@0 17 dimensions become inactive when they go to
samer@0 18 zero and the gradient > GEPS
samer@0 19 */
samer@0 20
samer@0 21 public class Positivity extends Constraints
samer@0 22 {
samer@0 23 double XEPS=1e-6;
samer@0 24 double GEPS=1e-4;
samer@0 25 int [] zerod;
samer@0 26 int released;
samer@0 27
samer@0 28 public Positivity(MinimiserBase minimiser)
samer@0 29 {
samer@0 30 super(minimiser);
samer@0 31 zerod=new int[n];
samer@0 32
samer@0 33 minimiser.add(new VParameter("XEPS", new DoubleModel() {
samer@0 34 public void set(double t) { XEPS=t; }
samer@0 35 public double get() { return XEPS; }
samer@0 36 } )
samer@0 37 );
samer@0 38
samer@0 39 minimiser.add(new VParameter("GEPS", new DoubleModel() {
samer@0 40 public void set(double t) { GEPS=t; }
samer@0 41 public double get() { return GEPS; }
samer@0 42 } )
samer@0 43 );
samer@0 44 }
samer@0 45
samer@0 46 /** constrain all dimensions which are currently set
samer@0 47 to zero.
samer@0 48 */
samer@0 49
samer@0 50 public void initialise()
samer@0 51 {
samer@0 52 int p=0, q=0;
samer@0 53
samer@0 54 for (int i=0; i<n; i++) {
samer@0 55 if (S.P1.x[i]<=0) { inactive[p++]=i; S.P1.x[i]=0; }
samer@0 56 else active[q++]=i;
samer@0 57 }
samer@0 58 m=q;
samer@0 59 }
samer@0 60
samer@0 61 /**
samer@0 62 This finds the constrained dimension with the
samer@0 63 largest positive gradient, and if of
samer@0 64 that gradient is bigger than 1, then releases
samer@0 65 that dimension so that it can take part in the
samer@0 66 optimization
samer@0 67 */
samer@0 68
samer@0 69 public boolean release(Datum P)
samer@0 70 {
samer@0 71 if (m==n) return false;
samer@0 72
samer@0 73 int imax=-1;
samer@0 74 double grad=-GEPS; // tolerance
samer@0 75
samer@0 76 for (int k=0; k<(n-m); k++) {
samer@0 77 int j=inactive[k];
samer@0 78 if (P.g[j]<grad) {
samer@0 79 grad=P.g[j];
samer@0 80 imax=j;
samer@0 81 }
samer@0 82 }
samer@0 83
samer@0 84 if (imax!=-1) { activate(imax); released=imax; return true; }
samer@0 85 else return false;
samer@0 86 }
samer@0 87
samer@0 88 public int getReleasedDimension() { return released; }
samer@0 89
samer@0 90 /**
samer@0 91 Take a step but make sure none of the coordinates
samer@0 92 becomes negative. This function returns true if
samer@0 93 any dimensions were inactivated - implying that
samer@0 94 we should finish the line search. The alternative
samer@0 95 is that even the clipped step was too long and
samer@0 96 we need to interpolate some more.
samer@0 97 */
samer@0 98
samer@0 99 public boolean clipStep(double beta)
samer@0 100 {
samer@0 101
samer@0 102 step(beta);
samer@0 103
samer@0 104
samer@0 105 // got to find sign swappers
samer@0 106 int imin=-1;
samer@0 107 double alphamin=beta; // ??
samer@0 108
samer@0 109 for (int k=0; k<m; k++) {
samer@0 110 int i=active[k];
samer@0 111 if (S.P2.x[i]<=XEPS) {
samer@0 112 double alpha=-S.P1.x[i]/S.h[i];
samer@0 113 if (imin==-1 || alpha<alphamin) {
samer@0 114 imin=i;
samer@0 115 alphamin=alpha;
samer@0 116 }
samer@0 117 }
samer@0 118 }
samer@0 119
samer@0 120 // if no negative values, evaluate and return
samer@0 121 if (imin==-1) { S.eval2(); return false; }
samer@0 122
samer@0 123 // atlease one dimension has become
samer@0 124 // zero or negative. imin was the first
samer@0 125 // what if alphamin=0?
samer@0 126 step(alphamin);
samer@0 127
samer@0 128 // now we should check for ANY unconstrained
samer@0 129 // x[i] being less than XEPS, and set it to
samer@0 130 // exactly zero, including, obviously x[j]
samer@0 131 int numzerod=0;
samer@0 132 for (int k=0; k<m; k++) {
samer@0 133 int j=active[k];
samer@0 134 if (S.P2.x[j]<=XEPS) {
samer@0 135 S.P2.x[j]=0;
samer@0 136 zerod[numzerod++]=j;
samer@0 137 }
samer@0 138 }
samer@0 139
samer@0 140 eval2();
samer@0 141
samer@0 142 // next, check zeroed dimensions
samer@0 143 // for constraint eligibilty
samer@0 144 boolean flag=false;
samer@0 145
samer@0 146 for (int k=0; k<numzerod; k++) {
samer@0 147 int j=zerod[k];
samer@0 148 if (S.P2.g[j]>=-GEPS) {
samer@0 149 inactivate(j);
samer@0 150 flag=true;
samer@0 151 }
samer@0 152 }
samer@0 153
samer@0 154 return flag;
samer@0 155 }
samer@0 156
samer@0 157
samer@0 158 public void lineSearch(Condition convergence, CubicLineSearch ls, double beta0)
samer@0 159 {
samer@0 160 if (clipStep(beta0)) return;
samer@0 161
samer@0 162 while (!convergence.test()) {
samer@0 163 // formulate any other direction change conditions
samer@0 164
samer@0 165 if (S.P2.f<S.P1.f && S.P2.s<0) {
samer@0 166 double beta=ls.extrapolate();
samer@0 167 S.move();
samer@0 168 if (clipStep(beta)) break;
samer@0 169 } else {
samer@0 170 // since both P1 and P2 must satisfy positivity
samer@0 171 // constraints, all points between them do alse,
samer@0 172 // so no worries about interpolation
samer@0 173 step(ls.interpolate());
samer@0 174 eval2();
samer@0 175 }
samer@0 176 }
samer@0 177 }
samer@0 178 }
samer@0 179