/*===========================================================================
  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);
}

/**@}*/
