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_WEIGHTED_H
0014 #define LINEAR_WEIGHTED_H
0015 
0016 #include <stdlib.h>
0017 #include <math.h>
0018 #include <gsl/gsl_multifit.h>
0019 #include "common.h"
0020 
0021 double calculate_matrix_entry( double dX, int iPos );
0022 
0023 extern "C" bool kstfit_linear_weighted(
0024   Kst::VectorPtr xVector, Kst::VectorPtr yVector, Kst::VectorPtr weightsVector,
0025   Kst::VectorPtr vectorOutYFitted, Kst::VectorPtr vectorOutYResiduals,
0026   Kst::VectorPtr vectorOutYParameters, Kst::VectorPtr vectorOutYCovariance,
0027   Kst::ScalarPtr scalarOutChi, int iNumParams);
0028 
0029 bool kstfit_linear_weighted(
0030   Kst::VectorPtr xVector, Kst::VectorPtr yVector, Kst::VectorPtr weightsVector,
0031   Kst::VectorPtr vectorOutYFitted, Kst::VectorPtr vectorOutYResiduals,
0032   Kst::VectorPtr vectorOutYParameters, Kst::VectorPtr vectorOutYCovariance,
0033     Kst::ScalarPtr scalarOutChi, int iNumParams)
0034 {
0035   gsl_matrix*   pMatrixX = NULL;
0036   gsl_matrix* pMatrixCovariance = NULL;
0037   gsl_vector*   pVectorY = NULL;
0038   gsl_vector* pVectorWeights = NULL;
0039   gsl_vector* pVectorParameters = NULL;
0040   gsl_multifit_linear_workspace* pWork = NULL;
0041   double dX;
0042   double dY;
0043   double dChiSq = 0.0;
0044   int i = 0;
0045   int j;
0046   int   iStatus = 0;
0047   int   iLength;
0048   bool bReturn = false;
0049 
0050   if (xVector->length() >= 2 &&
0051       yVector->length() >= 2 &&
0052       weightsVector->length() >= 2) {
0053     iLength = yVector->length();
0054     if( xVector->length() > iLength ) {
0055       iLength = xVector->length();
0056     }
0057 
0058     if( iLength > iNumParams + 1 ) {
0059       vectorOutYFitted->resize(iLength);
0060       vectorOutYResiduals->resize(iLength);
0061       vectorOutYParameters->resize(iNumParams);
0062       vectorOutYCovariance->resize(iNumParams * iNumParams);
0063 
0064       // create the matrices and vectors...
0065       //
0066       pMatrixX = gsl_matrix_alloc( iLength, iNumParams );
0067       if( pMatrixX != NULL ) {
0068         pVectorY = gsl_vector_alloc( iLength );
0069         if( pVectorY != NULL ) {
0070           pVectorParameters = gsl_vector_alloc( iNumParams );
0071           if( pVectorParameters != NULL ) {
0072             pMatrixCovariance = gsl_matrix_alloc( iNumParams, iNumParams );
0073             if( pMatrixCovariance != NULL ) {
0074               pWork = gsl_multifit_linear_alloc( iLength, iNumParams );
0075               if( pWork != NULL ) {
0076                 pVectorWeights = gsl_vector_alloc( iLength );
0077                 if( pVectorWeights != NULL ) {
0078                   //
0079                   // fill in the matrices and vectors...
0080                   //
0081                   for( i=0; i<iLength; i++ ) {
0082                     gsl_vector_set( pVectorY, i, interpolate(i, iLength, yVector->noNanValue(), yVector->length()));
0083                     gsl_vector_set( pVectorWeights, i, interpolate(i, iLength, weightsVector->noNanValue(), weightsVector->length()));
0084                     for( j=0; j<iNumParams; j++ ) {
0085                       dX = calculate_matrix_entry( interpolate(i, iLength, xVector->noNanValue(), xVector->length()), j );
0086                       gsl_matrix_set( pMatrixX, i, j, dX );
0087                     }
0088                   }
0089 
0090                   iStatus = gsl_multifit_wlinear( pMatrixX, 
0091                                                   pVectorWeights,
0092                                                   pVectorY, 
0093                                                   pVectorParameters, 
0094                                                   pMatrixCovariance, 
0095                                                   &dChiSq, 
0096                                                   pWork );
0097                   if( iStatus == 0 ) {
0098                     //
0099                     // fill in the output arrays and scalars...
0100                     //
0101                     for( i=0; i<iLength; i++ ) {
0102                       dY = 0.0;
0103                       for( j=0; j<iNumParams; j++ ) {
0104                         dY += gsl_matrix_get( pMatrixX, i, j ) * 
0105                               gsl_vector_get( pVectorParameters, j );
0106                       }
0107                       vectorOutYFitted->raw_V_ptr()[i] = dY;
0108                       vectorOutYResiduals->raw_V_ptr()[i] = interpolate(i, iLength, yVector->noNanValue(), yVector->length()) - dY;
0109                     }
0110 
0111                     for( i=0; i<iNumParams; i++ ) {
0112                       vectorOutYParameters->raw_V_ptr()[i] = gsl_vector_get( pVectorParameters, i );
0113                       for( j=0; j<iNumParams; j++ ) {
0114                         vectorOutYCovariance->raw_V_ptr()[(i*iNumParams)+j] = gsl_matrix_get( pMatrixCovariance, i, j );
0115                       }
0116                     }
0117 
0118                     scalarOutChi->setValue(dChiSq / ( (double)iLength - (double)iNumParams ));
0119 
0120                     bReturn = true;
0121                   }
0122                   gsl_vector_free( pVectorWeights );
0123                 }
0124                 gsl_multifit_linear_free( pWork );
0125               }
0126               gsl_matrix_free( pMatrixCovariance );
0127             }
0128             gsl_vector_free( pVectorParameters );
0129           }
0130           gsl_vector_free( pVectorY );
0131         }
0132         gsl_matrix_free( pMatrixX );
0133       }
0134     }
0135   }
0136 
0137   return bReturn;
0138 }
0139 
0140 #endif