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
00075 RFAbsVel.ReadAscii(Configuration.rfabsveldata);
00076 } catch (FatalException &e)
00077 {
00078 cerr << e.what() << endl;
00079 return -1;
00080 }
00081
00082
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
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;
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);
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 }