Marking and finding locations of elements of array in Matlab - arrays

I have a matrix having values between [0,1]. I want to find and mark the locations of those elements which have values <0.1 and >0.9.
So I use the matlab function find; but it returns me two vectors: a row and column vector distinctly which is difficult for analysis. So is there a way by which I can see the location of which elements meet the conditions without losing the original matrix structure?
I used the below line of code:
[r,c,v]= find(X<0.1 | X>0.9); % X is my 512*512 matrix of values
Thanks!

See if this works out for you -
%// cell array with each cell housing the matching indices for each row
out = cellfun(#find,mat2cell(X<0.1 | X>0.9,ones(1,size(X,1)),size(X,2)),'uni',0)
Browse through the values of out using - celldisp(out)

Just by using condition like this :
mask = (X < 0.1 | X > 0.9)
Will return an array logical with 1 where condition is respected.

Related

Sub2ind with three dimension - access all of dimension

Say A is a 3x4x5 array. I am given a vector a, say of dimension 2 and b of dimension 2. If I do A(a,b,:) it will give 5 matrices of dimensions 2x2. I instead want the piecewise vectors (without writing a for loop).
So, I want the two vectors of A which are given by (a's first element and b's first element) and (a's second element and b's second element)
How do I do this without a for loop? If A were two dimensions I could do this using sub2ind. I don't know how to access the entire vectors.
You can use sub2ind to find the linear index to the first element of each output vector: ind = sub2ind(size(A),a,b). To get the whole vectors, you can't do A(ind,:), because the : has to be the 3rd dimension. However, what you can do is reshape A to be 2D, collapsing the first two dimensions into one. We have a linear index to the vectors we want, that will correctly index the first dimension of this reshaped A:
% input:
A = rand(3,4,5);
a = [2,3];
b = [1,2];
% expected:
B = [squeeze(A(a(1),b(1),:)).';squeeze(A(a(2),b(2),:)).']
% solution:
ind = sub2ind(size(A),a,b);
C = reshape(A,[],size(A,3));
C = C(ind,:)
assert(isequal(B,C))
You can change a and b to be 3d arrays just like A and then the sub2ind should be able to index the whole matrix. Like this:
Edit: Someone pointed out a bug. I have changed it so that a correction gets added. The problem was that ind1, which should have had the index number for each desired element of A was only indexing the first "plane" of A. The fix is that for each additional "plane" in the z direction, the total number of elements in A in the previous "planes" must be added to the index.
A=rand(3,4,5);
a=[2,3];
b=[1,2];
a=repmat(a,1,1,size(A,3));
b=repmat(b,1,1,size(A,3));
ind1=sub2ind(size(A),a,b);
correction=(size(A,1)*size(A,2))*(0:size(A,3)-1);
correction=permute(correction,[3 1 2]);
ind1=ind1+repmat(correction,1,2,1);
out=A(ind1)

Matrix - Vector value matching

In my current project, I need to find values inside of an matrix that match with individual vector values. This is an example of the process; the main program has me using lat and lon values. But I create a 20x20 matrix and then a 20x1 array of randomly placed values.
When i do the for loop, each iteration of the Leroy vector is subtracted from every value in matrix. The first min function should return the smallest value from each column and its correspoding index. The second min function should return the smallest overall value from the first min function. and which index had the smallest value.
My concern is that im not sure which integer inside the matrix returned the smallest value. Is there a way I can use the indexes or something to figure that out?
Matrix = magic(20);
Leroy = randi(20,20,1);
for i = 1:length(Leroy)
[Jenkins, J] = min(min(Leroy(i) - Matrix);
end
As Cris Luego pointed in his comment, your for loop is not required since
Leroy(i) - Matrix
translates to something like
5 - [1 2 3; 4 5 6; 7 8 9]
However, your problem to get the index of the minimum in -Matrix can be solved by using min(-Matrix(:)):
[minimum, minidx] = min(-Matrix(:));
However, you will get the linear index. If you need the index for row and column, use
[colidx,rowidx] = ind2sub(size(Matrix), minidx);
Matrix = magic(20);
Leroy = randi(20,20,1);
for i = 1:length(Leroy)
[Jenkins, J] = min((Leroy(i) - Matrix).^2);
end
Using this will help get a match between two values in two arrays or a match between array values and matrix values

How to get the mean of first values in arrays in matrix in Matlab

If I have a square matrix of arrays such as:
[1,2], [2,3]
[5,9], [1,4]
And I want to get the mean of the first values in the arrays of each row such:
1.5
3
Is this possible in Matlab?
I've used the mean(matrix, 2) command to do this with a matrix of single values, but I'm not sure how to extend this to deal with the arrays.
Get the first elements in all arrays of matrix, then call mean function
mean(matrix(:,:,1))
maybe you need to reshape before call mean
a = matrix(:,:,1);
mean(a(:))
You can apply mean function inside mean function to get the total mean value of the 2D array at index 1. You can do similary with array at index 2. Consider the following snapshot.
After staring at your problem for a long time, it looks like your input is a 3D matrix where each row of your formatting corresponds to a 2D matrix slice. Therefore, in proper MATLAB syntax, your matrix is actually:
M = cat(3, [1,2; 2,3], [5,9; 1,4]);
We thus get:
>> M = cat(3, [1,2; 2,3], [5,9; 1,4])
M(:,:,1) =
1 2
2 3
M(:,:,2) =
5 9
1 4
The first slice is the matrix [1,2; 2,3] and the second slice is [5,9; 1,4]. From what it looks like, you would like the mean of only the first column of every slice and return this as a single vector of values. Therefore, use the mean function and index into the first column for all rows and slices. This will unfortunately become a singleton 3D array so you'll need to squeeze out the singleton dimensions.
Without further ado:
O = squeeze(mean(M(:,1,:)))
We thus get:
>> O = squeeze(mean(M(:,1,:)))
O =
1.5000
3.0000

Inserting a constant array in between every other column

Let's say, I have an M x N matrix. Now, I want to insert a constant M x 1 column vector (say all 1's) in between each of the N columns. Therefore, my resulting matrix would be of dimension (M x (2*N-1)), with every other column being 1's.
Is there an easy way to do that?
Vertically concatenate a matrix of ones, reshape, and cut off the last column of ones. For a matrix A:
B = reshape([A; ones(size(A))],size(A,1),[]);
B(:,end)=[]
Here is another way to do it, using the possibility of out of bounds indexing in assignments:
M(:,1:2:end*2)=M;
M(:,2:2:end)=1
If you don't mind creating a temporary matrix, one way to do it would be to do the following:
old_matrix = rand(M,N); % Just for example
new_matrix = ones(M,2*N-1);
new_matrix(:,1:2:end) = old_matrix;
Note that for an arbitrary constant matrix, you could replace the second line with the following:
new_matrix = repmat(const_array,1,2*N-1);

Sorting elements of a single array into different subarrays

I have an 1000 element array with values ranging from 1 - 120. I want to split this array into 6 different subarrays with respect to the value range
for ex:
array1 with values from ranges 0-20.
array 2 with values from range 20-40........100-120 etc.
At the end I would like to plot a histogram with X-axis as the range and each bar depicting the number of elements in that range. I dont know of any other way for 'this' kind of plotting.
Thanks
In other words, you want to create a histogram. Matlab's hist() will do this for you.
If you only need the histogram, you can achieve the result using histc, like this:
edges = 0:20:120; % edges to compute histogram
n = histc(array,edges);
n = n(1:end-1); % remove last (no needed in your case; see "histc" doc)
bar(edges(1:end-1)+diff(edges)/2, n); % do the plot. For x axis use
% mean value of each bin

Resources