GPLIB++
anisogajoint.cpp
Go to the documentation of this file.
1 #include <iostream>
2 #include <fstream>
3 #include <algorithm>
4 #include <numeric>
5 #include <sstream>
6 #include <string>
7 #include "SimpleSelect.h"
9 #include "UniformRNG.h"
10 #include "gentypes.h"
11 #include "BinaryPopulation.h"
12 #include "StandardPropagation.h"
13 #include "GrayTranscribe.h"
14 #include "AnnealingGA.h"
15 #include "ParetoGA.h"
16 #include "Aniso1DMTObjective.h"
18 #include "ParkSurfaceWaveData.h"
19 #include "PTensor1DMTObjective.h"
20 #include "MTStation.h"
21 #include "Adaptors.h"
22 #include "MTFitSetup.h"
23 #include "PTensorMTStation.h"
24 #include <boost/bind.hpp>
25 #include <boost/shared_ptr.hpp>
26 #include <boost/filesystem.hpp>
27 #include <boost/date_time/posix_time/posix_time.hpp>
28 #include <complex>
29 #include "Util.h"
30 #include "MTAnisoRoughness.h"
31 #include "SWAnisoRoughness.h"
32 #include "AnisoJointConf.h"
33 #include "MTInvConf.h"
34 #include "GAConf.h"
35 
36 using namespace std;
37 using namespace gplib;
38 
39 enum tgatype
40  {
42  };
43 
44 typedef boost::shared_ptr<GeneralObjective> pCGeneralObjective;
45 
46 void SetupAnnealingGA(boost::shared_ptr<GeneralGA> &GA,
47  const GAConf Configuration)
48  {
49  double InitTemperature = Configuration.inittemp;
50  if (Configuration.inittemp < 0)
51  {
52  double avgcombfit = 0;
53  GA->DoIteration(0, false);
54  /*for (int i = 0; i < GA->GetAvgFit().size(); ++i)
55  avgcombfit += GA->GetAvgFit().at(i);*/
56  avgcombfit = accumulate(GA->GetAvgFit().begin(), GA->GetAvgFit().end(),
57  0.0);
58  InitTemperature = avgcombfit * abs(Configuration.inittemp);
59  }
60  AnnealingGA *AnnealGA = dynamic_cast<AnnealingGA*> (GA.get());
61  AnnealGA->SetParams(InitTemperature, Configuration.annealinggeneration,
62  Configuration.coolingratio);
63  }
64 
65 void SetupSurfaceWaveObjective(const string surfinfofile,
66  MultiAnisoSurfaceWaveObjective &SurfObjective)
67  {
68  ifstream surfinfo(surfinfofile.c_str());
69  double backazimuth; //first column in swaveinfo
70  double avelratio; //third column in swaveinfo
71  string inputdata; //second column in swaveinfo
72  while (surfinfo.good())
73  {
74 
75  surfinfo >> backazimuth >> inputdata >> avelratio;
76  if (surfinfo.good())
77  {
79  Data.ReadAscii(inputdata);
80  SurfObjective.AddMeasurement(Data, backazimuth, avelratio);
81  }
82  }
83  }
84 
85 //! Program to invert MT and SW data for 1D anisotropic structure with a genetic algorithm
86 int main(int argc, char *argv[])
87  {
88  boost::posix_time::ptime starttime =
89  boost::posix_time::microsec_clock::local_time();
90  string version = "$Id: mtanisoga.cpp 1572 2007-12-17 18:20:43Z mmoorkamp $";
91  cout << endl << endl;
92  cout << "Program " << version << endl;
93  cout
94  << "Genetic algorithm to jointly invert MT and SW data for 1D anisotropy"
95  << endl;
96  cout << "look at anisogajoint.conf for configuration and setup " << endl;
97  cout << "The root name of log-files can be overwritten by using " << endl;
98  cout << "1dinvga newrootname " << endl;
99 
100  MTInvConf MTConf;
101  AnisoJointConf JointConf;
102  GAConf GaConf;
103 
104  std::ifstream conffile("anisogajoint.conf");
105 
106  MTConf.GetData(conffile);
107  conffile.clear();
108  conffile.seekg(0, std::ios::beg);
109  JointConf.GetData(conffile);
110  conffile.clear();
111  conffile.seekg(0, std::ios::beg);
112  GaConf.GetData(conffile);
113 
114  UniformRNG Random;
115  try
116  {
117  ttranscribed transcribed;
118  tgatype GAtype = pareto;
119 
120  string outputbase;
121 
122  if (argc > 1)
123  outputbase = argv[1];
124  else
125  outputbase = JointConf.outputbase;
126 
127  ofstream misfitfile;
128  ofstream valuefile;
129  ofstream probfile;
130  ofstream distancefile;
131  ofstream fitstat((outputbase + ".ftst").c_str());
132  ofstream uniquepop((outputbase + ".unpop").c_str());
133  ofstream rankfile((outputbase + ".rank").c_str());
134  ofstream frontfile((outputbase + ".front").c_str());
135  ofstream bestfile((outputbase + ".best").c_str());
136 
137  if (JointConf.verbose) // in most cases we do not need all of these values
138 
139  {
140  misfitfile.open((outputbase + ".msft").c_str());
141  valuefile.open((outputbase + ".vals").c_str());
142  probfile.open((outputbase + ".probs").c_str());
143  distancefile.open((outputbase + ".dist").c_str());
144  }
145 
146  if ((JointConf.thickbase.size() != JointConf.resbase.size())
147  || (JointConf.thickbase.size() != JointConf.aresbase.size())
148  || (JointConf.thickbase.size()
149  != JointConf.strikebase.size())
150  || (JointConf.thickbase.size()
151  != JointConf.dstrikebase.size())
152  || (JointConf.thickbase.size() != JointConf.avelbase.size()))
153  {
154  cerr << "Configuration of genes is not consistent ! ";
155  return 100;
156  }
157  const int nparam = 7;
158  const int genes = nparam * JointConf.thickbase.size();
159  const int popsize = GaConf.popsize;
160  const int maxgen = GaConf.generations;
161  const int paramlength = genes / nparam;
162  ttranscribed basevalues(genes);
163  ttranscribed stepsizes(genes);
164  tsizev genesizes(genes);
165 
166  misfitfile << popsize << " " << maxgen << " " << endl;
167  valuefile << genes << " " << popsize << " " << maxgen << endl;
168 
169  copy(JointConf.resbase.begin(), JointConf.resbase.end(),
170  basevalues.begin());
171  copy(JointConf.resstep.begin(), JointConf.resstep.end(),
172  stepsizes.begin());
173  copy(JointConf.ressizes.begin(), JointConf.ressizes.end(),
174  genesizes.begin());
175 
176  copy(JointConf.thickbase.begin(), JointConf.thickbase.end(),
177  basevalues.begin() + paramlength);
178  copy(JointConf.thickstep.begin(), JointConf.thickstep.end(),
179  stepsizes.begin() + paramlength);
180  copy(JointConf.thicksizes.begin(), JointConf.thicksizes.end(),
181  genesizes.begin() + paramlength);
182 
183  copy(JointConf.velbase.begin(), JointConf.velbase.end(),
184  basevalues.begin() + 2 * paramlength);
185  copy(JointConf.velstep.begin(), JointConf.velstep.end(),
186  stepsizes.begin() + 2 * paramlength);
187  copy(JointConf.velsizes.begin(), JointConf.velsizes.end(),
188  genesizes.begin() + 2 * paramlength);
189 
190  copy(JointConf.strikebase.begin(), JointConf.strikebase.end(),
191  basevalues.begin() + 3 * paramlength);
192  copy(JointConf.strikestep.begin(), JointConf.strikestep.end(),
193  stepsizes.begin() + 3 * paramlength);
194  copy(JointConf.strikesizes.begin(),
195  JointConf.strikesizes.end(), genesizes.begin() + 3
196  * paramlength);
197 
198  copy(JointConf.dstrikebase.begin(),
199  JointConf.dstrikebase.end(), basevalues.begin() + 4
200  * paramlength);
201  copy(JointConf.dstrikestep.begin(),
202  JointConf.dstrikestep.end(), stepsizes.begin() + 4
203  * paramlength);
204  copy(JointConf.dstrikesizes.begin(),
205  JointConf.dstrikesizes.end(), genesizes.begin() + 4
206  * paramlength);
207 
208  copy(JointConf.aresbase.begin(), JointConf.aresbase.end(),
209  basevalues.begin() + 5 * paramlength);
210  copy(JointConf.aresstep.begin(), JointConf.aresstep.end(),
211  stepsizes.begin() + 5 * paramlength);
212  copy(JointConf.aressizes.begin(), JointConf.aressizes.end(),
213  genesizes.begin() + 5 * paramlength);
214 
215  copy(JointConf.avelbase.begin(), JointConf.avelbase.end(),
216  basevalues.begin() + 6 * paramlength);
217  copy(JointConf.avelstep.begin(), JointConf.avelstep.end(),
218  stepsizes.begin() + 6 * paramlength);
219  copy(JointConf.avelsizes.begin(), JointConf.avelsizes.end(),
220  genesizes.begin() + 6 * paramlength);
221 
222  const int totalgenesize = accumulate(genesizes.begin(),
223  genesizes.end(), 0);
224  BinaryPopulation Population(popsize, totalgenesize, Random, true);
225  BinaryTournamentSelect Select(Random, boost::bind(
226  &GeneralPopulation::GetProbabilities, boost::ref(Population)),
227  boost::bind(&GeneralPopulation::GetCrowdingDistances, boost::ref(
228  Population)));
229  StandardPropagation Propagator(&Select, &Population, &Random);
230  double indmutationprob = 1.0 - std::pow(1.0
231  - GaConf.mutationprob, 1. / totalgenesize); // we specify the overall probability for mutation in config file
232  cout << "Individual Mutation set to: " << indmutationprob << endl;
233  Propagator.SetParams(indmutationprob, GaConf.crossoverprob);
234  GrayTranscribe Transcribe(basevalues, stepsizes, genesizes);
235 
236  //setup MT Objective function
237  boost::shared_ptr<PlottableObjective> MTObjective;
238 
239  if (MTConf.mtfit == "ptensor")
240  {
241  PTensorMTStation PTData;
242  PTData.GetData(JointConf.ptensordata);
243  boost::shared_ptr<PTensor1DMTObjective> PTObjective(
244  new PTensor1DMTObjective(PTData));
245  PTObjective->SetErrorLevel(MTConf.phaseerror);
246  MTObjective = PTObjective;
247  }
248  else
249  {
251  MTData.GetData(MTConf.mtinputdata);
252  boost::shared_ptr<Aniso1DMTObjective> AnisoObjective(
253  new Aniso1DMTObjective(MTData));
254  SetupMTFitParameters(MTConf, *AnisoObjective);
255  MTObjective = AnisoObjective;
256  }
257  MTObjective->SetFitExponent(MTConf.mtfitexponent);
258 
259  //Setup Surface wave objective
260  boost::shared_ptr<MultiAnisoSurfaceWaveObjective>
261  MultiSurfaceObjective(new MultiAnisoSurfaceWaveObjective);
262  SetupSurfaceWaveObjective("swaveinfo", *MultiSurfaceObjective.get());
263 
264  //setup MT regularization
265  boost::shared_ptr<MTAnisoRoughness> MTRegularization(
266  new MTAnisoRoughness());
267  MTRegularization->SetCondDiffWeight(JointConf.conddiffweight);
268  MTRegularization->SetAnisotropyWeight(JointConf.anisotropyweight);
269  MTRegularization->SetStrikeDiffWeight(JointConf.strikediffweight);
270 
271  //setup SW regularization
272  boost::shared_ptr<SWAnisoRoughness> SWRegularization(
273  new SWAnisoRoughness());
274  SWRegularization->SetVelDiffWeight(JointConf.veldiffweight);
275  SWRegularization->SetAnisovelWeight(JointConf.anisovelweight);
276  SWRegularization->SetStrikeDiffWeight(JointConf.strikediffweight);
277  SWRegularization->SetDeltaStrikeDiffWeight(
278  JointConf.deltastrikediffweight);
279 
280  vector<pCGeneralObjective> ObjVector;
281  ObjVector.push_back(MTObjective);
282  ObjVector.push_back(MultiSurfaceObjective);
283  ObjVector.push_back(SWRegularization);
284  ObjVector.push_back(MTRegularization);
285 
286  boost::shared_ptr<GeneralGA> GA;
287  if (GaConf.gatype == "pareto")
288  {
289  GAtype = pareto;
290  boost::shared_ptr<ParetoGA> Pareto(new ParetoGA(&Propagator,
291  &Population, &Transcribe, ObjVector));
292  GA = Pareto;
293  }
294  else if (GaConf.gatype == "anneal")
295  {
296  GAtype = anneal;
297  boost::shared_ptr<AnnealingGA> Annealing(new AnnealingGA(
298  &Propagator, &Population, &Transcribe, ObjVector));
299  GA = Annealing;
300  }
301  else
302  {
303  cerr << "Invalid GA type in configuration file." << endl;
304  cerr << " Has to be either 'pareto' or 'anneal' !" << endl;
305  return 100;
306  }
307  GA->SetWeights(JointConf.weights);
308 
309  //Setting up indices for forward modelling
310  GeneralGA::tparamindv ParamIndices;
311  const int nmtparam = 4 * JointConf.resbase.size();
312  std::vector<int> MTIndices, SurfaceWaveIndices;
313  generate_n(back_inserter(MTIndices), 2 * paramlength, IntSequence(0)); // generate indices for rho and t
314  generate_n(back_inserter(MTIndices), paramlength, IntSequence(5
315  * paramlength));
316  generate_n(back_inserter(MTIndices), paramlength, IntSequence(3
317  * paramlength));
318 
319  ParamIndices.push_back(MTIndices);//add indices for MT
320 
321  generate_n(back_inserter(SurfaceWaveIndices), 6 * paramlength,
322  IntSequence(paramlength)); // generate indices for Surface Wave objective
323  ParamIndices.push_back(SurfaceWaveIndices); //work on all parts of the model vector
324  ParamIndices.push_back(SurfaceWaveIndices);// regularization for SW
325  ParamIndices.push_back(MTIndices);//regularization takes same parameters as MT, because only resistivity is regularized
326 
327  GA->SetParameterIndices(ParamIndices);
328  GA->SetElitist(GaConf.elitist);
329  //we have to do a few things that are specific to the type of genetic algorithm
330  if (GAtype == anneal)
331  {
332  SetupAnnealingGA(GA, GaConf);
333  Population.InitPop();
334  }
335  //now comes the core loop
336  for (int i = 0; i < maxgen; ++i) //iterate over the specified number of generations
337 
338  {
339  GA->DoIteration(i, i == (maxgen - 1)); // pass iteration number to GA and tell whether it's the final iteration
340  if (JointConf.verbose) // in most cases we do not need all of these values
341  {
342  GA->PrintMisfit(misfitfile);
343  GA->PrintTranscribed(valuefile);
344  Population.PrintProbabilities(probfile);
345  Population.PrintDistances(distancefile);
346  }
347  GA->PrintBestMisfit(frontfile);
348 
349  fitstat << i << " ";
350  GA->PrintFitStat(fitstat);
351  }
352 
353  //the following is to organize the output of the best models
354  int bestcount = 0;
355  UniquePop FinalUnique; //we only want to write each model once, even if it is several times in the population
356  tfitvec bestfit(ObjVector.size());
357  tpopmember member(Population.GetGenesize());
358 
359  vector<int> BestIndices(GA->GetBestModelIndices()); // store the indices of the best models
360  const unsigned int noutmodels = GA->GetNBestmodels(); // and how many of them we have
361  assert(BestIndices.size() == noutmodels);
362  const unsigned int nobjective = ObjVector.size();
363  GeneralGA::tparamvector LocalParameters(nobjective);
364  for (unsigned int i = 0; i < nobjective; ++i)
365  LocalParameters.at(i).resize(ParamIndices.at(i).size(), false);
366  ofstream finalmodels((outputbase + ".final").c_str());
367  for (unsigned int h = 0; h < noutmodels; ++h) //for each best model
368 
369  {
370  member = row(Population.GetPopulation(), BestIndices.at(h)); //get the genetic string
371 
372 
373  transcribed = Transcribe.GetValues(member); //transcribe the genetic string to model parameters
374  GA->SetupParams(transcribed, LocalParameters); //copy the right parameters for each objective function
375 
376  for (unsigned int f = 0; f < nobjective; ++f) //calculate the performance for each function
377 
378  {
379  if (JointConf.weights.at(f) > 0)
380  bestfit(f) = ObjVector.at(f)->CalcPerformance(
381  LocalParameters.at(f));
382  else
383  bestfit(f) = 0;
384 
385  }
386 
387  if (FinalUnique.Insert(bestfit, transcribed)) //if we can insert it, it is a new model that we didn't output yet
388 
389  {
390  copy(bestfit.begin(), bestfit.end(), ostream_iterator<double> (
391  finalmodels, " ")); //print the misfits in the .final file
392  finalmodels << " " << bestcount << endl; // write the index in the last column for easier identification
393  ostringstream filename;
394  filename << "best_" << bestcount;
395  cout << "Best: " << h << " Index : " << BestIndices.at(h)
396  << " "; //write some info to screen
397  for (unsigned int f = 0; f < nobjective; ++f)
398  cout << bestfit(f) << " ";
399  cout << " Saved as : " << filename.str();
400  if (JointConf.weights.at(0) > 0)
401  {
402  MTObjective->WriteModel(filename.str() + "_mt.mod"); //write model, plotting file and synthetic data
403  MTObjective->WritePlot(filename.str() + "_mt.plot");
404  MTObjective->WriteData(filename.str());
405  }
406  //we also have to write out surface wave data
407  if (JointConf.weights.at(1) > 0)
408  {
409  MultiSurfaceObjective->WriteModel(filename.str()
410  + "_sw.mod"); //write model, plotting file and synthetic data
411  MultiSurfaceObjective->WritePlot(filename.str()
412  + "_sw.plot");
413  MultiSurfaceObjective->WriteData(filename.str()
414  + "_sw.cvel"); //write synthetic data as ascii file
415  }
416  filename.str("");
417  bestcount++;
418  cout << endl;
419  }
420 
421  }
422 
423  if (JointConf.verbose) // in most cases we do not need all of these values
424 
425  {
426  GA->PrintUniquePop(uniquepop);
427  FinalUnique.PrintAll(bestfile);
428  }
429  boost::posix_time::ptime endtime =
430  boost::posix_time::microsec_clock::local_time();
431  std::cout << "Total Runtime: " << endtime - starttime << std::endl;
432  } catch (FatalException &e)
433  {
434  cerr << e.what() << endl;
435  return -1;
436  }
437  }
std::vector< double > thickbase
int generations
Definition: GAConf.h:23
void SetupMTFitParameters(const tConfObject &Configuration, C1DMTObjective &Objective)
Definition: MTFitSetup.h:8
ublas::vector< double > ttranscribed
Definition: gentypes.h:21
std::string gatype
Definition: GAConf.h:26
double inittemp
Definition: GAConf.h:21
std::vector< double > resbase
Generate uniformly distributed random numbers, this is basically a wrapper for the boost random numbe...
Definition: UniformRNG.h:19
bool Insert(const tfitvec &fitness, const ttranscribed &popmember)
Definition: UniquePop.cpp:17
Caclulate the roughness for anisotropic MT models.
std::vector< int > avelsizes
This is a special objective function to fit phase tensor MT data.
Implements binary tournament selection for genetic algorithms.
void f(vector< double > &v1, vector< double > &v2, vector< double > &v3, vector< double > &v4)
Definition: perftest.cpp:17
int popsize
Definition: GAConf.h:20
A population that is encoded as a simple binary string.
double crossoverprob
Definition: GAConf.h:25
std::vector< double > avelbase
AnnealingGA implements a genetic algorithm with an annealing style objective function.
Definition: AnnealingGA.h:15
void GetData(std::ifstream &instream)
Definition: GAConf.cpp:28
virtual void GetData(const std::string filename)
read in data from file, determines format by ending
Definition: MTStation.cpp:597
Minimize the misfit for several surface wave dispersion curves simultaneously.
std::vector< double > aresstep
std::vector< double > avelstep
void h(vector< double > &v1, vector< double > &v2, vector< double > &v3, vector< double > &v4)
Definition: perftest.cpp:40
std::vector< double > strikestep
void SetParams(const double mutation, const double crossover)
boost::shared_ptr< PlottableObjective > MTObjective
Definition: cadianiso.cpp:16
virtual ttranscribed GetValues(const tpopmember &member)
Re-Implements the function from BinaryTranscribe.
double phaseerror
Definition: MTInvConf.h:24
std::vector< int > dstrikesizes
std::vector< gplib::rvec > tparamvector
We provide some typedefs that are used in other parts as well.
Definition: GeneralGA.h:29
This is the standard propagation class that generates a new population from the old one...
The class MTStation is used to store the transfer functions and related information for a MT-site...
Definition: MTStation.h:17
ublas::vector< bool > tpopmember
Definition: gentypes.h:22
int annealinggeneration
Definition: GAConf.h:27
std::vector< std::vector< int > > tparamindv
Definition: GeneralGA.h:32
std::vector< double > weights
CMTStation MTData
Definition: cadijoint.cpp:15
std::vector< double > aresbase
std::vector< double > dstrikebase
void GetData(const std::string &filename)
std::vector< int > ressizes
void PrintAll(std::ostream &output)
Definition: UniquePop.cpp:36
double coolingratio
Definition: GAConf.h:22
void AddMeasurement(const ParkSurfaceWaveData &Measured, const double back, const double avel)
void GetData(std::ifstream &instream)
Definition: MTInvConf.cpp:25
std::string mtfit
Definition: MTInvConf.h:27
std::vector< int > aressizes
void GetData(std::ifstream &instream)
int main(int argc, char *argv[])
Program to invert MT and SW data for 1D anisotropic structure with a genetic algorithm.
std::vector< double > velstep
std::vector< double > resstep
bool elitist
Definition: GAConf.h:28
This class stores a single unique copy of each population member that is added to it...
Definition: UniquePop.h:17
tgatype
Definition: mtanisoga.cpp:34
void SetupAnnealingGA(boost::shared_ptr< GeneralGA > &GA, const GAConf Configuration)
This class implements the Gray code representation of a binary string and the corresponding transcrip...
std::vector< double > thickstep
void SetupSurfaceWaveObjective(const string surfinfofile, MultiAnisoSurfaceWaveObjective &SurfObjective)
double mutationprob
Definition: GAConf.h:24
string version
Definition: makeinput.cpp:16
ublas::vector< double > tfitvec
Definition: gentypes.h:23
Implements a genetic algorithm based on the concept of pareto-optimality, best suited for multi-objec...
Definition: ParetoGA.h:17
virtual void ReadAscii(const std::string &filename)
Read a file in general ascii format, i.e lines with period velocity each.
CLevanisoConf Configuration
Definition: cadianiso.cpp:17
std::vector< int > velsizes
Calculate the roughness for anisotropic SW models.
std::string mtinputdata
Definition: MTInvConf.h:28
boost::shared_ptr< GeneralObjective > pCGeneralObjective
std::vector< int > strikesizes
ublas::vector< int > tsizev
Definition: gentypes.h:27
void SetParams(const double InitT, const int AnnealG, const double AnnealR)
Set the parameters for the annealing process.
Definition: AnnealingGA.cpp:35
std::vector< double > velbase
The basic exception class for all errors that arise in gplib.
std::vector< int > thicksizes
std::vector< double > dstrikestep
std::vector< double > strikebase