MATLAB - Get rid of leading zeros in each row of matrix, 1 at a time? - matlab

I want to get rid of leading zeros in each row of a matrix, but limit it to eliminating one zero at a time.
This is my current solution, but is there a simpler way of doing it?
a = [ 0 0 0 0 0 0 0 0 0 0
0 0 5 2 3 4 0 0 0 0
0 0 0 1 2 3 4 0 0 0
0 0 1 2 3 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0 ]
b=zeros(size(a));
for j=1:size(a,2)
for i=1:size(a,1)
temp=find(a(i,:),1,'first');
candelete=min(2,temp);
b(i,1:end-candelete+1)=a(i,candelete:end);
end
a=b
end
EDIT:
I'm want to print every iteration, so that the first output will only have the first leading zero removed:
0 0 0 0 0 0 0 0 0 0
0 5 2 3 4 0 0 0 0 0
0 0 1 2 3 4 0 0 0 0
0 1 2 3 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0
the second will have 2 zeros removed, and so on...

EDIT: Now that the question was clarified, here's a better answer using circshift:
index = (a(:, 1) == 0) & any(a, 2);
while any(index)
a(index, :) = circshift(a(index, :), -1, 2);
disp(a);
index = (a(:, 1) == 0) & index;
end

Related

Advanced Search and Remove in special Matrix

I have this matrix
X= [2 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0 0 1 0 1 250;
3 0 0 1 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1 250;
2 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0 0 1 0 1 250;
3 0 0 1 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1 250;
4 0 0 1 0 1 0 0 1 0 0 0 0 0 1 1 0 0 0 0 0 0 250;
3 0 0 1 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1 250;
2 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0 0 1 0 1 250;
4 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 1 1 0 0 0 0 250;
3 0 0 1 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1 250;
3 1 1 1 0 0 1 0 0 1 0 0 1 0 0 0 0 1 0 1 0 0 400]
I need to do three different sequence things in this matrix:
1- Search in this matrix to the following sequence 1 1 0 0 0 and write those rows that have this characteristic in new matrix (like row 1).
2- Use the matrix that generate in the first step and remove from it to the rows that have the same number in the same digits (like row 1,3,7) but at the same time keep only one row of each one (in the case of row 1,3,7 keep row 1 and remove other rows) .
3- use the matrix that generate in the second step and remove from this matrix any row that have following sequence 1 1 1 (like row 8) and put the other rows in this matrix in new matrix.
%Step-1
% Converting the matrix into a string, appending a semi-colon for similarity and removing the brackets from the string
req=mat2str(X); req(end)=';' ; req=req(2:end);
% Searching the sequence: 1 1 0 0 0
sp1=strfind(req, '1 1 0 0 0');
% Storing those rows of X in req matrix which contain the sequence
req=X(unique(ceil([sp1]/(size(req,2)/size(X,1)))),:);
%Step-2
req= unique(req,'rows');
%Step-3
% Converting the matrix into a string, appending a semi-colon for similarity and removing the brackets from the string
reqtemp=mat2str(req); reqtemp(end)=';' ; reqtemp=reqtemp(2:end);
% Searching the sequence: 1 1 1
sp1=strfind(reqtemp, '1 1 1');
% Removing those rows which contain the sequence
req(unique(ceil([sp1]/(size(reqtemp,2)/size(req,1)))),:)=[];

Interpolation inside a matrix. Matlab

I have a matrix looks like:
0 0 0 0 0
1 0 0 0 0
0 2 0 0 0
0 0 2 0 0
0 0 0 1 0
1 0 0 0 1
0 4 0 0 0
0 0 3 0 0
6 0 0 4 0
0 3 0 0 2
0 0 5 0 0
It is 11x5 matrix.
I want to interpolate between the values vertically for each column.
Any help ?
Thanks.
M =[0 0 0 0 0
1 0 0 0 0
0 2 0 0 0
0 0 2 0 0
0 0 0 1 0
1 0 0 0 1
0 4 0 0 0
0 0 3 0 0
6 0 0 4 0
0 3 0 0 2
0 0 5 0 0];
xi = 1:size(M,1)
for colIdx = 1:size(M,2)
col = M(:,colIdx);
x = xi(~~col); %// Note that ~~col is a logical vector of elements that are not equal to zero. i.e. it's the same as col ~= 0
y = col(~~col);
M(:,colIdx) = interp1(x,y,xi);
end
then if you want the outer points to be 0 add this line after the loop:
M(isnan(M)) = 0;

Extract multiple indices from matrix

I want to access multiple indices of a matrix as shown below. So what I want is indices (1,3),(2,6),(3,7) to be set to one. However, as you can see the entire column is set to one. I can see what it is doing but is there a way to do what I want it to (in an elegant way - no loops).
a=zeros(3,10)
a(1:3,[3 6 7])=1
a =
0 0 1 0 0 1 1 0 0 0
0 0 1 0 0 1 1 0 0 0
0 0 1 0 0 1 1 0 0 0
I realise that you can do something along the lines of
x_idx=1:3, y_idx=[3 6 7];
idx=x_idx*size(a,2)+y_idx;
a(idx)=1;
but just wondering if there was a better, or proper way of doing this in Matlab
You can use sub2ind, which essentially is doing what you have mentioned in your post, but MATLAB has this built-in:
a = zeros(3,10);
a(sub2ind(size(a), 1:3, [3 6 7])) = 1
a =
0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 1 0 0 0
Another way would be to create a logical sparse matrix, then use this to index into a:
a = zeros(3,10);
ind = logical(sparse(1:3, [3 6 7], true, size(a,1), size(a,2)));
a(ind) = 1
a =
0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 1 0 0 0

How to Count Total Number of pixel of padded value used in image(Padded Image)?

I have one binary image so it has only 2 value like 0 and 1. After, I convert this into a padded image of different values, like the image will have curve shape. I took a 3 X 3 matrix of value and if i get curve shape then I padded the image with 1, or any number. I use 15 different types shape values like junction point, end point etc.
After, I give the values 1 to 15 - or the appropriate number according its shape. As such, I am getting an image like:
Figure
0 0 0 0 0 0 0 0 0 0 5 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 5 0 0 0 0 0 0 0 1 1 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 5 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0
I would like to count how many 1s there are in the image, followed by 2s, 3s, etc. up to 15. For example,
as shown in the figure, if the pad number was 5, the total number of pixels would be 3. If the pad number was 1, the total number of pixels would be 6.
Use histc:
>> im = [ 0 0 0 0 0 0 0 0 0 0 5 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 5 0 0 0 0 0 0 0 1 1 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 5 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 ]; %// data
>> values = 1:15; %// possible values
>> count = histc(im(:), values)
count =
6 %// number of 1's
0 %// number of 2's, etc
0
0
3
0
0
0
0
0
0
0
0
0
0
Or compute it manually with bsxfun:
>> count = sum(bsxfun(#eq, im(:), values(:).'), 1)
>> count =
6 0 0 0 3 0 0 0 0 0 0 0 0 0 0
I can also suggest using accumarray:
im = [0 0 0 0 0 0 0 0 0 0 5 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 5 0 0 0 0 0 0 0 1 1 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 5 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 ]; %// data - borrowed from Luis Mendo
counts = accumarray(im(:) + 1, 1);
counts(1) = []
counts =
6
0
0
0
3
Note we have to offset by 1 as accumarray starts indexing the output array at 1. Because you want to disregard the 0s, I simply take the counts result and remove the first entry. This result agrees with what you are seeking. The first element is how many 1s we have encountered, which is 6. The last element is how many 5s you have encountered, which is 3. Because 5 is the largest number encountered in your image, we can say that all symbols after 5 (6, 7, 8, ..., 15) have a count of 0.

MATLAB one liner for batch assignment in 2D matrix?

Say I have a matrix
A = zeros(5, 5);
Instead of looping with a for loop, I wish to batch-modify some of the elements. For example, I wish to change elements marked by pts_to_modify to 1, where
pts_to_modify=[[2 3]; [3 2]];
So I wish A to become
0 0 0 0 0
0 0 1 0 0
0 1 0 0 0
0 0 0 0 0
However, when I do
A(pts_to_modify(:, 1), pts_to_modify(:, 2)) = 1,
I get
A =
0 0 0 0 0
0 1 1 0 0
0 1 1 0 0
0 0 0 0 0
0 0 0 0 0
How can I do it correctly?
You can use sub2ind:
>> ind = sub2ind(size(A), pts_to_modify(1,:), pts_to_modify(2,:))
ind =
12 8
>> A(ind) = 1
A =
0 0 0 0 0
0 0 1 0 0
0 1 0 0 0
0 0 0 0 0
0 0 0 0 0
sub2ind
linear indexing