private void UpdateDiagMinErr(double[] diag, double[] s, double[] y) { double low = 0.0; double high = 0.0; for (int i = 0; i < s.Length; i++) { double tmp = s[i] * (y[i] - diag[i]); high += tmp * tmp; } Say("M"); double alpha = System.Math.Sqrt((ArrayMath.Norm(y) / ArrayMath.Norm(s))) * System.Math.Sqrt((50.0 / (50.0 + k))); alpha = alpha * System.Math.Sqrt(ArrayMath.Average(diag)); Say(" alpha " + nf.Format(alpha)); high = System.Math.Sqrt(high) / (2 * alpha); IDoubleUnaryOperator func = new ScaledSGDMinimizer.Lagrange(s, y, diag, alpha); double lamStar; if (func.ApplyAsDouble(low) > 0) { lamStar = GetRoot(func, low, high); } else { lamStar = 0.0; Say(" * "); } for (int i_1 = 0; i_1 < s.Length; i_1++) { diag[i_1] = (System.Math.Abs(y[i_1] * s[i_1]) + 2 * lamStar * diag[i_1]) / (s[i_1] * s[i_1] + 1e-8 + 2 * lamStar); //diag[i] = (y[i]*s[i] + 2*lamStar*diag[i])/(s[i]*s[i] + 2*lamStar); if (diag[i_1] <= 1.0 / aMax) { diag[i_1] = 1.0 / gain; } } }