Array from vector on the basis of a second array - matlab

I have a vector v. I need to form an array a containing elements specified according to another array b. Each row in a (let's denote it by r) should contain all elements from v, with starting and ending indices corresponding to the first and last elements given in the matching column in b. For instance:
A(1, :) = v(b(1, 1):b(2, 1));
A(2, :) = v(b(1, 2):b(2, 2));
A(3, :) = v(b(1, 3):b(2, 3));
and so on. Obviously b(2,:) = b(1,:) + constant.
Can I do this without a loop in MATLAB?

Try this:
N=8; P=3; M=5;
v = rand(N,1);
b = zeros(2,M);
b(1,:) = [1 2 4 5 6];
b(2,:) = b(1,:) + P - 1;
A = cell2mat(arrayfun(#(i0,i1) v(i0:i1),b(1,:),b(2,:),'UniformOutput',false))'

You can use linear indexing and bsxfun to directly access the elements:
A = v(bsxfun(#plus, b(1,:).', 0:b(2,1)-b(1,1)));

Related

How can we use nchoosek() to get all the combinations of the rows of a matrix?

If we have a vector v of 1- 5 numbers we can use nchoosek(v,2) to get all the combinations having two elements. But this function does now allow us to get all the combinations of a matrix. I want to use it to get all the combinations of rows of a matrix.
Here's one way to do it:
function p = q47204269(inMat)
% Input handling:
if nargin == 0 || isempty(inMat)
inMat = magic(5);
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
rowsCell = num2cell(inMat,2);
nRows = size(inMat,1);
p = cell(nRows,1);
for indR = 1:nRows
r = nchoosek(1:nRows,indR);
p{indR} = cell2mat(reshape(rowsCell(r.',:).',indR,1,[]));
end
See also:
The perms function, as it might come in handy in what you're doing.
This question.
with square matrix A
v = 1:size(A,1);
a = nchoosek(v,2);
B = zeros(2,size(A,1),length(a));
for i = 1:length(a)
B(:,:,i) = A(a(i,:)',:);
end
Each layer of array B is a 2 row matrix with the row combos from A
Not the most readable answer, but just for the sake of a one-liner :-)
A = randn(5,3); % example matrix
N = 2; % number of rows to pick each time
result = permute(reshape(A(nchoosek(1:size(A,1), N).', :), N, [], size(A,2)), [1 3 2]);
The result is a 3D array, such that each third-dim slice gives one of the a submatrices of A.

Permuting columns of a matrix in MATLAB

Say I have an n by d matrix A and I want to permute the entries of some columns. To do this, I compute permutations of 1 ... n as
idx1 = randperm(n)'
idx2 = randperm(n)'
Then I could do:
A(:,1) = A(idx1,1)
A(:,2) = A(idx2,2)
However, I dont want to do this using a for-loop, as it'll be slow. Say I have an n by d matrix A and an n by d index matrix IDX that specifies the permutations, is there a quicker equivalent of the following for-loop:
for i = 1:d
A(:,i) = A(IDX(:,i),i);
end
Using linear-indexing with the help of bsxfun -
[n,m] = size(A);
newA = A(bsxfun(#plus,IDX,[0:m-1]*n))
I guess another rather stupid way to do it is with cellfun, stupid because you have to convert it into a cell and then convert it back, but it is there anyways.
N=ones(d,1)*n; %//create a vector of d length with each element = n
M=num2cell(N); %//convert it into a cell
P=cellfun(#randperm, M,'uni',0); %//cellfun applys randperm to each cell
res = cell2mat(P); %//Convert result back into a matrix (since results are numeric).
This also allows randperm of type Char and String, but the cell2mat will not work for those cases, results are in Cell Array format instead.
for d = 5, n = 3:
>> res =
1 3 2
1 2 3
2 3 1
3 1 2
3 2 1

How to find the index of the n smallest elements in a vector

How can I get the indices of "n smallest elements" in a 1D array in MATLAB?
The array is a row vector.
I can find the smallest element and its index using ;
[C, ind] = min(featureDist);
The vector is like:
featureDist =
Columns 1 through 8
48.4766 47.3743 59.5736 59.7450 55.0489 58.2620 63.3865 50.1101
and so on...
You can use the sort function. To get the smallest n elements, you can write a function like this:
function [smallestNElements smallestNIdx] = getNElements(A, n)
[ASorted AIdx] = sort(A);
smallestNElements = ASorted(1:n);
smallestNIdx = AIdx(1:n);
end
Let's try with your array:
B = [48.4766 47.3743 59.5736 59.7450 55.0489 58.2620 63.3865 50.1101];
[Bsort Bidx] = getNElements(B, 4);
returns
BSort =
47.3743 48.4766 50.1101 55.0489
Bidx =
2 1 8 5
I know this is an extremely late reply but I am hoping to help anyone who may have this question later.
If A is the array of elements, yu could try using the find function to determine the index of the n smallest elements.
[~, idx] = find(A > -Inf, n, 'first')
To determine the n largest elements,
[~, idx] = find(A < Inf, n, 'last')

Multiplying Cell with elements of a matrix Matlab

I have a 1xm cell array A{}, with each element of the array being NxN matrix and a matrix W(N1,m).
I need to calculate
Sum(j) = W(j,1)*A{1,1} + W(j,2)*A{1,2}
and I am doing the following:
for j=1:N1
sum=false(N);
for k=1:m
sum = sum + W(j,k)*A{1,k};
end
Sum(j)=sum
end
Or more visually :
Matrix W(let's say N1=2)
|W11 W12||A{1,1}| = |W11*A{1,1} + W12*A{1,2}|
|W21 W22||A{1,2}| = |W21*A{1,1} + W22*A{1,2}|
Is there a way of doing it without using the loops?
To do that without for-loops, you can rape (pardon the expression) the arrayfun command:
w_func = #(j)arrayfun(#(k)(W(j, k) * A{k}), 1:m, 'Un', 0)
sum_func = #(x)sum(cat(3, x{:}), 3)
S = arrayfun(#(j)sum_func(w_func(j)), 1:N1, 'Un', 0);
This produces a cell array S that contains all the sums, from S{1} to S{N1}.
I'm confused over what you are trying to do, but if I understand it correctly, this code should work:
temp = cell2mat(A);
a_sum = temp*repmat(eye(n),m,1); % this reduces A by performing sum like operation so [1 1 1 3;0 1 0 2]
% becomes [2 4; 0 3]
Sum = W * a_sum
I am also not sure I understood the question, but here is some code to consider:
%# create some data resembling what you described
N = 2;
m = 4;
N1 = 5;
W = rand(N1,m);
A = cell(1,m); for i=1:m, A{i} = rand(N); end
%# do the multiplications
s = cell(N1,1);
for j=1:N1
AA = cellfun(#times, A, num2cell(W(j,:)), 'UniformOutput',false);
s{j} = sum(cat(3,AA{:}), 3);
end
The cell array s now contains the result such that:
s{j} = W(j,1)*A{1} + W(j,2)*A{2} + ... + W(j,m)*A{m}
thus s is a cell array of size N1-by-1, where each cell contains an N-by-N matrix

How do I multiply all the elements in each row of a given matrix with corresponding elements of a given vector and sum them in MATLAB?

For example, given a matrix randn(3,2) - 3 rows, 2 columns and a vector of multipliers randn(1,2)) 2 columns, I want to get a vector of size (3, 1) in which each row would represent a sum of per element multiplication of the matrix's row elements and the given multipliers like
row_element_1*mul_element_1 + row_element_2*mul_element_2
Sounds like you want a matrix-vector multiplication.
1> x = randn(3, 2)
x =
0.62055 -1.08060
-0.24064 -2.56097
-0.53202 -0.49712
2> y = randn(1, 2)
y =
-1.26010 -0.25200
3> x * y'
ans =
-0.50964
0.94860
0.79567
Note the transposition y'.
I think you can do this with a combination of bsxfun and sum, like so:
a = rand(3,2);
b = rand(1,2);
result = sum(bsxfun(#times,a,b),2)
result =
0.333379034494579
0.613480382112731
0.093702948350719
Note dimension argument to SUM to sum along each row (rather than the default, which is down columns). BSXFUN applies a binary function with scalar expansion, which is ideal for the multiplication part here.
A = randn(3, 2);
B = randn(1, 2);
C = A(:, 1) * B(1) + A(:, 2) * B(2); % size(C) = [3, 1]
If you have to scale to a much larger array with lots more columns and didn't want to write out the equation for C in full, you can use repmat and element-wise multiplication
A = randn(300, 200);
B = randn(1, 200);
C = sum(A .* repmat(B, 300, 1), 2);