/* @(#)fitfunc.c	19.1 (ESO-IPG) 02/25/03 14:21:24 */
/* 

   Otmar Stahl
   
   fitfunc.c 

   Gauss-Hermite fitting routine
   determines Gauss-Hermite moments of line profiles

*/

/* system includes */

#include <math.h>
#include <stdio.h>

/* general Midas includes */


#include <midas_def.h>

/* FEROS specific includes */

#include "cpl_matrix.h"
#include <nrutil.h>
#include <fitnol.h>
#include <misc.h>
#include <fitfunc.h>

void
dhermite(double x, double p[], int np);

/*           Fit Gauss-Hermite function                        */
/*           uses   lsqfit, fit_gauss                           */
void 
#ifdef __STDC__
fit_gh (double *Xgaus, double *Ygaus, int npix, double *A, 
	int ncoef, double *coef)
#else
     fit_gh (Xgaus, Ygaus, npix, A, ncoef, coef)
     double *Xgaus, *Ygaus, *A, *coef; 
     int   npix, ncoef;
#endif
{
  
  int i, imax;
  double max;

  imax = npix / 2;
  max = -1e99;

  for (i=1; i<=npix; i++)
    {
      if (Ygaus[i]>max)
	{
	  max = Ygaus[i];
	  imax = i;
	}
    }
  A[1] = Ygaus[imax];
  A[2] = Xgaus[imax];
  A[3] = fabs(Xgaus[2]-Xgaus[1])*2.;
      
  fit_gauss (Xgaus, Ygaus, npix, A, 3);
  
  for (i=1; i<=npix; i++)
    {
      Xgaus[i] = (Xgaus[i] - A[2]) / A[3] ;
      Ygaus[i] = Ygaus[i] / A[1];
    }


  lsqfit_nr(Xgaus, Ygaus, NULL, npix, coef, ncoef, &dhermite);
}

void 
dhermite (double x, double p[], int np)
{

  /* Gauss-Hermite fitting routine */

  int facul[10] = {1,1,2,6,24,120,720,5040,40320,362880};
  int powerof2[10] = {1,2,4,8,16,32,64,128,256,512};
  int i;

  double exp1, h[10];

  /* compute Gauss-Hermite functions from recursion relation 
     Up to 8 fit parameters are allowed */

  h[0] = 1.0;
  h[1] = 2 * x;

  for (i=2; i<=np+1; i++)
    h[i] = 2 * x  * h[i-1] - 2 * (i-1) * h[i-2];

  /* h1 and h2 are zero for best fitting gaussian */

  exp1 = exp( -(x*x) / 2.0 );

  p[1] = h[0] * exp1;

  for (i=2; i <= np; i++)
    {
      p[i] = exp1 * h[i+1] /  sqrt( (double) ( facul[i+1] * powerof2[i+1]));
    }
}

