20#ifndef _GIMLI_INVERSION__H
21#define _GIMLI_INVERSION__H
24#include "inversionBase.h"
26#include "modellingbase.h"
27#include "numericbase.h"
28#include "regionManager.h"
31#include "sparsematrix.h"
38#define DOSAVE if (dosave_)
41#define PLUS_TMP_VECSUFFIX
44template <
class Vec > Vec
getIRLSWeights(
const Vec & a,
double locut = 0.0,
double hicut = 0.0) {
45 double suabs = sum(abs(a));
46 double suabsq = dot(a, a);
48 Vec tmp(suabsq / suabs / (abs(a) + TOLERANCE));
49 for(uint i = 0; i < a.size(); i++) {
50 if((locut > 0.0) && (tmp[ i ] < locut)) tmp[ i ] = locut;
51 if((hicut > 0.0) && (tmp[ i ] > hicut)) tmp[ i ] = hicut;
57template <
class Vec > Vec
getIRLSWeightsP(
const Vec & a,
int p,
double locut = 0.0,
double hicut = 0.0) {
58 Vec ap = pow(abs(a), p);
59 Vec aq = pow(abs(a), 2);
60 double suabsp = sum(ap);
61 double suabsq = sum(aq);
63 Vec tmp((ap + 1e-12) / (aq + 1e-12) * suabsp / suabsq);
64 for(uint i = 0; i < a.size(); i++) {
65 if((locut > 0.0) && (tmp[ i ] < locut)) tmp[ i ] = locut;
66 if((hicut > 0.0) && (tmp[ i ] > hicut)) tmp[ i ] = hicut;
78 typedef RVector ModelVector;
83 dosave_(dosave), saveModelHistory_(dosave){
89 bool verbose=
false,
bool dosave=
false)
91 dosave_(dosave), saveModelHistory_(dosave) {
100 bool verbose=
false,
bool dosave=
false)
102 dosave_(dosave), saveModelHistory_(dosave) {
114 Trans< Vec > & transData,
bool verbose=
true,
bool dosave=
false)
116 dosave_(dosave), saveModelHistory_(dosave) {
131 bool verbose =
true,
bool dosave =
false)
132 :
InversionBase< double >(), verbose_(verbose), dosave_(dosave), saveModelHistory_(dosave) {
147 delete transDataDefault_;
148 delete transModelDefault_;
163 tD_ = transDataDefault_;
164 tM_ = transModelDefault_;
167 useLinesearch_ =
true;
168 optimizeLambda_ =
false;
169 recalcJacobian_ =
true;
170 jacobiNeedRecalc_ =
true;
171 doBroydenUpdate_ =
false;
172 localRegularization_=
false;
175 haveReferenceModel_ =
false;
178 activateFillConstraintWeights_ =
true;
186 dPhiAbortPercent_ = 2.0;
197 inline const Vec &
data()
const {
return data_; }
222 inline void setError(
const Vec & err,
bool isRelative=
true) {
224 this->setRelativeError(err);
226 this->setAbsoluteError(err);
229 inline void setError(
double err,
bool isRelative=
true) {
231 this->setRelativeError(err);
233 this->setAbsoluteError(err);
237 inline const Vec &
error()
const {
return error_; }
242 if (error_.size() != data_.size()) {
243 std::cerr << WHERE_AM_I <<
" Warning error has the wrong size, reset to default. "
244 << error_.size() <<
" != " << data_.size() << std::endl;
246 }
else if (min(abs(error_)) < TOLERANCE &&
fixError_) {
247 std::cerr << WHERE_AM_I <<
" Warning error contains zero values, reset to default. " << std::endl;
251 dataWeight_ = 1.0 / tD_->error(fixZero(data_, TOLERANCE), error_);
253 if (verbose_) std::cout <<
"min/max(dweight) = " << min(dataWeight_) <<
"/"
254 << max(dataWeight_) << std::endl;
256 if (haveInfNaN(dataWeight_)){
257 DOSAVE save(dataWeight_,
"Nan_dataWeight_dweight");
258 DOSAVE save(error_,
"Nan_dataWeight_error");
259 DOSAVE save(data_,
"Nan_dataWeight_data");
261 throwError(WHERE_AM_I +
" dataWeight_ contains inf or nan");
270 forward_ = & forward;
271 forward_->clearConstraints();
273 forward_->initRegionManager();
305 inline bool verbose()
const {
return verbose_; }
309 inline bool doSave()
const {
return dosave_; }
313 saveModelHistory_ = doSaveModelHistory; }
317 inline bool lineSearch()
const {
return useLinesearch_; }
321 inline bool blockyModel()
const {
return isBlocky_; }
325 inline bool robustData()
const {
return isRobust_; }
328 inline void setLambda(
double lambda) { lambda_ = lambda; }
329 inline double lambda()
const {
return lambda_; }
330 inline double getLambda()
const {
return lambda_; }
331 inline void setLambdaFactor(
double lambdaFactor) { lambdaFactor_ = lambdaFactor; }
332 inline double lambdaFactor()
const {
return lambdaFactor_; }
342 localRegularization_ = localReg; }
348 inline bool optimizeLambda()
const {
return optimizeLambda_; }
352 inline int maxIter()
const {
return maxiter_; }
356 inline int maxCGLSIter()
const {
return maxCGLSIter_; }
360 inline double maxCGLSTolerance()
const {
return CGLStol_; }
363 inline uint
iter()
const {
return iter_; }
369 inline void abort() { abort_ =
true; }
376 inline double deltaPhiAbortPercent()
const {
return dPhiAbortPercent_; }
381 setLambdaFactor(lambdaFactor);
383 if (forward_) forward_->regionManager().setConstraintType(0);
388 if (forward_->regionManager().haveLocalTrans()) {
389 if (verbose_) std::cout <<
"use model trans from RegionManager" << std::endl;
397 recalcJacobian_ = recalc;
398 if (recalc) doBroydenUpdate_ =
false;
400 bool recalcJacobian()
const {
return recalcJacobian_; }
404 doBroydenUpdate_ = broydenUpdate;
405 if (doBroydenUpdate_) recalcJacobian_ =
false;
412 inline bool broydenUpdate()
const {
return doBroydenUpdate_; }
418 if (recalcJacobian_ &&
model != model_) jacobiNeedRecalc_ =
true;
423 inline const ModelVector &
model()
const {
return model_; }
427 haveReferenceModel_ =
true; modelRef_ =
model;
435 __MS(
"who use this. Please note any setting of this will be overwritten in run.")
436 constraintsH_ = constraintsH;
440 inline const Vec &
response()
const {
return response_; }
444 return getIRLSWeights(Vec(*forward_->constraints() * tM_->trans(model_) * constraintWeights_), 0.0, 1.0);
450 activateFillConstraintWeights_ =
false;
451 if (verbose_) std::cout <<
"min/max(cWeight) = " << min(constraintWeights_) <<
"/" << max(constraintWeights_) << std::endl;
455 inline const Vec &
cWeight()
const {
return constraintWeights_; }
459 modelWeight_ = mweight;
460 if (verbose_) std::cout <<
"min/max(mWeight) = " << min(modelWeight_) <<
"/" << max(modelWeight_) << std::endl;
464 inline const Vec &
mWeight()
const {
return modelWeight_; }
468 if (verbose_) std::cout <<
"Robust reweighting " << std::endl;
469 Vec deltaData((tD_->trans(data_) - tD_->trans(response_)) * dataWeight_);
482 if (verbose_) std::cout <<
"Blocky model constraints " << std::endl;
487 void checkConstraints();
490 void checkJacobian(
bool force=
false);
498 std::cout << iter_ <<
": " << xtra
499 <<
"Model: min = " << min(
model) <<
"; max = " << max(
model) << std::endl;
500 std::cout << iter_ <<
": " << xtra
501 <<
"Response: min = " << min(
response) <<
"; max = " << max(
response) << std::endl;
502 std::cout << iter_ <<
": rms/rrms(data, " << xtra <<
"Response) = "
504 << rrms(data_,
response) * 100.0 <<
"%" << std::endl;
505 std::cout << iter_ <<
": chi^2(data, " << xtra
506 <<
"Response, error, log) = " <<
chi2 << std::endl;
513 Vec resolution(model_.size(), 0.0);
514 resolution[ iModel ] = 1.0;
516 Vec sensCol = (*forward_->jacobian()) * resolution * tD_->deriv(response_) / tM_->deriv(model_)[ iModel ];
518 Vec deltaModel0(model_.size());
520 solveCGLSCDWWtrans(*forward_->jacobian(), *forward_->constraints(),
521 dataWeight_, sensCol, resolution,
522 constraintWeights_, modelWeight_,
523 tM_->deriv(model_), tD_->deriv(response_),
524 lambda_, deltaModel0, maxCGLSIter_,
false);
532 double mindist = 9e99;
533 R3Vector cellCenters = forward_->mesh()->cellCenter();
535 for (Index i = 0 ; i < model_.size() ; i++){
536 double dist = cellCenters[i].distance(pos);
537 if (dist < mindist) {
555 RVector r(*forward_->constraints()
556 * Vec(tM_->trans(
model) * modelWeight_)
557 * constraintWeights_);
559 if (haveReferenceModel_) {
560 r = r - constraintsH_;
570 return *forward_->constraints() * Vec(tM_->trans(
model));
574 double getPhiD(
const Vec & response)
const;
577 double getPhiM(
const Vec & model)
const;
595 inline double getPhi()
const {
return getPhiD() +
getPhiM() * lambda_ * (1.0 - double(localRegularization_)); }
609 inline double absrms()
const {
return rms(data_, response_); }
612 inline double relrms()
const {
return rrms(data_, response_) * 100.; }
615 double linesearch(
const Vec & modelNew,
const Vec & responseNew)
const {
616 Vec phiVector(101,
getPhi());
617 Vec phiDVector(101 ,
getPhiD());
619 Vec dModel(tM_->trans(modelNew) - tM_->trans(model_));
620 Vec dData( tD_->trans(responseNew) - tD_->trans(response_));
622 double tau = 0.0, minTau = 0.0;
623 double minPhi = phiVector[ 0 ];
625 if (localRegularization_) minPhi = phiDVector[ 0 ];
627 double thisPhi = minPhi;
628 for (
int i = 1; i < 101; i++) {
629 tau = 0.01 * (double) i;
630 Vec appModel (tM_->update(model_, dModel * tau));
631 Vec appResponse (tD_->update(response_, dData * tau));
632 phiVector[ i ] =
getPhi(appModel, appResponse);
633 phiDVector[ i ] =
getPhiD(appResponse);
634 thisPhi = phiVector[ i ];
636 if (localRegularization_) thisPhi = phiDVector[ i ];
637 if (thisPhi < minPhi){
642 DOSAVE save(phiVector,
"linesearchPhi");
643 DOSAVE save(phiDVector,
"linesearchPhiD");
649 double tauquad = 0.3;
650 if (verbose_) std::cout <<
"tau = " << tau
651 <<
". Trying parabolic line search with step length " << tauquad;
652 RVector modelQuad(tM_->update(model_, dModel * tauquad));
653 RVector responseQuad (forward_->response(modelQuad));
654 tau =
linesearchQuad(modelNew, responseNew, modelQuad, responseQuad, tauquad);
655 if (verbose_) std::cout <<
" ==> tau = " << tau;
658 if (verbose_) std::cout <<
" resetting to " << tau;
660 if (verbose_) std::cout << std::endl;
664 if (verbose_) std::cout <<
" tau < 0.03 ==> tau = " << tau << std::endl;
669 if (verbose_)
echoStatus(responseNew, modelNew,
"LS new");
672 if (verbose_) std::cout <<
"Performing line search with tau = " << tau << std::endl;
679 const Vec & modelQuad,
const Vec & responseQuad,
680 double tauquad)
const {
682 double phi10 =
getPhi(modelNew, responseNew) - phi0;
683 double phit0 =
getPhi(modelQuad, responseQuad) - phi0;
684 double dphit = phit0 - phi10 * tauquad;
685 if (abs(dphit) < TOLERANCE)
return 0.0;
686 double tauopt = (phit0 - phi10 * tauquad * tauquad) / dphit / 2.0;
688 DOSAVE std::cout <<
"LineSearchQuad: Phi = " << phi0 <<
" - " << phit0 + phi0
689 <<
" - " << phi10 + phi0 <<
" -> tau= " << tauopt << std::endl;
700 Vec deltaModel0(model_.size());
701 Vec solution(model_.size());
702 solveCGLSCDWWtrans(*forward_->jacobian(), *forward_->constraints(),
703 dataWeight_, rhs, solution, constraintWeights_,
705 tM_->deriv(model_), tD_->deriv(response_),
706 lambda_, deltaModel0, maxCGLSIter_, dosave_);
711 Vec optLambda(
const Vec & deltaData,
const Vec & deltaModel0);
717 const Vec & invert(
const Vec & data);
726 Vec
runChi1(
double acc = 0.01,
int maxiter = 50){
730 double lambda = lambda_;
732 double fak = 2.0, oldchi2 =
chi2;
733 double dir = 0, olddir = 0;
734 bool verbose = verbose_;
736 forward_->setVerbose(
false);
737 if (verbose) std::cout <<
"Optimizing lambda subject to chi^2=1." << std::endl;
738 if (verbose) std::cout <<
"chi^2 = " <<
chi2 <<
" lambda = " << lambda <<
" dir = " << dir << std::endl;
740 while (std::fabs(
chi2 - 1.0) > acc and
iter < maxiter){
741 if (dir < 0 && chi2 > oldchi2*1.001)
break;
742 dir = - sign(
chi2 - 1.0);
743 if (dir * olddir == -1) fak = std::pow(fak, 0.6);
744 lambda *= std::pow(fak, dir);
748 if(verbose) std::cout <<
"chi^2 = " <<
chi2 <<
" lambda = " << lambda <<
" dir = " << dir << std::endl;
756 const RVector & modelWeight()
const {
return modelWeight_; }
757 const RVector & modelRef()
const {
return modelRef_; }
758 const RVector & dataWeight()
const {
return dataWeight_; }
760 const RVector & deltaDataIter()
const {
return deltaDataIter_; }
761 const RVector & deltaModelIter()
const {
return deltaModelIter_; }
765 this->
setModel(forward_->startModel());
780 bool saveModelHistory_;
789 Vec constraintWeights_;
801 double lambdaFactor_;
803 double dPhiAbortPercent_;
810 bool optimizeLambda_;
813 bool doBroydenUpdate_;
814 bool localRegularization_;
815 bool haveReferenceModel_;
816 bool recalcJacobian_;
817 bool jacobiNeedRecalc_;
818 bool activateFillConstraintWeights_;
InversionBase()
Definition inversionBase.h:35
void push_back(const Vector< ValueType > &vec)
Definition matrix.h:483
Definition modellingbase.h:31
Definition inversion.h:75
double getPhi(const Vec &model, const Vec &response) const
Definition inversion.h:581
void setBlockyModel(bool isBlocky)
Definition inversion.h:320
double linesearchQuad(const Vec &modelNew, const Vec &responseNew, const Vec &modelQuad, const Vec &responseQuad, double tauquad) const
Definition inversion.h:678
RVector roughness(const RVector &model) const
Definition inversion.h:554
ModellingBase * fop()
Definition inversion.h:279
void setLineSearch(bool linesearch)
Definition inversion.h:316
uint iter() const
Definition inversion.h:363
void setForwardOperator(ModellingBase &forward)
Definition inversion.h:269
void echoStatus(const Vec &response, const Vec &model, const std::string &xtra="") const
Definition inversion.h:496
void setLambda(double lambda)
Definition inversion.h:328
bool isRunning() const
Definition inversion.h:366
double absrms() const
Definition inversion.h:609
void checkTransFunctions()
Definition inversion.h:387
void checkError()
Definition inversion.h:241
double lambdaMinimum() const
Definition inversion.h:338
void stopAtChi1(bool stopAtChi1)
Definition inversion.h:372
RVector roughness() const
Definition inversion.h:565
virtual ~RInversion()
Definition inversion.h:146
void setMarquardtScheme(double lambdaFactor=0.8)
Definition inversion.h:379
void setData(const Vec &data)
Definition inversion.h:194
const Vec & data() const
Definition inversion.h:197
void setVerbose(bool verbose)
Definition inversion.h:304
const Vec & cWeight() const
Definition inversion.h:455
RInversion(const Vec &data, ModellingBase &forward, Trans< Vec > &transData, bool verbose=true, bool dosave=false)
Definition inversion.h:113
void setAbsoluteError(double abserr)
Definition inversion.h:218
double getPhi() const
Definition inversion.h:595
double chi2() const
Definition inversion.h:606
void setModel(const Vec &model)
Definition inversion.h:417
RVector pureRoughness(const RVector &model) const
Definition inversion.h:569
void setRobustData(bool isRobust)
Definition inversion.h:324
const Vec & error() const
Definition inversion.h:237
RInversion(ModellingBase &forward, bool verbose=false, bool dosave=false)
Definition inversion.h:88
const Vec & run()
Definition inversion.cpp:133
void saveModelHistory(bool doSaveModelHistory)
Definition inversion.h:312
void setResponse(const Vec &response)
Definition inversion.h:431
bool fixError_
Definition inversion.h:821
void setMWeight(const Vec &mweight)
Definition inversion.h:458
void setReferenceModel(const Vec &model)
Definition inversion.h:426
Vec modelCellResolution(const RVector3 &pos)
Definition inversion.h:530
void setMaxCGLSIter(int iter)
Definition inversion.h:355
void setCGLSTolerance(double tol)
Definition inversion.h:359
double relrms() const
Definition inversion.h:612
bool localRegularization() const
Definition inversion.h:344
double getPhiM() const
Definition inversion.h:591
Vec invSubStep(const Vec &rhs)
Definition inversion.h:699
RInversion(const Vec &data, ModellingBase &forward, Trans< Vec > &transData, Trans< Vec > &transModel, bool verbose=true, bool dosave=false)
Definition inversion.h:129
double getPhiD(const Vec &response) const
Definition inversion.cpp:84
void setOptimizeLambda(bool opt)
Definition inversion.h:347
double getPhiD() const
Definition inversion.h:587
void constrainBlocky()
Definition inversion.h:481
double linesearch(const Vec &modelNew, const Vec &responseNew) const
Definition inversion.h:615
void setLocalRegularization(bool localReg)
Definition inversion.h:341
void setConstraintsH(const Vec &constraintsH)
Definition inversion.h:434
void setLambdaMinimum(double l)
Definition inversion.h:336
void setTransData(Trans< Vec > &tD)
Definition inversion.h:286
Vec errorDefault_()
Definition inversion.h:266
void setMaxIter(int maxiter)
Definition inversion.h:351
const Vec & mWeight() const
Definition inversion.h:464
void setAbsoluteError(const Vec &abserr)
Definition inversion.h:213
void setBroydenUpdate(bool broydenUpdate)
Definition inversion.h:403
void setRecalcJacobian(bool recalc)
Definition inversion.h:396
RMatrix modelResolutionMatrix()
Definition inversion.h:547
void reset()
Definition inversion.h:764
void setRelativeError(const Vec &e)
Definition inversion.h:200
void setDoSave(bool d)
Definition inversion.h:308
void init_()
Definition inversion.h:160
std::vector< RVector > modelHist_
Definition inversion.h:824
const std::vector< RVector > & modelHistory() const
Definition inversion.h:694
RInversion(const Vec &data, ModellingBase &forward, bool verbose=false, bool dosave=false)
Definition inversion.h:99
const ModelVector & model() const
Definition inversion.h:423
double getPhiM(const Vec &model) const
Definition inversion.cpp:100
double getChi2(const Vec &response) const
Definition inversion.h:603
void setDeltaPhiAbortPercent(double dPhi)
Definition inversion.h:375
void abort()
Definition inversion.h:369
double getChi2() const
Definition inversion.h:599
Vec modelCellResolution(int iModel)
Definition inversion.h:512
void setCWeight(const Vec &cWeight)
Definition inversion.h:448
RInversion(bool verbose=false, bool dosave=false)
Definition inversion.h:81
Vec getIRLS() const
Definition inversion.h:443
void setRelativeError(double relerr)
Definition inversion.h:207
void setTransModel(Trans< Vec > &tM)
Definition inversion.h:294
uint dataCount() const
Definition inversion.h:301
Vec runChi1(double acc=0.01, int maxiter=50)
Definition inversion.h:726
ModellingBase * forwardOperator()
Definition inversion.h:277
const Vec & response() const
Definition inversion.h:440
void robustWeighting()
Definition inversion.h:467
uint constraintsCount() const
Definition inversion.h:298
void echoStatus() const
Definition inversion.h:493
GIMLi main namespace for the Geophyiscal Inversion and Modelling Library.
Definition baseentity.h:24
Matrix3< ValueType > inv(const Matrix3< ValueType > &A)
Definition matrix.h:1051
Vec getIRLSWeights(const Vec &a, double locut=0.0, double hicut=0.0)
Definition inversion.h:44
Vec getIRLSWeightsP(const Vec &a, int p, double locut=0.0, double hicut=0.0)
Definition inversion.h:57