/** * @param function * @param lineSearcher * @param guess * @param direction * @return */ protected double[] doLineSearch( DifferentiableFunction function, BacktrackingLineSearcher lineSearcher, double[] guess, double[] direction) { return lineSearcher.minimize(function, guess, direction); }
public double[] minimize(DifferentiableFunction function, double[] initial, double tolerance) { boolean printProgress = true; BacktrackingLineSearcher lineSearcher = new BacktrackingLineSearcher(); double[] guess = DoubleArrays.clone(initial); // this grows linearly as the iterations go on (if stepSizeGrowthAmount // > 0.0) // but gets scaled back geometrically by lineSearcher double stepSize = initialStepSize; for (int iteration = 0; iteration < maxIterations; iteration++) { if (stepSizeGrowthAmount == 0.0) stepSize = initialStepSize; else { stepSize *= stepSizeGrowthAmount; } double[] subgradient = function.derivativeAt(guess); double value = function.valueAt(guess); double[] direction = subgradient; DoubleArrays.scale(direction, -1.0); if (iteration == 0) lineSearcher.stepSizeMultiplier = initialStepSizeMultiplier; else lineSearcher.stepSizeMultiplier = stepSizeMultiplier; lineSearcher.initialStepSize = stepSize; double[] nextGuess = doLineSearch(function, lineSearcher, guess, direction); stepSize = lineSearcher.getFinalStepSize(); double[] nextDerivative = function.derivativeAt(nextGuess); double nextValue = function.valueAt(nextGuess); if (printProgress) { Logger.i().logs("[Subgradient] Iteration %d: %.6f", iteration, nextValue); } if (iteration >= minIterations && converged(value, nextValue, tolerance)) { return nextGuess; } guess = nextGuess; value = nextValue; subgradient = nextDerivative; } return guess; }