Find min of several columns in matlab without for loop - matlab

I have got a matrix M with R rows and C*k columns. I want to create another matrix F with R rows and C columns, so that
F(:,j) = min(M(:,(j-1)*k+1:j*k),[],2)
In other words first column of F should be min of first k columns of M.
Second column of F should be min of second k columns of M and so on.
I am trying to reshape matrix M to R*C x k matrix D find min and reshape it again to R x C matrix.But I cannot properly reshape M to F, so that F(i, :) = M(b, (j-1)*k+1:j*k)
Here is a small example:
k=2;
M = [1 2 3 4; 5 6 7 8; 9 10 11 12;];
then
F = [1 3; 5 7; 9 11];

Your best bet is probably to reshape it to an R x k x (C / k) matrix and then compute the min along the second dimension and then squeeze the result to remove the now-empty second dimension.
F = squeeze(min(reshape(M, size(M, 1), k, size(M, 2)/k), [], 2))

Related

How to index a matrix with the column maxima of other matrix

I have 2 matrices A and B.
I find the max values in the columns of A, and keep their indices in I. So far so good.
Now, I need to choose those arrays of B with the same index as stored in I. I don't know how to do this.
See below:
A = [1,2,3; 0,8,9]
B = [0,1,2; 4,2,3]
[~,I] = max(A)
h = B(I)
I need to get these values of B:
h = [0 2 3]
But the code results in a different one. How can I fix it?
A =
1 2 3
0 8 9
B =
0 1 2
4 2 3
I =
1 2 2
h =
0 4 4
Thanks in advance
The max function how you used it works like
If A is a matrix, then max(A) is a row vector containing the maximum value of each column.
so M = max(A) is equivalent to M = max(A,[],1). But rather use the third input if you're not sure.
If you use max to find the maxima in the columns of the matrix, it returns the row indices. The column indices are for your case simply 1:size(A,2) = [1 2 3].
Now you need to convert your row and column indices to linear indices with sub2ind:
%// data
A = [1,2,3; 0,8,9]
B = [0,1,2; 4,2,3]
%// find maxima of each column in A
[~, I] = max( A, [], 1 ) %// returns row indices
%// get linear indices for both, row indices and column indices
I = sub2ind( size(A), I, 1:size(A,2) )
%// index B
h = B(I)
returns:
h =
0 2 3

How do I raise a vector to a vector in MATLAB? [duplicate]

I have two vectors, X of bases and N of exponents. I want to get the matrix of all values e = xn for each x in X and n in N.
For example, the following input:
X = [2 3 4]'
N = [1 2 3]
should produce:
ans = [2 4 8; 3 9 27; 4 16 64]
Is there a way to get this without looping (just like you can get all values of x×n by using the column by row product)?
Use bsxfun:
bsxfun(#power, X, N)
This assumes that X is a column vector and N is a row vector. If you want to guarantee that, use the following syntax which is more robust:
bsxfun(#power, X(:), N(:).')
This is probably a bit sloppier than the bsxfun answer, but you could use meshgrid:
E = X.^(meshgrid(N)')
This assumes both X and N are row vectors. If both are column vectors then it becomes:
E = X.^(meshgrid(N))

pick random numbers in certain range from vector

how would you use randperm to randomly pick three numbers out of a range of 5 in a vector?
i have a vector like this:
A = [1 2 3 4 5 6 7 8 9 10]
now from every 5 consecutive values i want to randomly pick 3 of them:
A_result = [1 3 5 6 7 9]
any help is appreciated!
This one uses different random indices in every 5-group.
A = [1 2 3 4 5 6 7 8 9 10]
B = reshape(A,5,[]) % (5 x 2)
ind = cell2mat(arrayfun(#(x)sort(randperm(5,3))',1:size(B,2),'UniformOutput',false)) % (3 x 2), row indices into B
ind = bsxfun(#plus,ind,size(B,1)*(0:size(B,2)-1)) % (3 x 2), linear indices into B
C = B(ind) % (3 x 2) result
C(:)' % result vector
Every sort(randperm(5,3))' call generates a random column vector with 3 ascending numbers from 1 to 5, like [1;3;4] or [2;4;5]. arrayfun with the dummy argument x calls this 2 times in this example, because A consists of 2 sub-vectors of length 5. With the argument 'Uniform output' set to false, it generates a cell array of these random vectors, and cell2mat converts it to the (3 x 2)-matrix ind. The bsxfun call converts the values in the matrix ind to a matrix of linear indices into matrix B or A.
For your (900 x 25)-matrix, do
A = rand(900,25); % (900 x 25)
B = A'; % (25 x 900)
ind = cell2mat(arrayfun(#(x)sort(randperm(25,17))',1:size(B,2),'UniformOutput',false)); % (17 x 900), row indices into B
ind = bsxfun(#plus,ind,size(B,1)*(0:size(B,2)-1)); % (17 x 900), linear indices into B
C = B(ind); % (17 x 900), result
You can use reshape and randsample
rA = reshape( A, 5, [] ); % groups of 5 in a a row
A_result = rA( randsample( 5, 3, false ), : );
A_result = reshape( A_result, 1, [] );
You can pre-generate all possible picking patterns, and then randomly select one such pattern for each group. This approach is suitable for small group sizes, otherwise it may use a lot of memory.
A = 1:10; %// example data
n = 5; %// group size. Assumed to divide numel(A)
k = 3; %// how many to pick from each group
S = numel(A);
patterns = nchoosek(1:n, k); %// all possible picking patterns
K = size(patterns, 1);
p = randi(K, S/n, 1); %// generate random indices for patterns
pick = bsxfun(#plus, patterns(p,:).', (0:n:S-1)); %'// to linear indices
A_result = A(pick(:));

Vectorized exponentiation

I have two vectors, X of bases and N of exponents. I want to get the matrix of all values e = xn for each x in X and n in N.
For example, the following input:
X = [2 3 4]'
N = [1 2 3]
should produce:
ans = [2 4 8; 3 9 27; 4 16 64]
Is there a way to get this without looping (just like you can get all values of x×n by using the column by row product)?
Use bsxfun:
bsxfun(#power, X, N)
This assumes that X is a column vector and N is a row vector. If you want to guarantee that, use the following syntax which is more robust:
bsxfun(#power, X(:), N(:).')
This is probably a bit sloppier than the bsxfun answer, but you could use meshgrid:
E = X.^(meshgrid(N)')
This assumes both X and N are row vectors. If both are column vectors then it becomes:
E = X.^(meshgrid(N))

MATLAB - extracting rows of a matrix

a = [1 2; 3 4; 5 6] I want to extract the first and third row of a, so I have x = [1; 3] (indices of rows).
a(x) doesn't work.
Like this: a([1,3],:)
The comma separates the dimensions, : means "entire range", and square brackets make a list.
In MATLAB if one parameter is given when indexing, it is so-called linear indexing. For example if you have 4x3 matrix, the linear indices of the elements look like this, they are growing by the columns:
1 5 9
2 6 10
3 7 11
4 8 12
Because you passed the [1 3] vector as a parameter, the 1st and 3rd elements were selected only.
When selecting whole columns or rows, the following format shall be used:
A(:, [list of columns]) % for whole columns
A([list of rows], :) % for whole rows
General form of 2d matrix indexing:
A([list of rows], [list of columns])
The result is the elements in the intersection of the indexed rows and columns. Results will be the elements marked by X:
A([2 4], [3 4 5 7])
. . C C C . C
R R X X X R X
. . C C C . C
R R X X X R X
Reference and some similar examples: tutorial on MATLAB matrix indexing.
x = a([1 3]) behaves like this:
temp = a(:) % convert matrix 'a' into a column wise vector
x = temp([1 3]) % get the 1st and 3rd elements of 'a'
you could write a loop to iterate across the rows of the matrix:
for i = [1,3]
a(i,:)
end
type this: a([1 3],[1 2])
the output is
ans =
1 2
5 6