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