julia> methods(isapprox)
# 9 methods for generic function "isapprox":
[1] isapprox(::Missing, ::Missing; kwargs...) in Base at missing.jl:89
[2] isapprox(::Missing, ::Any; kwargs...) in Base at missing.jl:90
[3] isapprox(::Any, ::Missing; kwargs...) in Base at missing.jl:91
[4] isapprox(x::Number, y::Number; atol, rtol, nans) in Base at floatfuncs.jl:274
[5] isapprox(x::AbstractArray, y::AbstractArray; atol, rtol, nans, norm) in LinearAlgebra at C:\cygwin\home\Administrator\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.3\LinearAlgebra\src\generic.jl:1522
[6] isapprox(J1::LinearAlgebra.UniformScaling{T}, J2::LinearAlgebra.UniformScaling{S}; atol, rtol, nans) where {T<:Number, S<:Number} in LinearAlgebra at C:\cygwin\home\Administrator\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.3\LinearAlgebra\src\uniformscaling.jl:253
[7] isapprox(J::LinearAlgebra.UniformScaling, A::AbstractArray{T,2} where T; atol, rtol, nans, norm) in LinearAlgebra at C:\cygwin\home\Administrator\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.3\LinearAlgebra\src\uniformscaling.jl:259
[8] isapprox(A::AbstractArray{T,2} where T, J::LinearAlgebra.UniformScaling; kwargs...) in LinearAlgebra at C:\cygwin\home\Administrator\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.3\LinearAlgebra\src\uniformscaling.jl:265
[9] isapprox(c1::D, c2::D) where D<:DiscreteNonParametric in Distributions at C:\Users\andre\.julia\packages\Distributions\wRw5p\src\univariate\discrete\discretenonparametric.jl:66
hi!, maybe it’s because is a keyword argument? and keywords don’t participate in dispatch. but it works anyway. for example:
x = rand(5)
y = rand(5)
mynorm(x) = length(x) - 5 #not a real norm, but if the length of (y-x) is 5, then they are equal
isapprox(x,y,norm=mynorm) #returns true
There is no norm option if the entries are Numbers. I have a composite data type that contained a Number and several Arrays. I need to pass the “norm” option on when computing the Array parts and not when computing the scalar part. This is clear from method list item [4] in the isapprox methods.
x = rand(1)
y = rand(1)
mynorm(x) = length(x) - 5 #not a real norm, but if the length of (y-x) is 5, then they are equal
isapprox(x,y,norm=mynorm)
Works
But
mynorm(x) = length(x) - 5 #a real norm, but if the length of (y-x) is 5, then they are equal
isapprox(1, 1,norm=mynorm)
I think that the docstring of isapprox is a bit misleading, since not all methods support all keyword arguments. Perhaps it should be broken up into relevant parts for each method.
That said, I think that specifying a custom norm, especially in tests, is often more convoluted than just calculating the discrepancy I care about directly.
Contrived:
Where scalars are part of a larger structure, think unit quaternions, with a scalar part and a vector part. In such a case the scalar norm might be part of a larger computation, and the most convenient thing might be a different scalar norm.
If I’m trying to optimize an attitude maneuver (a rotation), I want a partial order (semi-norm), on the size of the angle. The scalar part of a unit quaternion is \cos \frac{\theta}{2}, when the unit quaternion is representing a rotation. So I would want to take the \arccos and compare \theta’s not \cos \frac{\theta}{2}’s.
N.B. There are better ways to do this - I indicated it’s contrived.
Of course, scalar norm in the usual case should be blazingly fast. But that’s why Julia is compiled.