Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

allclose - How to check if two arrays are close in Julia

Tags:

numpy

julia

In numpy you can do np.allclose(A, B) to see if the arrays A & B are close.

Is there any function in Julia to do so ?

like image 735
spv Avatar asked Nov 24 '14 06:11

spv


3 Answers

(For the obsolete version of this answer, see below the horizontal line.)

An array version of isapprox was introduced in Julia 0.4, so you can now write:

isapprox(A, B)

Like in the scalar case, you can specify the relative tolerance rtol and the absolute tolerance atol as keyword arguments.

But note that unlike NumPy's allclose (and the previous solution of this answer below), array-isapprox calculates a norm of the difference first, and then decides for the resulting value. (Appearently, checking isapprox pointwise is wrong.) By default, LinearAlgebra.norm is used, which is the 2-norm for vectors and the Froebenius norm for matrices, but you can override this behavior using the norm keyword argument.

By the way, as mentioned in the linked pull request, in tests you can write @test isapprox(A, B), so @test_approx_eq is now obsolete and deprecated as of 0.6. Also, there is A ≈ B, which is equivalent to isapprox(A, B) and can be used like any comparison operator: a < b ≈ c ≤ d.


For reference, this is the previous, outdated version of this post:

For single numbers, isapprox is defined. If you want to extend this to an element-wise comparison on Arrays, you could use:

all(x -> isapprox(x...), zip(A, B))

all(x -> isapprox(x...), zip(A, A + 1e-5)) # => false
all(x -> isapprox(x...), zip(A, A + 1e-6)) # => true
like image 173
user4235730 Avatar answered Nov 20 '22 11:11

user4235730


There is no function called allclose that ships with Julia:

julia> allclose
ERROR: allclose not defined

I don't know whether an existing Julia function provides the functionality you want but, based on the numpy.allclose documentation, you can implement one yourself (complete with keyword arguments):

function allclose(a, b; rtol = 1e-5, atol = 1e-8)
  return all(abs(a - b) .<= (atol + rtol * abs(b)))
end

Tests at the Julia command line:

julia> A = rand(5, 5)
5x5 Array{Float64,2}:
 0.0833821  0.722352   0.474616  0.0997349  0.352403 
 0.557657   0.199624   0.748646  0.838296   0.0396182
 0.9716     0.230623   0.215245  0.689457   0.261951 
 0.64731    0.0799202  0.877895  0.582062   0.601394 
 0.875966   0.776157   0.664024  0.0996859  0.12747  

julia> allclose(A, A + 1e-4)
false

julia> allclose(A, A + 1e-6)
false

julia> allclose(A, A + 1e-8)
true

julia> allclose(A, A + 1, rtol = 1)
true
like image 38
jub0bs Avatar answered Nov 20 '22 12:11

jub0bs


If you're writing tests, using Base.Test and then @test_approx_eq A B should work.

like image 3
tholy Avatar answered Nov 20 '22 12:11

tholy