help-octave
[Top][All Lists]

## Re: vectorization challenge

 From: Jordi Gutiérrez Hermoso Subject: Re: vectorization challenge Date: Fri, 6 Aug 2010 01:38:45 -0500

```On 5 August 2010 23:00, Tim Rueth <address@hidden> wrote:

> I'm desperately trying to vectorize a calculation that I'm currently
> doing in a for-loop.  I haven't been able to figure this one out,
> and my brain now hurts.

> I have two column vectors A and B as inputs:
>
>   A              B             C
> -----------------------------------------
> 43.94          0          0.0000
> 44.25          0          0.7055
> 44.34          0          0.9103
> 44.81          0          1.9799
> 45.00          1          2.4123
> 44.97          0          -0.0666
> 44.97          0          -0.0666
> 44.66          1          -0.7555
> 44.72          0          0.1343
> 44.94          1          0.6269
> 44.59          0          -0.7788
> 43.47          0          -3.2710
> 43.44          0          -3.3377
> 43.41          1          -3.4045
> 43.56          0          0.3455
> 43.72          1          0.7141
> 43.69          1          -0.0686
> ...
>

> What I'm trying to do is calculate C without using a for-loop.  C is
> simply the running percent change in A since the last time there was
> a "1" in B.

Here's a tentative solution. It looks very inefficient to me, but at
least it has no for loops!

#Split up the a vector into a matrix where each column is monotone,
am = accumarray([ \
[1:length(b)]' - cummax(b.*([1:length(b)]'-1)), \
cumsum(b)+1 \
],
a);

#Compute the part of c ignoring troughs and peaks
a1 = repmat(am(1,:),size(am,1),1);
c  = 100*(am - a1)./a1;

#Fix the troughs and peaks
c(1,2:end) = 100*(am(1,2:end) - am(1,1:end-1))./am(1,1:end-1);

#Flatten c back into a vector
c = c(find(am))

I am sure I will be soon bested.

HTH,
- Jordi G. H.

```