IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jun 24, 2004, 2:46:17 PM (22 years ago)
Author:
gusciora
Message:

...

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/dataManip/psMinimize.c

    r1079 r1086  
    1313#include "psMemory.h"
    1414#include "psVector.h"
     15#include "psImage.h"
    1516#include "psTrace.h"
    1617#include "psError.h"
     
    2728typedef struct
    2829{
    29     size_t n;
    30     psVector *initialGuess;
     30    size_t n;   // Number of data points points in domain.
     31    int count;   // Number of non-masked parameters.
     32    psVector *restrict initialGuess;
     33    psImage  *domain;  //
    3134    psVector *data;
    3235    psVector *errors;
    3336    psVector *paramMask;
     37    // The first argument to evalModel() and
     38    // d_evalModel() specifies the data point.
     39    // It must have the same size as the second
     40    // dimension of *domain.
     41    // The second argument must have the same size
     42    // as *initialGuess and *paramMask.
    3443    float (*evalModel) (psVector *, psVector *);
    3544    float (*d_evalModel) (psVector *, psVector *);
    3645}
    37 psmodeldata;
    38 
    39 
     46psModelData;
    4047
    4148
     
    5360
    5461
     62/******************************************************************************
     63 ******************************************************************************
     64gsl_function_f(x, params, f): This function serves as a standardized wrapper
     65for the user supplied function which is to be minimized.  The GSL
     66minimization routines have no knowledge of the user-supplied function.  They
     67only clal this routine, which then calls the user-supplied function.  The
     68arguments are:
     69    x: These are the parameter which are to be varied by GSL in order to
     70       minimized chi2 over the data set.
     71    params:
     72    f
     73 
     74 
     75 ******************************************************************************
     76 *****************************************************************************/
    5577int gsl_function_f(const gsl_vector *x,
    5678                   void *params,
    5779                   gsl_vector *f)
    5880{
    59     size_t n  = ((psmodeldata *)params)->n;
    60     psVector *data   = ((psmodeldata *)params)->data;
    61     psVector *errors = ((psmodeldata *) params)->errors;
    62     psVector *mask   = ((psmodeldata *) params)->paramMask;
    63     psVector *initialguess = ((psmodeldata *)params)->initialguess;
    64     int count = 0;
    65     float (*evalModel) = ((psmodeldata *) params)->evalModel;
     81    psImage  *domain   = ((psModelData *)params)->domain;
     82    psVector *data     = ((psModelData *)params)->data;
     83    psVector *errors   = ((psModelData *) params)->errors;
     84    psVector *mask     = ((psModelData *) params)->paramMask;
     85    psVector *initialGuess = ((psModelData *)params)->initialGuess;
     86    psVector *inputParameterList = NULL;
     87    //    float (*evalModel)(psVector *, psVector *) = ((psModelData *) params)->evalModel;
    6688    size_t i;
    67 
    68     for (i=0;i<initialguess->n;i++) {
    69         if (mask->data.U8[i] != 0) {
    70             count++;
    71         }
    72     }
     89    int j;
     90    float tmpf;
     91
     92    // The GSL routines will call this functions with the masked parameters
     93    // removed.  However, the user-supplied function (to be modified) does not
     94    // have those parameters removed.  Here will create a new parameter list
     95    // with the masked parameters added (we expand initialGuess).
     96    inputParameterList = psVectorAlloc(initialGuess->n, PS_TYPE_F32);
    7397
    7498    if (mask != NULL) {
    7599        j = 0;
    76         inputparameterlist = psVectorAlloc(count, PS_TYPE_F32);
    77         for (i=0;i<initialguess->n;i++) {
    78             if (mask->data.U8[i] == 0) {
    79                 inputparameterlist->data.F32[j++] = initialguess->data.F32[i];
     100        for (i=0;i<mask->n;i++) {
     101            if (mask->data.U8[i] != 0) {
     102                inputParameterList->data.F32[i] = initialGuess->data.F32[i];
     103            } else {
     104                inputParameterList->data.F32[i] = gsl_vector_get(x, j++);
    80105            }
    81106        }
    82107    } else {
    83         for (i=0;i<initialguess->n;i++) {
    84             inputparameterlist->data.F32[i] = initialguess->data.F32[i];
    85         }
    86     }
    87     // PAUL: what is this?
    88     evalModel(entiredomain, inputparameterlist);
    89     ???
    90 
    91     loop i over domain size n
    92     {
    93         gsl_vector_set (f, i, (modelvalue[i] - data[i])/errors[i]);
    94     }
     108        for (i=0;i<initialGuess->n;i++) {
     109            inputParameterList->data.F32[i] = initialGuess->data.F32[i];
     110        }
     111    }
     112
     113    for (i=0;i<domain->numRows;i++) {
     114        //GUS        tmpf = evalModel(inputParameterList, domain->data.F32[i]);
     115        gsl_vector_set(f, i, (tmpf - data->data.F32[i])/errors->data.F32[i]);
     116    }
     117
    95118    return GSL_SUCCESS;
    96119}
    97120
    98 int gsl_function_df(const gsl_vector * x,
     121int gsl_function_df(const gsl_vector *x,
    99122                    void *params,
    100                     gsl_matrix* J)
    101 {
    102     size_t n  = ((psmodeldata *)params)->n;
    103     psVector *data   = ((psmodeldata *)params)->data;
    104     psVector *errors = ((psmodeldata *) params)->errors;
    105     psVector *mask   = ((psmodeldata *) params)->paramMask;
    106     psVector *initialguess = ((psmodeldata *)params)->initialguess;
    107     int count = 0;
    108     float (*d_evalModel) = ((psmodeldata *) params)->evalModel;
     123                    gsl_matrix *J)
     124{
     125    //    size_t n  = ((psModelData *)params)->n;
     126    psImage  *domain   = ((psModelData *)params)->domain;
     127    //    psVector *data   = ((psModelData *)params)->data;
     128    psVector *errors = ((psModelData *) params)->errors;
     129    psVector *mask   = ((psModelData *) params)->paramMask;
     130    psVector *initialGuess = ((psModelData *)params)->initialGuess;
     131    psVector *inputParameterList = NULL;
     132    //    int count = 0;
     133    //    float (*d_evalModel) = ((psModelData *) params)->evalModel;
    109134    size_t i;
    110 
    111     for (i=0;i<initialguess->n;i++) {
    112         if (mask->data.U8[i] != 0) {
    113             count++;
    114         }
    115     }
    116 
    117 
     135    int j;
     136    float tmpf;
     137
     138    // The GSL routines will call this functions with the masked parameters
     139    // removed.  However, the user-supplied function (to be modified) does not
     140    // have those parameters removed.  Here will create a new parameter list
     141    // with the masked parameters added (we expand initialGuess).
     142    inputParameterList = psVectorAlloc(initialGuess->n, PS_TYPE_F32);
    118143    if (mask != NULL) {
    119144        j = 0;
    120         inputparameterlist = psVectorAlloc(count, PS_TYPE_F32);
    121         for (i=0;i<initialguess->n;i++) {
    122             if (mask->data.U8[i] == 0) {
    123                 inputparameterlist->data.F32[j++] = initialguess->data.F32[i];
     145        for (i=0;i<mask->n;i++) {
     146            if (mask->data.U8[i] != 0) {
     147                inputParameterList->data.F32[i] = initialGuess->data.F32[i];
     148            } else {
     149                inputParameterList->data.F32[i] = gsl_vector_get(x, j++);
    124150            }
    125151        }
    126152    } else {
    127         for (i=0;i<initialguess->n;i++) {
    128             inputparameterlist->data.F32[i] = initialguess->data.F32[i];
    129         }
    130     }
    131 
    132     d_evalModel(entiredomain, inputparameterlist);
    133     ???
    134     loop i over domain size n
    135     // Jacobian matrix J(i,j) = dfi / dxj, where fi = (Modeli - datai)/errors[i]
    136     {
    137         loop j over the number of coefficients in model (excluding masks)
    138         {
    139             gsl_matrix_set (J, i, j, (d_modelvalue[i][j])/errors[i]);
    140         }
    141     }
     153        for (i=0;i<initialGuess->n;i++) {
     154            inputParameterList->data.F32[i] = initialGuess->data.F32[i];
     155        }
     156    }
     157
     158    for (i=0;i<domain->numRows;i++) {
     159        for (j=0;j<inputParameterList->n;j++) {
     160            //GUS            tmpf = d_evalModel(inputParameterList, domain->data.F32[i], j);
     161
     162            gsl_matrix_set(J, i, j, (tmpf/errors->data.F32[i]));
     163        }
     164    }
     165
    142166    return GSL_SUCCESS;
    143167}
    144168
    145 int gsl_function_fdf(const gsl_vector * x,
    146                      void *params,
    147                      gsl_vector * f,
    148                      gsl_matrix * J)
    149 {
    150     gsl_function_f (x, params, f);
    151     gsl_function_df (x, params, J);
     169int gsl_my_function_fdf(const gsl_vector *x,
     170                        void *params,
     171                        gsl_vector *f,
     172                        gsl_matrix *J)
     173{
     174    gsl_function_f(x, params, f);
     175    gsl_function_df(x, params, J);
    152176
    153177    return GSL_SUCCESS;
     
    166190               const psVector *restrict errors,
    167191               psVector *restrict initialGuess,
    168                const psVector *restrict paramMask)
    169 {
    170     size_t n = size(domain);
    171     size_t p = size(initialGuess);
    172     gsl_multifit_fdfsolver_type *T = NULL;
    173     gsl_multifit_fdfsolver *s = NULL;
     192               const psVector *restrict paramMask,
     193               float *chiSq)
     194{
     195    size_t n = domain->n;
     196    const gsl_multifit_fdfsolver_type *T = gsl_multifit_fdfsolver_lmsder;
     197    gsl_multifit_fdfsolver *s      = NULL;
    174198    int status;
    175199    size_t i = 0;
     200    int j = 0;
    176201    size_t iter = 0;
    177     psmodeldata inputdata = { n, initialguess, data, errors, paramMask, evalmodel, d_evalmodel};
     202    psModelData *inputData = NULL;
    178203    gsl_multifit_function_fdf f;
    179     double *x_init = NULL;
    180 
    181 
    182     //GUS: call psStatsGetnValues, allocate x_init.
    183     /* compress initialguess in light of mask */
    184     j = 0;
    185     loop i over length of initialguess
    186     {
    187         if not masked[i]
    188         {
    189             x_init[j] = initialguess[i];
    190             j++;
    191         } else
    192         { /* reduce p accordingly */
    193             p--;
    194         }
    195 }
    196 
    197 
    198 // Creates the vector for x which GSL uses.  Must deallocate.
    199 gsl_vector_view x = gsl_vector_view_array (x_init, p);
    200 
    201     const gsl_rng_type * type;
     204    double *xInit = NULL;
     205
     206    inputData = (psModelData *) psAlloc(sizeof(psModelData));
     207    inputData->n = n;
     208    inputData->count = 0;
     209    inputData->initialGuess = initialGuess;
     210    //    inputData->domain = domain;
     211    //    inputData->data = data;
     212    //    inputData->errors = errors;
     213    //    inputData->paramMask = paramMask;
     214    //    inputData->evalModel = evalModel;
     215    //    inputData->d_evalModel = DevalModel;
     216
     217    inputData->count = 0;
     218    if (paramMask != NULL) {
     219        for (i=0;i<paramMask->n;i++) {
     220            if (paramMask->data.U8[i] != 0) {
     221                inputData->count++;
     222            }
     223        }
     224    } else {
     225        inputData->count= initialGuess->n;
     226    }
     227
     228
     229
     230    // The initial guess at the parameters for the function are written into
     231    // the vector inputParameterList.  If the paramMask is not NULL, then those
     232    // parameters are masked out.  How can this possibly work?  The user-
     233    // supplied function will require a fixed number of parameters.
     234
     235    xInit = (double *) psAlloc(inputData->count * sizeof(double));
     236    if (paramMask != NULL) {
     237        j = 0;
     238        for (i=0;i<initialGuess->n;i++) {
     239            if (paramMask->data.U8[i] == 0) {
     240                xInit[j++] = initialGuess->data.F32[i];
     241            }
     242        }
     243    } else {
     244        for (i=0;i<initialGuess->n;i++) {
     245            xInit[i] = initialGuess->data.F32[i];
     246        }
     247    }
     248
     249    // Creates the vector for x which GSL uses.  Must deallocate.
     250    gsl_vector_view x = gsl_vector_view_array(xInit, inputData->count);
     251
     252    const gsl_rng_type *type;
    202253    gsl_rng *r;
    203254    gsl_rng_env_setup();
    204255
    205256    type = gsl_rng_default;
    206     r = gsl_rng_alloc (type);
     257    r = gsl_rng_alloc(type);
    207258
    208259    f.f = &gsl_function_f;
    209260    f.df = &gsl_function_df;
    210     f.fdf = &gsl_function_fdf;
     261    f.fdf = &gsl_my_function_fdf;
    211262    f.n = n;
    212     f.p = p;
    213     f.params = &inputdata;
    214 
    215     T = gsl_multifit_fdfsolver_lmsder;
    216     s = gsl_multifit_fdfsolver_alloc (T, n, p);
    217     gsl_multifit_fdfsolver_set (s, &f, &x.vector);
    218 
    219     print_state (iter, s);
    220 
     263    f.p = inputData->count;
     264    f.params = &inputData;
     265
     266    // This tells GSL to use the Levenberg-Marquardt algorithm for chi2
     267    // minimization.
     268    //    T = gsl_multifit_fdfsolver_lmsder;
     269
     270    // Creates an instance of the GSL solver that we will be iterating on.
     271    s = gsl_multifit_fdfsolver_alloc(T, n, inputData->count);
     272
     273    // Initialize the GSL minimizer.
     274    gsl_multifit_fdfsolver_set(s, &f, &x.vector);
     275
     276    //    print_state(iter, s);
    221277    do {
    222278        iter++;
    223         status = gsl_multifit_fdfsolver_iterate (s);
    224 
    225         printf ("status = %s\n", gsl_strerror (status));
    226 
    227         print_state (iter, s);
    228 
    229         // Figure this out
    230         if (status)
    231             break;
     279        // Perform an iteration of the GSL solver.
     280        status = gsl_multifit_fdfsolver_iterate(s);
     281
     282        //        printf("status = %s\n", gsl_strerror(status));
     283        //        print_state(iter, s);
     284
     285        // If there was a problem, abort.
     286        if (status) {
     287            psAbort(__func__, "gsl_multifit_fdfsolver_iterate()\n");
     288        }
    232289
    233290        // Checks whether the (L2-norm) computed derivative and the difference
    234         // between the real/actual for that test x-vector.  If were close enough
    235         // exit loop.
    236         status = gsl_multifit_test_delta (s->dx, s->x,
    237                                           1e-4, 1e-4);
     291        // between the real/actual for that test x-vector.  If were close
     292        // enough exit loop.
     293
     294        // Test if the parameters changed by a small enough amount.
     295        status = gsl_multifit_test_delta(s->dx, s->x, 1e-4, 1e-4);
    238296    } while (status == GSL_CONTINUE && iter < 500);
    239     gsl_matrix *covar = gsl_matrix_alloc (p, p);
    240     gsl_multifit_covar (s->J, 0.0, covar);
    241     gsl_matrix_fprintf (stdout, covar, "%g");
    242 
    243     /* add in masked values */
    244     j = 0;
    245     loop i over the length of initialguess
    246     {
    247         if mask(i)
    248     {
    249         // do nothing, initialguess shouldn't have changed */
    250     } else
    251     {
    252         initialguess(i)  = gsl_vector_get(s->x, j);  /* output */
    253             uncertainity = sqrt(gsl_matrix_get(covar,j,j));
    254             j++;
    255         }
    256     }
    257     double chi = gsl_blas_dnrm2(s->f);
    258     gsl_multifit_fdfsolver_free (s);
    259     return 0;
    260 }
    261 
    262 // For 3-element vectors
    263 int print_state(size_t iter,
    264                 gsl_multifit_fdfsolver * s)
    265 {
    266     printf ("iter: %3u x = % 15.8f % 15.8f % 15.8f "
    267             "|f(x)| = %g\n",
    268             iter,
    269             gsl_vector_get (s->x, 0),
    270             gsl_vector_get (s->x, 1),
    271             gsl_vector_get (s->x, 2),
    272             gsl_blas_dnrm2 (s->f));
    273 }
    274 
    275 
    276 
    277 
    278 
    279 
     297
     298
     299
     300
     301    if (paramMask != NULL) {
     302        j = 0;
     303        for (i=0;i<initialGuess->n;i++) {
     304            if (paramMask->data.U8[i] == 0) {
     305                initialGuess->data.F32[i] = gsl_vector_get(s->x, j++);
     306            } else {
     307                initialGuess->data.F32[i] = initialGuess->data.F32[i];
     308            }
     309        }
     310    } else {
     311        for (i=0;i<initialGuess->n;i++) {
     312            initialGuess->data.F32[i] = gsl_vector_get(s->x, i);
     313        }
     314    }
     315
     316    *chiSq = gsl_blas_dnrm2(s->f);
     317    gsl_multifit_fdfsolver_free(s);
     318    // Free all allocated memory
     319    psFree(xInit);
     320    psFree(inputData);
     321
     322    return(initialGuess);
     323}
    280324
    281325/** @brief This procedure calculates various combinations of powers of x and y
Note: See TracChangeset for help on using the changeset viewer.