Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Add fuzzy equals comparisons #3895

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

Merged
merged 22 commits into from
Jul 23, 2024
Merged

Add fuzzy equals comparisons #3895

merged 22 commits into from
Jul 23, 2024

Conversation

lindsayad
Copy link
Member

@lindsayad lindsayad commented Jul 1, 2024

Split off from #3883

  • Add unit tests

@moosebuild
Copy link

moosebuild commented Jul 1, 2024

Job Coverage on 6af1064 wanted to post the following:

Coverage

b76c44 #3895 6af106
Total Total +/- New
Rate 62.84% 62.85% +0.02% 89.36%
Hits 69469 69511 +42 42
Misses 41082 41080 -2 5

Diff coverage report

Full coverage report

Warnings

  • New new line coverage rate 89.36% is less than the suggested 90.0%

This comment will be updated on new commits.

* A given element will be deemed fuzzy equal if either a relative or absolute tolerance fuzzy
* equal comparison returns true
*/
bool fuzzy_equal(const NumericVector<T> & v,
Copy link
Member

@jwpeterson jwpeterson Jul 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have TypeVector<T>::relative_fuzzy_equals and TypeVector<T>::absolute_fuzzy_equals, so there is some precedent already for the "plural" form of "equal". So I would prefer to just maintain that unless you intend to replace the those existing "equals" functions as well?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to maintain that. "If you don't know whether you want absolute or relative tolerance, you don't know what you're doing" is a tautology on one level and a critically important statement on another. My "eh, it's all fuzzy equality" attitude in the libMesh shape-function-caching code long ago turned into a disaster when it eventually interacted with the MOOSE displaced-mesh code.

Copy link
Member Author

@lindsayad lindsayad Jul 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took @jwpeterson's comment to be more aimed at the plural naming vs. the separation of relative and absolute. I've addressed the former. For the latter, I added distinct tolerances for relative and absolute to the APIs in this PR. I think this is better than having separate APIs. i don't care to loop over the vector or matrix twice when I can do it once. We don't run SNES twice to see whether we meet the relative convergence criteria or absolute convergence criteria

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, looks like I misinterpreted; thanks for clarifying.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I read "plural" as "there's two of them", and the comment on the main page cuts off the function arguments below it. This looks good to me.

lindsayad added 2 commits July 2, 2024 09:33
Also introduce a `scale` API for `SparseMatrix`
@lindsayad lindsayad marked this pull request as ready for review July 2, 2024 16:37
@moosebuild
Copy link

Job Distributed make check sweep (even) on 52a5ebe : invalidated by @lindsayad

@moosebuild
Copy link

Job Test MOOSE min clang on 52a5ebe : invalidated by @lindsayad

typename std::enable_if<ScalarTraits<T>::value && ScalarTraits<T2>::value &&
ScalarTraits<T3>::value,
int>::type = 0>
bool absolute_fuzzy_equals(const T & var1, const T2 & var2, const T3 & tol = TOLERANCE * TOLERANCE);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tol should always conceptually be a positive real, right? What's the use case for const T3 & vs just Real?

* within an absolute tolerance
* @param var1 The first complex variable to be checked
* @param var2 The second complex variable to be checked
* @param tol The real tolerance to be used for comparing both real and imgainary parts
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @param tol The real tolerance to be used for comparing both real and imgainary parts
* @param tol The real tolerance to be used for comparing both real and imaginary parts

I feel like I just successfully found the "No Brown M&Ms" clause.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need a confused emoji

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the poor spelling is fixed though 😄

for (const auto i : make_range(libmesh_dim))
if (!relative_fuzzy_equals(var1(i), var2(i), tol))
return false;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't this conclude that the vectors [1e9, 1] and [1e9, 1+1e-5] aren't relatively equal? That doesn't seem like the behavior we want.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The simplest comparable thing to do here is to get the l∞ norm in one pass, then use that as the scale for each difference comparison on a second pass. We could avoid a 2-pass solution by keeping track of l∞ of both the values and the differences in a single pass and then comparing at the end. That doesn't let us take advantage of early-return cases, but I don't think I see a way around that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the norm we use really matter? I think I'm going to do a bit of consolidation. It looks like we're using the L1 norm in TypeVector

@lindsayad
Copy link
Member Author

I'm thinking that I might drop the fuzzy_equals routines for the global data structures

@roystgnr
Copy link
Member

Those are the trickiest, I admit. That's exactly the reason we want library routines for them IMHO, but if you want to get the obviously-acceptable parts merged right away then I'm fine with postponing anything that will take longer.

Developers should overload `libMesh::l1_norm` and `libMesh::l1_norm_diff` for
their numeric types and then they automatically get correct application of
`libMesh::*fuzzy_equals`
@lindsayad
Copy link
Member Author

lindsayad commented Jul 16, 2024

Ok I've attempted a fairly generic, yet I believe simple, implementation that supports the more complicated global data structures. Let's see what you think

@lindsayad lindsayad requested a review from roystgnr July 16, 2024 13:23
@moosebuild
Copy link

Job Test mac on 6af1064 : invalidated by @lindsayad

@lindsayad
Copy link
Member Author

Failures are unrelated. I think this should be ready for review

Copy link
Member

@roystgnr roystgnr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where/how do we end up instantiating TypeVector<bool>?

@lindsayad
Copy link
Member Author

MOOSE solid mechanics module does it 🤷‍♂️

@lindsayad lindsayad merged commit 3503133 into libMesh:devel Jul 23, 2024
18 of 20 checks passed
@lindsayad lindsayad deleted the fuzzy-equal branch July 23, 2024 01:24
lindsayad added a commit to arfc/moltres that referenced this pull request Sep 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants