Bug? isapprox different results elementwise (Julia 1.1.0)

I have this weird case where two tensors are element-wise and size-wise approx equal up to 3 digits but as a whole they aren’t. I’m still running Julia 1.1.0 though.

alldigits = cat([[0.375297  0.624703]; [0.39924 0.60076]], [[0.664557  0.335443]; [0.664557  0.335443]], dims=3)
2×2×2 Array{Float64,3}:
[:, :, 1] =
 0.375297  0.624703
 0.39924   0.60076 

[:, :, 2] =
 0.664557  0.335443
 0.664557  0.335443
julia> threedig = map(x -> round(x,digits=3), alldigits)
2×2×2 Array{Float64,3}:
[:, :, 1] =
 0.375  0.625
 0.399  0.601

[:, :, 2] =
 0.665  0.335
 0.665  0.335

julia> isapprox.(alldigits, threedig, atol=1e-3)
2×2×2 BitArray{3}:
[:, :, 1] =
 true  true
 true  true

[:, :, 2] =
 true  true
 true  true

julia> isapprox(alldigits, threedig, atol=1e-3)
false

julia> size(alldigits) == size(threedig)
true

I made a test script for it here:

Anyone who knows why or how this happens?

You’ll find the answer in the docstring of isapprox (?isapprox), given that

julia> norm(alldigits - threedig)
0.0010376001156515333

The norm computed is like an Euclidean norm of the difference, when viewing the 3D-tensors as if vectorized. But that Euclidean norm is something else than the maximum of the absolute value of the elementwise difference.

4 Likes

Oh, I see thanks. Should have read the manual better!

The element wise approx suffices for my use case. So not a bug, but what a response time!

Just a small addition to say that this is more general than just a quirk of isapprox. Julia treats matrices and arrays as real algebraic objects in their own right — they’re not “just” collections of numbers. You’ll see this distinction throughout: * vs .*, exp(A) vs. exp.(A), etc, etc. Same deal here.

2 Likes