sorting a matrix in MATLAB - matlab

I have a matrix that contains ( 6 rows, 2 columns) as shown in the attached image.
I'd like to have a new matrix (in MATLAB) that contains the second columns arranged in ascending order, but would like to keep their corresponding values in the row.
for example: the output matrix looks like this

You can do it as follows:
mat = randi(30, [6 2]); % creating the matrix
[mat(:,2),ind] = sort(mat(:,2));
mat(:,1) = mat(ind,1);
If you have access to the sortrows function, it is simpler:
mat = sortrows(mat,2);

Related

Allocating elements from a smaller matrix to a bigger one by user input

I have 3 smaller matrices (in multidimensional arrays), all of them 4x4. I want to build a bigger matrix (8x8) for each smaller one, but rearranging the position of each element of the smaller matrix into a new position in the bigger one, according to user matrix input:
For example, I have those 3 little matrices:
A=repmat(1, [4 4]);
B=repmat(2, [4 4]);
C=repmat(3, [4 4]);
and the bigger one K=zeros(8);. The user input matrix is this one:
user=[1 2 7 8; 3 4 1 2; 3 4 7 8];
So the first bigger matrix must have a configuration where:
The red numbers are the new row and columns in the bigger matrix, resulting in this for K:
How can I insert values from the smaller matrices to the bigger matrix in this way?
It is not clear why you need this, but this is the solution I thought.
K = zeros(8,8);
for ii=1:4
for jj=1:4
K(user(1,ii),user(1,jj)) = A(ii,jj);
K(user(2,ii),user(2,jj)) = B(ii,jj);
K(user(3,ii),user(3,jj)) = C(ii,jj);
end
end
You can easily do this by using a row of user as the row and column indices into K, like so:
K(user(1, :), user(1, :)) = A;
If you want to iterate over each smaller matrix and user input, inserting them all into the same larger matrix K, I'd first put the smaller matrices into a single cell array, then simply repeat the above in a for loop:
smallMats = {A, B, C};
K = zeros(8);
for row = 1:size(user, 1)
K(user(row, :), user(row, :)) = smallMats{row};
end
This can easily be extended to more matrices by adding to user and smallMats.

MATLAB: Accessing Multidimensional Cell Matrix Index

I have cell matrix which the dimensions are changing according to user input. As a user, I want to use one dimension's certain index meanwhile whole the elements of the other dimensions exist. I think it is better to explain the situation with a certain example:
Assume that my cell matrix A whose sizes are 2x3x4x5x7. I want to use whole elements of 1.,3. and 4. dimension. At the same time only the 2. element of the 2. dimension and 3., 5. elements of 5. dimension. This can be achieved easily with :
A(:,2,:,:,[3 5]);
What about the case A is input of a function and dimensions are changing. How can I obtain this result with linear indexing or another way?
I know that there is no such a syntax but my situation can be described as follows:
whole_indexes = sub2ind(size(A),[:,2,:,:,[3,5]]);
A(whole_indexes)
This problem can be solved the with the code below:
size_A = size(A); % A is the matrix whose elements will be selected
whole_index = cellfun(#(x) 1:x,num2cell(size_A),'UniformOut',false); % create a cell array which includes all the possible numbers
all_sizes = cellfun(#length,whole_index); % each dimension size
%% select the desired indexes in your desired dimensions
whole_index{1} = [1 2]; % first dimension first 2 elements
whole_index{2} = [2]; % second dimension second element
all_numbers = combvec(whole_index{:}).'; % whole possibilities
all_numbers = mat2cell(all_numbers,max(size_nums),ones(1,min(size_nums))); % cell format of possibilities
comb_inds = sub2ind(all_sizes,all_numbers{:});
desired_out = A(comb_inds);
Another solution would be written like:
size_A = size(A); % A is the matrix whose elements will be selected
whole_index = cellfun(#(x) 1:x,num2cell(size_A),'UniformOut',false);
%% select the desired indexes in your desired dimensions
whole_index{1} = [1 2]; % first dimension first 2 elements
whole_index{2} = [2]; % second dimension second element
desired_out = A(whole_index{:});

How to create matrix of nearest neighbours from dataset using matrix of indices - matlab

I have an Nx2 matrix of data points where each row is a data point. I also have an NxK matrix of indices of the K nearest neighbours from the knnsearch function. I am trying to create a matrix that contains in each row the data point followed by the K neighbouring data points, i.e. for K = 2 we would have something like [data1, neighbour1, neighbour2] for each row.
I have been messing round with loops and attempting to index with matrices but to no avail, the fact that each datapoint is 1x2 is confusing me.
My ultimate aim is to calculate gradients to train an RBF network in a similar manner to:
D = (x_dist - y_dist)./(y_dist+(y_dist==0));
temp = y';
neg_gradient = -2.*sum(kron(D, ones(1,2)) .* ...
(repmat(y, 1, ndata) - repmat((temp(:))', ndata, 1)), 1);
neg_gradient = (reshape(neg_gradient, net.nout, ndata))';
You could use something along those lines:
K = 2;
nearest = knnsearch(data, data, 'K', K+1);%// Gets point itself and K nearest ones
mat = reshape(data(nearest.',:).',[],N).'; %// Extracts the coordinates
We generate data(nearest.',:) to get a 3*N-by-2 matrix, where every 3 consecutive rows are the points that correspond to each other. We transpose this to get the xy-coordinates into the same column. (MATLAB is column major, i.e. values in a column are stored consecutively). Then we reshape the data, so every column contains the xy-coordinates of the rows of nearest. So we only need to transpose once more in the end.

How to access particular matrix element for all blocks in entire image?

I have a 512x512 image , which i made 4x4 block for entire image, then i want access the (3rd row , 3rd element) of the all indivial 4x4 matrices and add it to the index values, which i obtained. Please help me on below code.
[row col] = size(a);
m = zeros(row,col);
count = [(row-4)*(col-4)]/4;
outMat = zeros(4,4,count);
l = 0;
for i=2:4:row-4
for j=2:4:col-4
l = l + 1;
outMat(:,:,l) = double(a(i-1:i+2,j-1:j+2));% for each matrix i have to find(3rd row,3rd element of each matrix.
end;
end;
Adding the (3rd row,3rd element):
m(i,j) = sum(sum(a .* w)); %index value of each 4x4 matrix % w = 4x4 matrix.
LUT = m(i,j)+ outMat(3,3);%(3rd row,3rd element each matrix should be added to all m(i,j) values. In which i fail to add all(3rd row,3rd element) of all 4x4 matrices.
I am going to reword your question so that it's easier to understand, as well as allowing it to be easy for me to write an answer.
From your comments in Kostya's post, you have two images img1 and img2 where they are decomposed into 4 x 4 blocks. outMat would be a 3D matrix where each slice contains a 4 x 4 block extracted from img1. From this, you have a matrix m that stores a weighted sum of 4 x 4 blocks stored outMat.
Next, you'll have another matrix, let's call this outMat2, which also is a 3D matrix where each slice is a 4 x 4 block extracted from img2. From this 3D matrix, you wish to extract the third row and third column of each block, add this to the corresponding position of m and store the output into a variable called LUT.
All you have to do is extract a single vector that slices through all of the slices located at the third row and third column. You would then have to reshape this into a matrix that is the same size as m then add this on top of m and store it into a variable called LUT. Bear in mind that if we reshape this into a matrix, the reshaping will be done in column major format, and so you would stack the values by columns. Because your blocks were created row-wise, what we need to do reshape this matrix so that it has size(m,2) rows and size(m,1) columns then transpose it.
Therefore:
vec = outMat2(3,3,:);
vec = vec(:); %// Make sure it's a 1D vector
m2 = reshape(vec, size(m,2), size(m,1)).';
LUT = m + m2;
LUT will contain a 2D matrix where each element contains the weighted sum of the 4 x 4 blocks from img1 with the corresponding third row, third column of each block in img2.
Next time, please update your question so that you have all of the information. We shouldn't have to dig through your comments to figure out what you want.
I think you can do just
LUT = sum( sum( a(3:4:row,3:4,col) * w(3,3) ) );

2d matrix histogram in matlab that interprets each column as a separate element

I have a 128 x 100 matrix in matlab, where each column should be treated as a separate element. Lets call this matrix M.
I have another 128 x 2000 matrix(called V) composed of columns from matrix M.
How would I make a histogram that maps the frequency of each column being used in the second matrix?
hist(double(V),double(M)) gives the error:
Error using histc
Edge vector must be monotonically
non-decreasing.
what should I be doing?
Here is an example. We start with data that resembles what you described
%# a matrix of 100 columns
M = rand(128,100);
sz = size(M);
%# a matrix composed of randomly selected columns of M (with replacement)
V = M(:,randi([1 sz(2)],[1 2000]));
Then:
%# map the columns to indices starting at 1
[~,~,idx] = unique([M,V]', 'rows', 'stable');
idx = idx(sz(2)+1:end);
%# count how many times each column occurs
count = histc(idx, 1:sz(2));
%# plot histogram
bar(1:sz(2), count, 'histc')
xlabel('column index'), ylabel('frequency')
set(gca, 'XLim',[1 sz(2)])
[Lia,Locb] = ismember(A,B,'rows') also returns a vector, Locb,
containing the highest index in B for each row in A that is also a row
in B. The output vector, Locb, contains 0 wherever A is not a row of
B.
ismember with the rows argument can identify which row of one matrix the rows of another matrix come from. Since it works on rows, and you are looking for columns, just transpose both matrices.
[~,Locb]=ismember(V',M');
histc(Locb)