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:
Summing consecutively signed integers

Subject: Summing consecutively signed integers

From: K

Date: 26 Nov, 2012 18:51:10

Message: 1 of 12

I'll start with an example:

%My array:
x = [-1; -2; 5; 3; -4; -3; 1; 3]

%Desired output:
y = [-1; -3; 5; 8; -4; -7; 1; 4]

I understand that I can achieve this fairly easily with a for-loop, but I am aware that there is likely a much more compact and elegant approach to this that I am missing. If someone may guide me, I would be highly appreciative.

Many thanks.

Subject: Summing consecutively signed integers

From: Roger Stafford

Date: 26 Nov, 2012 20:54:11

Message: 2 of 12

"K" wrote in message <k90dmu$oq9$1@newscl01ah.mathworks.com>...
> I'll start with an example:
>
> %My array:
> x = [-1; -2; 5; 3; -4; -3; 1; 3]
>
> %Desired output:
> y = [-1; -3; 5; 8; -4; -7; 1; 4]
>
> I understand that I can achieve this fairly easily with a for-loop, but I am aware that there is likely a much more compact and elegant approach to this that I am missing. If someone may guide me, I would be highly appreciative.
>
> Many thanks.
- - - - - - - - -
 y = x;
 y(2:2:end) = y(2:2:end) + x(1:2:end-1);

Roger Stafford

Subject: Summing consecutively signed integers

From: K

Date: 26 Nov, 2012 21:05:17

Message: 3 of 12

> y = x;
> y(2:2:end) = y(2:2:end) + x(1:2:end-1);

Thank you for the reply, Mr. Stafford.

This would indeed work for the specific example I gave, but it needs to work for different array arrangements. They are not always spaced by two as given in the example, nor are their necessarily grouped equally.

e.g.

%Input
x = [-2; -3; -5; -4; 1; 3; -2; 1; 3; 6; 7; -2; -1; -9; 1; -1; -2]

%Ouput
y = [-2; -5; -10; -14; 1; 4; -2; 1; 4; 10; 17; -2; -3; -12; 1; -1; -2]

Thank you for your time.

Subject: Summing consecutively signed integers

From: dpb

Date: 26 Nov, 2012 21:40:10

Message: 4 of 12

On 11/26/2012 3:05 PM, K wrote:
>> y = x;
>> y(2:2:end) = y(2:2:end) + x(1:2:end-1);
>
> Thank you for the reply, Mr. Stafford.
>
> This would indeed work for the specific example I gave, but it needs to
> work for different array arrangements. They are not always spaced by two
> as given in the example, nor are their necessarily grouped equally.
...

Don't see any great shakes here other than brute force---which is why
didn't respond earlier.

There is cumsum() of course, but you'll still need to find the beginning
of sections for it. I think the loop is probably about as good as it
gets here.

--

Subject: Summing consecutively signed integers

From: K

Date: 26 Nov, 2012 22:07:08

Message: 5 of 12

> Don't see any great shakes here other than brute force---which is why
> didn't respond earlier.

Darn, I was afraid of that.

It was worth a try!

Thank you.

Subject: Summing consecutively signed integers

From: Roger Stafford

Date: 26 Nov, 2012 22:42:19

Message: 6 of 12

"K" wrote in message <k90p6c$64m$1@newscl01ah.mathworks.com>...
> Darn, I was afraid of that.
- - - - - - - - -
  I agree with dpb. I see a vectorized method that would give you the answer you are asking for, but I don't want to give it to you, because it is very awkward and inferior to an obvious and simple for-loop method. You should realize that for-loop and while-loop code constructs provide a very powerful means of algorithm computation and there is nothing disgraceful about using them. Buried within the underlying C compiler code of nearly all Mathworks "elegant" functions are the equivalent of many for-loops, and I don't think their programmers are in the least bit reluctant about using them. The thing you should always strive for is an efficient algorithm in terms of the operations a computer must perform, never mind whether it uses for-loops or not.

Roger Stafford

Subject: Summing consecutively signed integers

From: K

Date: 26 Nov, 2012 23:26:21

Message: 7 of 12

For those interested, here is my for-loop solution.

Please note that the first position in my array x is always a zero, hence me starting the loop at index 2.

k = -1;
for i = 2:length(x)
    if sign(x(i,1)) == -1 && k == -1
        k = -1;
        x(i,2) = x(i,1) + x(i-1,2);
    elseif sign(x(i,1)) == -1 && k == 1
        k = -1;
        x(i,2) = x(i,1);
    elseif sign(x(i,1)) == 1 && k == 1
        k = 1;
        x(i,2) = x(i,1) + x(i-1,2);
    elseif sign(x(i,1)) == 1 && k == -1
        k = 1;
        x(i,2) = x(i,1);
    elseif sign(x(i,1)) == 1 && k == 0
        k = 1;
        x(i,2) = x(i,1);
    elseif sign(x(i,1)) == -1 && k == 0
        k = -1;
        x(i,2) = x(i,1);
    else
        k = 0;
        x(i,2) = NaN;
    end
end

Subject: Summing consecutively signed integers

From: Roger Stafford

Date: 27 Nov, 2012 00:56:19

Message: 8 of 12

"K" wrote in message <k90tqt$lpe$1@newscl01ah.mathworks.com>...
> For those interested, here is my for-loop solution. ......
- - - - - - - -
  You can shorten that a bit, K. (I'm not sure how you wish to treat zeros. This treats them as though they were positive numbers.)

 y = zeros(size(x));
 b = true;
 s = 0;
 for k = 1:length(x);
   if b ~= (x(k)>=0)
     b = ~b;
     s = 0;
   end
   s = s + x(k);
   y(k) = s;
 end

  One essential feature here is to provide an initial memory allocation for y. In this case it is done with "y = zeros(size(x));". Otherwise, repeated memory expansion slows things down.

Roger Stafford

Subject: Summing consecutively signed integers

From: Roger Stafford

Date: 27 Nov, 2012 04:19:15

Message: 9 of 12

"K" wrote in message <k90tqt$lpe$1@newscl01ah.mathworks.com>...
> For those interested, here is my for-loop solution.
- - - - - - - - -
  My apologies. I didn't look at your code carefully enough to see what you were doing with zeros. Following up on a remark by dpb, I would be tempted to use a combination of vectorization and for-loop as follows:

 y = zeros(size(x)); % <-- Important!
 f = find([true;diff(sign(x))~=0;true]);
 for k = 1:length(f)-1
   t = f(k):f(k+1)-1;
   y(t) = cumsum(x(t));
 end
 y(x==0) = NaN;

Roger Stafford

Subject: Summing consecutively signed integers

From: K

Date: 27 Nov, 2012 16:53:17

Message: 10 of 12

> y = zeros(size(x)); % <-- Important!
> f = find([true;diff(sign(x))~=0;true]);
> for k = 1:length(f)-1
> t = f(k):f(k+1)-1;
> y(t) = cumsum(x(t));
> end
> y(x==0) = NaN;

Thanks for the shortened version. There seems to be a slight error here though. Best illustrated through this:

X inputs:
0
0
-0.0831258083036675
0
1.84389916830085
-0.150257539613450
-1.44635351810500
1.79129614112950
-0.912879153611207
-1.09397446371066
0.949512487814987

My code's output:
0
NaN
-0.0831258083036675
NaN
1.84389916830085
-0.150257539613450
-1.59661105771845
1.79129614112950
-0.912879153611207
-2.00685361732186
0.949512487814987

Your code's output:
NaN
NaN
-0.0831258083036675
NaN
1.84389916830085
-0.150257539613450
-1.74686859733190
1.79129614112950
-0.912879153611207
-2.91973277093307
0.949512487814987


Notice positions 6 and 7, specifically. In your code, the addition is happening to the previous variable from the output, whereas in my code it's adding from the original input. I'm trying to figure out exactly what your code is doing so that I can adjust it. It's much more compact and nice-looking.

Subject: Summing consecutively signed integers

From: K

Date: 27 Nov, 2012 17:46:12

Message: 11 of 12

> Notice positions 6 and 7, specifically. In your code, the addition is happening to the previous variable from the output, whereas in my code it's adding from the original input. I'm trying to figure out exactly what your code is doing so that I can adjust it. It's much more compact and nice-looking.

My apologies, I was incorrect. Your code works fine. The input I was giving was incorrect.

Many thanks!

Subject: Summing consecutively signed integers

From: Roger Stafford

Date: 29 Nov, 2012 02:50:23

Message: 12 of 12

"K" wrote in message <k92u94$est$1@newscl01ah.mathworks.com>...
> My apologies, I was incorrect. Your code works fine. The input I was giving was incorrect.
- - - - - - - -
  In spite of my earlier misgivings, here is a version that is completely free of for-loops. It requires only six lines but I fear those six lines will use up more CPU time than a well-designed for-loop version would. Note also that for very long sequences in x the cumulative error in this method with fractional values would be somewhat greater than with the use of a for-loop. Anyway you can try it. It is assumed here that x is a column vector.

 f = find(diff(sign(x))~=0);
 cx = cumsum(x);
 y = zeros(size(x));
 y(f+1) = diff([0;cx(f)]);
 y = cx-cumsum(y);
 y(x==0) = NaN; % <-- The result is now in y

Roger Stafford

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