IsApprox implements an interface for applying different definitions of "approximate" in tests for approximate (or exact) equality.
It is also fun and hip.
Methods in this package extend predicate functions defined in Base and LinearAlgebra.
In addition, a few predicate functions that do not have an analogue in Base or LinearAlgebra
are exported. All predicate methods defined here take an argument of type AbstractApprox in the final
position.
Previously, Base.isapprox was extended by taking an AbstractApprox in the first position.
All other predicate functions were duplicated or new in this package and could conflict with
names in Base and LinearAlgebra. With the new API, using IsApprox causes no conflicts
or piracy and does not interfere with any exsisting code using predicates, isapprox,
issymmetric, ishermitian, etc.
Design requirements of IsApprox are:
-
It extends
Base.isapproxas well as several application functions, such asisoneandissymmetric. In particular, many functions that currently check for a property exactly (to machine precision) will instead useIsApproxto implement both exact and approximate comparison. -
It should incur no run-time performance penalty for existing calls of
isapproxand other predicate functions, such asisone.
The Jupyter notebook is out of date.
See this Jupyter notebook for examples.
See also the test suite.
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.
Such packages include QuantumInformation(
code example)
,
QuantumInfo(
code example),
and
Yao(
code example).
Clearly, a general interface for approximate
equality is needed.
IsApprox allows users to specify different definitions of closeness, via a zero-cost
abstraction. That is, specifying the definition of closeness need not incur a run-time
cost. The code that implements tests for properties such as symmetry or positivity may
then be somewhat decoupled from the specification of closeness. Furthermore, a simple,
small, collection of closeness measures should be adequate for the vast majority of use
cases.
Four subtypes of AbstractApprox are included, Equal, Approx, EachApprox, and UpToPhase.
IsApprox implements the interface at least partially for each of: isone, iszero, ishermitian, issymmetric,
isreal, isinteger, istriu, istril, isbanded, isdiag, isposdef,
ispossemidef, isunitary, isinvolution, isnormalized, isprobdist.
Consider ishermitian.
-
ishermitian(A)or equivalentlyishermitian(A, Equal())demands exact equality.ishermitian(A, Equal())callsLinearAlgebra.ishermitian(A). -
ishermitian(A, Approx(kws...))has the same semantics asBase.isapprox. Namely,
ishermitian(A::AbstractMatrix, approx::Approx) = isapprox(A, adjoint(A), approx)ishermitian(A, EachApprox(kws...)).EachApproxspecifies element-wise closeness. IfAis not close to Hermitian, this test is much faster thanApproxbecause only order1elements must be tested.
AbstractApprox, Equal, Approx, UpToPhase, and EachApprox are exported.
This extends Base.isapprox with methods that take a final positional argument of type AbstractApprox.
The application functions below take an optional argument of type AbstractApprox also in the final
position and (may) forward this argument to isapprox.
This package will probably try to follow the Blue Style Guide.
An important rule is broken immediately: predicates are written isprop rather than is_prop.
And ispropmod1mod2 rather than is_prop_mod1_mod2. The main reason is that some of these
functions exist by the same name in Base. And some are very closely related.