Reputation: 253
I am assigning a 3D array, which contains some information for a number of different loadcases. Each row in the array defines a particular loadcase (of which there are 3) and I would like to remove the loadcase (i.e. the row) if ALL the elements of the row (in 3D) are equal to zero.
The code I have at the moment is:
Array = zeros(3,5) %# Initialise array
Numloadcases = 3;
Array(:,:,1) = [10 10 10 10 10;
0 0 0 0 0;
0 0 0 0 0;]; %# Expand to a 3D array
Array(:,:,2) = [10 10 10 10 10;
0 0 0 0 0;
0 0 0 0 0;];
Array(:,:,3) = [10 10 10 10 10;
0 0 0 0 0;
0 0 20 0 0;];
Array(:,:,4) = [10 10 10 10 10;
0 0 0 0 0;
0 0 20 0 0;];
%# And to remove the second row:
for i = 1:Numloadcases
if sum(Array(i,:,:)) == 0
Array(i,:,:) = [];
end
end
At the moment, the for loop I have to remove the rows causes an indexing error, as the size of the array changes in the loop.
Can anyone see a work around for this?
Upvotes: 2
Views: 3327
Reputation: 5595
the matlab command "any" tells you if there are any nonzero elements.
sum(Array(i,:,:) == 0) will produce true for some mixtures of positive and negative elements (e.g. [1 1 -2]) which is probably not the way to do it.
I would love to be clever and tell you how to do this with no for loops, but the overhead on a for loop here is small and the code is probably clearer if you keep your for loop. Your mistake is this line:
Array(i,:,:) = []
which probably causes Matlab to yell at you about a mismatch in the number of elements
the fix is to keep track of what elements you want to delete, then take care of that at the end of the loop
valid = false([1 Numloadcases]); %preallocate
for i = 1:Numloadcases
valid(i) = any(any(Array(i,:,:)));
end
Array = Array(valid,:,:);
If Array is a general ND array you probably don't want to tile up a bunch of any commands, so this alternate formulation will work
valid = false([1 Numloacases]);
for i = 1:Numloadcases
valid(i) = any(reshape(Array(i,:,:), 1, []);
end
Array = Array(valid,:,:);
Upvotes: 0
Reputation: 125864
Here is an alternative to looping, using the function ALL and logical indexing:
isAllZero = all(all(Array == 0,3),2); %# Logical index of rows with all zeroes
Array = Array(~isAllZero,:,:); %# Keep rows that have non-zero values
%# Or...
Array(isAllZero,:,:) = []; %# Set rows with all zeroes to the empty matrix
Upvotes: 3