00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "ne_sup_sa.h"
00024 #include "ne_evo.h"
00025 #include <time.h>
00026 #include <gsl/gsl_rng.h>
00027 #include <math.h>
00028
00029
00030 extern gsl_rng* neRng;
00031
00032
00033 ne_sup_sa_params_t * ne_sup_sa_params_alloc (int initialTrials, double tempReduce, int mainTrails,
00034 int acceptTrials, int acceptRunsNoChange, double minTemp,
00035 int maxIterations, double (*initialTempFn) (double),
00036 ne_per_t *QFn, ne_mut_t *mutationFn, ne_sim_fn_t *simFn,
00037 void *simParams, ne_dyn_vec_t *initCond,
00038 ne_sup_sa_analysis_fn_t *analysisFn, FILE *evoFile)
00039 {
00040 ne_sup_sa_params_t *params;
00041
00042 if ((params = (ne_sup_sa_params_t *)malloc(sizeof(ne_sup_sa_params_t))) == NULL) {
00043 ne_error("ne_sup_sa_alloc: Could not allocate memory for parameters.");
00044 return NULL;
00045 }
00046
00047 params->initialTrials = initialTrials;
00048 params->tempReduce = tempReduce;
00049 params->mainTrials = mainTrails;
00050 params->acceptTrials = acceptTrials;
00051 params->acceptRunsNoChange = acceptRunsNoChange;
00052 params->minTemp = minTemp;
00053 params->maxIterations = maxIterations;
00054 params->initialTempFn = initialTempFn;
00055 params->QFn = QFn;
00056 params->mutationFn = mutationFn;
00057 params->simFn = simFn;
00058 params->simParams = simParams;
00059 params->initCond = initCond;
00060 params->analysisFn = analysisFn;
00061 params->evoFile = evoFile;
00062
00063 return params;
00064 }
00065
00066
00067 void ne_sup_sa_params_free (ne_sup_sa_params_t *params)
00068 {
00069 free(params);
00070 }
00071
00072
00073 ne_sys_t * ne_sup_sa_run (ne_sys_t *sys, ne_sup_sa_params_t *params)
00074 {
00075 int i, accepts, noChange, iteration;
00076 double T, dQmax;
00077 ne_sup_sa_trail_results_t *results = NULL;
00078 double QChosen;
00079
00080
00081 iteration = 1;
00082
00083
00084 results = (ne_sup_sa_trail_results_t *)malloc(sizeof(ne_sup_sa_trail_results_t));
00085 results->curDyn = NULL;
00086 results->Q1 = -1;
00087
00088
00089 T = 10000000000000.0;
00090 dQmax = 0.0;
00091
00092 if (params->analysisFn != NULL) {
00093 (params->analysisFn)(sys, NULL, iteration, T, -1, TRUE);
00094 }
00095
00096 if (params->evoFile != NULL) {
00097 ne_evo_initial(sys, params->evoFile);
00098 }
00099
00100
00101
00102
00103 for ( i=0; i<params->initialTrials; i++ ) {
00104
00105
00106 sys = ne_sup_sa_trail(sys, T, results, params);
00107
00108
00109 if ( results->a == 1 ) {
00110 if (params->analysisFn != NULL) {
00111 (params->analysisFn)(sys, results->curDyn, iteration, T, results->Q2, FALSE);
00112 }
00113 }
00114 else {
00115 if (params->analysisFn != NULL) {
00116 (params->analysisFn)(sys, results->curDyn, iteration, T, results->Q1, FALSE);
00117 }
00118 }
00119
00120
00121 dQmax = fmax(results->dQ, dQmax);
00122
00123
00124 if ((results->a == 1 && results->Q2 == 0.0) ||
00125 (results->a == 0 && results->Q1 == 0.0)) {
00126 return sys;
00127 }
00128
00129 iteration++;
00130 }
00131
00132
00133 if (dQmax != 0.0) {
00134 T = (params->initialTempFn)(dQmax);
00135 }
00136 else {
00137
00138 T = results->Q1 * 0.2;
00139 }
00140
00141
00142
00143
00144 noChange = 0;
00145
00146
00147 if ( T != 0.0 ) {
00148
00149
00150 do {
00151
00152
00153 accepts = 0;
00154 for ( i=0; i<params->mainTrials; i++ ) {
00155
00156
00157 if (iteration > params->maxIterations) {
00158 break;
00159 }
00160
00161
00162 sys = ne_sup_sa_trail(sys, T, results, params);
00163
00164
00165 if ( results->a == 1 ){
00166 if (params->analysisFn != NULL) {
00167 (params->analysisFn)(sys, results->curDyn, iteration, T, results->Q2, FALSE);
00168 }
00169 QChosen = results->Q2;
00170 }
00171 else{
00172 QChosen = results->Q1;
00173 if (params->analysisFn != NULL) {
00174 (params->analysisFn)(sys, results->curDyn, iteration, T, results->Q1, FALSE);
00175 }
00176 }
00177
00178 iteration++;
00179
00180
00181 if ( (int)results->a == 1 ){
00182 accepts++;
00183 if ( results->Q2 == 0.0 )
00184 break;
00185 }
00186 else{
00187 if ( results->Q1 == 0.0 )
00188 break;
00189 }
00190 if ( accepts >= params->acceptTrials )
00191 break;
00192 }
00193
00194
00195 if ( accepts == 0 )
00196 noChange++;
00197 else
00198 noChange = 0;
00199
00200
00201 T = T*params->tempReduce;
00202
00203 } while (noChange <= params->acceptRunsNoChange &&
00204 T > params->minTemp &&
00205 iteration <= params->maxIterations &&
00206 QChosen != 0.0);
00207 }
00208
00209
00210
00211 if ( results->a == 1 ){
00212 if (params->analysisFn != NULL) {
00213 (params->analysisFn)(sys, results->curDyn, iteration, T, results->Q2, TRUE);
00214 }
00215 }
00216 else{
00217 if (params->analysisFn != NULL) {
00218 (params->analysisFn)(sys, results->curDyn, iteration, T, results->Q1, TRUE);
00219 }
00220 }
00221
00222
00223 ne_dyn_vec_free(results->curDyn);
00224 free(results);
00225
00226
00227 return sys;
00228 }
00229
00230
00231 ne_sys_t * ne_sup_sa_trail (ne_sys_t *sys, double T, ne_sup_sa_trail_results_t *results,
00232 ne_sup_sa_params_t *params)
00233 {
00234 int a;
00235 double dQ;
00236 igraph_bool_t res;
00237 ne_dyn_vec_t *dynOut2 = NULL;
00238 ne_sys_t *S2 = NULL;
00239 char strBuffer[1024];
00240
00241 strBuffer[0] = '\0';
00242
00243
00244 dQ = 0.0;
00245
00246
00247 S2 = ne_sys_clone(sys);
00248
00249
00250 (params->mutationFn->fn)(S2, params->mutationFn->params, strBuffer);
00251
00252
00253 a = 0;
00254
00255
00256
00257 switch (params->QFn->type) {
00258
00259 case NE_PER_TOP:
00260 if ( results->Q1 == -1 ) {
00261 results->Q1 = (params->QFn->fn)(sys, NULL, params->QFn->params);
00262 }
00263 else {
00264 if (results->a == 1) {
00265 results->Q1 = results->Q2;
00266 }
00267 }
00268 break;
00269
00270 case NE_PER_DYN:
00271 case NE_PER_TOP_AND_DYN:
00272 if ( results->Q1 == -1 ) {
00273 results->Q1 = ne_sup_sa_simulate(sys, params);
00274 }
00275 else{
00276 if ( results->a == 1 ) {
00277 results->Q1 = results->Q2;
00278 }
00279 }
00280 break;
00281
00282 default:
00283 results->Q1 = -1;
00284 break;
00285 }
00286
00287
00288 igraph_is_connected(S2->graph, &res, IGRAPH_WEAK);
00289 if (res == TRUE) {
00290
00291
00292 switch (params->QFn->type) {
00293
00294 case NE_PER_TOP:
00295 results->Q2 = (params->QFn->fn)(S2, NULL, params->QFn->params);
00296 dQ = results->Q2 - results->Q1;
00297 break;
00298
00299 case NE_PER_DYN:
00300 case NE_PER_TOP_AND_DYN:
00301 results->Q2 = ne_sup_sa_simulate(S2, params);
00302 dQ = results->Q2 - results->Q1;
00303 break;
00304
00305 default:
00306 dQ = 0;
00307 break;
00308 }
00309
00310 if (dQ < 0.0) {
00311
00312
00313 a = 1;
00314 }
00315 else {
00316
00317
00318 if (T != 0.0 && T > 0.0) {
00319
00320
00321
00322 if (gsl_rng_uniform(neRng) <= exp(-dQ/T)) {
00323
00324 a = 1;
00325 }
00326 }
00327 }
00328 }
00329
00330
00331 results->dQ = dQ;
00332 results->a = a;
00333
00334
00335 if ( a == 1 ) {
00336
00337
00338 ne_dyn_vec_free(results->curDyn);
00339 results->curDyn = dynOut2;
00340
00341
00342 if (params->evoFile != NULL){
00343 fprintf(params->evoFile, "%s%s", strBuffer, ne_evo_step(NE_STEP_EVO));
00344 fflush(params->evoFile);
00345 }
00346
00347
00348 ne_sys_free(sys);
00349 return S2;
00350 }
00351 else{
00352
00353
00354 ne_dyn_vec_free(dynOut2);
00355
00356
00357 ne_sys_free(S2);
00358 return sys;
00359 }
00360 }
00361
00362
00363 double ne_sup_sa_simulate (ne_sys_t *sys, ne_sup_sa_params_t *params) {
00364
00365 int i;
00366 ne_dyn_vec_t **dynOuts;
00367 double *perfVals;
00368 double perfSum = 0;
00369
00370
00371 clock_t ctime_1, ctime_2;
00372 ctime_1 = clock();
00373
00374
00375 perfSum = 0;
00376 dynOuts = (ne_dyn_vec_t **)malloc(sizeof(ne_dyn_vec_t *)*params->initCond->curSize);
00377 perfVals = (double *)malloc(sizeof(double)*params->initCond->curSize);
00378
00379
00380 #pragma omp parallel for
00381 for ( i=0; i<params->initCond->curSize; i++ ) {
00382
00383
00384 dynOuts[i] = (params->simFn)(sys, params->simParams, params->initCond->data[i], NULL);
00385
00386
00387 perfVals[i] += (params->QFn->fn)(sys, dynOuts[i], params->QFn->params);
00388
00389
00390 ne_dyn_vec_free(dynOuts[i]);
00391 }
00392
00393 for (i=0; i<params->initCond->curSize; i++ ) {
00394 perfSum += perfVals[i];
00395 }
00396
00397 free(dynOuts);
00398 free(perfVals);
00399
00400
00401 ctime_2 = clock();
00402 ne_log("BENCHMARK: ne_sup_sa_simulate - CPU time to simulate dynamics: %f seconds\n",
00403 (double)(ctime_2 - ctime_1) / (double)CLOCKS_PER_SEC);
00404
00405
00406
00407 return perfSum / params->initCond->curSize;
00408 }
00409
00410
00411 double ne_sup_sa_int_temp_basic (double qMax)
00412 {
00413 return 4*qMax;
00414 }
00415