[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
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.