minimize method

List<double> minimize(
  1. List<double> start,
  2. double f(
    1. List<double> x
    )
)

Implementation

List<double> minimize(List<double> start, double Function(List<double>) f) {
  final n = start.length;
  final simplex = List.generate(n+1, (_) => List<double>.from(start));
  for (int i=1;i<=n;i++){
    simplex[i][i-1] = simplex[i][i-1].abs()>1e-3 ? simplex[i][i-1]*(1+0.05) : simplex[i][i-1]+2.5e-4;
  }
  var values = simplex.map(f).toList();

  for (int it=0; it<maxIter; it++) {
    final idx = List<int>.generate(n+1, (i)=>i)..sort((a,b)=>values[a].compareTo(values[b]));
    final sorted = idx.map((i)=>simplex[i]).toList();
    final vals   = idx.map((i)=>values[i]).toList();
    for (int i=0;i<=n;i++){simplex[i]=sorted[i]; values[i]=vals[i];}

    final m = values.reduce((a,b)=>a+b)/(n+1);
    double v=0; for (final x in values) v+=(x-m)*(x-m);
    if (math.sqrt(v/(n+1)) < 1e-7) break;

    final c = List<double>.filled(n,0.0);
    for (int i=0;i<n;i++) for (int j=0;j<n;j++) c[j]+=simplex[i][j];
    for (int j=0;j<n;j++) c[j]/=n;

    final xr = List<double>.generate(n, (j)=> c[j] + alpha*(c[j]-simplex[n][j]));
    final fr = f(xr);

    if (fr < values[0]) {
      final xe = List<double>.generate(n, (j)=> c[j] + gamma*(xr[j]-c[j]));
      final fe = f(xe);
      if (fe < fr) { simplex[n]=xe; values[n]=fe; }
      else { simplex[n]=xr; values[n]=fr; }
    } else if (fr < values[n-1]) {
      simplex[n]=xr; values[n]=fr;
    } else {
      final outside = fr < values[n];
      final xc = List<double>.generate(n, (j)=> outside
        ? c[j] + rho*(xr[j]-c[j])
        : c[j] + rho*(simplex[n][j]-c[j]));
      final fc = f(xc);
      if (fc < (outside ? fr : values[n])) { simplex[n]=xc; values[n]=fc; }
      else {
        for (int i=1;i<=n;i++){
          for (int j=0;j<n;j++) simplex[i][j] = simplex[0][j] + sigma*(simplex[i][j]-simplex[0][j]);
          values[i] = f(simplex[i]);
        }
      }
    }
  }
  int bi=0; for (int i=1;i<values.length;i++) if (values[i]<values[bi]) bi=i;
  return simplex[bi];
}