Geophysical Inversion and Modelling Library v1.5.4
Loading...
Searching...
No Matches
inversion.h
1/******************************************************************************
2 * Copyright (C) 2006-2024 by the GIMLi development team *
3 * Carsten Rücker carsten@resistivity.net *
4 * Thomas Günther thomas@resistivity.net *
5 * *
6 * Licensed under the Apache License, Version 2.0 (the "License"); *
7 * you may not use this file except in compliance with the License. *
8 * You may obtain a copy of the License at *
9 * *
10 * http://www.apache.org/licenses/LICENSE-2.0 *
11 * *
12 * Unless required by applicable law or agreed to in writing, software *
13 * distributed under the License is distributed on an "AS IS" BASIS, *
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
15 * See the License for the specific language governing permissions and *
16 * limitations under the License. *
17 * *
18 ******************************************************************************/
19
20#ifndef _GIMLI_INVERSION__H
21#define _GIMLI_INVERSION__H
22
23// #include "vector.h"
24#include "inversionBase.h"
25#include "mesh.h"
26#include "modellingbase.h"
27#include "numericbase.h"
28#include "regionManager.h"
29#include "solver.h"
30#include "stopwatch.h"
31#include "sparsematrix.h"
32#include "trans.h"
33#include "vector.h"
34
35
36namespace GIMLI{
37
38#define DOSAVE if (dosave_)
39
40//#define PLUS_TMP_VECSUFFIX + ".vec"
41#define PLUS_TMP_VECSUFFIX
42
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);
47
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;
52 }
53 return tmp;
54}
55
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);
62
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;
67 }
68 return tmp;
69}
70
75class DLLEXPORT RInversion : public InversionBase< double > {
76public:
77 typedef RVector Vec;
78 typedef RVector ModelVector;
79
81 RInversion(bool verbose=false, bool dosave=false)
82 : InversionBase< double >(), verbose_(verbose),
83 dosave_(dosave), saveModelHistory_(dosave){
84 this->init_();
85 }
86
89 bool verbose=false, bool dosave=false)
90 : InversionBase< double >(), verbose_(verbose),
91 dosave_(dosave), saveModelHistory_(dosave) {
92 this->init_();
93
94 //** init: model_, modelRef, response_
95 this->setForwardOperator(forward);
96 }
97
99 RInversion(const Vec & data, ModellingBase & forward,
100 bool verbose=false, bool dosave=false)
101 : InversionBase< double >(), verbose_(verbose),
102 dosave_(dosave), saveModelHistory_(dosave) {
103 this->init_();
104
105 //** init: data_
106 this->setData(data);
107
108 //** init: model_, modelRef, response_
109 this->setForwardOperator(forward);
110 }
111
113 RInversion(const Vec & data, ModellingBase & forward,
114 Trans< Vec > & transData, bool verbose=true, bool dosave=false)
115 : InversionBase< double >(), verbose_(verbose),
116 dosave_(dosave), saveModelHistory_(dosave) {
117 //** set: default values
118 this->init_();
119 //** set: paraDomain init: modelWeight_, constraintWeights_, ConstraintMatrix
120 //** init: data_
121 this->setData(data);
122 //** init: model_, modelRef, response_
123 this->setForwardOperator(forward);
124
125 this->setTransData(transData);
126 }
127
129 RInversion(const Vec & data, ModellingBase & forward,
130 Trans< Vec > & transData, Trans< Vec > & transModel,
131 bool verbose = true, bool dosave = false)
132 : InversionBase< double >(), verbose_(verbose), dosave_(dosave), saveModelHistory_(dosave) {
133 //** set: default values
134 this->init_();
135 //** set: paraDomain init: modelWeight_, constraintWeights_, ConstraintMatrix
136 //** init: data_
137 this->setData(data);
138 //** init: model_, modelRef, response_
139 this->setForwardOperator(forward);
140
141 this->setTransData(transData);
142 this->setTransModel(transModel);
143 }
144
146 virtual ~RInversion(){
147 delete transDataDefault_;
148 delete transModelDefault_;
149 }
150
151private:
153 RInversion(const RInversion & inv){
154 THROW_TO_IMPL
155 }
156
157
158protected:
160 void init_(){
161 transDataDefault_ = new Trans< Vec >;
162 transModelDefault_ = new Trans< Vec >;
163 tD_ = transDataDefault_;
164 tM_ = transModelDefault_;
165 isRobust_ = false;
166 isBlocky_ = false;
167 useLinesearch_ = true;
168 optimizeLambda_ = false;
169 recalcJacobian_ = true;
170 jacobiNeedRecalc_ = true;
171 doBroydenUpdate_ = false;
172 localRegularization_= false;
173 abort_ = false;
174 stopAtChi1_ = true;
175 haveReferenceModel_ = false;
176 isRunning_ = false;
177 fixError_ = true;
178 activateFillConstraintWeights_ = true; //jointinv hack!!!
179
180 iter_ = 0;
181 maxiter_ = 20;
182 maxCGLSIter_ = 200;
183 lambda_ = 50.0;
184 lambdaFactor_ = 1.0;
185 lambdaMin_ = 1.0;
186 dPhiAbortPercent_ = 2.0;
187
188 CGLStol_ = -1.0; //** -1 means automatic scaled
189 }
190
191public:
192
194 inline void setData(const Vec & data) { data_ = data; }
195
197 inline const Vec & data() const { return data_; }
198
200 void setRelativeError(const Vec & e){
201 error_ = e;
202 checkError();
203 }
204
207 inline void setRelativeError(double relerr) {
208 if (relerr == 0.0) fixError_ = false;
209 setRelativeError(RVector(data_.size(), relerr));
210 }
211
213 inline void setAbsoluteError(const Vec & abserr) {
214 setRelativeError(abs(abserr) / abs(fixZero(data_, TOLERANCE)));
215 }
216
218 inline void setAbsoluteError(double abserr) {
219 setRelativeError(std::fabs(abserr) / abs(fixZero(data_, TOLERANCE)));
220 }
221
222 inline void setError(const Vec & err, bool isRelative=true) {
223 if (isRelative){
224 this->setRelativeError(err);
225 } else {
226 this->setAbsoluteError(err);
227 }
228 }
229 inline void setError(double err, bool isRelative=true) {
230 if (isRelative){
231 this->setRelativeError(err);
232 } else {
233 this->setAbsoluteError(err);
234 }
235 }
237 inline const Vec & error() const { return error_; }
238
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;
245 error_ = errorDefault_();
246 } else if (min(abs(error_)) < TOLERANCE && fixError_) {
247 std::cerr << WHERE_AM_I << " Warning error contains zero values, reset to default. " << std::endl;
248 error_ = errorDefault_();
249 }
250
251 dataWeight_ = 1.0 / tD_->error(fixZero(data_, TOLERANCE), error_);
252
253 if (verbose_) std::cout << "min/max(dweight) = " << min(dataWeight_) << "/"
254 << max(dataWeight_) << std::endl;
255
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");
260
261 throwError(WHERE_AM_I + " dataWeight_ contains inf or nan");
262 }
263 }
264
266 inline Vec errorDefault_(){ return Vec(data_.size(), 0.01); }
267
269 inline void setForwardOperator(ModellingBase & forward) {
270 forward_ = & forward;
271 forward_->clearConstraints();
273 forward_->initRegionManager();
274// model_ = forward_->startModel();
275 }
276
277 inline ModellingBase * forwardOperator() { return forward_; }
279 inline ModellingBase * fop() { return this->forwardOperator(); }
280
281 /*TODO Change interface to Trans < vec > *tD, or copy the trans ,giving non const reference is dangerous.*/
286 inline void setTransData(Trans< Vec > & tD) { tD_ = & tD; }
287 inline Trans< Vec > & transData() { return * tD_; }
288
289 /*TODO Change interface to Trans < vec > *tD, or copy the trans ,giving non const reference is dangerous. */
294 inline void setTransModel(Trans< Vec > & tM) { tM_ = & tM; }
295 inline Trans< Vec > & transModel() { return * tM_; }
296
298 inline uint constraintsCount() const { return constraintWeights_.size(); }
299
301 inline uint dataCount() const { return data_.size(); }
302
304 inline void setVerbose(bool verbose){ verbose_ = verbose; }
305 inline bool verbose() const { return verbose_; }
306
308 inline void setDoSave(bool d ){ dosave_ = d; }
309 inline bool doSave() const { return dosave_; }
310
312 inline void saveModelHistory(bool doSaveModelHistory){
313 saveModelHistory_ = doSaveModelHistory; }
314
316 inline void setLineSearch(bool linesearch) { useLinesearch_ = linesearch; }
317 inline bool lineSearch() const { return useLinesearch_; }
318
320 inline void setBlockyModel(bool isBlocky) { isBlocky_ = isBlocky; }
321 inline bool blockyModel() const { return isBlocky_; }
322
324 inline void setRobustData(bool isRobust) { isRobust_ = isRobust; }
325 inline bool robustData() const { return isRobust_; }
326
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_; }
333
336 inline void setLambdaMinimum(double l) { lambdaMin_ = l; }
338 inline double lambdaMinimum() const { return lambdaMin_; }
339
341 void setLocalRegularization(bool localReg){
342 localRegularization_ = localReg; }
343
344 bool localRegularization() const { return localRegularization_; }
345
347 inline void setOptimizeLambda(bool opt) { optimizeLambda_ = opt; }
348 inline bool optimizeLambda() const { return optimizeLambda_; }
349
351 inline void setMaxIter(int maxiter) { maxiter_ = maxiter; }
352 inline int maxIter() const { return maxiter_; }
353
355 inline void setMaxCGLSIter(int iter){ maxCGLSIter_ = iter; }
356 inline int maxCGLSIter() const { return maxCGLSIter_; }
357
359 inline void setCGLSTolerance(double tol){ CGLStol_ = tol; }
360 inline double maxCGLSTolerance() const { return CGLStol_; }
361
363 inline uint iter() const { return iter_; }
364
366 inline bool isRunning() const { return isRunning_ ; }
367
369 inline void abort() { abort_ = true; }
370
372 inline void stopAtChi1(bool stopAtChi1) { stopAtChi1_ = stopAtChi1; }
373
375 inline void setDeltaPhiAbortPercent(double dPhi){ dPhiAbortPercent_ = dPhi; }
376 inline double deltaPhiAbortPercent() const { return dPhiAbortPercent_; }
377
379 void setMarquardtScheme(double lambdaFactor=0.8){
381 setLambdaFactor(lambdaFactor);
382 stopAtChi1(false);
383 if (forward_) forward_->regionManager().setConstraintType(0);
384 }
385
388 if (forward_->regionManager().haveLocalTrans()) {
389 if (verbose_) std::cout << "use model trans from RegionManager" << std::endl;
390 setTransModel(*forward_->regionManager().transModel());
391 }
392 }
393
394
396 void setRecalcJacobian(bool recalc){
397 recalcJacobian_ = recalc;
398 if (recalc) doBroydenUpdate_ = false;
399 }
400 bool recalcJacobian() const { return recalcJacobian_; }
401
403 void setBroydenUpdate(bool broydenUpdate){
404 doBroydenUpdate_ = broydenUpdate;
405 if (doBroydenUpdate_) recalcJacobian_ = false;
406 //** puts transformation functions into jacobian since it is not changed anymore;
407 if (broydenUpdate) {
408 THROW_TO_IMPL
409 //scaleMatrix(*J_, tD_->deriv(response_), Vec(1.0 / tM_->deriv(model_)));
410 }
411 }
412 inline bool broydenUpdate() const { return doBroydenUpdate_; }
413
417 void setModel(const Vec & model){
418 if (recalcJacobian_ && model != model_) jacobiNeedRecalc_ = true;
419 model_ = model;
420 }
421
423 inline const ModelVector & model() const { return model_; }
424
426 inline void setReferenceModel(const Vec & model){
427 haveReferenceModel_ = true; modelRef_ = model;
428 }
429
431 inline void setResponse(const Vec & response){ response_ = response; }
432
434 inline void setConstraintsH(const Vec & constraintsH){
435 __MS("who use this. Please note any setting of this will be overwritten in run.")
436 constraintsH_ = constraintsH;
437 } // size check?
438
440 inline const Vec & response() const { return response_; }
441
443 Vec getIRLS() const {
444 return getIRLSWeights(Vec(*forward_->constraints() * tM_->trans(model_) * constraintWeights_), 0.0, 1.0);
445 }
446
448 void setCWeight(const Vec & cWeight){
449 constraintWeights_ = cWeight;
450 activateFillConstraintWeights_ = false; //jointinv hack!!!
451 if (verbose_) std::cout << "min/max(cWeight) = " << min(constraintWeights_) << "/" << max(constraintWeights_) << std::endl;
452 }
453
455 inline const Vec & cWeight() const { return constraintWeights_; }
456
458 void setMWeight(const Vec & mweight){
459 modelWeight_ = mweight;
460 if (verbose_) std::cout << "min/max(mWeight) = " << min(modelWeight_) << "/" << max(modelWeight_) << std::endl;
461 }
462
464 inline const Vec & mWeight() const { return modelWeight_; }
465
468 if (verbose_) std::cout << "Robust reweighting " << std::endl;
469 Vec deltaData((tD_->trans(data_) - tD_->trans(response_)) * dataWeight_);
470 //** reweight errors according to IRLS scheme
471 // cr: error wird nur noch von getPhiD genutzt und dataweight wird im Laufe der Inversion nicht mehr aktualisiert, soll das so sein? DRY?
472 // tg: checkerror ist doch genau das richtige oder?
473 error_ /= (getIRLSWeights(deltaData, 0.0, 1.0) + TOLERANCE);
474 checkError(); //** macht implizit:
475 // dataWeight_ = (1.0 / tD_->error(data_, error_));
476 // tg: maybe better just reweight dweight and hold error constant
477 // tg: geht nicht weil phiD auf Fehlern beruht (und das auch muss wegen Trafowechsel)
478 }
479
482 if (verbose_) std::cout << "Blocky model constraints " << std::endl;
483 setCWeight(getIRLSWeights(Vec((*forward_->constraints() * tM_->trans(model_)) * constraintWeights_), 0.0, 1.0));
484 }
485
487 void checkConstraints();
488
490 void checkJacobian(bool force=false);
491
493 inline void echoStatus() const { echoStatus(response_, model_); }
494
496 void echoStatus(const Vec & response, const Vec & model, const std::string & xtra = "") const {
497 double chi2 = getPhiD(response) / data_.size();
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) = "
503 << rms(data_, response) << "/"
504 << rrms(data_, response) * 100.0 << "%" << std::endl;
505 std::cout << iter_ << ": chi^2(data, " << xtra
506 << "Response, error, log) = " << chi2 << std::endl;
507 std::cout << iter_ << ": Phi = " << getPhiD(response) << "+" << getPhiM(model)
508 << "*" << lambda_ << "=" << getPhi(model, response) << std::endl;
509 }
510
512 Vec modelCellResolution(int iModel) {
513 Vec resolution(model_.size(), 0.0);
514 resolution[ iModel ] = 1.0; //** both for retrieving solumn and as starting model for resolution
515 //** retrieve one colomn from the jacobian matrix and scale according to data/model transformation
516 Vec sensCol = (*forward_->jacobian()) * resolution * tD_->deriv(response_) / tM_->deriv(model_)[ iModel ];
517 //** call inverse substep with sensCol on right hand side (see Gnther, 2004)
518 Vec deltaModel0(model_.size());// !!! h zvariante
519
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);
525
526 return resolution;
527 }
528
530 Vec modelCellResolution(const RVector3 & pos){
531 Index ipos = 0;
532 double mindist = 9e99;
533 R3Vector cellCenters = forward_->mesh()->cellCenter();
534
535 for (Index i = 0 ; i < model_.size() ; i++){
536 double dist = cellCenters[i].distance(pos);
537 if (dist < mindist) {
538 mindist = dist;
539 ipos = i;
540 }
541 }
542 // Achtung Parametermapping und Backgroundzellen!
543 return modelCellResolution(ipos);
544 }
545
548 RMatrix resMat;
549 for (size_t i = 0 ; i < model_.size(); i++) resMat.push_back(modelCellResolution(i));
550 return resMat;
551 }
552
554 RVector roughness(const RVector & model) const {
555 RVector r(*forward_->constraints()
556 * Vec(tM_->trans(model) * modelWeight_)
557 * constraintWeights_);
558
559 if (haveReferenceModel_) {
560 r = r - constraintsH_;
561 }
562 return r;
563 }
564
565 RVector roughness() const {
566 return roughness(model_);
567 }
568
569 RVector pureRoughness(const RVector & model) const {
570 return *forward_->constraints() * Vec(tM_->trans(model));
571 }
572
574 double getPhiD(const Vec & response) const;
575
577 double getPhiM(const Vec & model) const;
578
581 double getPhi(const Vec & model, const Vec & response) const {
582 return getPhiD(response) + getPhiM(model) * lambda_ * (1.0 - double(localRegularization_));
583 }
584
587 inline double getPhiD() const { return getPhiD(response_); }
588
591 inline double getPhiM() const { return getPhiM(model_); }
592
595 inline double getPhi() const { return getPhiD() + getPhiM() * lambda_ * (1.0 - double(localRegularization_)); }
596
599 inline double getChi2() const { return getPhiD() / data_.size(); }
600
603 inline double getChi2(const Vec & response) const { return getPhiD(response) / data_.size(); }
604
606 inline double chi2() const { return getPhiD() / data_.size(); }
607
609 inline double absrms() const { return rms(data_, response_); }
610
612 inline double relrms() const { return rrms(data_, response_) * 100.; }
613
615 double linesearch(const Vec & modelNew, const Vec & responseNew) const {
616 Vec phiVector(101, getPhi());
617 Vec phiDVector(101 , getPhiD());
618
619 Vec dModel(tM_->trans(modelNew) - tM_->trans(model_));
620 Vec dData( tD_->trans(responseNew) - tD_->trans(response_));
621
622 double tau = 0.0, minTau = 0.0;
623 double minPhi = phiVector[ 0 ];
624
625 if (localRegularization_) minPhi = phiDVector[ 0 ];
626
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 ];
635 //** this could also be controlled by another switch (which is enforced by local reg.)
636 if (localRegularization_) thisPhi = phiDVector[ i ];
637 if (thisPhi < minPhi){
638 minPhi = thisPhi;
639 minTau = tau;
640 }
641 }
642 DOSAVE save(phiVector, "linesearchPhi");
643 DOSAVE save(phiDVector, "linesearchPhiD");
644
645 tau = minTau;
646
648 if (tau < 0.03) {
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;
656 if (tau > 1.0) {
657 tau = 1.0;
658 if (verbose_) std::cout << " resetting to " << tau;
659 }
660 if (verbose_) std::cout << std::endl;
661
662 if (tau < 0.03) {
663 tau = 0.03;
664 if (verbose_) std::cout << " tau < 0.03 ==> tau = " << tau << std::endl;
665 }
666 } // else tau > 0.03
667
668 if (tau < 0.95) {
669 if (verbose_) echoStatus(responseNew, modelNew, "LS new");
670 }
671
672 if (verbose_) std::cout << "Performing line search with tau = " << tau << std::endl;
673
674 return tau;
675 }
676
678 double linesearchQuad(const Vec & modelNew, const Vec & responseNew,
679 const Vec & modelQuad, const Vec & responseQuad,
680 double tauquad) const {
681 double phi0 = getPhi();
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;
687
688 DOSAVE std::cout << "LineSearchQuad: Phi = " << phi0 << " - " << phit0 + phi0
689 << " - " << phi10 + phi0 << " -> tau= " << tauopt << std::endl;
690 return tauopt;
691 }
692
694 inline const std::vector < RVector > & modelHistory() const { return modelHist_; }
695
699 Vec invSubStep(const Vec & rhs) {
700 Vec deltaModel0(model_.size());
701 Vec solution(model_.size());
702 solveCGLSCDWWtrans(*forward_->jacobian(), *forward_->constraints(),
703 dataWeight_, rhs, solution, constraintWeights_,
704 modelWeight_,
705 tM_->deriv(model_), tD_->deriv(response_),
706 lambda_, deltaModel0, maxCGLSIter_, dosave_);
707 return solution;
708 }
709
711 Vec optLambda(const Vec & deltaData, const Vec & deltaModel0);
712
714 bool oneStep();
715
717 const Vec & invert(const Vec & data);
718
720 const Vec & start();
721
723 const Vec & run();
724
726 Vec runChi1(double acc = 0.01, int maxiter = 50){
727 stopAtChi1(false);
728 Vec model = run();
729
730 double lambda = lambda_;
731 double chi2 = getChi2();
732 double fak = 2.0, oldchi2 = chi2;
733 double dir = 0, olddir = 0;
734 bool verbose = verbose_;
735// setVerbose(false);
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;
739 int iter = 0;
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); //** direction: up (1) or down (-1)
743 if (dir * olddir == -1) fak = std::pow(fak, 0.6); //** change direction: decrease step
744 lambda *= std::pow(fak, dir); //** increase or decrease lambda
745 setLambda(lambda);
746 model = run();
747 chi2 = getChi2();
748 if(verbose) std::cout << "chi^2 = " << chi2 << " lambda = " << lambda << " dir = " << dir << std::endl;
749 olddir = dir; //** save old direction for step length
750 oldchi2 = chi2;
751 iter++;
752 }
753 return model;
754 }
755
756 const RVector & modelWeight() const { return modelWeight_; }
757 const RVector & modelRef() const { return modelRef_; }
758 const RVector & dataWeight() const { return dataWeight_; }
759
760 const RVector & deltaDataIter() const { return deltaDataIter_; }
761 const RVector & deltaModelIter() const { return deltaModelIter_; }
762
764 void reset(){
765 this->setModel(forward_->startModel());
766 }
767
768protected:
769
770 Vec data_;
771 ModellingBase * forward_;
772
773 Trans< Vec > * tD_;
774 Trans< Vec > * tM_;
775 Trans< Vec > * transModelDefault_;
776 Trans< Vec > * transDataDefault_;
777
778 bool verbose_;
779 bool dosave_;
780 bool saveModelHistory_;
781
782 Vec error_;
783 Vec response_;
784
785 Vec model_;
786 Vec modelRef_;
787
788 Vec constraintsH_;
789 Vec constraintWeights_;
790 Vec modelWeight_;
791 Vec dataWeight_;
792
793 Vec deltaDataIter_;
794 Vec deltaModelIter_;
795
796 int maxiter_;
797 int iter_;
798 int maxCGLSIter_;
799
800 double lambda_;
801 double lambdaFactor_;
802 double lambdaMin_;
803 double dPhiAbortPercent_;
804 double CGLStol_;
805
806 bool isBlocky_;
807 bool isRobust_;
808 bool isRunning_;
809 bool useLinesearch_;
810 bool optimizeLambda_;
811 bool abort_;
812 bool stopAtChi1_;
813 bool doBroydenUpdate_;
814 bool localRegularization_;
815 bool haveReferenceModel_;
816 bool recalcJacobian_;
817 bool jacobiNeedRecalc_;
818 bool activateFillConstraintWeights_; //jointinv hack!!!
819
822
824 std::vector < RVector > modelHist_;
825
826};
827
828} // namespace GIMLI
829
830#endif
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
Definition trans.h:33
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