MATLAB Answers

0

How to get the sum of numbers below a desired number in sets?

Asked by Prashant Kataria on 8 Dec 2018 at 20:23
Latest activity Edited by per isakson
on 9 Dec 2018 at 0:56
How to get the sum of the numbers in the array which are below -1 in sets.
For example
a=[1 -2 0 .5 -3 -4 5 7 -2 -3 -4];
so here the numbers which are consecutively less than -1 should be added only.
i.e. The answer should be
b=[-2 -7 -10]
PS: Actual data is very big.

  0 Comments

Sign in to comment.

Products


Release

R2013a

2 Answers

Answer by per isakson
on 8 Dec 2018 at 21:27
Edited by per isakson
on 9 Dec 2018 at 0:56

"data is very big" How big is that? Does it fit in the memory?
Test this function
function b = cssm( a )
%{
b = cssm([-2,0,.5,-3,-4,5,7,-2,-3,-4]);
b = cssm([1,-2,0,.5,-3,-4,5,7,-2,-3,-4]);
b = cssm([1,-2,0,.5,-3,-4,5,7,-2,-3,-4,3]);
a = randn(1,1e6);
tic, b = cssm( a ); toc
%}
%%
b = zeros(size(a));
%%
kk = 1;
for jj = find(a<-1,1,'first') : length(a)
if a(jj) < -1
b(kk) = b(kk) + a(jj);
else
if b(kk) ~= 0
kk = kk+1;
end
end
end
if a(end) < -1
b( kk+1 : end ) = [];
else
b( kk : end ) = [];
end
end
Performance comparison with the solution of Image Analyst
The test below indicates that the solution using a for-loop is significantly faster - in this case.
>> a = randn(1,1e6);
>> [ isEQ, et ] = cssm( a )
isEQ =
logical
1
et =
0.0069 1.0598
>> a = randi([-12,12],1,1e6,'int8');
>> [ isEQ, et ] = cssm( a )
isEQ =
logical
1
et =
0.0138 3.5893
where
function [ isEQ, et ] = cssm( a )
tic
b1 = loop( a );
et(1) = toc;
tic
b2 = ia( a );
et(2) = toc;
isEQ = all(abs(b1-b2)<1e-6);
end
function b = loop( a )
%%
b = zeros(size(a));
%%
kk = 1;
for jj = find(a<-1,1,'first') : length(a)
if a(jj) < -1
b(kk) = b(kk) + a(jj);
else
if b(kk) ~= 0
kk = kk+1;
end
end
end
if a(end) < -1
b( kk+1 : end ) = [];
else
b( kk : end ) = [];
end
end
function output = ia( a )
props = regionprops(a < -1, a, 'Area', 'MeanIntensity');
output = [props.Area] .* [props.MeanIntensity];
end
Caveat: It happens that I maketakes.

  0 Comments

Sign in to comment.


Answer by Image Analyst
on 8 Dec 2018 at 22:42
Edited by Image Analyst
on 8 Dec 2018 at 22:43

These two lines of code will do it.
a = [1 -2 0 .5 -3 -4 5 7 -2 -3 -4];
props = regionprops(a < -1, a, 'Area', 'MeanIntensity');
output = [props.Area] .* [props.MeanIntensity]
How big are your arrays? This should be pretty speedy for up to tens or hundreds of millions of elements. If you have gigabyte sized arrays, it could take a few minutes. The code requires the Image Processing Toolbox.

  0 Comments

Sign in to comment.