/*                                                                            *
 *   This file is part of the ESO SINFO Pipeline                              *
 *   Copyright (C) 2004,2005 European Southern Observatory                    *
 *                                                                            *
 *   This library 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: 2009-06-05 06:06:11 $
 * $Revision: 1.5 $
 * $Name: not supported by cvs2svn $
 *
 */

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

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif
#include<sinfo_msg.h>
//#include<sinfo_absolute.h>
#include<sinfo_boltzmann.h>
#include <cpl.h>
/*-----------------------------------------------------------------------------
                                Defines
 -----------------------------------------------------------------------------*/
static float  sqrarg ;
#define SQR(a) (sqrarg = (a) , sqrarg*sqrarg)
/*-----------------------------------------------------------------------------
                            Functions prototypes
 -----------------------------------------------------------------------------*/


/*----------------------------------------------------------------------------*/
/**
 * @defgroup sinfo_absolute_test  SINFO library unit tests
 */
/*----------------------------------------------------------------------------*/
/**@{*/

static cpl_error_code
sinfo_test_bolz(void){
    /*
    float
    sinfo_new_boltz ( float * xdat, float * parlist ) ;*/


    /*Test all possible NULL param options */
    float* xdat = NULL;
    float* parlist = NULL;
    const int ndat=4;
    float slope=0;

    /* 1st test both null input: */
    slope=sinfo_new_boltz(NULL, NULL) ;
    cpl_test_eq(slope, 0);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    parlist=cpl_calloc(ndat,sizeof(float)) ;
    slope=sinfo_new_boltz(NULL, parlist) ;
    cpl_test_eq(slope, 0);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    xdat=cpl_calloc(ndat,sizeof(float)) ;
    slope=sinfo_new_boltz(xdat, NULL) ;
    cpl_test_eq(slope, 0);
    cpl_test_error(CPL_ERROR_NULL_INPUT);


    /* For defined values we have the following cases:
     */

    /* case 1:
     * (parlist[0] - parlist[1]) / (1 + exp(( xdat[0] - parlist[2] ) /
                                    parlist[3])) + parlist[1] ;
     * */
    xdat[0]=0;
    xdat[1]=1;
    xdat[2]=2;
    xdat[3]=3;

    parlist[0]=1;
    parlist[1]=2;
    parlist[2]=10;
    parlist[3]=20;
    float result=(parlist[0] - parlist[1]) / (1 + exp(( xdat[0] - parlist[2] ) /
                    parlist[3])) + parlist[1] ;

    slope=sinfo_new_boltz(xdat, parlist) ;
    cpl_test_eq(slope, result);
    cpl_test_error(CPL_ERROR_NONE);

    /* free memory */
    cpl_free(xdat);
    cpl_free(parlist);

    return cpl_error_get_code();
}

static cpl_error_code
sinfo_test_bolz_deriv(void){

    /*  void
    sinfo_new_boltz_deriv( float * xdat, float * parlist, float * dervs ) ;
     */



    /*Test all possible NULL param options */
    float* xdat = NULL;
    float* parlist = NULL;
    float* dervs = NULL;
    const int ndat=4;
    float slope=0;

    /* 1st test both null input: */
    sinfo_new_boltz_deriv(NULL, NULL,NULL) ;
    cpl_test_eq(slope, 0);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    parlist=cpl_calloc(ndat,sizeof(float)) ;
    xdat=cpl_calloc(ndat,sizeof(float)) ;
    dervs=cpl_calloc(ndat,sizeof(float)) ;

    sinfo_new_boltz_deriv(NULL, parlist,dervs) ;
    cpl_test_eq(slope, 0);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    sinfo_new_boltz_deriv(xdat, NULL,dervs) ;
    cpl_test_eq(slope, 0);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    sinfo_new_boltz_deriv(xdat, parlist,NULL) ;
    cpl_test_eq(slope, 0);
    cpl_test_error(CPL_ERROR_NULL_INPUT);


    /* For defined values we have the following cases:
     */

    /* case 1:
     * if ( xdat[0] <= parlist[0] ) return
     *  dervs[0] = 0. ;
        dervs[1] = 0. ;
        dervs[2] = 1. ;
        dervs[3] = 0. ;
     * ;
     * */
    xdat[0]=0;
    xdat[1]=1;
    xdat[2]=2;
    xdat[3]=3;

    parlist[0]=1;
    parlist[1]=2;
    parlist[2]=10;
    parlist[3]=20;

    float subst ;
    float* result=cpl_calloc(ndat,sizeof(float)) ;
    subst = (xdat[0] - parlist[2]) / parlist[3] ;

    result[0] = 1. / ( 1. + exp(subst) ) ;

    result[1] = -1. / ( 1. + exp(subst) ) + 1. ;

    result[2] = ( (parlist[0] - parlist[1]) / parlist[3] * exp(subst) ) /
                    ( (1. + exp(subst)) * (1. + exp(subst)) ) ;

    result[3] = ( (parlist[0] - parlist[1]) * (xdat[0] - parlist[2]) /
                    (parlist[3]*parlist[3]) * exp(subst) ) /
                    ( (1. + exp(subst)) * (1. + exp(subst)) ) ;

    sinfo_new_boltz_deriv(xdat, parlist,dervs) ;

    cpl_test_eq(dervs[0], result[0]);
    cpl_test_eq(dervs[1], result[1]);
    cpl_test_eq(dervs[2], result[2]);
    cpl_test_eq(dervs[3], result[3]);

    cpl_test_error(CPL_ERROR_NONE);


    /* free memory */
    cpl_free(xdat);
    cpl_free(parlist);
    cpl_free(dervs);
    cpl_free(result);

    return cpl_error_get_code();
}

static cpl_error_code
sinfo_test_lsqfit(void){
/*
    int sinfo_new_lsqfit ( float * xdat,
                 int   * xdim,
                 float * ydat,
                 float * wdat,
                 int   * ndat,
                 float * fpar,
                 float * epar,
                 int   * mpar,
                 int   * npar,
                 float * tol ,
                 int   * its ,
                 float * lab  ) ;*/

    return cpl_error_get_code();
}

static cpl_error_code
sinfo_test_fit_slits_boltz(void){
/*
    int
    sinfo_new_fit_slits_boltz( cpl_image   * lineImage,
                       FitParams ** par,
                       float     ** sinfo_slit_pos,
                       int          box_length,
                       float        y_box,
                       float        diff_tol ) ;
                       */
    return cpl_error_get_code();
}



static cpl_error_code
sinfo_test_fit_slits_boltz_with_estimate(void){
/*
    int
    sinfo_new_fit_slits_boltz_with_estimate ( cpl_image   * lineImage,
                                    float     ** sinfo_slit_pos,
                                    int          box_length,
                                    float        y_box,
                                    float        diff_tol,
                                    int          low_pos,
                                    int          high_pos ) ;
                                    */
    return cpl_error_get_code();
}

/* NOT USED FUNCTIONS
int
sinfo_new_fit_slits_boltz_single_line ( cpl_image   * lineImage,
                      float     ** sinfo_slit_pos,
                      int          box_length,absolute
                      float        y_box,
                      int          low_pos,
                      int          high_pos ) ;

*/

/*----------------------------------------------------------------------------*/
/**
  @brief   SINFONI pipeline unit test for skycor

**/
/*----------------------------------------------------------------------------*/

int main(void)
{
    /* Initialize CPL + SINFO messaging */
  cpl_test_init(PACKAGE_BUGREPORT, CPL_MSG_WARNING);

  sinfo_test_bolz();
  sinfo_test_bolz_deriv();
/*
  sinfo_test_lsqfit();

  sinfo_test_fit_slits_boltz();
  sinfo_test_fit_slits_boltz_single_line();
  sinfo_test_fit_slits_boltz_with_estimate();
  */

  cpl_test_error(CPL_ERROR_NONE);
  return cpl_test_end(0);

}


/**@}*/
