/*
 * This file is part of the ESO UVES Pipeline
 * Copyright (C) 2004,2005 European Southern Observatory
 *
 * 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, 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA
 */

/*
 * $Author: amodigli $
 * $Date: 2011-12-08 13:54:13 $
 * $Revision: 1.25 $
 * $Name: not supported by cvs2svn $
 * $Log: not supported by cvs2svn $
 * Revision 1.24  2010/09/24 09:32:09  amodigli
 * put back QFITS dependency to fix problem spot by NRI on FIBER mode (with MIDAS calibs) data
 *
 * Revision 1.22  2007/09/11 17:08:49  amodigli
 * mooved uves_polynomial_convert_from_plist_midas to uves_dfs
 *
 * Revision 1.21  2007/06/20 08:30:03  amodigli
 * added index parameter to support FIBER mode lintab in uves_polynomial_convert_from_plist_midas
 *
 * Revision 1.20  2007/06/06 08:17:33  amodigli
 * replace tab with 4 spaces
 *
 * Revision 1.19  2007/05/03 15:18:31  jmlarsen
 * Added function to add polynomials
 *
 * Revision 1.18  2007/04/24 12:50:29  jmlarsen
 * Replaced cpl_propertylist -> uves_propertylist which is much faster
 *
 * Revision 1.17  2007/03/19 15:04:57  jmlarsen
 * Added get_degree function
 *
 * Revision 1.16  2007/03/05 10:20:51  jmlarsen
 * Added uves_polynomial_delete_const()
 *
 * Revision 1.15  2006/08/17 13:56:53  jmlarsen
 * Reduced max line length
 *
 * Revision 1.14  2006/04/24 09:28:29  jmlarsen
 * Added function to create zero-polynomial
 *
 * Revision 1.13  2005/12/19 16:17:56  jmlarsen
 * Replaced bool -> int
 *
 */
#ifndef UVES_UTILS_POLYNOMIAL_H
#define UVES_UTILS_POLYNOMIAL_H

/*-----------------------------------------------------------------------------
                                   Includes
 -----------------------------------------------------------------------------*/

#include <uves_propertylist.h>
#include <cpl.h>
#include <uves_cpl_size.h>
/*-----------------------------------------------------------------------------
                                   Typedefs
 -----------------------------------------------------------------------------*/

typedef struct _polynomial polynomial ;

/*-----------------------------------------------------------------------------
                                   Prototypes
 -----------------------------------------------------------------------------*/


polynomial *uves_polynomial_new(const cpl_polynomial *pol);
polynomial *uves_polynomial_new_zero(int dim);
polynomial *uves_polynomial_duplicate(const polynomial *p);


polynomial *uves_polynomial_convert_from_table(cpl_table *t);
polynomial *uves_polynomial_collapse(const polynomial *p, int varno, double value);
polynomial * uves_polynomial_fit_1d(const cpl_vector    *   x_pos,
                    const cpl_vector    *   values,
                    const cpl_vector    *   sigmas,
                    int                     poly_deg,
                    double              *   mse);
polynomial *uves_polynomial_fit_2d(const cpl_bivector     *  xy_pos,
                   const cpl_vector       *  values,
                   const cpl_vector       *  sigmas,
                   int                       poly_deg1,
                   int                       poly_deg2,
                   double                 *  mse,
                   double                 *  red_chisq,
                   polynomial             ** variance);

polynomial *uves_polynomial_add_2d(const polynomial *p1, const polynomial *p2);

int uves_polynomial_get_degree(const polynomial *p);

void uves_polynomial_delete(polynomial **p);
void uves_polynomial_delete_const(const polynomial **p);

cpl_table     *uves_polynomial_convert_to_table(const polynomial *p);
int            uves_polynomial_get_dimension(const polynomial *p);
void           uves_polynomial_dump(const polynomial *p, FILE *stream);
cpl_error_code uves_polynomial_shift(polynomial *p, int varno, double shift);
cpl_error_code uves_polynomial_rescale(polynomial *p, int varno, double scale);
double         uves_polynomial_get_coeff_1d(const polynomial *p, int degree);
double         uves_polynomial_get_coeff_2d(const polynomial *p,
                        int degree1, int degree2);
double         uves_polynomial_evaluate_1d(const polynomial *p, double x);
double         uves_polynomial_evaluate_2d(const polynomial *p, double x1, double x2);
double         uves_polynomial_solve_1d(const polynomial *p, double value, 
                    double guess, int multiplicity);
double         uves_polynomial_solve_2d(const polynomial *p, double value, 
                    double guess, int multiplicity, 
                    int varno, double x_value);
double         uves_polynomial_derivative_1d(const polynomial *p, double x);
double         uves_polynomial_derivative_2d(const polynomial *p, double x1,
                         double x2, int varno);
cpl_error_code uves_polynomial_derivative(polynomial *p, int varno);

#endif
