Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
Cumulative Difference Vectorization?

Subject: Cumulative Difference Vectorization?

From: Keith Rogers

Date: 16 Oct, 2003 21:59:22

Message: 1 of 6

x = cumsum(a) ->


x(1) = a(1)
x(2) = a(2) + x(1)
x(3) = a(3) + x(2)
.
.
.


Does anyone know how to vectorize a cumdiff function?


x = cumdiff(a) ->


x(1) = a(1)
x(2) = a(2) - x(1)
x(3) = a(3) - x(2)
.
.
.

Subject: Cumulative Difference Vectorization?

From: pjacklam@online.no (Peter J. Acklam)

Date: 17 Oct, 2003 08:48:40

Message: 2 of 6

"Keith Rogers" <keith.e.rogers@lmco.com> wrote:

> x = cumsum(a) ->
>
> x(1) = a(1)
> x(2) = a(2) + x(1)
> x(3) = a(3) + x(2)
> .
>
> Does anyone know how to vectorize a cumdiff function?
>
> x = cumdiff(a) ->
>
> x(1) = a(1)
> x(2) = a(2) - x(1)
> x(3) = a(3) - x(2)
> .

Try out the function below. You can always strip out the
essential part if you don't want the error checking etc. The
trickiest part was to find the index vectors that makes the
function work without using separate code for odd and even length
vectors.

------------------------------------------------------------------------
function y = cumdiff(x)
%CUMDIFF A "cumulative difference" function.
%
% CUMDIFF(Y) returns a vector Y satisfying
%
% Y(1) = X(1)
% Y(2) = X(2) - Y(1)
% ...
% Y(N) = X(N) - Y(N-1)
%
% See also CUMSUM, DIFF.

% Author: Peter J. Acklam
% Time-stamp: 2003-10-17 08:44:18 +0200
% E-mail: pjacklam@online.no
% URL: http://home.online.no/~pjacklam

   % check number of input arguments
   error(nargchk(1, 1, nargin));

   % input must be a vector
   if sum(size(x) > 1) > 1
      error('Input must be a vector.');
   end

   % initialize output
   y = zeros(size(x));

   % break out immediately if input is empty
   if isempty(x)
      return
   end

   n = length(x);
   p = fix((n - 1) / 2);
   q = fix(n / 2);
   r = fix((n + 1) / 2);

   v1 = cumsum(x(1:2:n));
   v2 = cumsum(x(2:2:n));

   y(1) = x(1);
   y(3:2:n) = v1(2 : r) - v2(1 : p);
   y(2:2:n) = v2 - v1(1 : q);
------------------------------------------------------------------------

Peter

--
Why does MATLAB have a "sin" function, but no "forgive" function?

Subject: Cumulative Difference Vectorization?

From: Benoit Bacquet

Date: 17 Oct, 2003 03:58:25

Message: 3 of 6

Peter J. Acklam wrote:
>
>
> "Keith Rogers" <keith.e.rogers@lmco.com> wrote:
>
>> x = cumsum(a) ->
>>
>> x(1) = a(1)
>> x(2) = a(2) + x(1)
>> x(3) = a(3) + x(2)
>> .
>>
>> Does anyone know how to vectorize a cumdiff function?
>>
>> x = cumdiff(a) ->
>>
>> x(1) = a(1)
>> x(2) = a(2) - x(1)
>> x(3) = a(3) - x(2)
>> .


Hello,


x(n)=a(n)-x(n-1)


It looks like a kind of infinite filter:
i think


[x]=function cumdiff(a)
x=filter(1,[1 1],a);


should works.


because


[x]=function cumsum(a)
x=filter(1,[1 -1],a);


works! (i don't know if it's done like in Matlab, because it's a
built in function, but it must be pretty close)


hth


Benoit

Subject: Cumulative Difference Vectorization?

From: Keith Rogers

Date: 17 Oct, 2003 21:05:32

Message: 4 of 6

Benoit and Peter,


Thanks! Great work. Benoit's solution works out to be much faster
than yours Peter.
FYI, I used the routine in the following way:


% function [rate, accel] = backrate(position,dt);
% Assuming constant accelerations, calculates the rates
% and accelerations that would generate the given position
% profile.


function [rate, accel] = backrate(position,dt);
if(size(position,1) > 1)
    rate = [0;cumdiff(2*diff(position))]/dt;
    accel = [diff(rate);0]/dt;
else
    rate = [0 cumdiff(2*diff(position))]/dt;
    accel = [diff(rate) 0]/dt;
end


function x = cumdiff(a)
x=filter(1,[1 1],a);


-Keith


Benoit Bacquet wrote:
>
>
> Peter J. Acklam wrote:
>>
>>
>> "Keith Rogers" <keith.e.rogers@lmco.com> wrote:
>>
>>> x = cumsum(a) ->
>>>
>>> x(1) = a(1)
>>> x(2) = a(2) + x(1)
>>> x(3) = a(3) + x(2)
>>> .
>>>
>>> Does anyone know how to vectorize a cumdiff function?
>>>
>>> x = cumdiff(a) ->
>>>
>>> x(1) = a(1)
>>> x(2) = a(2) - x(1)
>>> x(3) = a(3) - x(2)
>>> .
>
> Hello,
>
> x(n)=a(n)-x(n-1)
>
> It looks like a kind of infinite filter:
> i think
>
> [x]=function cumdiff(a)
> x=filter(1,[1 1],a);
>
> should works.
>
> because
>
> [x]=function cumsum(a)
> x=filter(1,[1 -1],a);
>
> works! (i don't know if it's done like in Matlab, because it's a
> built in function, but it must be pretty close)
>
> hth
>
> Benoit

Subject: Cumulative Difference Vectorization?

From: pjacklam@online.no (Peter J. Acklam)

Date: 18 Oct, 2003 08:08:53

Message: 5 of 6

"Keith Rogers" <keith.e.rogers@lmco.com> wrote:

> Benoit and Peter,
>
> Thanks! Great work. Benoit's solution works out to be much
> faster than yours Peter.

I'm sure it is faster. I didn't think of using "filter". :-)

Peter

--
Why does MATLAB have a "sin" function, but no "forgive" function?

Subject: Cumulative Difference Vectorization?

From: Blake Fleischer

Date: 13 May, 2013 20:52:11

Message: 6 of 6

So, maybe this is just me, but I didn't find this to work - eg:
a = [1;3;5;8;12];
b = filter(1,[1 1],a)

This yields:
b =

     1
     2
     3
     5
     7

The a cumulative difference should be the opposite of the cumsum - so one would expect the cum difference to be:
b =
     1
     2
     2
     3
     4

such that cumsum(b) yields:
ans =

     1
     3
     5
     8
    12

The reason an infinite filter wouldn't work is that it uses the previous output in the next input. If we only care about the difference between values (opposite of cumsum) then an IIR filter wouldn't yield the expected result.

The proper way to vectorize a 'cumdiff' is deceptively simple: just subtract the vector from itself:

b = a(2:end)-a(1:end-1);
b = [a(1); b] %append the first value so the cumsum will work

or in one line:
b = [a(1); a(2:end)-a(1:end-1)];

Tags for this Thread

No tags are associated with this thread.

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us