This question already has answers here:
Verify a matrix value on MATLAB
(3 answers)
Closed 8 years ago.
I am using MATLAB. I have a question about how i can verify that the values of a matrix are being repeating, like this:
A=[ 2 3 2 3 2 3 2 3]
with the answer AUX=1
If the matrix A repeat at least the first two values for all columns after, i want a AUX = 1. but if not, only AUX= 0.
or
A=[ 2 3 3 2 2 3 3 2]
with the answer AUX=1
If the matrix A repeat like before, i want a AUX = 1. but if not, only AUX= 0.
The matrix A can also have zeros numbers after the numbers. (example, A = [ 1 2 1 2 1 0 0 0], A = [ 2 3 3 2 2 3 3 2 0 0 0 ].)
I think you are looking for this, finding whether the same two numbers are used in each non overlapping window of 2 values:
% Cutting off the tail
x = [1 2 2 1 1 2 1 2 0 0];
x = x(1:find(x,1,'last'));
x = x(1:2*fix(numel(x)/2));
% Checking for allowed values (the first 2 values, each one once)
M=sort(reshape(x,2,[]));
AUX = size(unique(M','rows'),1)==1
Note that this cuts of trailing zeros, so you may need an extra step if the number of remaining elements is not always odd but that should be easy.
% A
A = [1 2 3 4 4 5; 1 3 4 5 6 5; 6 7 4 1 3 3];
% make A a column vector
A_col = A(:);
% calculate histogram of A with max(A_col) bins
n = hist(A_col, max(A_col));
AUX = sum(n > 1) > 0
Related
This question already has answers here:
Generate a matrix containing all combinations of elements taken from n vectors
(4 answers)
Closed 6 years ago.
I'm trying to do the following in a general way:
x = {0:1, 2:3, 4:6};
[a,b,c] = ndgrid(x{:});
Res = [a(:), b(:), c(:)]
Res =
0 2 4
1 2 4
0 3 4
1 3 4
0 2 5
1 2 5
0 3 5
1 3 5
0 2 6
1 2 6
0 3 6
1 3 6
I believe I have to start the following way, but I can't figure out how to continue:
cell_grid = cell(1,numel(x));
[cell_grid{:}] = ndgrid(x{:});
[cell_grid{:}]
ans =
ans(:,:,1) =
0 0 2 3 4 4
1 1 2 3 4 4
ans(:,:,2) =
0 0 2 3 5 5
1 1 2 3 5 5
ans(:,:,3) =
0 0 2 3 6 6
1 1 2 3 6 6
I can solve this in many ways for the case with three variables [a, b, c], both with and without loops, but I start to struggle when I get more vectors. Reshaping it directly will not give the correct result, and mixing reshape with permute becomes really hard when I have arbitrary number of dimensions.
Can you think of a clever way to do this that scales to 3-30 vectors in x?
You can use cellfun to flatten each of the cell array elements and then concatenate them along the second dimension.
tmp = cellfun(#(x)x(:), cell_grid, 'uniformoutput', false);
out = cat(2, tmp{:})
Alternately, you could avoid cellfun and concatenate them along the dimension that is one higher than your dimension of each cell_grid member (i.e. numel(x) + 1). Then reshape to flatten all dimensions but the last one you just concatenated along.
out = reshape(cat(numel(x) + 1, cell_grid{:}), [], numel(x));
I have got a problem with splitting a vector by zeros.
I have a vector for example
v=[1 3 2 6 4 0 0 2 4 6 0 0 0 3 1]
I need to get vectors like
v1=[1 3 2 6 4]
v2=[2 4 6]
v3=[3 1]
Is there any way to do this by using MATLAB functions?
Of course I don't know of how many subvectors are included in main vector v and how many zeros delimits vectors.
I'm not a programmer and also I'm not a pro in MATLAB.
I know a procedural way to do this but want do it by MATLAB somehow.
I found a function A = strsplit(str,delimiter) but I don't have string I have a vector.
So I searched for conversion function. I found S = char(V) but when I executed it it crashed.
It's better to have the output as a cell array, not as separate variables. That way the output will be easier to handle.
Try this:
v = [1 3 2 6 4 0 0 2 4 6 0 0 0 3 1]; %// data
w = [false v~=0 false]; %// "close" v with zeros, and transform to logical
starts = find(w(2:end) & ~w(1:end-1)); %// find starts of runs of non-zeros
ends = find(~w(2:end) & w(1:end-1))-1; %// find ends of runs of non-zeros
result = arrayfun(#(s,e) v(s:e), starts, ends, 'uniformout', false); %// build result
Result (for your example):
>> result{:}
ans =
1 3 2 6 4
ans =
2 4 6
ans =
3 1
The strsplit() solution for a vector of whole numbers smaller than 9 (so a very specific solution, for a general solution see Luis Mendo's). Split and convert back to number:
res = strsplit(char(v), char(0));
res = cellfun(#(x) x - 0,res,'un',0);
celldisp(res)
res{1} =
1 3 2 6 4
res{2} =
2 4 6
res{3} =
3 1
In Matlab I have a big matrix containing the coordinates (x,y,z) of many points (over 200000). There is an extra column used as identification. I have written this code in order to sort all coordinate points. My final goal is to find duplicated points (rows with same x,y,z). After sorting the coordinate points I use the diff function, two consecutive rows of the matrix with the same coordinates will take value [0 0 0], and then with ismember I can find which rows of that matrix resulting from applying "diff" have the [0 0 0] row. With the indices returned from ismember I can find which points are repeated.
Back to my question...This is the code I wrote to sort properly my coordintes+id matrix. I guess It could be done better. Any suggestion?
%coordinates are always positive
a=[ 1 2 8 4; %sample matrix
1 0 5 6;
2 4 7 1;
3 2 1 0;
2 3 5 0;
3 1 2 8;
1 2 4 8];
b=a; %for checking purposes
%sorting first column
a=sortrows(a,1);
%sorting second column
for i=0:max(a(:,1));
k=find(a(:,1)==i);
if not(isempty(k))
a(k,:)=sortrows(a(k,:),2);
end
end
%Sorting third column
for i=0:max(a(:,2));
k=find(a(:,2)==i);
if not(isempty(k))
%identifying rows with same value on first column
for j=1:length(k)
[rows,~] = ismember(a(:,1:2), [ a(k(j),1),i],'rows');
a(rows,3:end)=sortrows(a(rows,3:end),1);
end
end
end
%Checking that rows remain the same
m=ismember(b,a,'rows');
if length(m)~=sum(m)
disp('Error while sorting!');
end
Why don't you just use unique?
[uniqueRows, ii, jj] = unique(a(:,1:3),'rows');
Example
a = [1 2 3 5
3 2 3 6
1 2 3 9
2 2 2 8];
gives
uniqueRows =
1 2 3
2 2 2
3 2 3
and
jj =
1
3
1
2
meaning third row equals first row.
If you need the full unique rows, including the fourth column: use ii to index a:
fullUniqueRows = a(ii,:);
which gives
fullUniqueRows =
1 2 3 9
2 2 2 8
3 2 3 6
Trying to sort a based on the fourth column? Do this -
a=[ 1 2 8 4; %sample matrix
1 0 5 6;
2 4 7 1;
3 2 1 0;
2 3 5 0;
3 2 1 8;
1 2 4 8];
[x,y] = sort(a(:,4))
sorted_a=a(y,:)
Trying to get the row indices having repeated x-y-z coordinates being represented by the first three columns? Do this -
out = sum(squeeze(all(bsxfun(#eq,a(:,1:3),permute(a(:,1:3),[3 2 1])),2)),2)>1
and use it similarly for sorted_a.
I have in a matrix data that contains 0 and 'proper' data. I want to crete several matrixes (new ones) to separate the data from the zeros and get rid of these zeros.
So, here is a simple example:
data = 1 3 6 4
3 6 9 5
4 5 6 2
0 0 0 0
0 0 0 0
2 4 1 8
1 4 6 5
0 0 0 0
1 7 9 1
3 4 5 8
And i want to get in this case two matrixes that would be:
A =1 3 6 4
3 6 9 5
4 5 6 2
B= 2 4 1 8
1 4 6 5
C = 1 7 9 1
3 4 5 8
Obviously my data files have thousands of datapoint and i need to automat this.
Any ideas how to do it?
Step 1: create an index of the rows containing only zeros using all:
index = all(data==0,2); #% data==0<-- logical matrix; the 2 means along dimension 2
Step 2: create vectors containing the first and last indices of each segment of desired values:
index = [1; double(index); 1]; #% convert to numeric and pad with ones
firsts = diff(index)==-1; #% 0 (real row) - 1 (spacer row) = -1
lasts = (diff(index)==1)-1; #% subtract 1 because of padding
Step 3: Create a cell array which contains sequential segments of the original matrix in each cell (using cell arrays, each cell can be a different size, or even a different type):
#% firsts and lasts should be the same length
#% iterate through lists of first/last indices
for ii=1:length(firsts)
result{ii} = data(firsts(ii):lasts(ii), :);
end
Obligatory Matlab public service announcement: i and j are popular loop index variables... you'll notice I used ii instead. Here's why.
here's an alternative way that keeps the # of columns of data in the resulted cell array:
L=bwlabel(data);
for n=1:max(L)
result{n}=reshape(data(L==n),[],size(data,2));
end
result =
[3x4 double] [2x4 double] [2x4 double]
result{1}
ans =
1 3 6 4
3 6 9 5
4 5 6 2
This question already has answers here:
Get the indices of the n largest elements in a matrix
(4 answers)
Closed 8 years ago.
Suppose I have a matrix
A=[2 3 4; 6 1 2]
I want to find 2 largest elements and make all the other elements zero.
In this case A finally becomes
A=[0 0 4; 6 0 0]
Your line of action should be:
Sort the matrix in descending order and obtain the order of the indices of the sorted elements.
Discard the first two indices and use the rest to zero out the corresponding elements in A.
Example
A = [2 3 4; 6 1 2];
[Y, idx] = sort(A(:), 'descend')
A(idx(3:end)) = 0
This should result in:
A =
0 0 4
6 0 0
>> A=[2 3 4; 6 1 2]
A =
2 3 4
6 1 2
>> [~,idx] = sort(A(:), 'descend');
>> A(idx(3:end))=0
A =
0 0 4
6 0 0