Extract values from 2d array with indices from another array (without loops) - matlab

I have an array [2; 3] and a matrix [ 1 3 4 5; 2 4 9 2].
Now I would like to extract the second element from the first row and the third element from the second row and thus obtain [3 ; 9]. I managed it to do it with a loop, but since I'm working with much larger arrays, I would like to avoid these.

You can use sub2ind to convert each of the column subscripts (along with their row subscripts) into a linear index and then use that to index into your matrix.
A = [1 3 4 5; 2 4 9 2];
cols = [2; 3];
% Compute the linear index using sub2ind
inds = sub2ind(size(A), (1:numel(cols)).', cols);
B = A(inds)
% 3
% 9
Alternately, you could compute the linear indices yourself which is going to be more performant than sub2ind
B = A((cols - 1) * size(A, 1) + (1:numel(cols)).');
% 3
% 9

By exploiting the diag function, you can obtain an elegant one-line solution:
A = [1 3 4 5; 2 4 9 2];
cols = [2; 3];
B = diag(A(:,cols))
% 3
% 9
Here is what diag(A(:,cols)) does:
A(:,cols) selects the columns cols of A, with column k of A(:,cols) corresponding to the column cols(k) of A, giving [3 4; 4 9];
diag returns the diagonal entries of this matrix, thus returning at position k the k-th diagonal element of A(:,cols), which is A(k,cols(k)).

Related

how to find the order of elements in array in Matlab?

If I have an array of A = [10 1 5 20] I want a program to find indexes of the elements. In this case Idx = [3 1 2 4]. I am using [~,Idx]=sort([10 1 5 20]) and get the following:
Idx =
2 3 1 4
It's totally not what I expected. I even don't understand how the program got those numbers.
It is simple:
A = [10 1 5 20];
[~, Idx] = sort(A);
[~, orders] = sort(Idx);
% orders
% [3 1 2 4]
orders is your answer. You need to get the indices of sorted Idx.
Note that Idx(i) represents the index of i-th element in the original array A.

Index array of every element in MATLAB?

This might be a basic question.
To find out the maximum value and its index in array in MATLAB, I have used this code:
A = [1 2 3; 4 5 6; 7 8 9]
[val, idx] = max(A, [], 2);
Now, how can I find the index array of all the element (not finding maximum)?
May be you are talking bout subindices and global indices. Read about sub2ind and ind2sub. Check the below demo:
A = [1 2 3; 4 5 6; 7 8 9] ;
[m,n] = size(A) ;
% sub indices
[J,I] = meshgrid(1:m,1:n) ;
% global indices
idx = sub2ind(size(A),I,J)

shifting versions of a matrix

I have a m-by-n matrix and I want to shift each row elements k no. of times (" one resultant matrix for each one shift so a total of k matrices corresponding to each row shifts ")(k can be different for different rows and 0<=k<=n) and want to index all the resultant matrices corresponding to each individual shift.
Eg: I have the matrix: [1 2 3 4; 5 6 7 8; 2 3 4 5]. Now, say, I want to shift row1 by 2 times (i.e. k=2 for row1) and row2 by 3times (i.e. k=3 for row2) and want to index all the shifted versions of matrices (It is similar to combinatorics of rows but with limited and diffeent no. of shifts to each row).
Can someone help to write up the code? (please help to write the general code but not for the example I mentioned here)
I found the following question useful to some extent, but it won't solve my problem as my problem looks like a special case of this problem:
Matlab: How to get all the possible different matrices by shifting it's rows (Update: each row has a different step)
See if this works for you -
%// Input m-by-n matrix
A = rand(2,5) %// Edit this to your data
%// Initialize shifts, k for each row. The number of elements would be m.
sr = [2 3]; %// Edit this to your data
[m,n] = size(A); %// Get size
%// Get all the shits in one go
sr_ind = arrayfun(#(x) 0:x,sr,'un',0); %//'
shifts = allcomb(sr_ind{:},'matlab')'; %//'
for k1 = 1:size(shifts,2)
%// Get shift to be used for each row for each iteration
shift1 = shifts(:,k1);
%// Get circularly shifted column indices
t2 = mod(bsxfun(#minus,1:n,shift1),n);
t2(t2==0) = n;
%// Get the linear indices and use them to index into input to get the output
ind = bsxfun(#plus,[1:m]',(t2-1)*m); %//'
all_matrices = A(ind) %// outputs
end
Please note that this code uses MATLAB file-exchange code allcomb.
If your problem in reality is not more complex than what you showed us, it can be done by a double loop. However, i don't like my solution, because you would need another nested loop for each row you want to shift. Also it generates all shift-combinations from your given k-numbers, so it has alot of overhead. But this can be a start:
% input
m = [1 2 3 4; 5 6 7 8; 2 3 4 5];
shift_times = {0:2, 0:3}; % 2 times for row 1, 3 times for row 2
% desird results
desired_matrices{1} = [4 1 2 3; 5 6 7 8; 2 3 4 5];
desired_matrices{2} = [3 4 1 2; 5 6 7 8; 2 3 4 5];
desired_matrices{3} = [1 2 3 4; 8 5 6 7; 2 3 4 5];
desired_matrices{4} = [4 1 2 3; 8 5 6 7; 2 3 4 5];
desired_matrices{5} = [3 4 1 2; 8 5 6 7; 2 3 4 5];
% info needed:
[rows, cols] = size(m);
count = 0;
% make all shift combinations
for shift1 = shift_times{1}
% shift row 1
m_shifted = m;
idx_shifted = [circshift([1:cols]',shift1)]';
m_shifted(1, :) = m_shifted(1, idx_shifted);
for shift2 = shift_times{2}
% shift row 2
idx_shifted = [circshift([1:cols]',shift2)]';
m_shifted(2, :) = m_shifted(r_s, idx_shifted);
% store them
store{shift1+1, shift2+1} = m_shifted;
end
end
% store{i+1, j+1} stores row 1 shifted by i and row 2 shifted by j
% example
all(all(store{2,1} == desired_matrices{1})) % row1: 1, row2: 0
all(all(store{2,2} == desired_matrices{4})) % row1: 1, row2: 1
all(all(store{3,2} == desired_matrices{5})) % row1: 2, row2: 1

How to get row and column of actual element in Octave/MatLab

I'm trying to get the row of the actual element (indX) in a matrix when I use this
matrix2 = matrix .* indX;
Suppose that matrix = ones(2,2)
I'm waiting matrix2 with these values [1 1; 2 2]
I can use "for" for this
[rows columns] = size(matrix) for (indX=0; indX<rows; indX++) matrix2(indX,:) = matrix(indX,:) .* indX;endfor
Is it possible to get the indX without make use of "for" ?
If yes, how can I do that ?
You can use bsxfun:
matrix2 = bsxfun(#times, (1:size(matrix,1))', matrix); %'
matrix =
4 2
3 3
4 1
>> bsxfun(#times, (1:size(matrix,1))', matrix ), % '
ans =
4 2
6 6
12 3

Randomly interchange columns of a matrix: Matlab

Suppose
A = [1 2 3 5 7 9
6 5 0 3 2 3]
I want to randomize the position of the matrix column position; to give B like so:
B = [3 9 1 7 2 5
0 3 6 2 5 3]
How can I do this Matlab?
Try
B = A(randperm(length(A)))
Consult the documentation for explanations.
Now that code is formatted properly, it's clear the OP wants column preservation, although randperm is still the easiest option as given by HPM's answer.
idx = randperm(size(A,2)); % Create list of integers 1:n, in random order,
% where n = num of columns
B = A(:, idx); % Shuffles columns about, on all rows, to indixes in idx
You'll want to use the randperm function to generate a random permutation of column indices (from 1 to the number of columns in A), which you can then index A with:
B = A(:, randperm(size(A, 2)));