levjoint.cpp

Go to the documentation of this file.
00001 #include <iostream>
00002 #include "Iso1DMTObjective.h"
00003 #include "MTStation.h"
00004 #include "gentypes.h"
00005 #include "SeismicDataComp.h"
00006 #include "AbsVelRecObjective.h"
00007 #include "CLevmarConf.h"
00008 #include "lm.h"
00009 #include "MTFitSetup.h"
00010 #include "SurfaceWaveData.h"
00011 #include <boost/bind.hpp>
00012 #include <boost/shared_ptr.hpp>
00013 
00014 using namespace std;
00015 using namespace gplib;
00016 
00017 CLevmarConf Configuration("levmar.conf");
00018 MTStation MTData, Best;
00019 boost::shared_ptr<const SeismicDataComp> RecData(new SeismicDataComp(
00020     Configuration.recinputdata, SeismicDataComp::sac));
00021 Iso1DMTObjective MTObjective(MTData);
00022 SurfaceWaveData RFAbsVel;
00023 AbsVelRecObjective RecObjective(RecData, RFAbsVel, Configuration.shift,
00024     Configuration.sigma, Configuration.wlevel, Configuration.slowness);
00025 
00026 void misfit(double *p, double *x, int m, int n, void *data)
00027   {
00028     const unsigned int nlayers = m / 3;
00029     const unsigned int nparam = nlayers * 2;
00030     ttranscribed mtmember(nparam), recmember(nparam);
00031     for (unsigned int i = 0; i < nparam; ++i)
00032       {
00033         mtmember(i) = p[i];
00034       }
00035     for (unsigned int i = 0; i < nparam; ++i)
00036       recmember(i) = p[i + nlayers];
00037     int offset = 0;
00038     if (Configuration.weights.at(0) > 0)
00039       {
00040         MTObjective.CalcPerformance(mtmember);
00041         for (size_t i = 0; i < MTObjective.GetMisfit().size(); ++i)
00042           {
00043             x[i] = MTObjective.GetMisfit()(i) * Configuration.weights.at(0);
00044           }
00045         offset = MTObjective.GetMisfit().size();
00046       }
00047     if (Configuration.weights.at(1) > 0)
00048       {
00049         RecObjective.CalcPerformance(recmember);
00050         for (size_t i = 0; i < RecObjective.GetMisfit().size(); ++i)
00051           {
00052             x[i + offset] = RecObjective.GetMisfit()(i)
00053                 * Configuration.weights.at(1);
00054           }
00055       }
00056   }
00057 
00058 int main()
00059   {
00060 
00061     string version = "$Id: levjoint.cpp 1816 2009-09-07 11:28:35Z mmoorkamp $";
00062     cout << endl << endl;
00063     cout << "Program " << version << endl;
00064     cout << " Levenberg Marquardt to jointly invert seismic and MT data "
00065         << endl;
00066     cout << " look at levmar.conf for configuration and setup " << endl;
00067     cout << " output files will be of the form " << endl;
00068     cout << " best_lev + ending " << endl;
00069 
00070     Configuration.GetData("levmar.conf");
00071     try
00072       {
00073         MTData.GetData(Configuration.mtinputdata);
00074         //RecData.GetData(Configuration.recinputdata,SeismicDataComp::sac);
00075         RFAbsVel.ReadAscii(Configuration.rfabsveldata);
00076       } catch (FatalException &e)
00077       {
00078         cerr << e.what() << endl;
00079         return -1;
00080       }
00081 
00082     //we have to do this again becuase the global objects were initialized with the wrong inputdata
00083     MTObjective = Iso1DMTObjective(MTData);
00084     SetupMTFitParameters(Configuration, MTObjective);
00085     RecCalc::trfmethod rfmethod = RecCalc::specdiv;
00086     if (Configuration.recmethod == "iterdecon")
00087       {
00088         rfmethod = RecCalc::iterdecon;
00089       }
00090     RecObjective = AbsVelRecObjective(RecData, RFAbsVel, Configuration.shift,
00091         Configuration.sigma, Configuration.wlevel, Configuration.slowness,
00092         rfmethod);
00093     RecObjective.SetPoisson(Configuration.poisson);
00094     RecObjective.SetTimeWindow(Configuration.starttime, Configuration.endtime);
00095     RecObjective.SetErrorLevel(Configuration.recerror);
00096     RecObjective.SetRecWeight(Configuration.recweight);
00097     RecObjective.SetAbsVelWeight(Configuration.absvelweight);
00098 
00099     const int nlayers = Configuration.minres.size();
00100     const int nparams = nlayers * 3;
00101     ttranscribed mtmember(nlayers * 2), recmember(nlayers * 2);
00102     copy(Configuration.startres.begin(), Configuration.startres.end(),
00103         mtmember.begin());
00104     copy(Configuration.startthick.begin(), Configuration.startthick.end(),
00105         mtmember.begin() + nlayers);
00106     copy(Configuration.startthick.begin(), Configuration.startthick.end(),
00107         recmember.begin());
00108     copy(Configuration.startsvel.begin(), Configuration.startsvel.end(),
00109         recmember.begin() + nlayers);
00110     MTObjective.CalcPerformance(mtmember);
00111     RecObjective.CalcPerformance(recmember);
00112 
00113     //double p[nparams],lb[nparams],ub[nparams];
00114     double *p = new double[nparams];
00115     double *lb = new double[nparams];
00116     double *ub = new double[nparams];
00117     double *x;
00118 
00119     int n = 0;
00120     if (Configuration.weights.at(0) > 0)
00121       n += MTObjective.GetSynthData().size();
00122     if (Configuration.weights.at(1) > 0)
00123       n += RecObjective.GetSynthData().size();
00124 
00125     if (n == 0)
00126       {
00127         cerr << "One weight has to be > 0 !";
00128         return 100;
00129       }
00130     x = new double[n];
00131     double opts[LM_OPTS_SZ], info[LM_INFO_SZ];
00132 
00133     opts[0] = LM_INIT_MU;
00134     opts[1] = 1E-15;
00135     opts[2] = 1E-15;
00136     opts[3] = 1E-20;
00137     opts[4] = LM_DIFF_DELTA; // relevant only if the finite difference jacobian version is used
00138 
00139     for (int i = 0; i < nlayers; ++i)
00140       {
00141         p[i] = Configuration.startres.at(i);
00142         lb[i] = Configuration.minres.at(i);
00143         ub[i] = Configuration.maxres.at(i);
00144       }
00145     for (int i = 0; i < nlayers; ++i)
00146       {
00147         p[i + nlayers] = Configuration.startthick.at(i);
00148         lb[i + nlayers] = Configuration.minthick.at(i);
00149         ub[i + nlayers] = Configuration.maxthick.at(i);
00150       }
00151     for (int i = 0; i < nlayers; ++i)
00152       {
00153         p[i + 2 * nlayers] = Configuration.startsvel.at(i);
00154         lb[i + 2 * nlayers] = Configuration.minsvel.at(i);
00155         ub[i + 2 * nlayers] = Configuration.maxsvel.at(i);
00156       }
00157 
00158     for (int i = 0; i < n; i++)
00159       x[i] = 0.0;
00160 
00161     double ret = dlevmar_bc_dif(misfit, p, x, nparams, n, lb, ub,
00162         Configuration.maxiter, opts, info, NULL, NULL, NULL); // no jacobian
00163     cout << "Levenberg-Marquardt returned " << ret << " in " << info[5]
00164         << "iter, reason " << info[6] << endl;
00165 
00166     cout << endl << " Minimization info:" << endl;
00167     for (int i = 0; i < LM_INFO_SZ; ++i)
00168       cout << info[i] << " ";
00169     cout << endl;
00170 
00171     ttranscribed mtbest(nlayers * 2), recbest(nlayers * 2);
00172     for (int i = 0; i < nlayers * 2; ++i)
00173       {
00174         mtbest(i) = p[i];
00175         recbest(i) = p[i + nlayers];
00176       }
00177     cout << endl;
00178     double mtdiff = MTObjective.CalcPerformance(mtbest);
00179     double recfit = RecObjective.CalcPerformance(recbest);
00180 
00181     cout << "MT-Fit: " << mtdiff << " Rec-Fit: " << recfit << endl;
00182     ostringstream filename;
00183     filename << "best_lev";
00184 
00185     cout << " Saved as : " << filename.str() << endl;
00186     MTObjective.WriteData(filename.str());
00187     MTObjective.WriteModel(filename.str() + "_mt.mod");
00188     MTObjective.WritePlot(filename.str() + "_mt.plot");
00189     RecObjective.WriteData(filename.str() + ".rec");
00190     RecObjective.WriteModel(filename.str() + "_rec.mod");
00191     RecObjective.WritePlot(filename.str() + "_rec");
00192     delete[] x;
00193     delete[] p;
00194     delete[] lb;
00195     delete[] ub;
00196     return 0;
00197   }

Generated on Tue May 4 16:52:14 2010 for GPLIB++ by  doxygen 1.5.8