crown  1.0.0
src/crown-composite-annealing.cpp
Go to the documentation of this file.
00001 /*
00002  Copyright 2015 Nicolas Melot
00003 
00004  This file is part of Crown.
00005 
00006  Crown is free software: you can redistribute it and/or modify
00007  it under the terms of the GNU General Public License as published by
00008  the Free Software Foundation, either version 3 of the License, or
00009  (at your option) any later version.
00010 
00011  Crown is distributed in the hope that it will be useful,
00012  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00014  GNU General Public License for more details.
00015 
00016  You should have received a copy of the GNU General Public License
00017  along with Crown. If not, see <http://www.gnu.org/licenses/>.
00018 
00019 */
00020 
00021 
00022 #include <fstream>
00023 
00024 #include <pelib/argument_parsing.hpp>
00025 #include <pelib/dl.h>
00026 #include <pelib/Scalar.hpp>
00027 
00028 #include <crown/CrownModular.hpp>
00029 #include <crown/CrownCompositeAnnealing.hpp>
00030 
00031 #ifdef debug
00032 #undef debug
00033 #endif
00034 
00035 #define debug(var) cout << "[" << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "] " << #var << " = \"" << (var) << "\"" << endl;
00036 
00037 using namespace std;
00038 using namespace pelib;
00039 using namespace crown;
00040 
00041 #ifdef __cplusplus
00042 extern "C" {
00043 #endif
00044 
00045 struct args
00046 {
00047         double alpha, eta, zeta, kappa;
00048         pelib_argument_stream mapping, scaling;
00049         vector<pelib_argument_stream> composite;
00050         bool showError, showOutput;
00051         float init_temp, cooling, temp_final, max_trans, max_new, distance;
00052 };
00053 typedef struct args args_t;
00054 
00055 static args_t
00056 parse(char **args)
00057 {
00058         args_t out;
00059         out.showError = false;
00060         out.showOutput = false;
00061         out.alpha = 3;
00062         out.zeta = 0.649;
00063         out.eta = 0.018611;
00064         out.kappa = 52.639161335;
00065 
00066         out.init_temp = 8;
00067         out.cooling = 0.6;
00068         out.temp_final = 0.9;
00069         out.max_trans = 2;
00070         out.max_new = 2;
00071         out.distance = 0.5;
00072 
00073         pelib_argument_stream_init(&out.mapping);
00074         pelib_argument_stream_init(&out.scaling);
00075 
00076         for(; args[0] != NULL; args++)
00077         {
00078                 if(strcmp(args[0], "--show-stdout") == 0)
00079                 {
00080                         out.showOutput = true;
00081                         continue;
00082                 }
00083                 if(strcmp(args[0], "--show-stderr") == 0)
00084                 {
00085                         out.showError = true;
00086                         continue;
00087                 }
00088                 if(strcmp(args[0], "--alpha") == 0)
00089                 {
00090                         args++;
00091                         stringstream str(args[0]);
00092                         str >> out.alpha;
00093                         continue;
00094                 }
00095                 if(strcmp(args[0], "--eta") == 0)
00096                 {
00097                         args++;
00098                         stringstream str(args[0]);
00099                         str >> out.eta;
00100                         continue;
00101                 }
00102                 if(strcmp(args[0], "--zeta") == 0)
00103                 {
00104                         args++;
00105                         stringstream str(args[0]);
00106                         str >> out.zeta;
00107                         continue;
00108                 }
00109                 if(strcmp(args[0], "--kappa") == 0)
00110                 {
00111                         args++;
00112                         stringstream str(args[0]);
00113                         str >> out.kappa;
00114                         continue;
00115                 }
00116                 if(strcmp(args[0], "--init-temperature") == 0)
00117                 {
00118                         args++;
00119                         stringstream str(args[0]);
00120                         str >> out.init_temp;
00121                         continue;
00122                 }
00123                 if(strcmp(args[0], "--cooling-factor") == 0)
00124                 {
00125                         args++;
00126                         stringstream str(args[0]);
00127                         str >> out.cooling;
00128                         continue;
00129                 }
00130                 if(strcmp(args[0], "--final-temperature") == 0)
00131                 {
00132                         args++;
00133                         stringstream str(args[0]);
00134                         str >> out.temp_final;
00135                         continue;
00136                 }
00137                 if(strcmp(args[0], "--max-transformations") == 0)
00138                 {
00139                         args++;
00140                         stringstream str(args[0]);
00141                         str >> out.max_trans;
00142                         continue;
00143                 }
00144                 if(strcmp(args[0], "--max-new-state") == 0)
00145                 {
00146                         args++;
00147                         stringstream str(args[0]);
00148                         str >> out.max_new;
00149                         continue;
00150                 }
00151                 if(strcmp(args[0], "--distance") == 0)
00152                 {
00153                         args++;
00154                         stringstream str(args[0]);
00155                         str >> out.distance;
00156                         continue;
00157                 }
00158                 if(strcmp(args[0], "--mapping") == 0)
00159                 {
00160                         args++;
00161                         args += pelib_argument_stream_parse(args, &out.mapping) - 1;
00162                         continue;
00163                 }
00164                 if(strcmp(args[0], "--scaling") == 0)
00165                 {
00166                         args++;
00167                         args += pelib_argument_stream_parse(args, &out.scaling) - 1;
00168                         continue;
00169                 }
00170                 if(strcmp(args[0], "--composite") == 0)
00171                 {
00172                         args++;
00173                         pelib_argument_stream compo;
00174                         pelib_argument_stream_init(&compo);
00175                         args += pelib_argument_stream_parse(args, &compo) - 1;
00176                         out.composite.push_back(compo);
00177                         continue;
00178                 }
00179         }
00180 
00181         return out;
00182 }
00183 
00184 const CrownScheduler*
00185 crown_scheduler(size_t argc, char **argv, const CrownScheduler *composite)
00186 {
00187         args_t args = parse(argv);
00188         Algebra param;
00189         param.insert(new Scalar<float>("alpha", args.alpha));
00190         param.insert(new Scalar<float>("eta", args.eta));
00191         param.insert(new Scalar<float>("zeta", args.zeta));
00192         param.insert(new Scalar<float>("kappa", args.kappa));
00193 
00194         void *libMapping = load_lib(args.mapping.library);
00195         void *libScaling = load_lib(args.scaling.library);
00196         CrownMapping* (*map)(size_t argc, char **argv);
00197         CrownScaling* (*scal)(size_t argc, char **argv);
00198         CrownMapping* mapping = NULL;
00199         CrownScaling* scaling = NULL;
00200 
00201         // Load crown mapping
00202         if(args.mapping.library != NULL)
00203         {
00204                 void *libConfig = load_lib(args.mapping.library);
00205                 map = (CrownMapping* (*)(size_t argc, char **argv))load_function(libConfig, "crown_mapping");
00206                 mapping = map(args.mapping.argc, args.mapping.argv);
00207         }
00208 
00209         // Load crown scaling
00210         if(args.scaling.library != NULL)
00211         {
00212                 void *libConfig = load_lib(args.scaling.library);
00213                 scal = (CrownScaling* (*)(size_t argc, char **argv))load_function(libConfig, "crown_scaling");
00214                 scaling = scal(args.scaling.argc, args.scaling.argv);
00215         }
00216 
00217         const CrownScheduler *scheduler = composite;
00218         for(vector<pelib_argument_stream>::iterator i = args.composite.begin(); i != args.composite.end(); i++)
00219         {
00220                 pelib_argument_stream compo = *i;
00221                 void *libCompo = load_lib(compo.library);
00222                 const CrownScheduler* (*sched)(size_t argc, char **argv, const CrownScheduler*) = (const CrownScheduler* (*)(size_t argc, char **argv, const CrownScheduler*))load_function(libCompo, "crown_scheduler");
00223                 const CrownScheduler *new_scheduler = sched(compo.argc, compo.argv, scheduler);
00224                 if(scheduler != NULL)
00225                 {
00226                         delete scheduler;
00227                 }
00228                 scheduler = new_scheduler->clone();
00229                 void (*del)(const CrownScheduler*) = (void (*)(const CrownScheduler*))load_function(libCompo, "crown_delete_scheduler");
00230                 del(new_scheduler);
00231                 destroy_lib(libCompo);
00232         }
00233 
00234         // Final scheduler
00235         CrownScheduler *final = new CrownCompositeAnnealing(param, args.init_temp, args.cooling, args.temp_final, args.max_trans, args.max_new, args.distance, scheduler, mapping, scaling, args.showOutput, args.showError);
00236         
00237         // Destroy object instances by libraries
00238         if(args.mapping.library != NULL)
00239         {
00240                 void (*del)(CrownMapping *) = (void (*)(CrownMapping*))load_function(libMapping, "crown_delete_algebra");
00241                 del(mapping);
00242                 destroy_lib(libMapping);
00243         }
00244 
00245         // Destroy object instances by libraries
00246         if(args.scaling.library != NULL)
00247         {
00248                 void (*del)(CrownScaling *) = (void (*)(CrownScaling*))load_function(libScaling, "crown_delete_algebra");
00249                 del(scaling);
00250                 destroy_lib(libScaling);
00251         }
00252 
00253         return final;
00254 }
00255 
00256 #ifdef __cplusplus
00257 }
00258 #endif
00259