public float MomentumBasedGradientDescent(Single1D p, Single1D df, Single1D v, Func <int, float> func, float eta, float mu) { int n = p.Count; if (n != df.Count) { throw new UnequalValueException(n, df.Count, 750074); } float f2 = float.NaN; for (int iter = 0; iter < MaxIter; iter++) { float f1 = f2; v = mu * v - eta * df; f2 = func(iter); if (EndCriteriumMet(f1, f2)) { break; } for (int j = 0; j < n; j++) { float temp = mu * v[j] - eta * df[j]; v[j] = temp; p[j] += temp; } } return(f2); }
// ---------------------------------------------------------------------------------------- #region Minimization public float GradientDescent(Single1D p, Single1D df, Func <int, float> func, float eta) { int n = p.Count; if (n != df.Count) { throw new UnequalValueException(n, df.Count, 750074); } float f2 = float.NaN; for (int iter = 0; iter < MaxIter; iter++) { float f1 = f2; f2 = func(iter); if (EndCriteriumMet(f1, f2)) { break; } for (int j = 0; j < n; j++) { p[j] -= eta * df[j]; } } return(f2); }
public static string ArrayToString(Single1D x) { int n = x.Count; StringBuilder builder = new StringBuilder(); for (int i = 0; i < n; i++) { if (builder.Length > 0) { builder.Append(", "); } builder.Append(x[i].ToString("F3")); } return(builder.ToString()); }
public float Calculate(Single1D x, Single1D df) { int n = N; if (n != x.Count) { throw new UnequalValueException(n, x.Count, 539428); } if (n != df.Count) { throw new UnequalValueException(n, df.Count, 624376); } double f = 0f; for (int i = 0; i <= n; i++) { double xi = i < n ? x[i] : 1f; for (int j = 0; j <= n; j++) { double xj = j < n ? x[j] : 1f; for (int k = 0; k <= n; k++) { double xk = k < n ? x[k] : 1f; f += _c[i, j, k] * xi * xj * xk; } } } double[] df2 = new double[n]; for (int l = 0; l < n; l++) { df2[l] = 0; } for (int i = 0; i <= n; i++) { double xi = i < n ? x[i] : 1f; for (int j = 0; j <= n; j++) { double xj = j < n ? x[j] : 1f; for (int k = 0; k <= n; k++) { double xk = k < n ? x[k] : 1f; for (int l = 0; l < n; l++) { double t = 0f; if (i == l && j == l && k == l) { t = 3 * xi * xi; } else if (i == l && j == l) { t = 2 * xi * xk; } else if (i == l && k == l) { t = 2 * xi * xj; } else if (j == l && k == l) { t = 2 * xj * xk; } else if (i == l) { t = xj * xk; } else if (j == l) { t = xi * xk; } else if (k == l) { t = xi * xj; } df2[l] += _c[i, j, k] * t; } } } } for (int l = 0; l < n; l++) { df[l] = (float)(f * df2[l]); } f = 0.5f * f * f; return((float)f); }
public float ConjugateGradient(Single1D p2, Single1D df2, Func <int, float> func, float alpha) // Frprmn { int n = p2.Count; float[] p1 = new float[n]; float[] df1 = new float[n]; float[] g = new float[n]; float[] h = new float[n]; float f2 = func(0); Console.WriteLine($"{0:000}: f({ArrayToString(p2)}) = {f2:E3}"); for (int j = 0; j < n; j++) { float t = -df2[j]; g[j] = t; h[j] = t; df1[j] = t; } for (int iter = 0; iter < MaxIter; iter++) { float f1 = f2; for (int j = 0; j < n; j++) { p1[j] = p2[j]; } for (int j = 0; j < n; j++) { df1[j] = df2[j]; } float xmin, dfmin; (xmin, f2, dfmin) = DBrentPlus(0f, alpha, DBrentTol, x1 => { for (int j = 0; j < n; j++) { p2[j] = p1[j] - x1 * df1[j]; } float fx = func(iter); Console.WriteLine($" x1 = {x1:F3}: f({ArrayToString(p2)}) = {fx:E3}"); float dfx = 0; for (int j = 0; j < n; j++) { dfx += df2[j] * df1[j]; } return(fx, dfx); }); Console.WriteLine($"{iter + 1:000}: f({ArrayToString(p2)}) = {f2:E3}"); if (EndCriteriumMet(f1, f2)) { break; } float gg = 0f, dgg = 0f; for (int j = 0; j < n; j++) { gg += Sqr(g[j]); switch (MinimizationAlgorithm) { case MinimizationAlgorithmEnum.PolakRibiere: dgg += (df1[j] + g[j]) * df1[j]; break; case MinimizationAlgorithmEnum.FletcherReeves: dgg += Sqr(df1[j]); break; default: throw new InvalidCaseException(nameof(MinimizationAlgorithm), MinimizationAlgorithm, 374911); } } if (gg == 0f) { break; } float gam = dgg / gg; for (int j = 0; j < n; j++) { g[j] = -df1[j]; h[j] = g[j] + gam * h[j]; df1[j] = h[j]; } } return(f2); }