# ANN: IsApprox.jl Interface for approximate and exact equality

**URL:** <https://discourse.julialang.org/t/ann-isapprox-jl-interface-for-approximate-and-exact-equality/41786>\
**Category:** Package Announcements\
**Tags:** announcement\
**Created:** [June 20, 2020, 5:57pm UTC](https://discourse.julialang.org/t/ann-isapprox-jl-interface-for-approximate-and-exact-equality/41786 "2020-06-20T17:57:02Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![jlapeyre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlapeyre/32/4514_2.png) [@jlapeyre](https://discourse.julialang.org/u/jlapeyre)\
**Post date:** [June 20, 2020, 5:57pm UTC](https://discourse.julialang.org/t/ann-isapprox-jl-interface-for-approximate-and-exact-equality/41786/1 "2020-06-20T17:57:02Z")

</div>

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.

> **[GitHub - jlapeyre/IsApprox.jl: Interface for approximate and exact equality](https://github.com/jlapeyre/IsApprox.jl)**
>
> Interface for approximate and exact equality. Contribute to jlapeyre/IsApprox.jl development by creating an account on GitHub.

---

<div class="post-metadata">

**Author:** ![tlienart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tlienart/32/7640_2.png) [@tlienart](https://discourse.julialang.org/u/tlienart)\
**Post date:** [June 20, 2020, 7:54pm UTC](https://discourse.julialang.org/t/ann-isapprox-jl-interface-for-approximate-and-exact-equality/41786/2 "2020-06-20T19:54:50Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![jlapeyre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlapeyre/32/4514_2.png) [@jlapeyre](https://discourse.julialang.org/u/jlapeyre)\
**Post date:** [June 20, 2020, 9:26pm UTC](https://discourse.julialang.org/t/ann-isapprox-jl-interface-for-approximate-and-exact-equality/41786/3 "2020-06-20T21:26:43Z")

</div>

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)`

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [June 20, 2020, 11:23pm UTC](https://discourse.julialang.org/t/ann-isapprox-jl-interface-for-approximate-and-exact-equality/41786/4 "2020-06-20T23:23:15Z")

</div>

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).

---

<div class="post-metadata">

**Author:** ![jlapeyre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlapeyre/32/4514_2.png) [@jlapeyre](https://discourse.julialang.org/u/jlapeyre)\
**Post date:** [June 21, 2020, 12:01am UTC](https://discourse.julialang.org/t/ann-isapprox-jl-interface-for-approximate-and-exact-equality/41786/5 "2020-06-21T00:01:23Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [June 21, 2020, 5:42am UTC](https://discourse.julialang.org/t/ann-isapprox-jl-interface-for-approximate-and-exact-equality/41786/6 "2020-06-21T05:42:27Z")

</div>

> [@jlapeyre](#):
>
> EDIT: It’s not obvious to me how to do approximate `unique` in less than O(n^2) for a collection of numbers. hmmm…

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.
