-
Notifications
You must be signed in to change notification settings - Fork 280
Minor improvements to UpdateIRLS stopping criteria #1604
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Ditch the hard-coded 1e-12 value that gets added to the `f_old` to avoid division by zero: assign `f_change` to `np.inf` instead. Remove the absolute value computation while comparing `1 - chi_factor` with the `misfit_tolerance`. This way we avoid ending the inversion with a chi factor above the 1.0.
|
@domfournier would you like to take a look at this? Just some minor improvements to a couple of things I noticed in the stopping criteria for the IRLS.
Please, let me know what do you think. |
simpeg/directives/_regularization.py
Outdated
| chi_factor_diff = 1.0 - self.invProb.phi_d / self.misfit_from_chi_factor( | ||
| self.chifact_target | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One other thing: shouldn't the hard coded 1.0 be the self.chifact_target? Or should it always be 1.0?
| chi_factor_diff = 1.0 - self.invProb.phi_d / self.misfit_from_chi_factor( | |
| self.chifact_target | |
| ) | |
| chi_factor_diff = self.chifact_target - self.invProb.phi_d / self.misfit_from_chi_factor( | |
| self.chifact_target | |
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dont think so? The 1 in there is equivalent as doing
(phi_d* - phi_d) / phi_d*
meaning the relative deviation from the target. The function self.misfit_from_chi_factor converts the chifact to phi_d value.
Unfortunately the units of what you are proposing don't match: chi_fact is phi_d / N, the other is unitless.
I guess the name change that was previously merged doesn't really reflect the quantity calculated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right! My bad. I think what we can do is to rename the variable to make it reflect better what value it holds.
One minor thing: I get that by definition the chi factor is going to have the units of phi_d / N, but we always assume that the chi factor is unitless, meaning that phi_d is also unitless (because we are dividing by the uncertainties). This becomes quite clear when we look at the stopping criteria in TargetMisfit where we check if phi_d < chifact * phi_d_star, meaning that chifact is assumed to be always unitless. Nothing to take action on, but just wanted to mention it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, you are right - that would make phi_d already unitless.
simpeg/directives/_regularization.py
Outdated
| chi_factor_diff = 1.0 - self.invProb.phi_d / self.misfit_from_chi_factor( | ||
| self.chifact_target | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dont think so? The 1 in there is equivalent as doing
(phi_d* - phi_d) / phi_d*
meaning the relative deviation from the target. The function self.misfit_from_chi_factor converts the chifact to phi_d value.
Unfortunately the units of what you are proposing don't match: chi_fact is phi_d / N, the other is unitless.
I guess the name change that was previously merged doesn't really reflect the quantity calculated.
simpeg/directives/_regularization.py
Outdated
| - self.invProb.phi_d / self.misfit_from_chi_factor(self.chifact_target) | ||
| ) | ||
| < self.misfit_tolerance | ||
| and (0 <= chi_factor_diff < self.misfit_tolerance) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The absolute value was intended to allow to be "within range" of the target. That is, it's ok if the misfit is slightly higher or lower than the target.
Forcing it to be strictly smaller is a bit more restrictive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, not using the absolute value would make the stopping criteria more restrictive. The reason of the change is that it sounds unintuitive that it's possible to get a model that generates a chifact greater than the target.
Talking with @lheagy, one option would be to offer a flag to allow users to make the stopping criteria less restrictive by using the abs, but not using the abs by default. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no objection. The only risk I can foresee is an IRLS that runs longer, but ending below the target makes sense.
We can make the change, and revert the default later if we see instability.
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #1604 +/- ##
==========================================
- Coverage 86.52% 86.50% -0.03%
==========================================
Files 409 409
Lines 52692 52695 +3
Branches 5000 5000
==========================================
- Hits 45594 45584 -10
- Misses 5678 5691 +13
Partials 1420 1420 ☔ View full report in Codecov by Sentry. |
Now if phi_d > phi_d_star, then misfit_ratio will be positive.
Summary
Apply some minor improvements to the stopping criteria method of
directives.UpdateIRLS. Ditch the hard-coded1e-12value that gets added to thef_oldto avoid division by zero: assignf_changetonp.infinstead. Remove the absolute value computation while comparing1 - chi_factorwith themisfit_tolerance. This way we avoid ending the inversion with a chi factor above the 1.0.PR Checklist
expect style.
to a Pull Request
@simpeg/simpeg-developerswhen ready for review.Reference issue
What does this implement/fix?
Additional information
TODO
np.abswhen checking for the chifactor within tolerance. Basically, allow users to stop the IRLS even if the chifact is slightly higher than the target.