00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00018 #include "yanera.h"
00019 #include "yanera_siman.h"
00020 #include "yanera_mdmin.h"
00021 #include "yanera_util.h"
00022 #include "yanera_xml_util.h"
00023
00024 int yanera_siman_main(yanera_container *yanera)
00025 {
00026 double start_temp, final_temp;
00027 const gsl_rng *rng;
00028 gsl_siman_params_t params;
00029
00030 rng = gsl_rng_alloc(gsl_rng_rand);
00031 gsl_rng_set(rng, time(NULL));
00032
00033
00034 start_temp = 4.0*mdmin_chisq(yanera);
00035 final_temp = start_temp / 1e6;
00036
00037 params.n_tries = 200;
00038 params.iters_fixed_T = yanera->misc.fit_write_iterations;
00039 params.step_size = 0.1;
00040 params.k = 1.0;
00041 params.t_initial = start_temp;
00042 params.mu_t = exp(log(1.0E6)/yanera->misc.fit_iterations);
00043 params.t_min = final_temp;
00044
00045 gsl_siman_solve(rng, (void *)yanera, \
00046 siman_energy, \
00047 siman_step, \
00048 siman_metric, \
00049 siman_print, \
00050 siman_copy, siman_copy_construct, siman_destroy,
00051 0, params);
00052
00053 yanera_report(yanera,-1,NULL);
00054 return GSL_SUCCESS;
00055 }
00056
00057 double siman_energy(void *yanera_pointer)
00058 {
00059 double tmp;
00060 tmp = mdmin_chisq((yanera_container *)yanera_pointer);
00061
00062 return tmp;
00063 }
00064
00065 void siman_step(const gsl_rng *rng, void *yanera_pointer, double step_size)
00066 {
00067 int i;
00068 double s;
00069 yanera_container *yanera;
00070
00071 yanera = (yanera_container *)yanera_pointer;
00072
00073 for (i=0; i<yanera->parameters.n; i++)
00074 {
00075 if (yanera->parameters.f[i] == NO)
00076 {
00077 s = gsl_rng_uniform(rng);
00078 yanera->parameters.p[i] += step_size * (2.0*s-1.0);
00079
00080
00081 if ((yanera->parameters.con[i] == CONSTRAIN_MAX) || \
00082 (yanera->parameters.con[i] == CONSTRAIN_BOTH))
00083 {
00084 if (yanera->parameters.p[i] > yanera->parameters.max[i])
00085 { yanera->parameters.p[i] = yanera->parameters.max[i]; }
00086 }
00087 if ((yanera->parameters.con[i] == CONSTRAIN_MIN) || \
00088 (yanera->parameters.con[i] == CONSTRAIN_BOTH))
00089 {
00090 if (yanera->parameters.p[i] < yanera->parameters.min[i])
00091 { yanera->parameters.p[i] = yanera->parameters.min[i]; }
00092 }
00093
00094 }
00095 }
00096 return;
00097 }
00098
00099 double siman_metric(void *yanera_pointer1, void *yanera_pointer2)
00100 {
00101 yanera_container *yanera1;
00102 yanera_container *yanera2;
00103 double sum;
00104 int i;
00105
00106 yanera1 = (yanera_container *)yanera_pointer1;
00107 yanera2 = (yanera_container *)yanera_pointer2;
00108 sum = 0.0;
00109 for (i=0; i<yanera1->parameters.n; i++)
00110 {
00111 sum += fabs(yanera1->parameters.p[i] - yanera2->parameters.p[i]);
00112 }
00113 return sum;
00114 }
00115
00116 void siman_print(void *yanera_pointer)
00117 {
00118 int i;
00119 yanera_container *yanera;
00120
00121 yanera = (yanera_container *)yanera_pointer;
00122
00123 for (i=0; i<yanera->parameters.n; i++)
00124 {
00125 if (yanera->parameters.f[i] == NO)
00126 {
00127 printf("%8.4g", yanera->parameters.p[i]);
00128 }
00129 }
00130 return;
00131 }
00132
00133 void siman_copy(void *source_yanera_pointer, void *dest_yanera_pointer)
00134 {
00135 int i;
00136 yanera_container *new_yanera, *yanera;
00137 new_yanera = (yanera_container *)dest_yanera_pointer;
00138 yanera = (yanera_container *)source_yanera_pointer;
00139
00140
00141
00142 for (i=0; i<yanera->parameters.n; i++)
00143 {
00144 new_yanera->parameters.p[i] = yanera->parameters.p[i];
00145 }
00146
00147
00148 return;
00149 }
00150
00151 void *siman_copy_construct(void *yanera_pointer)
00152 {
00153 int i, j;
00154 yanera_container *new_yanera, *yanera;
00155 yanera_layer *new_layer, *layer;
00156
00157
00158
00159 new_yanera = yanera_initialize(NULL);
00160 yanera = (yanera_container *)yanera_pointer;
00161
00162
00163
00164 new_yanera->type = yanera->type;
00165 new_yanera->parrattFunction = yanera->parrattFunction;
00166 new_yanera->profileFunctionReal = yanera->profileFunctionReal;
00167 new_yanera->profileFunctionImag = yanera->profileFunctionImag;
00168
00169
00170
00171 new_yanera->number_of_models = yanera->number_of_models;
00172 for (i=0; i<yanera->number_of_models; i++)
00173 {
00174 new_yanera->data[i].q = malloc(yanera->data[i].n * sizeof(double));
00175 new_yanera->data[i].R = malloc(yanera->data[i].n * sizeof(double));
00176 new_yanera->data[i].e = malloc(yanera->data[i].n * sizeof(double));
00177 new_yanera->data[i].resolution.value = \
00178 malloc(yanera->data[i].resolution.n * sizeof(double));
00179 new_yanera->data[i].resolution.q = \
00180 malloc(yanera->data[i].resolution.n * sizeof(double));
00181
00182 layer = yanera->models_complete[i].first_layer;
00183 while (layer != NULL)
00184 {
00185 new_layer = copyLayer(layer);
00186 linkLayerIntoModel(new_layer, &new_yanera->models_complete[i]);
00187 layer = layer->next;
00188 }
00189
00190 new_yanera->models_complete[i].background = \
00191 yanera->models_complete[i].background;
00192 new_yanera->models_complete[i].polarized = \
00193 yanera->models_complete[i].polarized;
00194
00195 new_yanera->data[i].n = yanera->data[i].n;
00196 for (j=0; j<yanera->data[i].n; j++)
00197 {
00198 new_yanera->data[i].q[j] = yanera->data[i].q[j];
00199 new_yanera->data[i].R[j] = yanera->data[i].R[j];
00200 new_yanera->data[i].e[j] = yanera->data[i].e[j];
00201 }
00202 new_yanera->data[i].resolution.type = yanera->data[i].resolution.type;
00203 new_yanera->data[i].resolution.n = yanera->data[i].resolution.n;
00204 for (j=0; j<yanera->data[i].resolution.n; j++)
00205 {
00206 new_yanera->data[i].resolution.value[j] = \
00207 yanera->data[i].resolution.value[j];
00208 new_yanera->data[i].resolution.q[j] = \
00209 yanera->data[i].resolution.q[j];
00210 }
00211 }
00212
00213
00214
00215 new_yanera->parameters.p = malloc(yanera->parameters.n * sizeof(double));
00216 new_yanera->parameters.f = malloc(yanera->parameters.n * \
00217 sizeof(unsigned short));
00218 new_yanera->parameters.con = malloc(yanera->parameters.n * \
00219 sizeof(unsigned short));
00220 new_yanera->parameters.min = malloc(yanera->parameters.n * sizeof(double));
00221 new_yanera->parameters.max = malloc(yanera->parameters.n * sizeof(double));
00222 new_yanera->parameters.n = yanera->parameters.n;
00223 for (i=0; i<yanera->parameters.n; i++)
00224 {
00225 new_yanera->parameters.p[i] = yanera->parameters.p[i];
00226 new_yanera->parameters.f[i] = yanera->parameters.f[i];
00227 new_yanera->parameters.min[i] = yanera->parameters.min[i];
00228 new_yanera->parameters.max[i] = yanera->parameters.max[i];
00229 new_yanera->parameters.con[i] = yanera->parameters.con[i];
00230 }
00231
00232
00233
00234 new_yanera->misc.quadrature_error = yanera->misc.quadrature_error;
00235 new_yanera->misc.quadrature_thik = yanera->misc.quadrature_thik;
00236 new_yanera->misc.fit_weighting = yanera->misc.fit_weighting;
00237 new_yanera->misc.fit_iterations = yanera->misc.fit_iterations;
00238 new_yanera->misc.fit_iterations = yanera->misc.fit_write_iterations;
00239
00240
00241 siman_copy(yanera_pointer, (void *)new_yanera);
00242 return (void *)new_yanera;
00243 }
00244
00245 void siman_destroy(void *yanera_pointer)
00246 {
00247 yanera_free((yanera_container *)yanera_pointer);
00248 return;
00249 }