File indexing completed on 2024-12-22 04:18:15

0001 /***************************************************************************
0002  *                                                                         *
0003  *   copyright : (C) 2007 The University of Toronto                        *
0004  *                   netterfield@astro.utoronto.ca                         *
0005   *                                                                         *
0006  *   This program is free software; you can redistribute it and/or modify  *
0007  *   it under the terms of the GNU General Public License as published by  *
0008  *   the Free Software Foundation; either version 2 of the License, or     *
0009  *   (at your option) any later version.                                   *
0010  *                                                                         *
0011  ***************************************************************************/
0012 
0013 #ifndef LINEAR_H
0014 #define LINEAR_H
0015 
0016 #include <gsl/gsl_multifit.h>
0017 #include "common.h"
0018 
0019 double calculate_matrix_entry( double dX, int iPos );
0020 
0021 extern "C" bool kstfit_linear_unweighted(
0022   Kst::VectorPtr xVector, Kst::VectorPtr yVector,
0023   Kst::VectorPtr vectorOutYFitted, Kst::VectorPtr vectorOutYResiduals,
0024   Kst::VectorPtr vectorOutYParameters, Kst::VectorPtr vectorOutYCovariance,
0025   Kst::ScalarPtr scalarOutChi, int iNumParams);
0026 
0027 bool kstfit_linear_unweighted(
0028   Kst::VectorPtr xVector, Kst::VectorPtr yVector,
0029   Kst::VectorPtr vectorOutYFitted, Kst::VectorPtr vectorOutYResiduals,
0030   Kst::VectorPtr vectorOutYParameters, Kst::VectorPtr vectorOutYCovariance,
0031   Kst::ScalarPtr scalarOutChi, int iNumParams)
0032 {
0033   gsl_matrix* pMatrixX = NULL;
0034   gsl_matrix* pMatrixCovariance = NULL;
0035   gsl_vector* pVectorY = NULL;
0036   gsl_vector* pVectorParameters = NULL;
0037   gsl_multifit_linear_workspace* pWork = NULL;
0038   double dXInterpolated;
0039   double dX;
0040   double dY;
0041   double dChiSq = 0.0;
0042   int i = 0;
0043   int j;
0044   int iStatus = 0;
0045   int iLength;
0046   bool bReturn = false;
0047 
0048   if (xVector->length() >= 2 &&
0049       yVector->length() >= 2 ) {
0050     iLength = yVector->length();
0051     if( xVector->length() > iLength ) {
0052       iLength = xVector->length();
0053     }
0054 
0055     if( iLength > iNumParams + 1 ) {
0056       vectorOutYFitted->resize(iLength);
0057       vectorOutYResiduals->resize(iLength);
0058       vectorOutYParameters->resize(iNumParams);
0059       vectorOutYCovariance->resize(iNumParams * iNumParams);
0060       //
0061       // create the matrices and vectors...
0062       //
0063       pMatrixX = gsl_matrix_alloc( iLength, iNumParams );
0064       if( pMatrixX != NULL ) {
0065         pVectorY = gsl_vector_alloc( iLength );
0066         if( pVectorY != NULL ) {
0067           pVectorParameters = gsl_vector_alloc( iNumParams );
0068           if( pVectorParameters != NULL ) {
0069             pMatrixCovariance = gsl_matrix_alloc( iNumParams, iNumParams );
0070             if( pMatrixCovariance != NULL ) {
0071               pWork = gsl_multifit_linear_alloc( iLength, iNumParams );
0072               if( pWork != NULL ) {
0073 
0074                 //
0075                 // fill in the matrices and vectors...
0076                 //
0077                 for( i=0; i<iLength; i++ ) {
0078                   gsl_vector_set( pVectorY, i, interpolate(i, iLength, yVector->noNanValue(), yVector->length()));
0079                   dXInterpolated = interpolate(i, iLength, xVector->noNanValue(), xVector->length());
0080                   for( j=0; j<iNumParams; j++ ) {
0081                     dX = calculate_matrix_entry( dXInterpolated, j );
0082                     gsl_matrix_set( pMatrixX, i, j, dX );
0083                   }
0084                 }
0085 
0086 
0087                 iStatus = gsl_multifit_linear( pMatrixX,
0088                                                 pVectorY,
0089                                                 pVectorParameters,
0090                                                 pMatrixCovariance,
0091                                                 &dChiSq,
0092                                                 pWork );
0093                 if( iStatus == 0 ) {
0094                   //
0095                   // fill in the output arrays and scalars...
0096                   //
0097                   for( i=0; i<iLength; i++ ) {
0098                     dY = 0.0;
0099                     for( j=0; j<iNumParams; j++ ) {
0100                       dY += gsl_matrix_get( pMatrixX, i, j ) *
0101                             gsl_vector_get( pVectorParameters, j );
0102                     }
0103                     vectorOutYFitted->raw_V_ptr()[i] = dY;
0104                     vectorOutYResiduals->raw_V_ptr()[i] = interpolate(i, iLength, yVector->noNanValue(), yVector->length()) - dY;
0105                   }
0106 
0107                   for( i=0; i<iNumParams; i++ ) {
0108                     vectorOutYParameters->raw_V_ptr()[i] = gsl_vector_get( pVectorParameters, i );
0109                     for( j=0; j<iNumParams; j++ ) {
0110                       vectorOutYCovariance->raw_V_ptr()[(i*iNumParams)+j] = gsl_matrix_get( pMatrixCovariance, i, j );
0111                     }
0112                   }
0113 
0114                   scalarOutChi->setValue(dChiSq / ( (double)iLength - (double)iNumParams ));
0115 
0116                   bReturn = true;
0117                 }
0118 
0119                 gsl_multifit_linear_free( pWork );
0120               }
0121               gsl_matrix_free( pMatrixCovariance );
0122             }
0123             gsl_vector_free( pVectorParameters );
0124           }
0125           gsl_vector_free( pVectorY );
0126         }
0127         gsl_matrix_free( pMatrixX );
0128       }
0129     }
0130   }
0131 
0132   return bReturn;
0133 }
0134 
0135 #endif