help-octave
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: MacOSX: Octave.app 2.9.14


From: David Bateman
Subject: Re: MacOSX: Octave.app 2.9.14
Date: Fri, 28 Sep 2007 22:12:09 +0200
User-agent: Thunderbird 1.5.0.7 (X11/20060921)

Ok, I've been talking to Vic and Thomas offline on this issue and the
problem appears to be in the norm.m function and the changes made
between 2.9.10 and 2.9.11. The change to use blas for vector norms is
faster for large vectors, but some of the associated changes slow it up
for small vectors.

The advantages of the blas norm function can easily be seen with the test

function [] = test_functions ()
  A = rand (100, 1); tic;
  for i = 1:50000
    B = __vnorm__ (A, 2);
  endfor
  printf ("1st testset: "); toc;

  A = rand (100, 1); tic;
  for i = 1:50000
    B = sqrt (sum (abs (A) .^ 2));
  endfor
  printf ("2nd testset: "); toc;
endfunction

that on my machine returns

test_functions
1st testset: Elapsed time is 0.867805 seconds.
2nd testset: Elapsed time is 2.475632 seconds.

However, I download a copy of the norm function from 2.9.10 called it
mynorm.m and ran

function [] = test_functions ()
  A = rand (100, 1); tic;
  for i = 1:50000
    B = norm(A);
  endfor
  printf ("1st testset: "); toc;

  A = rand (100, 1); tic;
  for i = 1:50000
    B = mynorm(A);
  endfor
  printf ("2nd testset: "); toc;
endfunction

The result was

1st testset: Elapsed time is 12.406967 seconds.
2nd testset: Elapsed time is 7.624680 seconds.

which is frankly quite surprising given the above. So norm is 15 times
slower than calling __vnorm__ directly on the same matrix. However, what
is more surprising is that even though the blas code is 3 times faster
than the sqrt(sum(abs(A).^2)) method of  calculating the norm, the norm
function itself is almost twice as slow... Huhhh

Well, I traced the issue to the line

if (is_vector (x))

in norm.m. Firstly, it should call isvector(x) rather than the
deprecated is_vector and remove one function call. That improves the
above test to

1st testset: Elapsed time is 10.360291 seconds.
2nd testset: Elapsed time is 7.657280 seconds.

So that added function call costed 2 seconds in the above example. In
the 2.9.10 version of norm the line is

if (rows (x) == 1 || columns (x) == 1)

instead. Making that change gives instead

1st testset: Elapsed time is 6.738678 seconds.
2nd testset: Elapsed time is 7.762543 seconds.

which is more like it, though using norm rather than __vnorm__ directly
we're loosing a significant part of the speed advantage of the blas for
this example. However one point is that the isvector(x) code also checks
than "ndims(x) == 2" and so that should be added for correctness.
Thinking about it, should it be possible to have a vector norm along any
dimension in ND? That is shouldn't "norm (randn([1,1,100])" also use the
__vnorm__ code? Though trying it gives

__vnorm__(randn([1,1,100]),2)
error: invalid conversion of NDArray to Matrix
error: norm: expecting real vector

So maybe not... Adding the ndims(x)==2 to norm.m and rerunning the test
gives.

1st testset: Elapsed time is 7.216400 seconds.
2nd testset: Elapsed time is 7.680885 seconds.

So this leads me to two conclusions

1) The attached patch should be applied, and
2) Perhaps we should promote __vnorm__ from the status of internal
function to a fully fledged function. In any case Vic, I'd strong
suggest you use __vnorm__(x,2) rather than norm(x) in your code for a 15
times speed up in the norm calculations..

Regards
David
*** ./scripts/linear-algebra/norm.m.orig12      2007-09-28 22:10:25.300075772 
+0200
--- ./scripts/linear-algebra/norm.m     2007-09-28 22:10:36.164519559 +0200
***************
*** 78,84 ****
  
    ## Do we have a vector or matrix as the first argument?
  
!   if (is_vector (x))
      if (isinteger (x) || issparse (x))
        if (ischar (p))
          if (strcmp (p, "fro"))
--- 78,84 ----
  
    ## Do we have a vector or matrix as the first argument?
  
!   if (ndims(x) == 2 && (rows (x) == 1 || columns (x) == 1))
      if (isinteger (x) || issparse (x))
        if (ischar (p))
          if (strcmp (p, "fro"))
2007-09-28  David Bateman  <address@hidden>

        * linear-algebra/norm.m: Inline the isvector(x) calculation for
        speed with small vectors.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]