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());
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(),
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
00073
00074
00075
00076
00077
00078
00079
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
00100 const unsigned int ndata = min(SynthData.GetPhaseVelocities().size(), MeasuredData.GetPhaseVelocities().size());
00101 tmisfit LocalMisfit(ndata);
00102 tdata LocalData(ndata);
00103 double returnvalue = 0;
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);
00112 returnvalue += fabs(currvalue);
00113 }
00114 SetMisfit(LocalMisfit);
00115 SetSynthData(LocalData);
00116
00117 SetRMS(pow(returnvalue/LocalMisfit.size(), 1.0/GetFitExponent()));
00118 }