sqrt(abs2(x)) Vs abs(x)

295 views
Skip to first unread message

antony schutz

unread,
May 18, 2015, 10:51:48 AM5/18/15
to julia...@googlegroups.com
Hello, 

I just discover abs2() function :v 

And I have to say that i'm really surprised that: 
sqrt(abs2( x ))  is quicker than  abs( x ) 

For a Matrix of size 512*512 and then a vector of size 512 
10000 realizations, the mean results are (on a macbook): 

abs(x[:,:])

0.0073665214096

sqrt(abs2(x[:,:]))

0.0046861180318999995

abs(x[:])

1.2221291200000001e-5

sqrt(abs2(x[:]))

1.15177585e-5


Regards



Kristoffer Carlsson

unread,
May 18, 2015, 11:10:32 AM5/18/15
to julia...@googlegroups.com
When you benchmark stuff like this it is good to make a benchmark with as little noise in it as possible. Here is a version which removes slicing, bounds checking, allocations etc:

function timeit()
    A = rand(1024, 1024)
    B = similar(A)
    a = @elapsed for i = 1:size(A, 1), j = 1:size(A, 2)
        @inbounds B[i,j] = sqrt(abs2(A[i,j]))
    end

    b = @elapsed for i = 1:size(A, 1), j = 1:size(A, 2)
        @inbounds B[i,j] = abs(A[i,j])
    end

    return a,b
end

as = Float64[]
bs = Float64[]

for i in 1:20
    a, b = timeit()
    push!(as, a)
    push!(bs, b)
    println(i)
end

This gives me the results:

julia> mean(as)
0.04173319045

julia> mean(bs)
0.0417097596

which seems pretty much equal to me

Steven G. Johnson

unread,
May 18, 2015, 2:08:46 PM5/18/15
to julia...@googlegroups.com


On Monday, May 18, 2015 at 10:51:48 AM UTC-4, antony schutz wrote:
Hello, 

I just discover abs2() function :v 

And I have to say that i'm really surprised that: 
sqrt(abs2( x ))  is quicker than  abs( x ) 

Note that the abs(x) function is more robust because it avoids spurious overflow when x is large.

For example, if x=1e300, then abs(x) correctly returns x, but abs2(x) is Inf (infinity, i.e. it overflowed the largest representable double-precision floating-point number), so sqrt(abs2(x)) = sqrt(Inf) = Inf.

For benchmarking, I used:

       function foo!(Y,X,n)
          for i = 1:length(X), j = 1:n
             @inbounds Y[i] = abs(X[i])
          end
          return Y
       end

       function bar!(Y,X,n)
          for i = 1:length(X), j=1:n
             @inbounds Y[i] = sqrt(abs2(X[i]))
          end
          return Y
       end

For real data, I got:

X = rand(10^3); Y = similar(X);
foo!(Y, X, 10000); bar!(Y, X, 10000); # call once to eliminate JIT cost
@time foo!(Y, X, 10000);
@time bar!(Y, X, 10000);

elapsed time: 0.003777997 seconds (80 bytes allocated)
elapsed time: 0.041755933 seconds (80 bytes allocated)

i.e. abs was much faster.  For complex data, X = rand(Complex128, 10^3), Y = Array(Float64, 10^3), I got:

elapsed time: 0.09278846 seconds (80 bytes allocated)
elapsed time: 0.041389585 seconds (80 bytes allocated)

so in this case sqrt(abs2) was faster (though less robust): the abs function is costly because it requires both a branch and a rescaling (division) in addition to the square root and mul/adds.  See also the hypot(x,y) function.

antony schutz

unread,
May 19, 2015, 11:38:50 AM5/19/15
to julia...@googlegroups.com
Thank You Steven

I consider complexe number and I'm glad u notice the same difference between those two ways to compute absolute value. 
I agree with you about the robustness, for sure. In my case I performed the functions directly on array, without making loop. 

Regards
Reply all
Reply to author
Forward
0 new messages