// Подпрограмма nelder, реализующая метод деформируемого многогранника.
// Содержимое файла minim.c
//
// (c) Boland 1994

#define MAXITER 200

float x[14][10];

float func(float*);

void nelder(float x0[10],float eps,float xN[10],float *fmin,int n)
{
  int i,j,h,l;
  float krit,fxh,fxl,fxn2,fxn3,f;
  errorlevel=0;
  for(i=0;i<=n;i++)
   for(j=0;j<n;j++)
     {
       x[i][j]=x0[j];
       if (i==(j+1)) x[i][j]+=5.0;
     }
  for(itern=0;itern<MAXITER;itern++)
  {
    h=l=0; fxh=fxl=func(x[0]);
    if (errorlevel) return;
    for(i=1;i<=n;i++)
    {
      fxn2=func(x[i]);
      if (errorlevel) return;
      if (fxn2<fxl)
	  { fxl=fxn2; l=i; }
      if (fxn2>fxh)
	  { fxh=fxn2; h=i; }
    }
    for(i=0;i<n;i++)
	iters[itern][i]=x[l][i];
    for(i=0;i<n;i++) x[11][i]=-x[h][i];
    for(i=0;i<=n;i++)
     for(j=0;j<n;j++)
      x[11][j]+=x[i][j];
    for(i=0;i<n;i++) x[11][i]/=n;
    fxn2=func(x[11]);
    if (errorlevel) return;
    krit=0;
    for(i=0;i<=n;i++)
    {
      fxn3=func(x[i])-fxn2;
      if (errorlevel) return;
      krit+=fxn3*fxn3;
    }
    krit/=(n+1);
    if (krit<=eps*eps)
        {
          *fmin=fxl;
          for(i=0;i<n;i++) xN[i]=x[l][i];
          return;
        }
    for(i=0;i<n;i++)
      x[12][i]=2*x[11][i]-x[h][i];
    fxn3=func(x[12]);
    if (errorlevel) return;
    if (fxn3>=fxh)
        {
          for(i=0;i<=n;i++)
            for(j=0;j<n;j++)
              x[i][j]=0.5*(x[i][j]+x[l][j]);
          continue;
        }
      else
        if (fxn3<fxl)
            {
              for(i=0;i<n;i++)
                x[13][i]=2*x[12][i]-x[11][i];
              f=func(x[13]);
              if (errorlevel) return;
              j=(f<fxn3)?13:12;
              for(i=0;i<n;i++) x[h][i]=x[j][i];
              continue;
            }
          else
           {
             for(i=0;i<n;i++)
             x[h][i]=0.5*(x[h][i]+x[11][i]);
             continue;
           }
  } 
  errorlevel=8;
  return;
}
