help-octave
[Top][All Lists]

## Re: Stupid New User Question

 From: John W. Eaton Subject: Re: Stupid New User Question Date: Thu, 13 Jul 2006 14:34:00 -0400

```On 13-Jul-2006, Muthiah Annamalai wrote:

| If you looked into the nice code in octave .m files
| which come with the distribution at
| /usr/share/octave/\$VERSION/m/scripts/
| youd get a nice idea of how to write great functions.
|
| For making this code work with arrays you just need
| to use  the find() function.
|
| function  retval = killnegatives(x)
|
|      retval = x;
|
|      %if(retval<0) retval = 0;
|      negatives=find(retval<0);
|      retval(negatives)=0;
|
| endfunction

The find function works, but it also works to just use the mask (i.e.,
the result of the "retval < 0" expression) directly as the index:

function  retval = killnegatives(x)
retval = x;
retval(retval<0)=0;
endfunction

This should be more efficient since it eliminates the call to find and
the extra vector of indices produced by find.  Here's some timing code
that graphs the ratio of times required for the two versions.

function r = f (x)
r = x;
n = find (r < 0);
r(n) = 0;
endfunction

function r = g (x)
r = x;
r(r<0) = 0;
endfunction

function r = h (n, v)
x = rand (n) - v;
t = cputime (); f(x); tf = cputime () - t;
t = cputime (); g(x); tg = cputime () - t;
r = tf / tg;
endfunction

m = 20;
z = zeros (m, m);
n = logspace (log10 (500), log10 (3000), m);
v = linspace (0, 1, m);
for i = 1:m
for j = 1:m
z(i,j) = h (n(i), v(j));
endfor
endfor

[x, y] = meshdom (n, v);
zlabel ("find / logical indexing");
xlabel ("matrix size")
ylabel ("approx frac of neg vals")
mesh (x, y, z);

When I run this with the current 2.9.x sources, the find solution is
always slower.  So if there are any functions in the Octave sources
that still use find instead of logical indexing for this kind of
operation, I think we should eliminate the calls to find.

Thanks,

jwe

```