/*===========================================================================
  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
  ===========================================================================*/
/*-------------------------------------------------------------------------*/
/**
 * @defgroup flames_getordslope Substep: Get the order slope 
 *
 */
/*-------------------------------------------------------------------------*/

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

#include <math.h>
#include <flames_midas_def.h>
#include <flames_uves.h>
#include <flames_getordslope.h>
#include <flames_newmatrix.h>

/**@{*/

/*---------------------------------------------------------------------------
  Implementation
  ---------------------------------------------------------------------------*/
/**
   @name  flames_getordslope()  
   @short Get the order slope 
   @author G. Mulas  -  ITAL_FLAMES Consortium. Ported to CPL by A. Modigliani
   @param ordpos pointer to orderpos 
   @param m      order value
   @param x      order position
   @param slope  Output (order) slope

   @return success or failure code

   DRS Functions called:          
   singlecorrel                                                       
   dvector                                                             
   free_dvector                                                        
                                                                          
   Pseudocode:                                                             
   Use polynomial coefficients to get the order slope                     
 
   @doc
   the following function calculates the slope of the 
   center of a given order "m" at a given "x", 
   and returns it in the double variable to which "slope" points. 
   Beware: both "m" and "n" are double! 

*/


flames_err 
get_ordslope(
             orderpos *ordpos, 
	     double m,
             double x, 
             double *slope)

{
  /*TO DO: check for sanity of the input parameters m and x? */
  int ordx=0;
  int ordm=0;
  double *xpowers=0;
  double *mpowers=0;

  mpowers = dvector(0, ordpos->mdegree);
  xpowers = dvector(0, ordpos->xdegree);

  /* build the vectors of powers */
  mpowers[0] = xpowers[1] = 1;
  for (ordm=1; ordm <= ordpos->mdegree; ordm++) {
    mpowers[ordm] = mpowers[ordm-1]*m;
  }
  /* compute directly derivatives of x powers */
  for (ordx=2; ordx <= ordpos->xdegree; ordx++) {
    xpowers[ordx] = xpowers[ordx-1]*x*(double)ordx;
    //xpowers[ordx] = xpowers[ordx-1]*(doubflames_getordslope.cle)ordx;
  }
  /* initialise the slope */
  *slope=0;
  /* loop over powers of the polynomial. If the order of the polynomial
     is 0 in x, the loop is never actually executed */
  if(ordpos->xdegree >= 1) {
    /* treat the linear part in x separately, in order to avoid stupid
       undeterminations in the case 0^0 */
    *slope += ordpos->orderpol[0][1];
    for (ordm=1; ordm <= ordpos->mdegree; ordm++) {
      *slope += ordpos->orderpol[ordm][1]*mpowers[ordm];
    }

    for (ordx=2; ordx <= ordpos->xdegree && ordx<=2; ordx++) {
       //   for (ordx=2; ordx <= ordpos->xdegree; ordx++) {
      *slope += ((ordpos->orderpol)[0][ordx])*xpowers[ordx];
      for (ordm=1; ordm <= ordpos->mdegree; ordm++) {
	/* add the contribution of each power to the order slope */
	*slope += ordpos->orderpol[ordm][ordx]*xpowers[ordx]*mpowers[ordm];
      }
    }
  }

  free_dvector(mpowers, 0, ordpos->mdegree);
  free_dvector(xpowers, 0, ordpos->xdegree);

  return(NOERR);
}

/**@}*/
