CGeneralLinInversion.cpp
Go to the documentation of this file.00001 #include "CGeneralLinInversion.h"
00002 #include <iostream>
00003 #include <limits>
00004 using namespace std;
00005
00006 CGeneralLinInversion::CGeneralLinInversion(const unsigned int ndatapoints, const unsigned int nmodel)
00007 {
00008 Iterationnumber = 0;
00009 CurrentRMS = 1e90;
00010 nparams = nmodel;
00011 ndata = ndatapoints;
00012 InversionResult.resize(ndata,false);
00013 CurrentData.resize(ndata,false);
00014 CurrentMisfit.resize(ndata,false);
00015 Gradient.resize(nparams,false);
00016 CurrentModel.resize(nparams,false);
00017 DataCovar.resize(ndata,ndata,false);
00018 ModelCovar.resize(nparams,nparams,false);
00019 PartialDerivs.resize(ndata,nparams,false);
00020 epsilon = sqrt(numeric_limits<double>::epsilon());
00021 }
00022
00023 CGeneralLinInversion::~CGeneralLinInversion()
00024 {
00025 }
00026
00027 void CGeneralLinInversion::CalcGradient()
00028 {
00029
00030 const double delta = 0.0001;
00031 const double poschange = 1. + delta;
00032 const double negchange = 1. - delta;
00033 double denominator;
00034 CurrentRMS = 0;
00035 double posrms, negrms;
00036
00037 CurrentRMS = MisfitCalculator->CalcPerformance(CurrentModel);
00038 CurrentMisfit = MisfitCalculator->GetMisfit();
00039 CurrentData = MisfitCalculator->GetSynthData();
00040
00041 posmodel = CurrentModel;
00042 negmodel = CurrentModel;
00043
00044 for (unsigned int i = 0; i < nparams; ++i)
00045 {
00046 if (i > 0)
00047 {
00048 posmodel(i-1) = CurrentModel(i-1);
00049 negmodel(i-1) = CurrentModel(i-1);
00050 }
00051 posmodel(i) = CurrentModel(i) * poschange;
00052 negmodel(i) = CurrentModel(i) * negchange;
00053 posrms = MisfitCalculator->CalcPerformance(posmodel);
00054 negrms = MisfitCalculator->CalcPerformance(negmodel);
00055
00056
00057
00058 denominator = 1./(2.* delta * CurrentModel(i));
00059 Gradient(i) = (posrms - negrms)*denominator;
00060 }
00061 }
00062
00063 void CGeneralLinInversion::CalcPartialDerivs()
00064 {
00065 unsigned int i,j;
00066
00067 const double delta = 0.0001;
00068 const double poschange = 1. + delta;
00069 const double negchange = 1. - delta;
00070 double denominator;
00071 CurrentRMS = 0;
00072
00073
00074 CurrentRMS = MisfitCalculator->CalcPerformance(CurrentModel);
00075 CurrentMisfit = MisfitCalculator->GetMisfit();
00076 CurrentData = MisfitCalculator->GetSynthData();
00077
00078 posmodel = CurrentModel;
00079 negmodel = CurrentModel;
00080
00081 for (i = 0; i < nparams; ++i)
00082 {
00083 if (i > 0)
00084 {
00085 posmodel(i-1) = CurrentModel(i-1);
00086 negmodel(i-1) = CurrentModel(i-1);
00087 }
00088 posmodel(i) = CurrentModel(i) * poschange;
00089 negmodel(i) = CurrentModel(i) * negchange;
00090 MisfitCalculator->CalcPerformance(posmodel);
00091 posdata = MisfitCalculator->GetSynthData();
00092 MisfitCalculator->CalcPerformance(negmodel);
00093 negdata = MisfitCalculator->GetSynthData();
00094
00095
00096 denominator = 1./(2.* delta * CurrentModel(i));
00097 for (j = 0; j < ndata; ++j)
00098 {
00099 PartialDerivs(j,i) = (posdata(j) - negdata(j))*denominator;
00100 }
00101 }
00102
00103
00104 }