| 3 | import com.winvector.opt.def.ScalarFn; |
| 4 | |
| 5 | public final class LinMax { |
| 6 | public int maxInitialProbeLevels = 5; |
| 7 | public int maxGrowLevels = 5; |
| 8 | private static double golden = 2.0/(1.0+Math.sqrt(5.0)); // 0.618 |
| 9 | |
| 10 | public double maximize(final ScalarFn f, double f0, final double initialScale, final int maxSteps) { |
| 11 | int stepNum = 0; |
| 12 | if(Double.isNaN(f0)||Double.isInfinite(f0)) { |
| 13 | f0 = f.eval(0.0); |
| 14 | } |
| 15 | // start preparing a bracket around a maximum (aX,midX,bX) a three point ordered interval aX<midX<bX and max(f(aX),f(bX))<=f(midX) |
| 16 | double midX = 0; |
| 17 | double fmid = f0; |
| 18 | double aX = midX - initialScale; |
| 19 | double fA = f.eval(aX); |
| 20 | double bX = midX + initialScale; |
| 21 | double fB = f.eval(bX); |
| 22 | // establish bracket |
| 23 | while(fA>=fmid) { |
| 24 | final double step = midX-aX; |
| 25 | midX = aX; |
| 26 | fmid = fA; |
| 27 | aX -= 2*step; |
| 28 | fA = f.eval(aX); |
| 29 | if((++stepNum)>maxSteps) { |
| 30 | return midX; |
| 31 | } |
| 32 | } |
| 33 | while(fB>=fmid) { |
| 34 | final double step = bX - midX; |
| 35 | midX = bX; |
| 36 | fmid = fB; |
| 37 | bX += 2*step; |
| 38 | fB = f.eval(bX); |
| 39 | if((++stepNum)>maxSteps) { |
| 40 | return midX; |
| 41 | } |
| 42 | } |
| 43 | while(true) { |
| 44 | // now have f(midX) >= max(f(aX),f(bX)), maintain this and sub-divide larger interval |
| 45 | /* |
| 46 | System.out.println("\tf(" + aX + ")=" + fA |
| 47 | + "\tf(" + midX + ")=" + fmid |
| 48 | + "\tf(" + bX + ")=" + fB |
| 49 | + "\t\tgood: " + ((fmid>=fA)&&(fmid>=fB) && ((aX<midX && midX<bX)||(aX>midX && midX>bX)))); |
| 50 | */ |
| 51 | if(Math.abs(midX-aX)>=Math.abs(bX-midX)) { |
| 52 | final double pX = (1-golden)*aX+golden*midX; |
| 53 | final double fx = f.eval(pX); |
| 54 | if(fx>fmid) { |
| 55 | bX = midX; |
| 56 | fB = fmid; |
| 57 | midX = pX; |
| 58 | fmid = fx; |
| 59 | } else { |
| 60 | aX = pX; |
| 61 | fA = fx; |
| 62 | } |
nothing calls this directly
no outgoing calls
no test coverage detected