yanera_util.c

Go to the documentation of this file.
00001 /*============================================================================
00002 Copyright 2006 Thad Harroun, Kevin Yager
00003 
00004 This file is part of "yanera 2.0".
00005 
00006 "yanera 2.0" is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
00007 
00008 "yanera 2.0" is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
00009 
00010 You should have received a copy of the GNU General Public License along with "yanera 2.0"; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 
00011 ============================================================================*/ 
00012 /*============================================================================*/
00018 #define _CRT_SECURE_NO_DEPRECATE
00019 
00020 #include "yanera.h"
00021 #include "yanera_util.h"
00022 #include "yanera_xml_input.h"
00023 #include "yanera_mdmin.h"
00024 #include "yanera_lstsq.h"
00025 #include "yanera_profile.h"
00026 #include "yanera_quadrature.h"
00027 #include "yanera_reflectivity.h"
00028 #include "yanera_xml_output.h"
00029 /*============================================================================*/
00030 yanera_container *yanera_initialize(const char *filename)
00031 {
00032   unsigned short    i, j;
00033   yanera_container *yanera;
00034   
00035   fprintf(stdout,"YANERA         : 2.0 beta\n");
00036   fprintf(stdout,"   Date        : %s\n", __DATE__ );
00037   fprintf(stdout,"               :\n");
00038 
00039   /*---------------------------------
00040    *  Allocate a new yanera struct.
00041    */
00042   yanera = (yanera_container *)malloc(sizeof(yanera_container));
00043   if (yanera == NULL) 
00044   {
00045     yanera_error("No memory for new yanera_container", \
00046                  __FILE__, __LINE__, NULL);
00047   }
00048   /*---------------------------------
00049    *
00050    */
00051   yanera->filename = (char *)calloc((1+strlen(filename)),sizeof(char));
00052   if (yanera->filename == NULL) 
00053   {
00054     yanera_error("No memory for new yanera XML filename", \
00055                  __FILE__, __LINE__, yanera);
00056   }
00057   strcpy(yanera->filename, filename);
00058 
00059   /*---------------------------------
00060    *  
00061    */
00062   yanera->type = MODEL_LAYER;
00063   yanera->parrattFunction = &calcParrattFromModel;
00064   yanera->profileFunctionReal = &layerProfileReal;
00065   yanera->profileFunctionImag = &layerProfileImag;
00066   /*---------------------------------
00067    *  
00068    */
00069   for (i=0; i<10; i++)
00070   {
00071     yanera->models_xml[i].data_idref  = NULL;
00072     yanera->models_xml[i].name        = NULL;
00073     yanera->models_xml[i].background  = -1;
00074     yanera->models_xml[i].polarized   = POLARIZED_NONE;
00075     yanera->models_xml[i].first_layer = NULL;
00076     yanera->models_xml[i].last_layer  = NULL;
00077     yanera->models_xml[i].slabs.number_of_slab_edges = 0;
00078     yanera->models_xml[i].slabs.number_of_slabs      = 0;
00079     for (j=0; j<USHRT_MAX; j++)
00080     {
00081       yanera->models_xml[i].slabs.zpos[j] = 0.0;
00082       yanera->models_xml[i].slabs.thik[j] = 0.0;
00083       yanera->models_xml[i].slabs.rsld[j] = 0.0;
00084       yanera->models_xml[i].slabs.isld[j] = 0.0;
00085     }
00086     
00087     yanera->models_complete[i].data_idref  = NULL;
00088     yanera->models_complete[i].name        = NULL;
00089     yanera->models_complete[i].background  = -1;
00090     yanera->models_complete[i].polarized   = POLARIZED_NONE;
00091     yanera->models_complete[i].first_layer = NULL;
00092     yanera->models_complete[i].last_layer  = NULL;
00093     yanera->models_complete[i].slabs.number_of_slab_edges = 0;
00094     yanera->models_complete[i].slabs.number_of_slabs      = 0;
00095     for (j=0; j<USHRT_MAX; j++)
00096     {
00097       yanera->models_complete[i].slabs.zpos[j] = 0.0;
00098       yanera->models_complete[i].slabs.thik[j] = 0.0;
00099       yanera->models_complete[i].slabs.rsld[j] = 0.0;
00100       yanera->models_complete[i].slabs.isld[j] = 0.0;
00101     }
00102     
00103     yanera->data[i].data_id   = NULL;
00104     yanera->data[i].file_name = NULL;
00105     yanera->data[i].n         = 0;
00106     yanera->data[i].q         = NULL;
00107     yanera->data[i].R         = NULL;
00108     yanera->data[i].e         = NULL;
00109     yanera->data[i].idx = 0;
00110     yanera->data[i].resolution.type      = RESOLUTION_NONE;
00111     yanera->data[i].resolution.value     = NULL;
00112     yanera->data[i].resolution.q         = NULL;
00113     yanera->data[i].resolution.n         = 0;
00114     yanera->data[i].resolution.file_name = NULL;
00115   }
00116   yanera->number_of_models = 0;
00117   yanera->number_of_data   = 0;
00118   yanera->idx              = 0;
00119 
00120   /*---------------------------------
00121    *  zero the paramter struct
00122    */
00123   yanera->parameters.p   = NULL;
00124   yanera->parameters.f   = NULL;
00125   yanera->parameters.min = NULL;
00126   yanera->parameters.max = NULL;
00127   yanera->parameters.con = NULL;
00128   yanera->parameters.n   = 0;
00129   yanera->parameters.tmp = NULL;
00130   yanera->parameters.idx = 0;
00131   
00132   /*---------------------------------
00133    *  zero the components struct
00134    */
00135   yanera->components  = NULL;
00136   
00137   /*---------------------------------
00138    *  Default misc options/values
00139    */
00140   yanera->misc.write_results           = NO;
00141   yanera->misc.write_profile           = YES;
00142   yanera->misc.write_reflectivity      = YES;
00143   yanera->misc.write_slabs             = NO;
00144   yanera->misc.q_min                   = 1.0E-05;
00145   yanera->misc.q_max                   = 0.2;
00146   yanera->misc.q_num                   = 201;
00147   yanera->misc.z_num                   = 201;
00148   yanera->misc.quadrature_error        = 0.5E-02;
00149   yanera->misc.quadrature_thik         = 100.0;
00150   yanera->misc.fit_do                  = NO;
00151   yanera->misc.fit_weighting           = WEIGHT_NONE;
00152   yanera->misc.fit_iterations          = 25;
00153   yanera->misc.fit_write_iterations    = 10;
00154   yanera->misc.fit_method              = LMSDR;
00155   yanera->misc.fit_method_mdmin        = \
00156                                   gsl_multimin_fdfminimizer_conjugate_fr; 
00157   yanera->misc.fit_method_mdmin_simplex = \
00158                                   gsl_multimin_fminimizer_nmsimplex; 
00159   yanera->misc.fit_method_lstsq        = gsl_multifit_fdfsolver_lmsder;
00160 #ifdef HAVE_OOL
00161   yanera->misc.fit_method_ool          = ool_conmin_minimizer_spg;
00162 #endif
00163   return yanera;
00164 }
00165 /*=========================================================================*/
00166 void yanera_free(yanera_container *yanera)
00167 {
00168   struct _postfix_queue_element *postfix1, *postfix2;
00169   short         i;
00170   yanera_layer *layer_pointer_1, *layer_pointer_2;
00171 
00172   
00173   free(yanera->filename);
00174   
00175   free(yanera->parameters.p);
00176   free(yanera->parameters.f);
00177   free(yanera->parameters.tmp);
00178   free(yanera->parameters.min);
00179   free(yanera->parameters.max);
00180   free(yanera->parameters.con);
00181   
00182   for (i=0; i<10; i++)
00183   {
00184     /* free layers */
00185     layer_pointer_1 = yanera->models_xml[i].first_layer;
00186     while (layer_pointer_1 != NULL)
00187     {
00188       free(layer_pointer_1->layer_id);
00189       free(layer_pointer_1->layer_idref);
00190       free(layer_pointer_1->component_id);
00191       free(layer_pointer_1->component_idref);
00192       free(layer_pointer_1->name);
00193       free(layer_pointer_1->func);
00194       free(layer_pointer_1->parm_names);
00195       free(layer_pointer_1->parm_values);
00196         
00197       layer_pointer_2 = layer_pointer_1;
00198       layer_pointer_1 = layer_pointer_1->next;
00199       free(layer_pointer_2);
00200     };
00201     
00202     free(yanera->models_xml[i].data_idref);
00203     free(yanera->models_xml[i].name);
00204   };
00205 
00206   for (i=0; i<10; i++)
00207   {
00208     /* free layers */
00209     layer_pointer_1 = yanera->models_complete[i].first_layer;
00210     while (layer_pointer_1 != NULL)
00211     {
00212       free(layer_pointer_1->layer_id);
00213       free(layer_pointer_1->layer_idref);
00214       free(layer_pointer_1->component_id);
00215       free(layer_pointer_1->component_idref);
00216       free(layer_pointer_1->name);
00217       free(layer_pointer_1->func);
00218       if (layer_pointer_1->type == LAYER_FUNCTION)
00219       {
00220         postfix1 = layer_pointer_1->func_postfix->front;
00221         while (postfix1 != NULL)
00222         { 
00223           postfix2 = postfix1;
00224           postfix1 = postfix1->next;
00225           free(postfix2);
00226         }
00227       }
00228       free(layer_pointer_1->func_postfix);
00229       free(layer_pointer_1->parm_names);
00230       free(layer_pointer_1->parm_values);
00231       layer_pointer_2 = layer_pointer_1;
00232       layer_pointer_1 = layer_pointer_1->next;
00233       free(layer_pointer_2);
00234     };
00235     
00236     free(yanera->models_complete[i].data_idref);
00237     free(yanera->models_complete[i].name);
00238   };
00239 
00240 
00241   /* free components */
00242   layer_pointer_1 = yanera->components;
00243   while (layer_pointer_1 != NULL)
00244   {
00245       free(layer_pointer_1->layer_id);
00246       free(layer_pointer_1->layer_idref);
00247       free(layer_pointer_1->component_id);
00248       free(layer_pointer_1->component_idref);
00249       free(layer_pointer_1->name);
00250       free(layer_pointer_1->func);
00251       free(layer_pointer_1->parm_names);
00252       free(layer_pointer_1->parm_values);
00253     
00254     layer_pointer_2 = layer_pointer_1;
00255     layer_pointer_1 = layer_pointer_1->next;
00256     free(layer_pointer_2);
00257   };
00258 
00259   /* free datafiles */
00260   for (i=0; i<10; i++)
00261   {
00262     free(yanera->data[i].file_name);
00263     free(yanera->data[i].data_id);
00264     free(yanera->data[i].resolution.value);
00265     free(yanera->data[i].resolution.q);
00266     free(yanera->data[i].resolution.file_name);
00267     free(yanera->data[i].q);
00268     free(yanera->data[i].R);
00269     free(yanera->data[i].e);
00270   };
00271  
00272   free(yanera);
00273   yanera = NULL;
00274 }
00275 /*============================================================================*/
00276 void yanera_error(const char       *reason, \
00277                   const char       *file,   \
00278                   int               line,   \
00279                   yanera_container *yanera)
00280 {
00281   fprintf(stdout, "               :\n");
00282   fprintf(stdout, "YANERA ERROR   : %s\n", reason);
00283   fprintf(stdout, "   In file     : %s\n", file);
00284   fprintf(stdout, "   At line     : %d\n", line);
00285   fprintf(stdout, "\n");
00286   
00287   if (yanera != NULL) yanera_free(yanera);
00288   
00289   exit(EXIT_FAILURE);
00290 }
00291 /*============================================================================*/
00292 void yanera_report(yanera_container *yanera, \
00293                   int iteration, \
00294                   void *solver)
00295 {
00296   int j, i;
00297   gsl_multifit_fdfsolver    *mfs;
00298   gsl_multimin_fdfminimizer *mms;
00299   gsl_multimin_fminimizer   *mms2; 
00300 #ifdef HAVE_OOL
00301   ool_conmin_minimizer      *oos;
00302 #endif
00303 
00304   /*===========*/
00305   if (iteration >= 0)
00306   {
00307     fprintf(stderr,"   Iteration   :%3u \n", iteration);
00308     /*===========*/
00309     if ((yanera->misc.fit_method == LMSDR) || \
00310         (yanera->misc.fit_method == LMDR)  || \
00311         (yanera->misc.fit_method == CLMDR) || \
00312         (yanera->misc.fit_method == CLMSDR))
00313     {
00314       if (solver != NULL)
00315       { 
00316         mfs = (gsl_multifit_fdfsolver *)solver;
00317         for (j=0; j<yanera->parameters.n; j++)
00318         { yanera->parameters.p[j] = gsl_vector_get(mfs->x, j); }
00319         fprintf(stderr,"   Chi-squared : %12.6e\n", mdmin_chisq(yanera));
00320       }
00321     }
00322     if ((yanera->misc.fit_method == CONJUGATE_FR) || \
00323         (yanera->misc.fit_method == CONJUGATE_PR) || \
00324         (yanera->misc.fit_method == VECTOR_BFGS)  || \
00325         (yanera->misc.fit_method == STEEP_DESC)   || \
00326         (yanera->misc.fit_method == NMSIMPLEX))
00327     { fprintf(stderr,"   Chi-squared : %12.6e\n", mdmin_chisq(yanera)); }
00328 #ifdef HAVE_OOL
00329     if ((yanera->misc.fit_method == OOL_SPG)      || \
00330         (yanera->misc.fit_method == OOL_GENCAN))
00331     { fprintf(stderr,"   Chi-squared : %12.6e\n", mdmin_chisq(yanera)); }
00332 #endif
00333 #ifdef HAVE_LEVMAR       
00334     if (yanera->misc.fit_method == LEVMAR)
00335     { fprintf(stderr,"   Chi-squared : %12.6e\n", mdmin_chisq(yanera)); }
00336 #endif        
00337   }
00338 
00339   /*===========*/
00340   if (iteration == -1)
00341   {
00342     fprintf(stderr,"YANERA FINISHED: \n");
00343     /*===========*/
00344     if (solver != NULL)
00345     {
00346       if ((yanera->misc.fit_method == LMSDR) || \
00347           (yanera->misc.fit_method == LMDR)  || \
00348           (yanera->misc.fit_method == CLMDR) || \
00349           (yanera->misc.fit_method == CLMSDR))
00350       { 
00351         mfs = (gsl_multifit_fdfsolver *)solver;
00352         /*
00353         fprintf(stderr,"CHISQ     : %12.6e\n", gsl_blas_dnrm2(mfs->f));
00354         */
00355         for (j=0; j<yanera->parameters.n; j++)
00356         { yanera->parameters.p[j] = gsl_vector_get(mfs->x, j); }
00357         fprintf(stderr,"   Chi-squared : %12.6e\n", mdmin_chisq(yanera));
00358       }
00359       if ((yanera->misc.fit_method == CONJUGATE_FR) || \
00360           (yanera->misc.fit_method == CONJUGATE_PR) || \
00361           (yanera->misc.fit_method == VECTOR_BFGS)  || \
00362           (yanera->misc.fit_method == STEEP_DESC))
00363       { 
00364         mms = (gsl_multimin_fdfminimizer *)solver;
00365         for (j=0; j<yanera->parameters.n; j++)
00366         { yanera->parameters.p[j] = gsl_vector_get(mms->x, j); }
00367         fprintf(stderr,"   Chi-squared : %12.6e\n", mdmin_chisq(yanera));
00368       }  
00369       if (yanera->misc.fit_method == NMSIMPLEX)
00370       { 
00371         mms2 = (gsl_multimin_fminimizer *)solver;
00372         for (j=0, i=0; j<yanera->parameters.n; j++)
00373         { 
00374           if (yanera->parameters.f[j] == NO)
00375           {
00376             yanera->parameters.p[j] = gsl_vector_get(mms2->x, i);
00377             i++;
00378           }
00379         }
00380         fprintf(stderr,"   Chi-squared : %12.6e\n", mdmin_chisq(yanera));
00381       }
00382 #ifdef HAVE_OOL
00383       if ((yanera->misc.fit_method == OOL_SPG) || \
00384           (yanera->misc.fit_method == OOL_GENCAN))
00385       { 
00386         oos = (ool_conmin_minimizer *)solver;
00387         for (j=0; j<yanera->parameters.n; j++)
00388         { yanera->parameters.p[j] = gsl_vector_get(oos->x, j); }
00389         fprintf(stderr,"   Chi-squared : %12.6e\n", mdmin_chisq(yanera));
00390       } 
00391 #endif
00392     }
00393     if (yanera->misc.fit_method == SIMAN)
00394     {
00395       fprintf(stderr,"   Chi-squared : %12.6e\n", mdmin_chisq(yanera));
00396     }
00397 #ifdef HAVE_LEVMAR
00398     if (yanera->misc.fit_method == LEVMAR)
00399     {
00400       fprintf(stderr,"   Chi-squared : %12.6e\n", mdmin_chisq(yanera));
00401     }
00402 #endif
00403   }
00404   if (((fmod(iteration,yanera->misc.fit_write_iterations) == 0) && \
00405       (iteration > 0)) || \
00406       (iteration == -1))
00407   {
00408     fprintf(stderr,"   Writing out :");
00409     /*===========*/
00410     /*---------------------------------
00411      * Write the profiles to file.
00412      */
00413     if (yanera->misc.write_profile == YES)
00414     {
00415       fprintf(stderr,"...profile");
00416       yanera_write_profile(yanera); 
00417     }
00418     /*---------------------------------
00419      * Do slab profiles to file.
00420      */
00421     if (yanera->misc.write_slabs == YES)
00422     {
00423       if (yanera->type != MODEL_LAYER)
00424       {
00425         yanera_write_slabs(yanera); 
00426         fprintf(stderr,"...slabs");
00427       }
00428     }
00429    /*---------------------------------
00430     * Write reflectivity to file
00431     */
00432     if (yanera->misc.write_reflectivity == YES)
00433     {
00434       yanera_write_reflectivity(yanera);
00435       fprintf(stderr,"...reflectivity");
00436     }
00437     /*---------------------------------
00438     * Write an XML file of the results
00439     */
00440     if (yanera->misc.write_results == YES)  
00441     {
00442       if (yanera->misc.fit_do == YES) yanera_find_errors(yanera);
00443       yanera_write_xml(yanera);
00444       fprintf(stderr,"...results\n");
00445     }
00446   }
00447   
00448   return;
00449 }
00450 /*============================================================================*/
00451 int yanera_find_errors(yanera_container *yanera)
00452 {
00453   int          i, count;
00454   gsl_matrix  *covar;
00455   gsl_matrix  *jacob;
00456   gsl_vector  *guess;
00457   
00458   for (i=0, count=0; i<yanera->number_of_models; i++) 
00459   {
00460     count += yanera->data[i].n;
00461   }
00462   jacob = gsl_matrix_alloc(count,yanera->parameters.n);
00463   
00464   covar = gsl_matrix_alloc(yanera->parameters.n, yanera->parameters.n);
00465   
00466   guess = gsl_vector_alloc(yanera->parameters.n);
00467   for (i=0; i<yanera->parameters.n; i++) 
00468   {
00469     gsl_vector_set(guess, i, yanera->parameters.p[i]);
00470   }
00471     
00472   lstsq_df(guess, (void *)yanera, jacob);
00473   gsl_multifit_covar(jacob, 0.0, covar);
00474   
00475   for (i=0; i<yanera->parameters.n; i++)
00476   {
00477     yanera->parameters.tmp[i] = gsl_matrix_get(covar,i,i);
00478   }
00479   
00480   gsl_matrix_free(covar);
00481   gsl_matrix_free(jacob);
00482   gsl_vector_free(guess);
00483   
00484   return GSL_SUCCESS;
00485 }

Generated on Thu May 29 10:56:33 2008 by  doxygen 1.5.5