surfinvga.cpp

Go to the documentation of this file.
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         /*for (int i = 0; i < GA->GetAvgFit().size(); ++i)
00042          avgcombfit += GA->GetAvgFit().at(i);*/
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 //! Program to invert MT data for 1D anisotropic structure with a genetic algorithm
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) // in most cases we do not need all of these values
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); // we specify the overall probability for mutation in config file
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         //setup regularization
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         //Setting up indices for forward modelling
00188         GeneralGA::tparamindv ParamIndices;
00189         std::vector<int> LocalIndices;
00190         generate_n(back_inserter(LocalIndices), genes, IntSequence(0)); //generate Indices 0 .. nmtparam for MT Objective function
00191         ParamIndices.push_back(LocalIndices);//both data misfit and regularization
00192         ParamIndices.push_back(LocalIndices); //work on all parts of the model vector
00193 
00194         GA->SetParameterIndices(ParamIndices);
00195         GA->SetElitist(Configuration.elitist);
00196         //we have to do a few things that are specific to the type of genetic algorithm
00197         if (GAtype == anneal)
00198           {
00199             SetupAnnealingGA(GA, Configuration);
00200             Population.InitPop();
00201           }
00202         //now comes the core loop
00203         for (int i = 0; i < maxgen; ++i) //iterate over the specified number of generattions
00204           {
00205             GA->DoIteration(i, i == (maxgen - 1)); // pass iteration number to GA and tell whether it's the final iteration
00206             if (Configuration.verbose) // in most cases we do not need all of these values
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             //system("rm -r j*");
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         //the following is to organize the output of the best models
00223         int bestcount = 0;
00224         UniquePop FinalUnique; //we only want to write each model once, even if it is several times in the population
00225         tfitvec bestfit(ObjVector.size());
00226         tpopmember member(Population.GetGenesize());
00227 
00228         vector<int> BestIndices(GA->GetBestModelIndices()); // store the indices of the best models
00229         const unsigned int noutmodels = GA->GetNBestmodels(); // and how many of them we have
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) //for each best model
00237           {
00238             member = row(Population.GetPopulation(), BestIndices.at(h)); //get the genetic string
00239 
00240 
00241             transcribed = Transcribe.GetValues(member); //transcribe the genetic string to model parameters
00242             GA->SetupParams(transcribed, LocalParameters); //copy the right parameters for each objective function
00243 
00244             for (unsigned int f = 0; f < nobjective; ++f) //calculate the performance for each function
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)) //if we can insert it, it is a new model that we didn't output yet
00255               {
00256                 copy(bestfit.begin(), bestfit.end(), ostream_iterator<double> (
00257                     finalmodels, " ")); //print the misfits in the .final file
00258                 finalmodels << "  " << bestcount << endl; // write the index in the last column for easier identification
00259                 ostringstream filename;
00260                 filename << "best_" << bestcount;
00261                 cout << "Best: " << h << " Index : " << BestIndices.at(h)
00262                     << " "; //write some info to screen
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()); //write model, plotting file and synthetic data
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) // in most cases we do not need all of these values
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   }

Generated on Tue Nov 3 13:24:14 2009 for GPLIB++ by  doxygen 1.5.8