00001 #include <iostream>
00002 #include <fstream>
00003 #include <algorithm>
00004 #include <numeric>
00005 #include <sstream>
00006 #include <string>
00007 #include "GA.h"
00008 #include "C1dInvGaConf.h"
00009 #include "Adaptors.h"
00010 #include <boost/bind.hpp>
00011 #include <boost/shared_ptr.hpp>
00012 #include <boost/filesystem.hpp>
00013 #include <boost/date_time/posix_time/posix_time.hpp>
00014 #include <complex>
00015 #include "Util.h"
00016 #include "SurfaceWaveObjective.h"
00017 #include "SurfaceWaveData.h"
00018 #include "SurfInvGaConf.h"
00019 #include "SeismicModelDiff.h"
00020 #include "ResPkModel.h"
00021
00022
00023 using namespace std;
00024 using namespace gplib;
00025
00026 enum tgatype
00027 {
00028 pareto, anneal
00029 };
00030 typedef boost::shared_ptr<GeneralObjective> pCGeneralObjective;
00031
00032
00033 void SetupAnnealingGA(boost::shared_ptr<GeneralGA> &GA,
00034 const SurfInvGaConf Configuration)
00035 {
00036 double InitTemperature = Configuration.inittemp;
00037 if (Configuration.inittemp < 0)
00038 {
00039 double avgcombfit = 0;
00040 GA->DoIteration(0, false);
00041
00042
00043 avgcombfit = accumulate(GA->GetAvgFit().begin(), GA->GetAvgFit().end(),
00044 0.0);
00045 InitTemperature = avgcombfit * abs(Configuration.inittemp);
00046 }
00047 AnnealingGA *AnnealGA = dynamic_cast<AnnealingGA*> (GA.get());
00048 AnnealGA->SetParams(InitTemperature, Configuration.annealinggeneration,
00049 Configuration.coolingratio);
00050 }
00051
00052
00053 int main(int argc, char *argv[])
00054 {
00055 boost::posix_time::ptime starttime =
00056 boost::posix_time::microsec_clock::local_time();
00057 string version = "$Id: mtanisoga.cpp 1446 2007-11-09 11:05:47Z mmoorkamp $";
00058 cout << endl << endl;
00059 cout << "Program " << version << endl;
00060 cout << "Genetic algorithm to jointly invert MT data for 1D anisotropy"
00061 << endl;
00062 cout << "look at mtanisoga.conf for configuration and setup " << endl;
00063 cout << "The root name of log-files can be overwritten by using " << endl;
00064 cout << "1dinvga newrootname " << endl;
00065
00066 SurfInvGaConf Configuration;
00067
00068 UniformRNG Random;
00069 try
00070 {
00071 Configuration.GetData("surfinvga.conf");
00072
00073 ttranscribed transcribed;
00074 tgatype GAtype = pareto;
00075
00076 string outputbase;
00077
00078 if (argc > 1)
00079 outputbase = argv[1];
00080 else
00081 outputbase = Configuration.outputbase;
00082
00083 ofstream misfitfile;
00084 ofstream valuefile;
00085 ofstream probfile;
00086 ofstream distancefile;
00087 ofstream fitstat((outputbase + ".ftst").c_str());
00088 ofstream uniquepop((outputbase + ".unpop").c_str());
00089 ofstream rankfile((outputbase + ".rank").c_str());
00090 ofstream frontfile((outputbase + ".front").c_str());
00091 ofstream bestfile((outputbase + ".best").c_str());
00092
00093 if (Configuration.verbose)
00094 {
00095 misfitfile.open((outputbase + ".msft").c_str());
00096 valuefile.open((outputbase + ".vals").c_str());
00097 probfile.open((outputbase + ".probs").c_str());
00098 distancefile.open((outputbase + ".dist").c_str());
00099 }
00100
00101 if (Configuration.thickbase.size() != Configuration.svelbase.size())
00102 {
00103 cerr << "Configuration of genes is not consistent ! ";
00104 return 100;
00105 }
00106 const int nparam = 2;
00107 const int genes = 2 * Configuration.thickbase.size();
00108 const int popsize = Configuration.popsize;
00109 const int maxgen = Configuration.generations;
00110 const int paramlength = genes / nparam;
00111 ttranscribed basevalues(genes);
00112 ttranscribed stepsizes(genes);
00113 tsizev genesizes(genes);
00114
00115 misfitfile << popsize << " " << maxgen << " " << endl;
00116 valuefile << genes << " " << popsize << " " << maxgen << endl;
00117
00118 copy(Configuration.thickbase.begin(), Configuration.thickbase.end(),
00119 basevalues.begin());
00120 copy(Configuration.thickstep.begin(), Configuration.thickstep.end(),
00121 stepsizes.begin());
00122 copy(Configuration.thicksizes.begin(), Configuration.thicksizes.end(),
00123 genesizes.begin());
00124
00125 copy(Configuration.svelbase.begin(), Configuration.svelbase.end(),
00126 basevalues.begin() + paramlength);
00127 copy(Configuration.svelstep.begin(), Configuration.svelstep.end(),
00128 stepsizes.begin() + paramlength);
00129 copy(Configuration.svelsizes.begin(), Configuration.svelsizes.end(),
00130 genesizes.begin() + paramlength);
00131
00132 const int totalgenesize = accumulate(genesizes.begin(),
00133 genesizes.end(), 0);
00134 BinaryPopulation Population(popsize, totalgenesize, Random, true);
00135 BinaryTournamentSelect Select(Random, boost::bind(
00136 &GeneralPopulation::GetProbabilities, boost::ref(Population)),
00137 boost::bind(&GeneralPopulation::GetCrowdingDistances, boost::ref(
00138 Population)));
00139 StandardPropagation Propagator(&Select, &Population, &Random);
00140 double indmutationprob = 1.0 - pow(1.0 - Configuration.mutationprob, 1.
00141 / totalgenesize);
00142 cout << "Individual Mutation set to: " << indmutationprob << endl;
00143 Propagator.SetParams(indmutationprob, Configuration.crossoverprob);
00144 GrayTranscribe Transcribe(basevalues, stepsizes, genesizes);
00145
00146 SurfaceWaveData Data;
00147 Data.ReadFile(Configuration.inputdata);
00148 boost::shared_ptr<SurfaceWaveObjective> SeisObjective(
00149 new SurfaceWaveObjective(Data));
00150 SeisObjective->SetFitExponent(Configuration.fitexponent);
00151 SeisObjective->SetPoisson(Configuration.poisson);
00152 SeisObjective->SetErrorLevel(Configuration.errorlevel);
00153
00154
00155 ResPkModel VRefModel;
00156 VRefModel.ReadModel(Configuration.vrefmodel);
00157 boost::shared_ptr<SeismicModelDiff> Regularization(
00158 new SeismicModelDiff(VRefModel));
00159
00160 vector<pCGeneralObjective> ObjVector;
00161 ObjVector.push_back(SeisObjective);
00162 ObjVector.push_back(Regularization);
00163
00164 boost::shared_ptr<GeneralGA> GA;
00165 if (Configuration.gatype == "pareto")
00166 {
00167 GAtype = pareto;
00168 boost::shared_ptr<ParetoGA> Pareto(new ParetoGA(&Propagator,
00169 &Population, &Transcribe, ObjVector, Configuration.threads));
00170 GA = Pareto;
00171 }
00172 else if (Configuration.gatype == "anneal")
00173 {
00174 GAtype = anneal;
00175 boost::shared_ptr<AnnealingGA> Annealing(new AnnealingGA(
00176 &Propagator, &Population, &Transcribe, ObjVector,
00177 Configuration.threads));
00178 GA = Annealing;
00179 }
00180 else
00181 {
00182 cerr << "Invalid GA type in configuration file." << endl;
00183 cerr << " Has to be either 'pareto' or 'anneal' !" << endl;
00184 return 100;
00185 }
00186 GA->SetWeights(Configuration.weights);
00187
00188 GeneralGA::tparamindv ParamIndices;
00189 std::vector<int> LocalIndices;
00190 generate_n(back_inserter(LocalIndices), genes, IntSequence(0));
00191 ParamIndices.push_back(LocalIndices);
00192 ParamIndices.push_back(LocalIndices);
00193
00194 GA->SetParameterIndices(ParamIndices);
00195 GA->SetElitist(Configuration.elitist);
00196
00197 if (GAtype == anneal)
00198 {
00199 SetupAnnealingGA(GA, Configuration);
00200 Population.InitPop();
00201 }
00202
00203 for (int i = 0; i < maxgen; ++i)
00204 {
00205 GA->DoIteration(i, i == (maxgen - 1));
00206 if (Configuration.verbose)
00207 {
00208 GA->PrintMisfit(misfitfile);
00209 GA->PrintTranscribed(valuefile);
00210 Population.PrintProbabilities(probfile);
00211 Population.PrintDistances(distancefile);
00212 }
00213 GA->PrintBestMisfit(frontfile);
00214
00215 fitstat << i << " ";
00216 GA->PrintFitStat(fitstat);
00217
00218 }
00219 boost::posix_time::ptime partime =
00220 boost::posix_time::microsec_clock::local_time();
00221 std::cout << "Parallel Runtime: " << partime - starttime << std::endl;
00222
00223 int bestcount = 0;
00224 UniquePop FinalUnique;
00225 tfitvec bestfit(ObjVector.size());
00226 tpopmember member(Population.GetGenesize());
00227
00228 vector<int> BestIndices(GA->GetBestModelIndices());
00229 const unsigned int noutmodels = GA->GetNBestmodels();
00230 assert(BestIndices.size() == noutmodels);
00231 const unsigned int nobjective = ObjVector.size();
00232 GeneralGA::tparamvector LocalParameters(nobjective);
00233 for (unsigned int i = 0; i < nobjective; ++i)
00234 LocalParameters.at(i).resize(ParamIndices.at(i).size(), false);
00235 ofstream finalmodels((outputbase + ".final").c_str());
00236 for (unsigned int h = 0; h < noutmodels; ++h)
00237 {
00238 member = row(Population.GetPopulation(), BestIndices.at(h));
00239
00240
00241 transcribed = Transcribe.GetValues(member);
00242 GA->SetupParams(transcribed, LocalParameters);
00243
00244 for (unsigned int f = 0; f < nobjective; ++f)
00245 {
00246 if (Configuration.weights.at(f) > 0)
00247 bestfit(f) = ObjVector.at(f)->CalcPerformance(
00248 LocalParameters.at(f));
00249 else
00250 bestfit(f) = 0;
00251
00252 }
00253
00254 if (FinalUnique.Insert(bestfit, transcribed))
00255 {
00256 copy(bestfit.begin(), bestfit.end(), ostream_iterator<double> (
00257 finalmodels, " "));
00258 finalmodels << " " << bestcount << endl;
00259 ostringstream filename;
00260 filename << "best_" << bestcount;
00261 cout << "Best: " << h << " Index : " << BestIndices.at(h)
00262 << " ";
00263 for (unsigned int f = 0; f < nobjective; ++f)
00264 cout << bestfit(f) << " ";
00265 cout << " Saved as : " << filename.str();
00266
00267 SeisObjective->WriteModel(filename.str());
00268 SeisObjective->WritePlot(filename.str());
00269 SeisObjective->WriteData(filename.str());
00270
00271 filename.str("");
00272 bestcount++;
00273 cout << endl;
00274 }
00275
00276 }
00277
00278 if (Configuration.verbose)
00279 {
00280 GA->PrintUniquePop(uniquepop);
00281 FinalUnique.PrintAll(bestfile);
00282 }
00283 boost::posix_time::ptime endtime =
00284 boost::posix_time::microsec_clock::local_time();
00285 std::cout << "Total Runtime: " << endtime - starttime << std::endl;
00286 } catch (FatalException &e)
00287 {
00288 cerr << e.what() << endl;
00289 return -1;
00290 }
00291 }