sinfo_recipes.c

00001 /*
00002  * This file is part of the ESO SINFONI Pipeline
00003  * Copyright (C) 2004,2005 European Southern Observatory
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA
00018  */
00019 /***************************************************************************
00020 * E.S.O. - VLT project
00021 *
00022 *
00023 *
00024 * who       when      what
00025 * --------  --------  ----------------------------------------------
00026 * schreib  05/06/00  created
00027 */
00028 
00029 #ifdef HAVE_CONFIG_H
00030 #  include <config.h>
00031 #endif
00032 
00033 #include "sinfo_vltPort.h"
00034 
00035 /*
00036  * System Headers
00037  */
00038 
00039 /*
00040  * Local Headers
00041  */
00042 
00043 #include "sinfo_recipes.h"
00044 #include "sinfo_globals.h"
00045 
00046 /*----------------------------------------------------------------------------
00047  *                                    Local variables
00048  *--------------------------------------------------------------------------*/
00049 
00050 static float  sqrarg ;
00051 
00052 static double chi1 ;                    /* old reduced chi-squared */
00053 static double sinfo_chi2 ;                    /* new reduced chi-squared */
00054 static double labda ;                   /* mixing parameter */
00055 static double vec[MAXPAR] ;             /* correction sinfo_vector */
00056 static double matrix1[MAXPAR][MAXPAR] ; /* original sinfo_matrix */
00057 static double matrix2[MAXPAR][MAXPAR] ; /* inverse of matrix1 */
00058 static int    nfree ;                   /* number of free parameters */
00059 static int    parptr[MAXPAR] ;          /* parameter pointer */
00060 
00061 /*----------------------------------------------------------------------------
00062  *                                 Defines
00063  *--------------------------------------------------------------------------*/
00064 
00065 #define SQR(a) (sqrarg = (a) , sqrarg*sqrarg)
00066 
00067 /*----------------------------------------------------------------------------
00068  *                    Functions private to this module
00069  *--------------------------------------------------------------------------*/
00070 
00071 
00072 static int new_inv_mat (void) ;
00073 
00074 static void new_get_mat ( float  * xdat,
00075                      int    * xdim,
00076                      float  * ydat,
00077                      float  * wdat,
00078                      int    * ndat,
00079                      float  * fpar,
00080                      float  * epar/*,
00081                      int    * npar */) ;
00082 
00083 static int new_get_vec ( float  * xdat,
00084                     int    * xdim,
00085                     float  * ydat,
00086                     float  * wdat,
00087                     int    * ndat,
00088                     float  * fpar,
00089                     float  * epar,
00090                     int    * npar ) ;
00091 
00092 static float 
00093 new_gaussian ( float * xdat, float * parlist/*, int * npar*/ );
00094 static void 
00095 new_gaussian_deriv( float * xdat, float * parlist, 
00096                     float * dervs/*, int * npar*/ );
00097 
00098 
00099 
00107 /*----------------------------------------------------------------------------
00108  *                            Function codes
00109  *--------------------------------------------------------------------------*/
00110 
00111 
00112 float sinfo_new_f_median(float * array, int n)
00113 {
00114  pixelvalue p_array[100];
00115  int i;
00116  
00117  for (i=0;i<n;i++)
00118      p_array[i]= (pixelvalue) array[i];
00119 
00120  return (float) sinfo_new_median(p_array, n);
00121 }
00122 
00123 
00140 float sinfo_new_clean_mean( float * array, 
00141                   int     n_elements,
00142                   float   throwaway_low,
00143                   float   throwaway_high )
00144 {
00145     int i, n ;
00146     int lo_n, hi_n ;
00147     float sum ;
00148     
00149     if ( array == NULL )
00150     {
00151         sinfo_msg_error(" no array given in sinfo_clean_mean!") ;
00152         return FLT_MAX ;
00153     }
00154   
00155     if ( n_elements <= 0 )
00156     {
00157         sinfo_msg_error("wrong number of elements given") ;
00158         return FLT_MAX ;
00159     }
00160 
00161     if ( throwaway_low < 0. || throwaway_high < 0. ||
00162          throwaway_low + throwaway_high >= 100. )
00163     {
00164         sinfo_msg_error("wrong throw away percentage given!") ;
00165         return FLT_MAX ;
00166     }
00167 
00168     lo_n = (int) (throwaway_low * (float)n_elements / 100.) ;
00169     hi_n = (int) (throwaway_high * (float)n_elements / 100.) ;
00170 
00171     /* sort the array */
00172     sinfo_pixel_qsort( array, n_elements ) ;
00173 
00174     n = 0 ;
00175     sum = 0. ;
00176     for ( i = lo_n ; i < n_elements - hi_n ; i++ )
00177     {
00178         if ( !isnan(array[i]) )
00179         {
00180             sum += array[i] ;
00181             n++ ;
00182         }
00183     }
00184     if ( n == 0 )  
00185     {
00186         return FLAG ;
00187     }
00188     else
00189     {
00190         return sum/(float)n ;
00191     }
00192 }
00193 
00194 /*--------------------------------------------------------------------------*/
00207 pixelvalue sinfo_new_median(pixelvalue * array, int n)
00208 {
00209     pixelvalue med ;
00210     
00211     if ( array == NULL || n <= 0 )
00212     {
00213         sinfo_msg_warning("nothing in the pixelvalue array, ZERO returned");
00214         return ZERO ;
00215     }
00216     
00217     if ( n == 1 )
00218     {
00219         return array[0] ;
00220     }
00221  
00222     sinfo_pixel_qsort((float*) array, n) ;
00223     if ( n % 2 == 1 )
00224     {
00225         med = array[n/2] ;
00226     }
00227     else
00228     {
00229         med = (array[n/2] + array[n/2 - 1])/2. ;
00230     }
00231     return med ;
00232 }
00233 
00234 
00235 
00236 
00237 
00285 int sinfo_new_lsqfit_c ( float * xdat,
00286                int   * xdim,
00287                float * ydat,
00288                float * wdat,
00289                int   * ndat,
00290                float * fpar,
00291                float * epar,
00292                int   * mpar,
00293                int   * npar,
00294                float * tol ,
00295                int   * its ,
00296                float * lab  )
00297 {
00298     int i, n, r ;
00299     int itc ;                      /* fate of fit */
00300     int found ;                    /* fit converged: 1, not yet converged: 0 */
00301     int  nuse ;                    /* number of useable data points */
00302     double tolerance ;             /* accuracy */
00303 
00304     itc   = 0 ;                    /* fate of fit */
00305     found = 0 ;                    /* reset */
00306     nfree = 0 ;                    /* number of free parameters */
00307     nuse  = 0 ;                    /* number of legal data points */
00308 
00309     if ( *tol < (FLT_EPSILON * 10.0 ) )
00310     {
00311         tolerance = FLT_EPSILON * 10.0 ;  /* default tolerance */
00312     }
00313     else
00314     {
00315         tolerance = *tol ;                /* tolerance */
00316     }
00317     
00318     labda = fabs( *lab ) * LABFAC ;   /* start value for mixing parameter */
00319     for ( i = 0 ; i < (*npar) ; i++ )
00320     {
00321         if ( mpar[i] )
00322         {
00323             if ( nfree > MAXPAR )         /* too many free parameters */
00324             {
00325                 return -1 ;
00326             }
00327             parptr[nfree++] = i ;         /* a free parameter */
00328         }
00329     }
00330     
00331     if (nfree == 0)                       /* no free parameters */     
00332     {
00333         return -2 ;
00334     }
00335     
00336     for ( n = 0 ; n < (*ndat) ; n++ )
00337     {
00338         if ( wdat[n] > 0.0 )              /* legal weight */
00339         {
00340             nuse ++ ;
00341         }
00342     }
00343     
00344     if ( nfree >= nuse )
00345     {
00346         return -3 ;                       /* no degrees of freedom */
00347     }
00348     if ( labda == 0.0 )                   /* linear fit */
00349     {
00350         /* initialize fpar array */
00351         for ( i = 0 ; i < nfree ; fpar[parptr[i++]] = 0.0 ) ;  
00352         new_get_mat ( xdat, xdim, ydat, wdat, ndat, fpar, epar/*, npar*/ ) ;
00353         r =  new_get_vec ( xdat, xdim, ydat, wdat, ndat, fpar, epar, npar ) ;
00354         if ( r )                         /* error */
00355         {
00356             return r ;
00357         }
00358         for ( i = 0 ; i < (*npar) ; i++ )
00359         {
00360             fpar[i] = epar[i] ;           /* save new parameters */
00361             epar[i] = 0.0 ;               /* and set errors to zero */
00362         }
00363         chi1 = sqrt( chi1 / (double) (nuse - nfree) ) ;
00364         for ( i = 0 ; i < nfree ; i++ )
00365         {
00366             if ( (matrix1[i][i] <= 0.0 ) || (matrix2[i][i] <= 0.0) )
00367             {
00368                 return -7 ;
00369             }
00370             epar[parptr[i]] = chi1 * sqrt( matrix2[i][i] ) / 
00371                                      sqrt( matrix1[i][i] ) ;
00372         }
00373     }
00374     else                                  /* non-linear fit */
00375     {
00376         /*----------------------------------------------------------------
00377          * the non-linear fit uses the steepest descent method in combination
00378          * with the Taylor method. The mixing of these methods is controlled
00379          * by labda. In the outer loop ( called the iteration loop ) we build
00380          * the matrix and calculate the correction vector. In the inner loop
00381          * (called the interpolation loop) we check whether we have obtained a
00382          * better solution than the previous one. If so, we leave the inner 
00383            loop else we increase labda (give more weight to the steepest 
00384            descent method) calculate the correction vector and check again. 
00385            After the inner loop we do a final check on the goodness of the 
00386            fit and if this satisfies
00387          * the tolerance we calculate the errors of the fitted parameters.
00388          */
00389         while ( !found )                  /* iteration loop */
00390         {      
00391             if ( itc++ == (*its) )        /* increase iteration counter */
00392             {
00393                 return -4 ;               
00394             }
00395             new_get_mat( xdat, xdim, ydat, wdat, ndat, fpar, epar/*, npar */) ;
00396             
00397             /*-------------------------------------------------------------
00398              * here we decrease labda since we may assume that each iteration
00399              * brings us closer to the answer.
00400              */
00401             if ( labda > LABMIN )
00402             {
00403                 labda = labda / LABFAC ;         /* decrease labda */
00404             }
00405             r = new_get_vec( xdat, xdim, ydat, wdat, ndat, fpar, epar, npar ) ;
00406             if ( r )                      /* error */
00407             {
00408                 return r ;
00409             }
00410 
00411             while ( chi1 >= sinfo_chi2 )        /* interpolation loop */
00412             {
00413                 /*-----------------------------------------------------------
00414                  * The next statement is based on experience, not on the 
00415                    mathematics of the problem. It is assumed that we have 
00416                    reached convergence when the pure steepest descent method 
00417                    does not produce a better solution.
00418                  */
00419                 if ( labda > LABMAX )    /* assume solution found */
00420                 {
00421                     break ;
00422                 }
00423                 labda = labda * LABFAC ;     /* increase mixing parameter */
00424                 r = new_get_vec(xdat,xdim,ydat,wdat,ndat,fpar,epar,npar) ;
00425                 if ( r )                  /* error */
00426                 {
00427                     return r ;
00428                 }
00429             }
00430 
00431             if ( labda <= LABMAX )        /* save old parameters */
00432             {
00433                 for ( i = 0 ; i < *npar ; i++ )
00434                 {
00435                     fpar[i] = epar[i] ;
00436                 }
00437             }
00438             if ( (fabs( sinfo_chi2 - chi1 ) <= (tolerance * chi1)) || 
00439                  (labda > LABMAX) )
00440             {
00441                 /*-------------------------------------------------------------
00442                  * we have a satisfying solution, so now we need to calculate 
00443                    the correct errors of the fitted parameters. This we do by 
00444                    using the pure Taylor method because we are very close to 
00445                    the real solution.
00446                  */
00447                 labda = 0.0 ;              /* for Taylor solution */
00448                 new_get_mat(xdat,xdim,ydat,wdat,ndat,fpar,epar/*, npar */) ;
00449                 r = new_get_vec(xdat,xdim,ydat,wdat,ndat,fpar,epar,npar) ;
00450 
00451                 if ( r )                    /* error */
00452                 {
00453                     return r ;
00454                 }
00455                 for ( i = 0 ; i < (*npar) ; i++ )
00456                 {
00457                     epar[i] = 0.0 ;          /* set error to zero */
00458                 }
00459                 sinfo_chi2 = sqrt ( sinfo_chi2 / (double) (nuse - nfree) ) ;
00460 
00461                 for ( i = 0 ; i < nfree ; i++ )
00462                 {
00463                     if ( (matrix1[i][i] <= 0.0) || (matrix2[i][i] <= 0.0) )
00464                     {
00465                         return -7 ;
00466                     }
00467                     epar[parptr[i]] = sinfo_chi2 * sqrt( matrix2[i][i] ) / 
00468                                                    sqrt( matrix1[i][i] ) ;
00469                 }
00470                 found = 1 ;                  /* we found a solution */
00471             }
00472         }
00473     }
00474     return itc ;                             /* return number of iterations */
00475 }
00476 
00477 
00478 
00485 void sinfo_new_convert_ZEROs_to_0_for_images(cpl_image * im)
00486 {
00487     int i ;
00488     int ilx=0;
00489     int ily=0;
00490     float* pidata=NULL;
00491 
00492     if ( im == NULL )
00493     {
00494         sinfo_msg_error("no input image given!\n") ; 
00495         return ;
00496     }
00497     ilx=cpl_image_get_size_x(im);
00498     ily=cpl_image_get_size_y(im);
00499     pidata=cpl_image_get_data(im);
00500     for ( i = 0 ; i < (int) ilx*ily ; i++ )
00501     {
00502         if( isnan(pidata[i]) )
00503         {
00504             pidata[i] = 0. ;
00505         }
00506     }
00507     return ;
00508 }
00509 
00518 void sinfo_new_convert_ZEROs_to_0_for_cubes(cpl_imagelist * cube)
00519 {
00520     int i ;
00521     int inp=0;
00522     cpl_image* i_img=NULL;  
00523 
00524     if ( cube == NULL )
00525     {
00526         sinfo_msg_error("no input cube given!") ; 
00527         return ;
00528     }
00529     inp=cpl_imagelist_get_size(cube);
00530 
00531     for ( i = 0 ; i < inp ; i++ )
00532     {
00533       i_img=cpl_imagelist_get(cube,i);
00534       sinfo_new_convert_ZEROs_to_0_for_images(i_img) ;
00535       cpl_imagelist_set(cube,i_img,i);
00536     }
00537     return ;
00538 }
00539 
00540 
00549 void 
00550 sinfo_new_convert_ZEROs_to_0_for_cubes_range(cpl_imagelist * cube,
00551                                              const int z_min,const int z_max)
00552 {
00553     int i ;
00554     cpl_image* i_img=NULL;  
00555 
00556     if ( cube == NULL )
00557     {
00558         sinfo_msg_error("no input cube given!") ; 
00559         return ;
00560     }
00561     for ( i = z_min ; i < z_max ; i++ )
00562     {
00563       i_img=cpl_imagelist_get(cube,i);
00564       sinfo_new_convert_ZEROs_to_0_for_images(i_img) ;
00565       cpl_imagelist_set(cube,i_img,i);
00566     }
00567     return ;
00568 }
00575 void sinfo_new_convert_0_to_ZEROs_for_images(cpl_image * im)
00576 {
00577     int i ;
00578     int ilx=0;
00579     int ily=0;
00580     float* pidata=NULL;
00581 
00582     if ( im == NULL )
00583     {
00584         sinfo_msg_error("no input image given!") ;
00585         return ;
00586     }
00587     ilx=cpl_image_get_size_x(im);
00588     ily=cpl_image_get_size_y(im);
00589     pidata=cpl_image_get_data(im);
00590     for ( i = 0 ; i < (int) ilx*ily ; i++ )
00591     {
00592         if( pidata[i] == 0. )
00593         {
00594             pidata[i] = ZERO ;
00595         }
00596     }
00597     return ;
00598 }
00599 
00606 void sinfo_new_convert_0_to_ZERO_for_cubes(cpl_imagelist * cube)
00607 {
00608     int i ;
00609     int inp=0;
00610     cpl_image* i_img=NULL;
00611 
00612     if ( cube == NULL )
00613     {
00614         sinfo_msg_error("no input cube given!") ;
00615         return ;
00616     }
00617     inp=cpl_imagelist_get_size(cube);
00618     for ( i = 0 ; i < inp ; i++ )
00619     {
00620       i_img=cpl_imagelist_get(cube,i);
00621       sinfo_new_convert_0_to_ZEROs_for_images(i_img) ;
00622       cpl_imagelist_set(cube,i_img,i);
00623     }
00624     return ;
00625 }
00626 
00627 
00636 void 
00637 sinfo_new_convert_0_to_ZERO_for_cubes_range(cpl_imagelist * cube,
00638                                             const int z_min,const int z_max)
00639 {
00640     int i ;
00641     int inp=0;
00642     cpl_image* i_img=NULL;
00643 
00644     if ( cube == NULL )
00645     {
00646         sinfo_msg_error("no input cube given!") ;
00647         return ;
00648     }
00649     inp=cpl_imagelist_get_size(cube);
00650     for ( i = z_min ; i < z_max ; i++ )
00651     {
00652       i_img=cpl_imagelist_get(cube,i);
00653       sinfo_new_convert_0_to_ZEROs_for_images(i_img) ;
00654       cpl_imagelist_set(cube,i_img,i);
00655     }
00656     return ;
00657 }
00664 void sinfo_new_invert(cpl_image * im)
00665 {
00666     int i ;
00667     int ilx=0;
00668     int ily=0;
00669     float* pidata=NULL;
00670 
00671     ilx=cpl_image_get_size_x(im);
00672     ily=cpl_image_get_size_y(im);
00673     pidata=cpl_image_get_data(im);
00674 
00675     for ( i = 0 ; i < (int) ilx*ily ; i++ )
00676     {
00677         pidata[i] = -pidata[i] ;
00678     }
00679     return ;
00680 }
00681 
00689 int sinfo_new_nint ( double x ) 
00690 {
00691     int k ;
00692 
00693     k = x ;
00694     if ( x >= 0. )
00695     {
00696         if ( (x - (double) k) <= 0.5 )
00697         {
00698             return k ;
00699         }
00700         else
00701         {
00702             return k + 1 ;
00703         }
00704     }
00705     else
00706     {
00707         if ( (x - (double) k) <= -0.5 )
00708         {
00709             return k - 1;
00710         }
00711         else
00712         {
00713             return k ;
00714         }
00715     }
00716 }
00717 
00718 
00732 #define STEP_MIN        (-half_search)
00733 #define STEP_MAX        (half_search)
00734 
00735 double * sinfo_new_xcorrel(
00736     float      *    line_i,
00737     int             width_i,
00738     float      *    line_t,
00739     int             width_t,
00740     int             half_search,
00741     int     *       delta,
00742     int       *     maxpos,
00743     double     *    xcorr_max 
00744     
00745 )
00746 {
00747     double  * xcorr ;
00748     double   mean_i, mean_t ;
00749     double   rms_i, rms_t ;
00750     double   sum, sqsum ;
00751     double   norm ;
00752     int      nsteps ;
00753     int      i ;
00754     int      step ;
00755     int      nval ;
00756     /*double   r;*/
00757 
00758 
00759     /* Compute normalization factors */
00760     sum = sqsum = 0.00 ;
00761     for (i=0 ; i<width_i ; i++) {
00762         sum += (double)line_i[i] ;
00763         sqsum += (double)line_i[i] * (double)line_i[i];
00764     }
00765     mean_i = sum / (double)width_i ;
00766     sqsum /= (double)width_i ;
00767     rms_i = sqsum - mean_i*mean_i ;
00768 
00769     sum = sqsum = 0.00 ;
00770     for (i=0 ; i<width_t ; i++) {
00771         sum += (double)line_t[i] ;
00772         sqsum += (double)line_t[i] * (double)line_t[i];
00773     }
00774     mean_t = sum / (double)width_t ;
00775     sqsum /= (double)width_t ;
00776     rms_t = sqsum - mean_t*mean_t ;
00777 
00778     norm = 1.00 / sqrt(rms_i * rms_t);
00779 
00780     nsteps = (STEP_MAX - STEP_MIN)  ;
00781     xcorr = cpl_malloc(nsteps * sizeof(double));
00782     for (step=STEP_MIN ; step<STEP_MAX ; step++) {
00783         xcorr[step-STEP_MIN] = 0.00 ;
00784         nval = 0 ;
00785         for (i=0 ; i<width_t ; i++) {
00786             if ((i+step >= 0) &&
00787                 (i+step < width_i)) {
00788             xcorr[step-STEP_MIN] += ((double)line_t[i] - mean_t) *
00789                                     ((double)line_i[i+step] - mean_i) *
00790                                     norm ;
00791                 nval++ ;
00792             }
00793         }
00794         xcorr[step-STEP_MIN] /= (double)nval ;
00795     }
00796     *xcorr_max = xcorr[0] ;
00797     *maxpos    = 0 ;
00798     for (i=0 ; i<nsteps ; i++) {
00799         if (xcorr[i]>*xcorr_max) {
00800             *maxpos = i ;
00801             *xcorr_max = xcorr[i];
00802         }
00803     }
00804     (*delta) = + (STEP_MIN + *maxpos);
00805     return xcorr ;
00806 }
00807 
00808 /* FILE ELEMENT: sinfo_nev_ille.c                                           */
00809 /*                                                                    */
00810 /**********************************************************************/
00811 /*                                                                    */
00812 /*                      double sinfo_nev_ille()                             */
00813 /*                                                                    */
00814 /**********************************************************************/
00815 /*                                                                    */
00816 /*  DESCRIPTION:                                                      */
00817 /*  For a given table (x , f(x )), i = 0(1)n  and a given argument z  */
00818 /*  the function computes the interpolated value for the argument z   */
00819 /*  using Neville's interpolation/ extrapolation algorithm.           */
00820 /*                                                                    */
00821 /*  FUNCTIONS CALLED:                                                 */
00822 /*  System library: <stdio.h> printf(), fabs();                       */
00823 /*  Numlib library: None                                              */
00824 /*  Local functions: nevtable();                                      */
00825 /*  User supplied: None                                               */
00826 /*                                                                    */
00827 /*  PROGRAMMED BY: T.Haavie                                           */
00828 /*  DATE/VERSION: 88-07-06/1.0                                        */
00829 /*                                                                    */
00830 /**********************************************************************/
00831 double sinfo_nev_ille(double x[], double f[], int n, double z, int* flag)
00832                /* PARAMETERS(input):                                  */
00833 /* double x[];     Abscissae values in the table.                      */
00834 /* double f[];     Function values in the table.                       */
00835 /* int n;         The number of elements in the table is n+1.         */
00836 /* double z;       Argument to be used in interpolation/extrapolation. */
00837 
00838 
00839 /*                PARAMETERS(input/output):                           */
00840 /* int *flag;    Flag parameter(output):                             */
00841                /* = 0, n < 0 and/or eps < 0, should be positive+.     */
00842                /* = 1, required rel.err. is not obtained.             */
00843                /* = 2, required rel. err. is obtained.                */
00844 
00845 /* the computed estimate for the interpolated/extrapolated  value re- */
00846 /* turned through function name sinfo_nev_ille.                             */
00847 
00848 {
00849         double p[11]; /* Array used for storing the new row elements */
00850                        /* in the interpolation/extrapolation table.   */
00851         double q[11]; /* Array used for storing the old row elements */
00852                        /* in the interpolation/extrapolation table    */
00853 
00854         double factor;
00855         int m, k;
00856 
00857        
00858 
00859         if (n < 0 )
00860         {
00861                 *flag = 0;
00862                 return(0.);
00863         }
00864 
00865 
00866         q[0] = f[0];               /* Set initial value in the table. */
00867 
00868         for (k = 1; k <= n; k++)   /* k counts rows in the table.     */
00869         {
00870                 p[0] = f[k];
00871                 for (m = 1; m <= k; m++) /* m counts element in row.  */
00872                 {
00873                         factor = (z - x[k]) / (x[k] - x[k-m]);
00874                         p[m] = p[m-1] + factor * (p[m-1] - q[m-1]);
00875                 }
00876 
00877 
00878                 for (m = 0; m <= k; m++) /* Shift old row to new row.  */
00879                         q[m] = p[m];
00880 
00881         } /* End of k-loop. */
00882 
00883         *flag = 1;              /* Required rel.error is not obtained. */
00884         return(p[n]);
00885 
00886 } /* End of sinfo_nev_ille(). */
00887 
00888 
00889 
00890 float sinfo_new_nev_ille(float x[], float f[], int n, float z, int* flag)
00891                /* PARAMETERS(input):                                  */
00892 /* float x[];     Abscissae values in the table.                      */
00893 /* float f[];     Function values in the table.                       */
00894 /* int n;         The number of elements in the table is n+1.         */
00895 /* float z;       Argument to be used in interpolation/extrapolation. */
00896 
00897 
00898 /*                PARAMETERS(input/output):                           */
00899 /* int *flag;    Flag parameter(output):                             */
00900                /* = 0, n < 0 and/or eps < 0, should be positive+.     */
00901                /* = 1, required rel.err. is not obtained.             */
00902                /* = 2, required rel. err. is obtained.                */
00903 
00904 /* the computed estimate for the interpolated/extrapolated  value re- */
00905 /* turned through function name sinfo_nev_ille.                             */
00906 
00907 {
00908         float p[11]; /* Array used for storing the new row elements */
00909                        /* in the interpolation/extrapolation table.   */
00910         float q[11]; /* Array used for storing the old row elements */
00911                        /* in the interpolation/extrapolation table    */
00912 
00913         float factor;
00914         int m, k;
00915 
00916        
00917 
00918         if (n < 0 )
00919         {
00920                 *flag = 0;
00921                 return(0.);
00922         }
00923 
00924 
00925         q[0] = f[0];               /* Set initial value in the table. */
00926 
00927         for (k = 1; k <= n; k++)   /* k counts rows in the table.     */
00928         {
00929                 p[0] = f[k];
00930                 for (m = 1; m <= k; m++) /* m counts element in row.  */
00931                 {
00932                         factor = (z - x[k]) / (x[k] - x[k-m]);
00933                         p[m] = p[m-1] + factor * (p[m-1] - q[m-1]);
00934                 }
00935 
00936 
00937                 for (m = 0; m <= k; m++) /* Shift old row to new row.  */
00938                         q[m] = p[m];
00939 
00940         } /* End of k-loop. */
00941 
00942         *flag = 1;              /* Required rel.error is not obtained. */
00943         return(p[n]);
00944 
00945 } /* End of sinfo_nev_ille(). */
00946 
00947 
00972 static int new_get_vec ( float * xdat,
00973                     int   * xdim,
00974                     float * ydat,
00975                     float * wdat,
00976                     int   * ndat,
00977                     float * fpar,
00978                     float * epar,
00979                     int   * npar )
00980 {
00981     double dj ;
00982     double dy ;
00983     double mii ;
00984     double mji ;
00985     double mjj ;
00986     double wn ;
00987     int i, j, n, r ;
00988 
00989     /* loop to modify and scale the sinfo_matrix */
00990     for ( j = 0 ; j < nfree ; j++ )
00991     {
00992         mjj = matrix1[j][j] ;
00993         if ( mjj <= 0.0 )             /* diagonal element wrong */
00994         {
00995             return -5 ;
00996         }
00997         mjj = sqrt( mjj ) ;
00998         for ( i = 0 ; i < j ; i++ )
00999         {
01000             mji = matrix1[j][i] / mjj / sqrt( matrix1[i][i] ) ;
01001             matrix2[i][j] = matrix2[j][i] = mji ;
01002         }
01003         matrix2[j][j] = 1.0 + labda ;  /* scaled value on diagonal */
01004     }    
01005     
01006     if ( (r = new_inv_mat()) )       /* sinfo_invert sinfo_matrix inlace */
01007     {
01008         return r ;
01009     }
01010     
01011     for ( i = 0 ; i < (*npar) ; i ++ )
01012     {
01013         epar[i] = fpar[i] ;
01014     }
01015     
01016     /* loop to calculate correction sinfo_vector */
01017     for ( j = 0 ; j < nfree ; j++ )
01018     {
01019         dj = 0.0 ;
01020         mjj = matrix1[j][j] ;
01021         if ( mjj <= 0.0)               /* not allowed */
01022         {
01023             return -7 ;
01024         }
01025         mjj = sqrt ( mjj ) ;
01026         for ( i = 0 ; i < nfree ; i++ )
01027         {
01028             mii = matrix1[i][i] ;
01029             if ( mii <= 0.0 )
01030             {
01031                 return -7 ;
01032             }
01033             mii = sqrt( mii ) ;
01034             dj += vec[i] * matrix2[j][i] / mjj / mii ;
01035         }
01036         epar[parptr[j]] += dj ;       /* new parameters */
01037     }    
01038     chi1 = 0.0 ;                      /* reset reduced chi-squared */
01039  
01040     /* loop through the data points */
01041     for ( n = 0 ; n < (*ndat) ; n++ )
01042     {
01043         wn = wdat[n] ;               /* get weight */
01044         if ( wn > 0.0 )              /* legal weight */
01045         {
01046             dy = ydat[n] - new_gaussian( &xdat[(*xdim) * n], epar/*, npar*/ ) ;
01047             chi1 += wdat[n] * dy * dy ;
01048         }
01049     }
01050     return 0 ;
01051 }   
01052     
01053 
01069 static void new_get_mat ( float * xdat,
01070                      int   * xdim,
01071                      float * ydat,
01072                      float * wdat,
01073                      int   * ndat,
01074                      float * fpar,
01075                      float * epar/*,
01076                      int   * npar */)
01077 {
01078     double wd ;
01079     double wn ;
01080     double yd ;
01081     int i, j, n ;
01082 
01083     for ( j = 0 ; j < nfree ; j++ )
01084     {
01085         vec[j] = 0.0 ; /* zero sinfo_vector */
01086         for ( i = 0 ; i<= j ; i++ )   
01087         /* zero sinfo_matrix only on and below diagonal */
01088         {
01089             matrix1[j][i] = 0.0 ;
01090         }
01091     }
01092     sinfo_chi2 = 0.0 ;  /* reset reduced chi-squared */
01093     
01094     /* loop through data points */
01095     for ( n = 0 ; n < (*ndat) ; n++ )
01096     {
01097         wn = wdat[n] ;
01098         if ( wn > 0.0 )  /* legal weight ? */
01099         {
01100             yd = ydat[n] - new_gaussian( &xdat[(*xdim) * n], fpar/*, npar*/ ) ;
01101             new_gaussian_deriv( &xdat[(*xdim) * n], fpar, epar/*, npar*/ ) ;
01102             sinfo_chi2 += yd * yd * wn ; /* add to chi-squared */
01103             for ( j = 0 ; j < nfree ; j++ )
01104             {
01105                 wd = epar[parptr[j]] * wn ;  /* weighted derivative */
01106                 vec[j] += yd * wd ;       /* fill sinfo_vector */
01107                 for ( i = 0 ; i <= j ; i++ ) /* fill sinfo_matrix */
01108                 {
01109                     matrix1[j][i] += epar[parptr[i]] * wd ;
01110                 }
01111             }
01112         }
01113     }                   
01114 }  
01115    
01116 
01117 
01118 
01119 
01120  
01129 static int new_inv_mat (void)
01130 {
01131     double even ;
01132     double hv[MAXPAR] ;
01133     double mjk ;
01134     double rowmax ;
01135     int evin ;
01136     int i, j, k, row ;
01137     int per[MAXPAR] ;
01138    
01139     /* set permutation array */
01140     for ( i = 0 ; i < nfree ; i++ )
01141     {
01142         per[i] = i ;
01143     }
01144     
01145     for ( j = 0 ; j < nfree ; j++ ) /* in j-th column */
01146     {
01147         /* determine largest element of a row */                               
01148         rowmax = fabs ( matrix2[j][j] ) ;
01149         row = j ;                         
01150 
01151         for ( i = j + 1 ; i < nfree ; i++ )
01152         {
01153             if ( fabs ( matrix2[i][j] ) > rowmax )
01154             {
01155                 rowmax = fabs( matrix2[i][j] ) ;
01156                 row = i ;
01157             }
01158         }
01159 
01160         /* determinant is zero! */
01161         if ( matrix2[row][j] == 0.0 )
01162         {
01163             return -6 ;
01164         }
01165         
01166         /*if the largest element is not on the diagonal, then permutate rows */
01167         if ( row > j )
01168         {
01169             for ( k = 0 ; k < nfree ; k++ )
01170             {
01171                 even = matrix2[j][k] ;
01172                 matrix2[j][k] = matrix2[row][k] ;
01173                 matrix2[row][k] = even ;
01174             }
01175             /* keep track of permutation */
01176             evin = per[j] ;
01177             per[j] = per[row] ;
01178             per[row] = evin ;
01179         }
01180         
01181         /* modify column */
01182         even = 1.0 / matrix2[j][j] ;
01183         for ( i = 0 ; i < nfree ; i++ )
01184         {
01185             matrix2[i][j] *= even ;
01186         }
01187         matrix2[j][j] = even ;
01188         
01189         for ( k = 0 ; k < j ; k++ )
01190         {
01191             mjk = matrix2[j][k] ;
01192             for ( i = 0 ; i < j ; i++ )
01193             {
01194                 matrix2[i][k] -= matrix2[i][j] * mjk ;
01195             }
01196             for ( i = j + 1 ; i < nfree ; i++ )
01197             {
01198                 matrix2[i][k] -= matrix2[i][j] * mjk ;
01199             }
01200             matrix2[j][k] = -even * mjk ;
01201         }
01202     
01203         for ( k = j + 1 ; k < nfree ; k++ )
01204         {
01205             mjk = matrix2[j][k] ;
01206             for ( i = 0 ; i < j ; i++ )
01207             {
01208                 matrix2[i][k]  -= matrix2[i][j] * mjk ;
01209             }
01210             for ( i = j + 1 ; i < nfree ; i++ )
01211             {
01212                 matrix2[i][k]  -= matrix2[i][j] * mjk ;
01213             }
01214             matrix2[j][k] = -even * mjk ;
01215         }
01216     }
01217     
01218     /* finally, repermute the columns */
01219     for ( i = 0 ; i < nfree ; i++ )
01220     {
01221         for ( k = 0 ; k < nfree ; k++ )
01222         {
01223             hv[per[k]] = matrix2[i][k] ;
01224         }
01225         for ( k = 0 ; k < nfree ; k++ )
01226         {
01227             matrix2[i][k] = hv[k] ;
01228         }
01229     }
01230         
01231     /* all is well */
01232     return 0 ;
01233 }       
01234 
01235 
01236 
01237 
01258 float new_gaussian ( float * xdat, float * parlist/*, int * npar*/ )
01259 {
01260     double  xd ;  /* FWHM's of gauss function */
01261     double   x ;  /* position */
01262 
01263     xd = fabs((double) parlist[1]) ;
01264     x  = (double) xdat[0] - (double) parlist[2] ;
01265     return (float) (
01266            (double) parlist[0] * exp( -4.0 * log(2.0) * (x/xd) * (x/xd) )
01267            + (double) parlist[3] ) ;
01268 }
01269       
01270        
01295 void 
01296 new_gaussian_deriv(float * xdat,float * parlist,float * dervs/*, int * npar*/ )
01297 {
01298     double xd ; /* FWHM of sinfo_gaussian */
01299     double x, expon ; /* position and exponent */
01300 
01301     xd = fabs( (double) parlist[1] ) ;
01302     
01303     /* offset from peak position */
01304     x = (double) xdat[0] - (double) parlist[2] ;
01305 
01306     /* determine the derivatives: */
01307     expon = -4.0 * log(2.0) * (x/xd) * (x/xd) ;
01308     expon = exp( expon ) ;
01309 
01310     /* partial derivative by the amplitude */
01311     dervs[0] = (float) expon ;
01312 
01313     /* calculate a * exp(-arg) */
01314     expon = (double) parlist[0] * expon ;
01315 
01316     /* partial derivative by FWHM */
01317     dervs[1] = (float) ( expon * 8.0 * log(2.0) * x*x / (xd*xd*xd) ) ;
01318 
01319     /* partial derivative by the x position (parlist[2]) */
01320     dervs[2] = (float) (expon * 8.0 * log(2.0) * x/(xd*xd) ) ;
01321 
01322     /* partial derivative by the zero level */
01323     dervs[3] = 1.0 ;
01324 }
01325 
01326 
01327 /*==================================================================*/
01328 
01329 
01349 void 
01350 sinfo_my_fit(float x[], float y[], int ndata, float sig[], int mwt, float *a, 
01351            float *b, float *siga, float *sigb, float *chi2, float *q)
01352 {
01353     int i ;
01354     float wt, t, sxoss, sx=0., sy=0., st2=0., ss, sigdat ;
01355 
01356     *b = 0. ;             /*accumulate sums ...*/
01357     if ( mwt )
01358     {
01359         ss = 0. ;
01360         for ( i = 0 ; i < ndata ; i++ )  /*... with weights*/
01361         {
01362             wt = 1./SQR(sig[i]) ;
01363             ss += wt ;
01364             sx += x[i]*wt ;
01365             sy += y[i]*wt ;
01366         }
01367     }
01368     else
01369     {
01370         for ( i = 0 ; i < ndata ; i++ ) /*... or without weights*/
01371         {
01372              sx += x[i] ;
01373              sy += y[i] ;
01374         }
01375         ss = ndata ;
01376     }
01377     sxoss = sx/ss ;
01378              
01379     if ( mwt )
01380     {
01381         for ( i = 0 ; i < ndata ; i ++ )
01382         {
01383             t = (x[i] - sxoss)/sig[i] ;
01384             st2 += t*t ;
01385             *b += t*y[i]/sig[i] ;
01386         }
01387     }
01388     else
01389     {
01390         for ( i = 0 ; i < ndata ; i++ )
01391         {
01392             t = x[i] - sxoss ;
01393             st2 += t*t ;
01394             *b += t*y[i] ;           
01395         }
01396     }
01397 
01398     *b /= st2 ;
01399     *a = (sy - sx*(*b))/ss ;
01400     *siga = sqrt ((1.0 + sx*sx/(ss*st2))/ss) ;
01401     *sigb = sqrt (1.0/st2) ;
01402     *chi2 = 0.0 ;  /*calculate chi-square*/
01403     if ( mwt == 0 )
01404     {
01405         for ( i = 0 ; i < ndata ; i++ )
01406         {
01407             *chi2 += SQR (y[i] - (*a) - (*b)*x[i]) ;
01408         }
01409         *q = 1. ;
01410         
01411         /*------------------------------------------------------------------
01412          * for unweighted data evaluate typical sig using chi2, and adjust
01413          * the standard deviation
01414          */
01415         sigdat = sqrt ((*chi2)/(ndata - 2)) ;
01416         *siga *= sigdat ;
01417         *sigb *= sigdat ;
01418     }
01419     else
01420     {
01421         for (i = 0 ; i < ndata ; i++)
01422         {
01423             *chi2 += SQR ((y[i] - (*a) - (*b) * x[i])/sig[i]) ;
01424         }    
01425         *q = 1. ; /* delete rest of lines. q is not a good value */
01426     }
01427 }
01428 
01443 int sinfo_new_correlation ( float * data1, float * data2, int ndata )
01444 {
01445     /*float help[3*ndata] ; 
01446     float corsum[3*ndata] ;*/
01447     float* help=NULL ; 
01448     float* corsum=NULL ;
01449     float maxval ;
01450     int i, j, k, position, shift ;
01451     int /*start,end,size,*/ndata3,limit;
01452     
01453     
01454     /*ndata3=3*ndata;*/
01455     ndata3=ndata+300;
01456 
01457     if ( NULL == data1 || NULL == data2 || ndata <= 1 )
01458     {
01459         sinfo_msg_error(" wrong input for sinfo_correlation\n") ;
01460         return INT32_MAX ;
01461     }
01462 
01463     /* initialize the help arrays with zeros */
01464     help=cpl_calloc(ndata+300,sizeof(float));
01465     for ( i = 0 ; i < ndata3 ; i++ )
01466     {
01467         help[i] = 0. ;
01468     }
01469 
01470     /* shift the second data array by ndata in the help array */
01471     for ( i = 0 ; i < ndata ; i++ )
01472     {
01473         help[(300/2) + i] = data2[i] ;
01474     }
01475 
01476     /* compute the cross sinfo_correlation sum array */
01477     corsum=cpl_calloc(ndata+300,sizeof(float));
01478     for ( j = 0 ; j < ndata3 ; j++ )
01479     {
01480         if ( ndata3-j <= ndata) 
01481         limit = ndata3-j;
01482     else
01483         limit = ndata;
01484         corsum[j] = 0. ;
01485         for ( k = 0 ; k < limit ; k++ )
01486         {
01487             /*if ( k + j >= ndata3 )
01488             {
01489                 break ;
01490             }*/
01491             corsum[j] += data1[k] * help[k + j] ;
01492         }
01493     }
01494 
01495     /* search for the maximal corsum value and determine its position */
01496     maxval = -FLT_MAX ;
01497     position = -1 ;
01498     for ( i = 0 ; i < ndata3 ; i++ )
01499     {
01500         if ( maxval < corsum[i] )
01501         {
01502             maxval = corsum[i] ;
01503             position = i ;
01504         }
01505     }
01506     
01507     /* determine shift of data2 relative to the data1 array */
01508     shift = position - 300/2 ;
01509     cpl_free(help);
01510     cpl_free(corsum);
01511  
01512     return shift ;
01513 }
01514 
01515 /*--------------------------------------------------------------------------*/

Generated on 3 Mar 2013 for SINFONI Pipeline Reference Manual by  doxygen 1.6.1