ANN: IsApprox.jl Interface for approximate and exact equality

I posted about a preliminary version a few months ago. The package is now registered.

From the README:

For some applications, LinearAlgebra wants to know if a matrix is exactly Hermitian. Quantum information packages, on the other hand, might want to know if a matrix is approximately (or exactly) Hermitian. Furthermore, many functions that check whether a property (approximately) holds are interdependent. For example isdiag calls functions that eventually call iszero. And isposdef calls ishermitian. Furthermore again, one might want to check approximate equality in norm; or elementwise. One might want to specify a tolerance and have it propagate. In practice, packages tend to reimplement tests in ways that do not satisfy all these criteria, and fail to be composable…Clearly, a general interface for approximate equality is needed.

11 Likes

Cool!

one thing that I end up using a fair bit is “approximation between strings”, basically comparing two strings after removing whitespace characters (\s|\n); this is quite useful in tests for instance where you might be testing two strings that have indentations etc to be similar and it can be a bit of a headache otherwise to make sure all the spaces are in the right place to get an == to work when using multiline strings """...""" & using the raw string with \n\t etc is less readable.

Not sure if that would be an appropriate addition for your project though as it would mostly be something for tests and doesn’t meet a mathematical notion of proximity.

3 Likes

I think that makes sense. Can you open an issue ? Maybe show the code that you use. Eg is it something more efficient than comparing copies with whitespace stripped ? Maybe something like isapprox(Approx(chars=(\n), a, b)

Nice! Can this be used with unique? E.g. uniquify objects if they are within 1e-5 of each other (although this is not transitive).

It looks like unique uses hashing. I don’t see an easy way to do this by modifying the existing code… maybe you could also modify get to return an approximate match for a Dict. But the hashes of two objects that are close are not close in general.

You could have unique(A; approx=Approx(atol=atol) dispatch to a different algorithm. I like the idea of a consistent interface for this sort of thing, as it is generally useful, even if you can’t always share a code path.

EDIT: It’s not obvious to me how to do approximate unique in less than O(n^2) for a collection of numbers. hmmm… Maybe you can adjust each number to a canonical value based on a tolerance before hashing.

1 Like

I think it’s possible to do in O(n log n) with sorting and only comparing pairs of neighbours afterwards. However, the semantics have to be carefully determined beforehand as it’s not really obvious due to nontransitivity.

3 Likes