/*===========================================================================
  Copyright (C) 2001 European Southern Observatory (ESO)
 
  This program is free software; you can redistribute it and/or 
  modify it under the terms of the GNU General Public License as 
  published by the Free Software Foundation; either version 2 of 
  the License, or (at your option) any later version.
 
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
 
  You should have received a copy of the GNU General Public 
  License along with this program; if not, write to the Free 
  Software Foundation, Inc., 675 Massachusetss Ave, Cambridge, 
  MA 02139, USA.
 
  Corresponding concerning ESO-MIDAS should be addressed as follows:
    Internet e-mail: midas@eso.org
    Postal address: European Southern Observatory
            Data Management Division 
            Karl-Schwarzschild-Strasse 2
            D 85748 Garching bei Muenchen 
            GERMANY
===========================================================================*/
/* Program  : lfit.c                                                       */
/* Author   : G. Mulas  -  ITAL_FLAMES Consortium (adapted by NR)          */
/* Date     :                                                              */
/*                                                                         */
/* Purpose  : linear fit                                                   */
/*                                                                         */
/*                                                                         */
/* Input:  see interface                                                   */ 
/*                                                                      */
/* Output:                                                              */
/*                                                                         */
/* DRS Functions called:                                                   */
/* none                                                                    */ 
/*                                                                         */ 
/* Pseudocode:                                                             */
/* Missing                                                                 */ 
/*                                                                         */ 
/* Version  :                                                              */
/* Last modification date: 2002/08/05                                      */
/* Who     When        Why                Where                            */
/* AMo     02-08-05   Add header         header                            */
/*-------------------------------------------------------------------------*/

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <flames_lfit.h>
#include <flames_dgaussj.h>
#include <flames_midas_tblsys.h>
#include <flames_midas_tblerr.h>
#include <flames_midas_tbldef.h>
#include <flames_midas_macrogen.h>
#include <flames_midas_atype.h>
#include <flames_midas_def.h>
#include <math.h>
#include <flames_uves.h>
#include <flames_newmatrix.h>
#include <flames_covsrt.h>
#define NRANSI


void lfit(double x[], double y[], double sig[], int32_t ndat, double a[], 
      int ia[], int ma, double **covar, double *chisq, 
      void (*funcs)(double, double [], int))
{

    int i=0;
    int j=0;
    int k=0;
    int l=0;
    int m=0;
    int mfit=0;
    double ym=0;
    double wt=0;
    double sum=0;
    double sig2i=0;
    double **beta=0;
    double *afunc=0;
    double dbuf=0;

    beta=dmatrix(1,ma,1,1);
    afunc=dvector(1,ma);
    for (i=1; i<=ma; i++) {
      beta[i][1] = 0;
      afunc[i] = 0;
    }
    for (j=1;j<=ma;j++)
        if (ia[j]) mfit++;
    if (mfit == 0) nrerror("lfit: no parameters to be fitted");
    for (j=1;j<=mfit;j++) {
        for (k=1;k<=mfit;k++) covar[j][k]=0.0;
        beta[j][1]=0.0;
    }
    for (i=1;i<=ndat;i++) {
        (*funcs)(x[i],afunc,ma);
        ym=y[i];
        if (mfit < ma) {
            for (j=1;j<=ma;j++)
                if (!ia[j]) ym -= a[j]*afunc[j];
        }
        sig2i=1.0/(sig[i]*sig[i]);
        for (j=0,l=1;l<=ma;l++) {
            if (ia[l]) {
                wt=afunc[l]*sig2i;
                for (j++,k=0,m=1;m<=l;m++)
                    if (ia[m]) covar[j][++k] += wt*afunc[m];
                beta[j][1] += ym*wt;
            }
        }
    }
    for (j=2;j<=mfit;j++)
        for (k=1;k<j;k++)
            covar[k][j]=covar[j][k];
    dgaussj(covar,mfit,beta,1);
    for (j=0,l=1;l<=ma;l++)
        if (ia[l]) a[l]=beta[++j][1];
    *chisq=0.0;
    for (i=1;i<=ndat;i++) {
        (*funcs)(x[i],afunc,ma);
        for (sum=0.0,j=1;j<=ma;j++) sum += a[j]*afunc[j];
        dbuf = (y[i]-sum)/sig[i];
        *chisq += dbuf*dbuf;
    }
    covsrt(covar,ma,ia,mfit);
    free_dvector(afunc,1,ma);
    free_dmatrix(beta,1,ma,1,1);
}
#undef NRANSI
/* (C) Copr. 1986-92 Numerical Recipes Software m#. */











