@@ -0,0 +1,1267 @@
+package org.antlr.codebuff;%0A%0Aimport java.util.Arrays;%0Aimport java.util.function.Function;%0A%0Apublic class Optimizer %7B%0A%09/** Use a simple gradient descent approach to find weights */%0A%09public static double%5B%5D minimize(Function%3Cdouble%5B%5D, Double%3E f, double%5B%5D x0, double eta, double h, double precision) %7B%0A%09%09double%5B%5D x = Arrays.copyOf(x0, x0.length);%0A%09%09double%5B%5D prev_x = null;%0A%09%09while ( true ) %7B%0A%09%09%09prev_x = x;%0A%09%09%09double finite_diff = f.apply(vector_scalar_add(x,h)) - f.apply(x);%09// division by h rolls into learning rate%0A%09%09%09x = vector_scalar_sub(x, eta * finite_diff);                 %09%09// decelerates x jump as it flattens out%0A%09%09%09// print %22f(%251.12f) = %251.12f%22 %25 (x, f(x)),%0A%09%09%09double delta = f.apply(x) - f.apply(prev_x);%0A%09%09%09// print %22, delta = %251.20f%22 %25 delta%0A%09%09%09// stop when small change in vertical but not heading down%0A%09%09%09if ( delta %3E= 0 && Math.abs(delta) %3C precision ) %7B%0A%09%09%09%09break;%0A%09%09%09%7D%0A%09%09%7D%0A%09%09return x;%0A%09%7D%0A%0A%09public static double%5B%5D vector_scalar_add(double%5B%5D x, double v) %7B%0A%09%09double%5B%5D y = new double%5Bx.length%5D;%0A%09%09for (int i = 0; i%3Cx.length; i++) %7B%0A%09%09%09y%5Bi%5D = x%5Bi%5D + v;%0A%09%09%7D%0A%09%09return y;%0A%09%7D%0A%0A%09public static double%5B%5D vector_scalar_sub(double%5B%5D x, double v) %7B%0A%09%09double%5B%5D y = new double%5Bx.length%5D;%0A%09%09for (int i = 0; i%3Cx.length; i++) %7B%0A%09%09%09y%5Bi%5D = x%5Bi%5D - v;%0A%09%09%7D%0A%09%09return y;%0A%09%7D%0A%7D%0A

add optimizer function