SurfaceWaveObjective.cpp

Go to the documentation of this file.
00001 #include "SurfaceWaveObjective.h"
00002 #include <boost/bind.hpp>
00003 #include "SeisTools.h"
00004 #include <gsl/gsl_math.h>
00005 #include <numeric>
00006 #include <boost/shared_ptr.hpp>
00007 #include "Sdisp96Model.h"
00008 
00009 using namespace std;
00010 
00011 SurfaceWaveObjective::SurfaceWaveObjective(const SurfaceWaveData &Data) :
00012   MeasuredData(Data)
00013   {
00014     poisson=sqrt(3.);
00015     errorlevel = 0.02;
00016   }
00017 
00018 SurfaceWaveObjective& SurfaceWaveObjective::operator=(const SurfaceWaveObjective& source)
00019   {
00020     if (this == &source) return *this;
00021     MeasuredData = source.MeasuredData;
00022     SynthData = source.SynthData;
00023     Synthetic = source.Synthetic;
00024     errorlevel = source.errorlevel;
00025     poisson = source.poisson;
00026     return *this;
00027   }
00028 
00029 SurfaceWaveObjective::SurfaceWaveObjective(const SurfaceWaveObjective &Old) :
00030   MeasuredData(Old.MeasuredData), SynthData(Old.SynthData),
00031       Synthetic(Old.Synthetic)
00032   {
00033     errorlevel = Old.errorlevel;
00034     poisson = Old.poisson;
00035   }
00036 
00037 SurfaceWaveObjective::~SurfaceWaveObjective()
00038   {
00039   }
00040 
00041 void SurfaceWaveObjective::PreParallel(const ttranscribed &member)
00042   {
00043     std::string temp(tmpnam(NULL));
00044     tempname = temp;
00045     const unsigned int nfulllayers = member.size()/2;
00046     boost::shared_ptr<Sdisp96Model> Model(new Sdisp96Model);
00047     ttranscribed thickness(nfulllayers), velocity(nfulllayers);
00048     copy(member.begin(), member.begin()+nfulllayers, thickness.begin()); //copy values
00049     copy(member.begin()+nfulllayers, member.begin()+2*nfulllayers,
00050         velocity.begin());
00051 
00052     Model->SetThicknesses().assign(nfulllayers, 0.0);
00053     Model->SetShVelocities().assign(nfulllayers, 0.0);
00054     Model->SetSvVelocities().assign(nfulllayers, 0.0);
00055     Model->SetPhVelocities().assign(nfulllayers, 0.0);
00056     Model->SetPvVelocities().assign(nfulllayers, 0.0);
00057     Model->SetDensities().assign(nfulllayers, 0.0);
00058     Model->SetEta().assign(nfulllayers, 0.0);
00059     Model->SetQmu().assign(nfulllayers, 0.0);
00060     Model->SetQkappa().assign(nfulllayers, 0.0);
00061 
00062     copy(thickness.begin(), thickness.end(), Model->SetThicknesses().begin());
00063     copy(velocity.begin(), velocity.end(), Model->SetShVelocities().begin());
00064     copy(velocity.begin(), velocity.end(), Model->SetSvVelocities().begin());
00065     transform(velocity.begin(), velocity.end(), Model->SetDensities().begin(), CalcDensity());
00066     transform(velocity.begin(), velocity.end(), //PVelocity is calculated by multiplication of SVel by poisson's ratio
00067         Model->SetPhVelocities().begin(), boost::bind(multiplies<double>(), _1, poisson));
00068     copy(Model->GetPhVelocities().begin(), Model->GetPhVelocities().end(), Model->SetPvVelocities().begin());
00069     fill_n(Model->SetEta().begin(), nfulllayers, 1.0);
00070     fill_n(Model->SetQmu().begin(), nfulllayers, 100.0);
00071     fill_n(Model->SetQkappa().begin(), nfulllayers, 99999.00);
00072     //  for (int i = 0; i < Model->GetThicknesses().size(); ++i) // vector size changes, so we have to use the current size 
00073     //  {
00074     //          double currdepth = accumulate(Model->GetThicknesses().begin(),Model->GetThicknesses().begin()+i,0.0);
00075     //          double maxdepth = Model->GetMaxDepth(currdepth);
00076     //          i = Model->SplitLayer(i,maxdepth); //this function manipulates the value of i
00077     //  }
00078     //cout << "After: " << Model.GetThicknesses().size() << endl;
00079     //Model.MergeModel(Background);
00080     Synthetic.SetModel(Model);
00081     if (Synthetic.GetCalculationPeriods().empty())
00082       {
00083         Synthetic.SetCalculationPeriods(MeasuredData.GetPeriods());
00084       }
00085     Synthetic.PreParallel(tempname);
00086   }
00087 
00088 double SurfaceWaveObjective::PostParallel(const ttranscribed &member)
00089   {
00090     return GetRMS();
00091 
00092   }
00093 
00094 void SurfaceWaveObjective::SafeParallel(const ttranscribed &member)
00095   {
00096 
00097     SynthData = Synthetic.SafeParallel(tempname);
00098     assert(errorlevel> 1e-4);
00099     // an errorlevel < 0.01% is absolutely unrealistic
00100     const unsigned int ndata = min(SynthData.GetPhaseVelocities().size(), MeasuredData.GetPhaseVelocities().size());
00101     tmisfit LocalMisfit(ndata); // we need vectors of the right size for misfit
00102     tdata LocalData(ndata); // and  data
00103     double returnvalue = 0; // init returnvalue
00104     double currvalue = 0.0;
00105     for (unsigned int i = 0; i < ndata; ++i)
00106       {
00107         currvalue = SynthData.GetPhaseVelocities().at(i) - MeasuredData.GetPhaseVelocities().at(i);
00108         currvalue /= MeasuredData.GetPhaseVelocities().at(i) * errorlevel;
00109         currvalue = gsl_pow_int(currvalue, GetFitExponent());
00110         LocalMisfit(i)= fabs(currvalue);
00111         LocalData(i)= SynthData.GetPhaseVelocities().at(i); //copy data (for levmar algorithm)
00112         returnvalue += fabs(currvalue); // add misfit to returnvalue
00113       }
00114     SetMisfit(LocalMisfit); // set appropriate members of baseclass
00115     SetSynthData(LocalData);
00116 
00117     SetRMS(pow(returnvalue/LocalMisfit.size(), 1.0/GetFitExponent())); //return misfit
00118   }

Generated on Fri Jul 4 15:30:21 2008 for GPLIB++ by  doxygen 1.5.5