00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 #include "NLfit_model.c"
00050
00051
00052
00053
00054
00055
00056 #include <setjmp.h>
00057 static int jump_on_NLfit_error = 0 ;
00058 static jmp_buf NLfit_error_jmpbuf ;
00059
00060 void NLfit_error
00061 (
00062 char * message
00063 )
00064
00065 {
00066 fprintf (stderr, "%s Error: %s \n", PROGRAM_NAME, message);
00067 if( jump_on_NLfit_error ) longjmp( NLfit_error_jmpbuf , 1 ) ;
00068 exit(1);
00069 }
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 void initialize_signal_model
00081 (
00082 NLFIT_MODEL_array * model_array,
00083 char * sname,
00084 vfp * smodel,
00085 int * p,
00086 char ** spname,
00087 float * min_sconstr,
00088 float * max_sconstr
00089 )
00090
00091 {
00092 int im, ip, index;
00093 char message[MAX_NAME_LENGTH];
00094
00095
00096 index = -1;
00097 for (im = 0; im < model_array->num; im++)
00098 if (strncmp(model_array->modar[im]->interface->label,
00099 sname, MAX_NAME_LENGTH) == 0) index = im;
00100 if (index < 0)
00101 {
00102 sprintf (message, "Unable to locate signal model %s", sname);
00103 NLfit_error (message);
00104 }
00105
00106 if (model_array->modar[index]->interface->model_type != MODEL_SIGNAL_TYPE)
00107 {
00108 sprintf (message, "%s has not been declared a signal model", sname);
00109 NLfit_error (message);
00110 }
00111
00112 *smodel = model_array->modar[index]->interface->call_func;
00113 if (*smodel == NULL)
00114 {
00115 sprintf (message, "Signal model %s not properly implemented", sname);
00116 NLfit_error (message);
00117 }
00118
00119 *p = model_array->modar[index]->interface->params;
00120 if ((*p < 0) || (*p > MAX_PARAMETERS))
00121 {
00122 sprintf (message, "Illegal number of parameters for signal model %s",
00123 sname);
00124 NLfit_error (message);
00125 }
00126
00127 for (ip = 0; ip < *p; ip++)
00128 {
00129 strncpy (spname[ip], model_array->modar[index]->interface->plabel[ip],
00130 MAX_NAME_LENGTH);
00131 min_sconstr[ip] = model_array->modar[index]->interface->min_constr[ip];
00132 max_sconstr[ip] = model_array->modar[index]->interface->max_constr[ip];
00133 if (min_sconstr[ip] > max_sconstr[ip])
00134 NLfit_error("Must have signal parameter min cnstrnts <= max cnstrnts");
00135 }
00136
00137 }
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148 void initialize_noise_model
00149 (
00150 NLFIT_MODEL_array * model_array,
00151 char * nname,
00152 vfp * nmodel,
00153 int * r,
00154 char ** npname,
00155 float * min_nconstr,
00156 float * max_nconstr
00157 )
00158
00159 {
00160 int im, ip, index;
00161 char message[MAX_NAME_LENGTH];
00162
00163
00164 index = -1;
00165 for (im = 0; im < model_array->num; im++)
00166 if (strncmp(model_array->modar[im]->interface->label,
00167 nname, MAX_NAME_LENGTH) == 0) index = im;
00168 if (index < 0)
00169 {
00170 sprintf (message, "Unable to locate noise model %s", nname);
00171 NLfit_error (message);
00172 }
00173
00174 if (model_array->modar[index]->interface->model_type != MODEL_NOISE_TYPE)
00175 {
00176 printf ("type = %d \n",
00177 model_array->modar[index]->interface->model_type);
00178 sprintf (message, "%s has not been declared a noise model", nname);
00179 NLfit_error (message);
00180 }
00181
00182 *nmodel = model_array->modar[index]->interface->call_func;
00183 if (*nmodel == NULL)
00184 {
00185 sprintf (message, "Noise model %s not properly implemented", nname);
00186 NLfit_error (message);
00187 }
00188
00189 *r = model_array->modar[index]->interface->params;
00190 if ((*r < 0) || (*r > MAX_PARAMETERS))
00191 {
00192 sprintf (message, "Illegal number of parameters for noise model %s",
00193 nname);
00194 NLfit_error (message);
00195 }
00196
00197 for (ip = 0; ip < *r; ip++)
00198 {
00199 strncpy (npname[ip], model_array->modar[index]->interface->plabel[ip],
00200 MAX_NAME_LENGTH);
00201 min_nconstr[ip] = model_array->modar[index]->interface->min_constr[ip];
00202 max_nconstr[ip] = model_array->modar[index]->interface->max_constr[ip];
00203 if (min_nconstr[ip] > max_nconstr[ip])
00204 NLfit_error("Must have noise parameter min cnstrnts <= max cnstrnts");
00205 }
00206
00207 }
00208
00209
00210
00211
00212
00213
00214
00215 void calc_linear_regression
00216 (
00217 matrix x,
00218 vector y,
00219 vector * b,
00220 float * sse
00221 )
00222
00223 {
00224 matrix xt, xtx, xtxinv, xtxinvxt;
00225 vector yhat;
00226 vector e;
00227 int ok;
00228
00229
00230
00231 matrix_initialize (&xt);
00232 matrix_initialize (&xtx);
00233 matrix_initialize (&xtxinv);
00234 matrix_initialize (&xtxinvxt);
00235 vector_initialize (&yhat);
00236 vector_initialize (&e);
00237
00238
00239 matrix_transpose (x, &xt);
00240 matrix_multiply (xt, x, &xtx);
00241 ok = matrix_inverse (xtx, &xtxinv);
00242 if (!ok) NLfit_error ("Unable to invert matrix");
00243 matrix_multiply (xtxinv, xt, &xtxinvxt);
00244 vector_multiply (xtxinvxt, y, b);
00245
00246
00247 vector_multiply (x, *b, &yhat);
00248
00249
00250 vector_subtract (y, yhat, &e);
00251 *sse = vector_dot (e, e);
00252
00253
00254 vector_destroy (&e);
00255 vector_destroy (&yhat);
00256 matrix_destroy (&xtxinvxt);
00257 matrix_destroy (&xtxinv);
00258 matrix_destroy (&xtx);
00259 matrix_destroy (&xt);
00260
00261 }
00262
00263
00264
00265
00266
00267
00268
00269
00270 void calc_reduced_model
00271 (
00272 int n,
00273 int r,
00274 float ** x_array,
00275 float * y_array,
00276 float * b_array,
00277 float * sse
00278 )
00279
00280 {
00281 matrix x;
00282 vector y;
00283 vector b;
00284
00285
00286
00287 matrix_initialize (&x);
00288 vector_initialize (&y);
00289 vector_initialize (&b);
00290
00291
00292 array_to_matrix (n, r, x_array, &x);
00293 array_to_vector (n, y_array, &y);
00294
00295
00296 calc_linear_regression (x, y, &b, sse);
00297
00298
00299 vector_to_array (b, b_array);
00300
00301
00302 vector_destroy (&b);
00303 vector_destroy (&y);
00304 matrix_destroy (&x);
00305 }
00306
00307
00308
00309
00310
00311
00312
00313 void initialize_full_model
00314 (
00315 int dimension,
00316 int nbest,
00317 float *** parameters,
00318 float ** sse
00319 )
00320
00321 {
00322 int i;
00323
00324 *sse = (float *) malloc (sizeof(float) * nbest);
00325 *parameters = (float **) malloc (sizeof(float *) * nbest);
00326 for (i = 0; i < nbest; i++)
00327 (*parameters)[i] = (float *) malloc (sizeof(float) * dimension);
00328
00329 }
00330
00331
00332
00333
00334
00335
00336
00337 int calc_constraints
00338 (
00339 int r,
00340 int p,
00341 int nabs,
00342 float * b_array,
00343 float * min_nconstr,
00344 float * max_nconstr,
00345 float * min_sconstr,
00346 float * max_sconstr,
00347 float * vertex
00348 )
00349
00350 {
00351 int i;
00352
00353
00354
00355 if (nabs)
00356 for (i = 0; i < r; i++)
00357 {
00358 if (vertex[i] < min_nconstr[i]) return (1);
00359 if (vertex[i] > max_nconstr[i]) return (1);
00360 }
00361 else
00362 for (i = 0; i < r; i++)
00363 {
00364 if (vertex[i] < min_nconstr[i] + b_array[i]) return (1);
00365 if (vertex[i] > max_nconstr[i] + b_array[i]) return (1);
00366 }
00367
00368
00369 for (i = 0; i < p; i++)
00370 {
00371 if (vertex[i+r] < min_sconstr[i]) return (1);
00372 if (vertex[i+r] > max_sconstr[i]) return (1);
00373 }
00374
00375 return (0);
00376 }
00377
00378 #define SAVE_RAN
00379 #ifdef SAVE_RAN
00380
00381
00382
00383
00384
00385
00386 static vfp OLD_nmodel = NULL ;
00387 static int OLD_r = -1 ;
00388 static float * OLD_min_nconstr = NULL ;
00389 static float * OLD_max_nconstr = NULL ;
00390 static float * RAN_npar = NULL ;
00391 static float * RAN_nts = NULL ;
00392
00393
00394
00395 static vfp OLD_smodel = NULL ;
00396 static int OLD_p = -1 ;
00397 static float * OLD_min_sconstr = NULL ;
00398 static float * OLD_max_sconstr = NULL ;
00399 static float * RAN_spar = NULL ;
00400 static float * RAN_sts = NULL ;
00401
00402 static int OLD_ts_length = -1 ;
00403 static int OLD_nrand = -1 ;
00404 static float OLD_x0 = -666.0 ;
00405 static float OLD_x1 = -777.0 ;
00406
00407 static int RAN_sind = -1 ;
00408
00409
00410
00411
00412 int RAN_compare_vect( int n , float * a , float * b )
00413 {
00414 int ii ;
00415 if( n < 1 || a == NULL || b == NULL ) return 1 ;
00416 for( ii=0 ; ii < n ; ii++ ) if( a[ii] != b[ii] ) return 1 ;
00417 return 0 ;
00418 }
00419
00420
00421
00422
00423
00424 void RAN_setup
00425 (
00426 vfp nmodel,
00427 vfp smodel,
00428 int r,
00429 int p,
00430 int nabs,
00431 float * min_nconstr,
00432 float * max_nconstr,
00433 float * min_sconstr,
00434 float * max_sconstr,
00435 int ts_length,
00436 float ** x_array,
00437 int nrand
00438 )
00439 {
00440 int ip , ipt ;
00441 float * par ;
00442 float * ts ;
00443
00444
00445
00446 if( smodel == NULL ){
00447 OLD_smodel = NULL ;
00448 OLD_p = -1 ;
00449 if( OLD_min_sconstr != NULL ){ free(OLD_min_sconstr); OLD_min_sconstr = NULL; }
00450 if( OLD_max_sconstr != NULL ){ free(OLD_max_sconstr); OLD_max_sconstr = NULL; }
00451 if( RAN_spar != NULL ){ free(RAN_spar) ; RAN_spar = NULL; }
00452 if( RAN_sts != NULL ){ free(RAN_sts ) ; RAN_sts = NULL; }
00453 return ;
00454 }
00455
00456
00457
00458 if( smodel != OLD_smodel ||
00459 p != OLD_p ||
00460 ts_length != OLD_ts_length ||
00461 nrand != OLD_nrand ||
00462 x_array[0][1] != OLD_x0 ||
00463 x_array[1][1] != OLD_x1 ||
00464 RAN_compare_vect(p,min_sconstr,OLD_min_sconstr) ||
00465 RAN_compare_vect(p,max_sconstr,OLD_max_sconstr) ){
00466
00467
00468
00469 #if 0
00470 fprintf(stderr,"++ NLfit: initializing random signal models") ;
00471 #endif
00472
00473 OLD_smodel = smodel ;
00474 OLD_p = p ;
00475 OLD_ts_length = ts_length ;
00476 OLD_nrand = nrand ;
00477 OLD_x0 = x_array[0][1] ;
00478 OLD_x1 = x_array[1][1] ;
00479 if( OLD_min_sconstr != NULL ) free(OLD_min_sconstr) ;
00480 if( OLD_max_sconstr != NULL ) free(OLD_max_sconstr) ;
00481 OLD_min_sconstr = (float *) malloc(sizeof(float)*p) ;
00482 OLD_max_sconstr = (float *) malloc(sizeof(float)*p) ;
00483 memcpy( OLD_min_sconstr , min_sconstr , sizeof(float)*p ) ;
00484 memcpy( OLD_max_sconstr , max_sconstr , sizeof(float)*p ) ;
00485
00486
00487
00488 if( RAN_spar != NULL ) free(RAN_spar) ;
00489 if( RAN_sts != NULL ) free(RAN_sts ) ;
00490 RAN_spar = (float *) malloc(sizeof(float)*nrand*p) ;
00491 RAN_sts = (float *) malloc(sizeof(float)*nrand*ts_length) ;
00492
00493
00494
00495 for( ipt=0 ; ipt < nrand ; ipt++ ){
00496
00497 par = RAN_spar + (ipt*p) ;
00498 ts = RAN_sts + (ipt*ts_length) ;
00499
00500 for( ip=0 ; ip < p ; ip++ )
00501 par[ip] = get_random_value(min_sconstr[ip], max_sconstr[ip]) ;
00502
00503 #if 0
00504 smodel( par , ts_length , x_array , ts ) ;
00505 #else
00506 AFNI_CALL_VOID_4ARG(smodel ,
00507 float *,par , int,ts_length,
00508 float **,x_array , float *,ts ) ;
00509 #endif
00510 }
00511
00512 #if 0
00513 fprintf(stderr," - done\n") ;
00514 #endif
00515 }
00516
00517 return ;
00518 }
00519
00520 #endif
00521
00522
00523
00524
00525
00526
00527 void full_model
00528 (
00529 vfp nmodel,
00530 vfp smodel,
00531 float * gn,
00532 float * gs,
00533 int ts_length,
00534 float ** x_array,
00535 float * yhat_array
00536 )
00537
00538 {
00539 int it;
00540 float * y_array = NULL;
00541 #ifdef SAVE_RAN
00542 int use_model = ( RAN_sind < 0 || ts_length != OLD_ts_length ) ;
00543 #endif
00544
00545
00546
00547 #ifdef SAVE_RAN
00548 if( use_model ){
00549 #endif
00550 y_array = (float *) malloc (sizeof(float) * (ts_length));
00551 if (y_array == NULL)
00552 NLfit_error ("Unable to allocate memory for y_array");
00553 #if 0
00554 smodel (gs, ts_length, x_array, y_array);
00555 #else
00556 AFNI_CALL_VOID_4ARG(smodel ,
00557 float *,gs , int,ts_length,
00558 float **,x_array , float *,y_array ) ;
00559 #endif
00560
00561 #ifdef SAVE_RAN
00562 } else
00563 y_array = RAN_sts + (ts_length*RAN_sind) ;
00564 #endif
00565
00566
00567 #if 0
00568 nmodel (gn, ts_length, x_array, yhat_array);
00569 #else
00570 AFNI_CALL_VOID_4ARG(nmodel ,
00571 float *,gn , int,ts_length,
00572 float **,x_array , float *,yhat_array ) ;
00573 #endif
00574
00575
00576 for (it = 0; it < ts_length; it++)
00577 yhat_array[it] += y_array[it];
00578
00579
00580
00581 #ifdef SAVE_RAN
00582 if( use_model )
00583 #endif
00584 free (y_array) ;
00585
00586 y_array = NULL;
00587 }
00588
00589
00590
00591
00592
00593
00594
00595
00596 float calc_sse
00597 (
00598 vfp nmodel,
00599 vfp smodel,
00600 int r,
00601 int p,
00602 int nabs,
00603 float * min_nconstr,
00604 float * max_nconstr,
00605 float * min_sconstr,
00606 float * max_sconstr,
00607 float * b_array,
00608 float * vertex,
00609 int ts_length,
00610 float ** x_array,
00611 float * ts_array
00612 )
00613
00614 {
00615 const float BIG_NUMBER = 1.0e+10;
00616
00617 int i;
00618 float t;
00619 float diff;
00620 float sse;
00621 float * y_array = NULL;
00622
00623
00624
00625 y_array = (float *) malloc (sizeof(float) * ts_length);
00626
00627
00628 if (calc_constraints (r, p, nabs, b_array, min_nconstr, max_nconstr,
00629 min_sconstr, max_sconstr, vertex))
00630 {
00631 free (y_array); y_array = NULL;
00632 return (BIG_NUMBER);
00633 }
00634
00635
00636 full_model (nmodel, smodel, vertex, vertex + r, ts_length, x_array, y_array);
00637
00638
00639 sse = 0.0;
00640 for (i = 0; i < ts_length; i++)
00641 {
00642 diff = ts_array[i] - y_array[i];
00643 sse += diff * diff;
00644 }
00645
00646
00647 free (y_array); y_array = NULL;
00648
00649
00650 return (sse);
00651 }
00652
00653
00654
00655
00656
00657
00658
00659 void random_search
00660 (
00661 vfp nmodel,
00662 vfp smodel,
00663 int r,
00664 int p,
00665 int nabs,
00666 float * min_nconstr,
00667 float * max_nconstr,
00668 float * min_sconstr,
00669 float * max_sconstr,
00670 int ts_length,
00671 float ** x_array,
00672 float * ts_array,
00673 float * par_rdcd,
00674 int nrand,
00675 int nbest,
00676 float ** parameters,
00677 float * response
00678 )
00679
00680 {
00681 int ip;
00682 int iv, ipt;
00683 float sse;
00684 float * par = NULL;
00685
00686
00687 #ifdef SAVE_RAN
00688
00689
00690 #undef BEST_NOISE
00691 #ifdef BEST_NOISE
00692 float * qts = (float *) malloc(sizeof(float)*ts_length) ;
00693 float junk ;
00694 #endif
00695 #endif
00696
00697
00698
00699 #ifdef SAVE_RAN
00700 RAN_setup( nmodel , smodel , r , p , nabs ,
00701 min_nconstr, max_nconstr,
00702 min_sconstr, max_sconstr,
00703 ts_length, x_array, nrand ) ;
00704 #endif
00705
00706
00707 par = (float *) malloc (sizeof(float) * (r+p));
00708
00709
00710 for (iv = 0; iv < nbest; iv++)
00711 response[iv] = 1.0e+30;
00712
00713
00714
00715 for (ipt = 0; ipt < nrand; ipt++)
00716 {
00717
00718
00719 #ifdef BEST_NOISE
00720 for( ip=0 ; ip < ts_length ; ip++ )
00721 qts[ip] = ts_array[ip] - RAN_sts[ts_length*ipt+ip] ;
00722 calc_reduced_model( ts_length , r , x_array , qts , par , &junk ) ;
00723 #else
00724
00725 if (nabs)
00726 for (ip = 0; ip < r; ip++)
00727 par[ip] = get_random_value (min_nconstr[ip], max_nconstr[ip]);
00728 else
00729 for (ip = 0; ip < r; ip++)
00730 par[ip] = get_random_value (min_nconstr[ip] + par_rdcd[ip],
00731 max_nconstr[ip] + par_rdcd[ip]);
00732 #endif
00733
00734
00735 #ifdef SAVE_RAN
00736 for( ip=0 ; ip < p ; ip++ )
00737 par[ip+r] = RAN_spar[ipt*p+ip] ;
00738 #else
00739 for (ip = 0; ip < p; ip++)
00740 par[ip+r] = get_random_value (min_sconstr[ip], max_sconstr[ip]);
00741 #endif
00742
00743
00744
00745 #ifdef SAVE_RAN
00746 RAN_sind = ipt ;
00747 #endif
00748
00749 sse = calc_sse (nmodel, smodel, r, p, nabs, min_nconstr, max_nconstr,
00750 min_sconstr, max_sconstr, par_rdcd, par,
00751 ts_length, x_array, ts_array);
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764 #define PUSH_BEST
00765 #ifdef PUSH_BEST
00766 for (iv = 0; iv < nbest; iv++)
00767 if (sse < response[iv]){
00768 int jv ;
00769 for( jv=nbest-1 ; jv > iv ; jv-- ){
00770 response[jv] = response[jv-1] ;
00771 for( ip=0 ; ip < r+p ; ip++ )
00772 parameters[jv][ip] = parameters[jv-1][ip] ;
00773 }
00774
00775 response[iv] = sse ;
00776 for( ip=0 ; ip < r+p ; ip++ )
00777 parameters[iv][ip] = par[ip] ;
00778 break ;
00779 }
00780 #else
00781 for (iv = 0; iv < nbest; iv++)
00782 if (sse < response[iv])
00783 {
00784 for (ip = 0; ip < r+p; ip++)
00785 parameters[iv][ip] = par[ip];
00786 response[iv] = sse;
00787 break;
00788 }
00789 #endif
00790 }
00791
00792
00793 free (par); par = NULL;
00794
00795 #ifdef SAVE_RAN
00796 RAN_sind = -1 ;
00797 #endif
00798
00799 #if 0
00800
00801 { static count=-1 ;
00802 count++ ;
00803 if( count%10 == 0 ){
00804 printf("Random search sse:\n") ;
00805 for( iv=0 ; iv < nbest ; iv++ ) printf(" %g",response[iv]) ;
00806 printf("\n") ;
00807 }
00808 }
00809 #endif
00810
00811 }
00812
00813
00814
00815
00816
00817
00818
00819 void calc_full_model
00820 (
00821 vfp nmodel,
00822 vfp smodel,
00823 int r,
00824 int p,
00825 float * min_nconstr,
00826 float * max_nconstr,
00827 float * min_sconstr,
00828 float * max_sconstr,
00829 int ts_length,
00830 float ** x_array,
00831 float * ts_array,
00832 float * par_rdcd,
00833 float sse_rdcd,
00834 int nabs,
00835 int nrand,
00836 int nbest,
00837 float rms_min,
00838 float * par_full,
00839 float * sse_full,
00840 int * novar
00841 )
00842
00843 {
00844 int iv;
00845 int ip;
00846 float ** parameters = NULL;
00847 float * sse = NULL;
00848
00849
00850
00851
00852
00853 if ( (p < 1) || (sqrt(sse_rdcd/(ts_length - r)) < rms_min) )
00854 {
00855 *novar = 1;
00856 for (ip = 0; ip < r; ip++)
00857 par_full[ip] = par_rdcd[ip];
00858 for (ip = r; ip < r+p; ip++)
00859 par_full[ip] = 0.0;
00860 *sse_full = sse_rdcd;
00861 return;
00862 }
00863 else
00864 *novar = 0;
00865
00866
00867
00868 srand48 (1234567);
00869
00870
00871 initialize_full_model (r+p, nbest, ¶meters, &sse);
00872
00873
00874 random_search (nmodel, smodel, r, p, nabs,
00875 min_nconstr, max_nconstr, min_sconstr, max_sconstr,
00876 ts_length, x_array, ts_array, par_rdcd, nrand, nbest,
00877 parameters, sse);
00878
00879
00880
00881 for (iv = 0; iv < nbest; iv++)
00882 {
00883 simplex_optimization (nmodel, smodel, r, p,
00884 min_nconstr, max_nconstr, min_sconstr, max_sconstr,
00885 nabs, ts_length, x_array, ts_array, par_rdcd,
00886 parameters[iv], &sse[iv]);
00887 }
00888
00889
00890 *sse_full = 1.0e+30;
00891 for (iv = 0; iv < nbest; iv++)
00892 {
00893 if (sse[iv] < *sse_full)
00894 {
00895 *sse_full = sse[iv];
00896 for (ip = 0; ip < r+p; ip++)
00897 par_full[ip] = parameters[iv][ip];
00898 }
00899 }
00900
00901
00902
00903 for (iv = 0; iv < nbest; iv++)
00904 {
00905 free (parameters[iv]);
00906 parameters[iv] = NULL;
00907 }
00908 free (parameters); parameters = NULL;
00909 free (sse); sse = NULL;
00910
00911 }
00912
00913
00914
00915
00916
00917
00918
00919
00920 void calc_partial_derivatives
00921 (
00922 vfp nmodel,
00923 vfp smodel,
00924 int r,
00925 int p,
00926 float * min_nconstr,
00927 float * max_nconstr,
00928 float * min_sconstr,
00929 float * max_sconstr,
00930 int ts_length,
00931 float ** x_array,
00932 float * par_full,
00933 matrix d
00934 )
00935
00936 {
00937 const float EPSILON = 1.0e-10;
00938 int dimension;
00939 int ip, jp;
00940 int it;
00941 float delp;
00942 float * par = NULL;
00943 float * ts1_array = NULL;
00944 float * ts2_array = NULL;
00945
00946
00947
00948 dimension = r + p;
00949
00950
00951 ts1_array = (float *) malloc (sizeof(float) * ts_length);
00952 ts2_array = (float *) malloc (sizeof(float) * ts_length);
00953 par = (float *) malloc (sizeof(float) * dimension);
00954
00955
00956 full_model (nmodel, smodel, par_full, par_full + r,
00957 ts_length, x_array, ts1_array);
00958
00959
00960 for (jp = 0; jp < dimension; jp++)
00961 {
00962
00963 for (ip = 0; ip < dimension; ip++)
00964 par[ip] = par_full[ip];
00965
00966
00967 if (jp < r)
00968 delp = (max_nconstr[jp] - min_nconstr[jp]) / 1000.0;
00969 else
00970 delp = (max_sconstr[jp-r] - min_sconstr[jp-r]) / 1000.0;
00971 par[jp] += delp;
00972
00973
00974 full_model (nmodel, smodel, par, par + r,
00975 ts_length, x_array, ts2_array);
00976
00977
00978 if (delp > EPSILON)
00979 for (it = 0; it < ts_length; it++)
00980 d.elts[it][jp] = (ts2_array[it] - ts1_array[it]) / delp;
00981 else
00982 for (it = 0; it < ts_length; it++)
00983 d.elts[it][jp] = 0.0;
00984
00985 }
00986
00987
00988 free (par); par = NULL;
00989 free (ts2_array); ts2_array = NULL;
00990 free (ts1_array); ts1_array = NULL;
00991
00992 }
00993
00994
00995
00996
00997
00998
00999
01000 float calc_rsqr
01001 (
01002 float ssef,
01003 float sser
01004 )
01005
01006 {
01007 const float EPSILON = 1.0e-5;
01008 float rsqr;
01009
01010
01011
01012 if (sser < EPSILON)
01013 rsqr = 0.0;
01014 else
01015 rsqr = (sser - ssef) / sser;
01016
01017
01018
01019 if (rsqr < 0.0) rsqr = 0.0;
01020 if (rsqr > 1.0) rsqr = 1.0;
01021
01022
01023
01024 return (rsqr);
01025 }
01026
01027
01028
01029
01030
01031
01032
01033
01034 void analyze_results
01035 (
01036 vfp nmodel,
01037 vfp smodel,
01038 int r,
01039 int p,
01040 int novar,
01041 float * min_nconstr,
01042 float * max_nconstr,
01043 float * min_sconstr,
01044 float * max_sconstr,
01045 int ts_length,
01046 float ** x_array,
01047 float * par_rdcd,
01048 float sse_rdcd,
01049 float * par_full,
01050 float sse_full,
01051 float * rmsreg,
01052 float * freg,
01053 float * rsqr,
01054 float * smax,
01055 float * tmax,
01056 float * pmax,
01057 float * area,
01058 float * parea,
01059 float * tpar_full
01060 )
01061
01062 {
01063 const float EPSILON = 1.0e-10;
01064 int dimension;
01065 int ip;
01066 int df_rdcd;
01067 int df_full;
01068 float mse_full;
01069 float mse_reg;
01070 int ok;
01071 float * y_array = NULL;
01072 float * base_array = NULL;
01073 float barea;
01074 int it;
01075 float y1, y2, y3;
01076
01077
01078
01079 dimension = r + p;
01080 *rmsreg = *freg = *rsqr = *smax = *tmax = *pmax = *area = *parea = 0.0;
01081 for (ip = 0; ip < dimension; ip++)
01082 tpar_full[ip] = 0.0;
01083
01084
01085
01086 if (novar) return;
01087
01088
01089
01090 df_rdcd = ts_length - r;
01091 df_full = ts_length - dimension;
01092
01093 for (ip = 0; ip < r; ip++)
01094 if (min_nconstr[ip] == max_nconstr[ip])
01095 {
01096 df_rdcd++;
01097 df_full++;
01098 }
01099
01100 for (ip = 0; ip < p; ip++)
01101 if (min_sconstr[ip] == max_sconstr[ip])
01102 df_full++;
01103
01104
01105
01106 mse_full = sse_full / df_full;
01107
01108
01109 if (df_rdcd == df_full)
01110 mse_reg = 0.0;
01111 else
01112 mse_reg = (sse_rdcd - sse_full) / (df_rdcd - df_full);
01113 if (mse_reg < 0.0) mse_reg = 0.0;
01114
01115
01116 if (mse_full > EPSILON)
01117 *freg = mse_reg / mse_full;
01118 else
01119 *freg = 0.0;
01120
01121
01122 *rmsreg = sqrt(mse_full);
01123
01124
01125 *rsqr = calc_rsqr (sse_full, sse_rdcd);
01126
01127
01128 y_array = (float *) malloc (sizeof(float) * (ts_length));
01129 if (y_array == NULL)
01130 NLfit_error ("Unable to allocate memory for y_array");
01131 #if 0
01132 smodel (par_full+r, ts_length, x_array, y_array);
01133 #else
01134 AFNI_CALL_VOID_4ARG(smodel ,
01135 float *,(par_full+r) , int,ts_length,
01136 float **,x_array , float *,y_array ) ;
01137 #endif
01138
01139
01140 base_array = (float *) malloc (sizeof(float) * (ts_length));
01141 if (base_array == NULL)
01142 NLfit_error ("Unable to allocate memory for base_array");
01143 #if 0
01144 nmodel (par_full, ts_length, x_array, base_array);
01145 #else
01146 AFNI_CALL_VOID_4ARG(nmodel ,
01147 float *,par_full , int,ts_length,
01148 float **,x_array , float *,base_array ) ;
01149 #endif
01150
01151
01152 *tmax = x_array[0][1];
01153 *smax = y_array[0];
01154 if (fabs(base_array[0]) > EPSILON)
01155 *pmax = 100.0 * y_array[0] / fabs(base_array[0]);
01156 else
01157 *pmax = 0.0;
01158 *area = 0.0;
01159 barea = 0.0;
01160 *parea = 0.0;
01161
01162
01163 for (it = 1; it < ts_length; it++)
01164 {
01165
01166
01167 if (fabs(y_array[it]) > fabs(*smax))
01168 {
01169 *tmax = x_array[it][1];
01170 *smax = y_array[it];
01171 if (fabs(base_array[it]) > EPSILON)
01172 *pmax = 100.0 * y_array[it] / fabs(base_array[it]);
01173 }
01174
01175
01176 y1 = y_array[it-1]; y2 = y_array[it];
01177 if ((y1 > 0.0) && (y2 > 0.0))
01178 {
01179 *area += (y1 + y2) / 2.0;
01180 *parea += (y1 + y2) / 2.0;
01181 }
01182 else if ((y1 < 0.0) && (y2 < 0.0))
01183 {
01184 *area -= (y1 + y2) / 2.0;
01185 *parea += (y1 + y2) / 2.0;
01186 }
01187 else
01188 {
01189 y3 = fabs(y1) + fabs(y2);
01190 if (y3 > EPSILON)
01191 {
01192 *area += (y1*y1 + y2*y2) / (2.0 * y3);
01193 if (y1 > y2)
01194 *parea += (y1*y1 - y2*y2) / (2.0 * y3);
01195 else
01196 *parea -= (y1*y1 - y2*y2) / (2.0 * y3);
01197 }
01198 }
01199
01200 y1 = base_array[it-1]; y2 = base_array[it];
01201 if ((y1 > 0.0) && (y2 > 0.0))
01202 {
01203 barea += (y1 + y2) / 2.0;
01204 }
01205 else if ((y1 < 0.0) && (y2 < 0.0))
01206 {
01207 barea -= (y1 + y2) / 2.0;
01208 }
01209 else
01210 {
01211 y3 = fabs(y1) + fabs(y2);
01212 if (y3 > EPSILON)
01213 {
01214 barea += (y1*y1 + y2*y2) / (2.0 * y3);
01215 }
01216 }
01217 }
01218
01219 if (barea > EPSILON)
01220 *parea *= 100.0/barea;
01221 else
01222 *parea = 0.0;
01223
01224 free (base_array); base_array = NULL;
01225 free (y_array); y_array = NULL;
01226
01227
01228
01229 if (calc_tstats)
01230 {
01231 float stddev;
01232 matrix d, dt, dtd, dtdinv;
01233
01234
01235 matrix_initialize (&d);
01236 matrix_initialize (&dt);
01237 matrix_initialize (&dtd);
01238 matrix_initialize (&dtdinv);
01239
01240
01241 matrix_create (ts_length, dimension, &d);
01242 calc_partial_derivatives (nmodel, smodel, r, p,
01243 min_nconstr, max_nconstr,
01244 min_sconstr, max_sconstr,
01245 ts_length, x_array, par_full, d);
01246
01247
01248 matrix_transpose (d, &dt);
01249 matrix_multiply (dt, d, &dtd);
01250 ok = matrix_inverse (dtd, &dtdinv);
01251 if (ok)
01252 for (ip = 0; ip < dimension; ip++)
01253 {
01254 stddev = sqrt((sse_full/(df_full)) * dtdinv.elts[ip][ip]);
01255 if (stddev > EPSILON)
01256 tpar_full[ip] = par_full[ip] / stddev;
01257 else
01258 tpar_full[ip] = 0.0;
01259 }
01260 else
01261 for (ip = 0; ip < dimension; ip++)
01262 {
01263 tpar_full[ip] = 0.0;
01264 }
01265
01266
01267
01268 matrix_destroy (&dtdinv);
01269 matrix_destroy (&dtd);
01270 matrix_destroy (&dt);
01271 matrix_destroy (&d);
01272
01273 }
01274
01275 }
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285 double fstat_t2p( double ff , double dofnum , double dofden )
01286 {
01287 int which , status ;
01288 double p , q , f , dfn , dfd , bound ;
01289
01290 which = 1 ;
01291 p = 0.0 ;
01292 q = 0.0 ;
01293 f = ff ;
01294 dfn = dofnum ;
01295 dfd = dofden ;
01296
01297 cdff( &which , &p , &q , &f , &dfn , &dfd , &status , &bound ) ;
01298
01299 if( status == 0 ) return q ;
01300 else return 1.0 ;
01301 }
01302
01303
01304
01305
01306
01307
01308 void report_results
01309 (
01310 char * nname,
01311 char * sname,
01312 int r,
01313 int p,
01314 char ** npname,
01315 char ** spname,
01316 int ts_length,
01317 float * par_rdcd,
01318 float sse_rdcd,
01319 float * par_full,
01320 float sse_full,
01321 float * tpar_full,
01322 float rmsreg,
01323 float freg,
01324 float rsqr,
01325 float smax,
01326 float tmax,
01327 float pmax,
01328 float area,
01329 float parea,
01330 char ** label
01331 )
01332
01333 {
01334 int ip;
01335 double pvalue;
01336
01337
01338
01339 if (label == NULL) return;
01340
01341
01342 lbuf[0] = '\0';
01343
01344
01345 sprintf (sbuf, "Reduced (%s) Model: \n", nname);
01346 strcat (lbuf, sbuf);
01347 for (ip = 0; ip < r; ip++)
01348 {
01349 sprintf (sbuf, "b[%d]= %12.6f %s \n", ip, par_rdcd[ip], npname[ip]);
01350 strcat (lbuf, sbuf);
01351 }
01352
01353
01354 sprintf (sbuf, "\nFull (%s + %s) Model: \n", nname, sname);
01355 strcat (lbuf, sbuf);
01356 for (ip = 0; ip < r; ip++)
01357 {
01358 sprintf (sbuf, "gn[%d]=%12.6f %s \n", ip, par_full[ip], npname[ip]);
01359 strcat (lbuf, sbuf);
01360
01361 }
01362 for (ip = 0; ip < p; ip++)
01363 {
01364 sprintf (sbuf, "gs[%d]=%12.6f %s \n", ip, par_full[ip+r], spname[ip]);
01365 strcat (lbuf, sbuf);
01366 }
01367
01368 sprintf (sbuf, "\nSignal Tmax = %12.3f \n", tmax);
01369 strcat (lbuf, sbuf);
01370 sprintf (sbuf, "Signal Smax = %12.3f \n", smax);
01371 strcat (lbuf, sbuf);
01372 sprintf (sbuf, "Signal PSmax = %12.3f \n", pmax);
01373 strcat (lbuf, sbuf);
01374 sprintf (sbuf, "Signal Area = %12.3f \n", area);
01375 strcat (lbuf, sbuf);
01376 sprintf (sbuf, "Signal PArea = %12.3f \n", parea);
01377 strcat (lbuf, sbuf);
01378
01379 sprintf (sbuf, "\nRMSE Rdcd = %8.3f \n", sqrt(sse_rdcd/(ts_length-r)));
01380 strcat (lbuf, sbuf);
01381 sprintf (sbuf, "RMSE Full = %8.3f \n", sqrt(sse_full/(ts_length-r-p)));
01382 strcat (lbuf, sbuf);
01383
01384 sprintf (sbuf, "\nR^2 = %7.3f \n", rsqr);
01385 strcat (lbuf, sbuf);
01386 sprintf (sbuf, "F[%2d,%3d] = %7.3f \n", p, ts_length-r-p, freg);
01387 strcat (lbuf, sbuf);
01388 pvalue = fstat_t2p ( (double) freg, (double) p, (double) ts_length-r-p);
01389 sprintf (sbuf, "p-value = %e \n", pvalue);
01390 strcat (lbuf, sbuf);
01391
01392
01393
01394 *label = lbuf;
01395
01396 }
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409