Skip to content

Commit 9ccdbff

Browse files
committed
add isapprox for arrays, with ≈ and ≉ synonyms
1 parent 8b1ae03 commit 9ccdbff

File tree

7 files changed

+53
-19
lines changed

7 files changed

+53
-19
lines changed

NEWS.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ Library improvements
317317

318318
* The `MathConst` type has been renamed `Irrational` ([#11922]).
319319

320-
* `isapprox` now has simpler and more sensible default tolerances ([#12393]).
320+
* `isapprox` now has simpler and more sensible default tolerances ([#12393]), supports arrays, and has synonyms `≈` ([U+2248](http://www.fileformat.info/info/unicode/char/2248/index.htm), LaTeX `\approx`) and `≉` ([U+2249](http://www.fileformat.info/info/unicode/char/2249/index.htm), LaTeX `\napprox`) for `isapprox` and `!isapprox`, respectively ([#12472]).
321321

322322
* Numbers
323323

@@ -1563,11 +1563,13 @@ Too numerous to mention.
15631563
[#11891]: https://github.com/JuliaLang/julia/issues/11891
15641564
[#11922]: https://github.com/JuliaLang/julia/issues/11922
15651565
[#11985]: https://github.com/JuliaLang/julia/issues/11985
1566+
[#12025]: https://github.com/JuliaLang/julia/issues/12025
15661567
[#12031]: https://github.com/JuliaLang/julia/issues/12031
15671568
[#12034]: https://github.com/JuliaLang/julia/issues/12034
15681569
[#12087]: https://github.com/JuliaLang/julia/issues/12087
15691570
[#12137]: https://github.com/JuliaLang/julia/issues/12137
15701571
[#12162]: https://github.com/JuliaLang/julia/issues/12162
15711572
[#12393]: https://github.com/JuliaLang/julia/issues/12393
15721573
[#12458]: https://github.com/JuliaLang/julia/issues/12458
1574+
[#12472]: https://github.com/JuliaLang/julia/issues/12472
15731575
[#12491]: https://github.com/JuliaLang/julia/issues/12491

base/docs/helpdb.jl

+9-2
Original file line numberDiff line numberDiff line change
@@ -2935,11 +2935,18 @@ cis
29352935
doc"""
29362936
```rst
29372937
::
2938-
isapprox(x::Number, y::Number; rtol::Real=sqrt(eps), atol::Real=0)
2938+
isapprox(x, y; rtol::Real=sqrt(eps), atol::Real=0)
29392939
2940-
Inexact equality comparison: ``true`` if ``abs(x-y) <= atol + rtol*max(abs(x), abs(y))``. The default ``atol`` is zero and the default ``rtol`` depends on the types of ``x`` and ``y``.
2940+
Inexact equality comparison: ``true`` if ``norm(x-y) <= atol + rtol*max(norm(x), norm(y))``. The default ``atol`` is zero and the default ``rtol`` depends on the types of ``x`` and ``y``.
29412941
29422942
For real or complex floating-point values, ``rtol`` defaults to ``sqrt(eps(typeof(real(x-y))))``. This corresponds to requiring equality of about half of the significand digits. For other types, ``rtol`` defaults to zero.
2943+
2944+
``x`` and ``y`` may also be arrays of numbers, in which case ``norm``
2945+
defaults to ``vecnorm`` but may be changed by passing a
2946+
``norm::Function`` keyword argument. (For numbers, ``norm`` is the
2947+
same thing as ``abs``.)
2948+
2949+
The binary operator ``≈`` is equivalent to ``isapprox`` with the default arguments, and ``x ≉ y`` is equivalent to ``!isapprox(x,y)``.
29432950
```
29442951
"""
29452952
isapprox

base/exports.jl

+2
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,8 @@ export
455455
zero,
456456
,
457457
,
458+
,
459+
,
458460

459461
# specfun
460462
airy,

base/floatfuncs.jl

+6-2
Original file line numberDiff line numberDiff line change
@@ -166,10 +166,14 @@ for f in (:round, :ceil, :floor, :trunc)
166166
end
167167

168168
# isapprox: approximate equality of numbers
169-
isapprox(x::Number, y::Number; rtol::Real=rtoldefault(x,y), atol::Real=0) =
169+
function isapprox(x::Number, y::Number; rtol::Real=rtoldefault(x,y), atol::Real=0)
170170
x == y || (isfinite(x) && isfinite(y) && abs(x-y) <= atol + rtol*max(abs(x), abs(y)))
171+
end
172+
173+
const = isapprox
174+
(x,y) = !(x y)
171175

172176
# default tolerance arguments
173177
rtoldefault{T<:AbstractFloat}(::Type{T}) = sqrt(eps(T))
174178
rtoldefault{T<:Real}(::Type{T}) = 0
175-
rtoldefault{T<:Number,S<:Number}(x::T, y::S) = rtoldefault(promote_type(real(T),real(S)))
179+
rtoldefault{T<:Number,S<:Number}(x::Union(T,Type{T}), y::Union(S,Type{S})) = rtoldefault(promote_type(real(T),real(S)))

base/linalg.jl

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ module LinAlg
55
importall Base
66
importall ..Base.Operators
77
import Base: USE_BLAS64, size, copy, copy_transpose!, power_by_squaring,
8-
print_matrix, transpose!, unsafe_getindex, unsafe_setindex!
8+
print_matrix, transpose!, unsafe_getindex, unsafe_setindex!,
9+
isapprox
910

1011
export
1112
# Modules

base/linalg/generic.jl

+5
Original file line numberDiff line numberDiff line change
@@ -535,3 +535,8 @@ det(x::Number) = x
535535
logdet(A::AbstractMatrix) = logdet(lufact(A))
536536
logabsdet(A::AbstractMatrix) = logabsdet(lufact(A))
537537

538+
# isapprox: approximate equality of arrays [like isapprox(Number,Number)]
539+
function isapprox{T<:Number,S<:Number}(x::AbstractArray{T}, y::AbstractArray{S}; rtol::Real=Base.rtoldefault(T,S), atol::Real=0, norm::Function=vecnorm)
540+
d = norm(x - y)
541+
return isfinite(d) ? d <= atol + rtol*max(norm(x), norm(y)) : x == y
542+
end

test/floatapprox.jl

+26-13
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,40 @@
11
# This file is a part of Julia. License is MIT: http://julialang.org/license
22

33
# Floating point numbers - basic tests
4-
@test isapprox(4.00000000000001, 4.0)
5-
@test isapprox(5.0,4.999999999999993)
6-
@test !isapprox(4.000000002, 4.00300002)
4+
@test 4.00000000000001 4.0
5+
@test 5.0 4.999999999999993
6+
@test 4.000000002 4.00300002
77

88
# Other tolerance levels
99
@test isapprox(4.32, 4.3; rtol=0.1, atol=0.01)
1010
@test isapprox(1.001, 1.002; rtol=0.001, atol=0.0001)
1111
@test !isapprox(4.5, 4.9; rtol=0.001, atol=0.001)
1212

1313
# Complex numbers
14-
@test isapprox(1.0 + 1.0im, 1.0 + 1.00000000000001im)
15-
@test isapprox(0.9999999999999 + 1.0im, 1.0 + 1.000000000000001im)
14+
@test 1.0 + 1.0im 1.0 + 1.00000000000001im
15+
@test 0.9999999999999 + 1.0im 1.0 + 1.000000000000001im
1616
@test isapprox(0.9999 + 1.0im, 1.0 + 1.1im; rtol = 0.0001, atol=1.1)
1717

1818
# Complex <-> reals
19-
@test isapprox(1.0 + 0im, 1.0000000000001)
19+
@test 1.0 + 0im 1.0000000000001
2020
@test isapprox(0.9999999999999, 1.0 + 0im)
2121
@test !isapprox(1.0+1im, 1.000000000000001)
2222

2323
# Comparing NaNs
24-
@test !isapprox(4.0,NaN)
25-
@test !isapprox(NaN,4.0)
26-
@test !isapprox(complex(2.3,NaN), complex(NaN,2.3))
27-
@test !isapprox(NaN, NaN)
28-
@test !isapprox(complex(NaN,NaN), complex(NaN,NaN))
29-
@test !isapprox(complex(NaN,2.3), complex(NaN,2.3))
30-
@test !isapprox(complex(2.3,NaN), complex(2.3,NaN))
24+
@test 4.0 NaN
25+
@test NaN 4.0
26+
@test complex(2.3,NaN) complex(NaN,2.3)
27+
@test NaN NaN
28+
@test complex(NaN,NaN) complex(NaN,NaN)
29+
@test complex(NaN,2.3) complex(NaN,2.3)
30+
@test complex(2.3,NaN) complex(2.3,NaN)
31+
32+
# Comparing Infs
33+
@test Inf Inf
34+
@test Inf 1
35+
@test Inf -Inf
36+
@test complex(0.0,Inf) complex(0.0,Inf)
37+
@test complex(0.0,Inf) complex(0.0,-Inf)
3138

3239
# Tests for integers and rationals
3340
@test isapprox(4,4)
@@ -46,3 +53,9 @@
4653

4754
# issue #12375:
4855
@test !isapprox(1e17, 1)
56+
57+
# Tests for arrays:
58+
@test [1,2,3] [1,2,3+1e-9]
59+
@test [0,1] [1e-9, 1]
60+
@test [0,Inf] [0,Inf]
61+
@test [0,Inf] [0,-Inf]

0 commit comments

Comments
 (0)