/** * L2-norm */ public static double l2norm(double[] v) { return Math.sqrt(innerProduct(v, v)); }
/** * L-BFGS two-loop recursion (see Nocedal & Wright 2006, Numerical Optimization, p. 178) */ private void computeDirection(double[] direction) { // Implemented two-loop Hessian update method. int k = updateInfo.kCounter; double[] rho = updateInfo.rho; double[] alpha = updateInfo.alpha; // just to avoid recreating alpha double[][] S = updateInfo.S; double[][] Y = updateInfo.Y; // First loop for (int i = k - 1; i >= 0; i--) { alpha[i] = rho[i] * ArrayMath.innerProduct(S[i], direction); for (int j = 0; j < dimension; j++) { direction[j] = direction[j] - alpha[i] * Y[i][j]; } } // Second loop for (int i = 0; i < k; i++) { double beta = rho[i] * ArrayMath.innerProduct(Y[i], direction); for (int j = 0; j < dimension; j++) { direction[j] = direction[j] + S[i][j] * (alpha[i] - beta); } } for (int i = 0; i < dimension; i++) { direction[i] = -direction[i]; } }
@Override public double valueAt(double[] x) { checkDimension(x); double value = f.valueAt(x); if (l2Cost > 0) { value += l2Cost * ArrayMath.innerProduct(x, x); } return value; }
double valueAtNextPoint; double dirGradientAtX = ArrayMath.innerProduct(direction, gradAtX);