Splitting matrix into columns - matlab

I ve got a matrix and i want to split is in the columns vectors. I want to have as output the
above vectors [a b c d e f g h k l m n o p q r s t u] and as an input the matrix A. is there any idea?

You can do this by converting your matrix to a cell array as follows:
M = rand(4); % create a 4x4 random example matrix
C = num2cell(M,1); % convert every column to a cell
[a,b,c,d] = deal(C{:}); % assign to variables a...d
This results in four column vectors a, b, c, d. Add more letters as needed.
I'm not really sure why you would want to do this though, I think it's probably more efficient to just index your original matrix with the column number you need.

Related

Sub-tensor of a tensor with arbitrary degree in matlab

I have a function where I input a tensor T of arbitrary degree d which is of size n1 x n2 x ... x nd. I want to output the tensor T(1:r,1:r,...,1:r). In other words, an r x r x ... x r sub-tensor with d number of r's. I'm having difficulty working around the variable number 1:r's. Ideally I'd like to do this without reshaping T if possible.
This is quite straightforward to do with cell arrays, consider following example:
% example setup
a = ones(3,3,3,3);
r = 2;
% create indices in cell array
b = cell(1,ndims(a));
b(:) = {1:r};
% evaluate
c = a(b{:});
disp(size(c))

How to efficiently get all elements along 3rd direction at specified locations in a matrix?

A is an M*N*S matrix of values and B is a P*1 vector of indices of locations in an M*N matrix. I want to get the P*S matrix, C, that is all values along 3rd direction form A, at locations specified by B (on the A(:, :, 1)).
This is my current code:
%% sample inputs
M = 2; N = 3; S = 3;
A = reshape(1:M*N*S, M, N, S)
B = (1:3:M*N)'
P = numel(B);
%% solution
B2 = repmat(B, 1, S)+repmat((0:S-1)*M*N, P, 1);
C = A(B2)
But it calls repmat twice, and I need this in a for loop that P changes in every iteration. So how can I make it more efficient?
First of all, I would strongly discourage the use of O as a variable name. It looks like a zero. Similarly, avoid a lower-case l as it looks like a 1. Below I will use S in place of your O.
You can simply reshape your initial matrix into an [M*N, S] matrix and then user the indices on the first column.
% Collapse the first two dimensions into rows
data = reshape(A, [], size(A, 3));
% Grab the rows that correspond to the indices in B
C = data(B, :);
The use of reshape is very efficient here because MATLAB doesn't need to make a copy of the underlying data, just alter how it is accessed.

I have N*M matrix and two 1*M row vectors I want to vectorize mathematical operations on them

I have N by M matrix A , a 1 by M matrix or a row vector B
and another 1 by M row vector C. Can I vectorize the following code more than that?
for i = 1:N
A(i,:) = (A(i,:)-B)./C;
end;
and what about more general case where we have K by M matrices(K divisible by N) instead of vectors
This is what bsxfun was designed to do:
A = bsxfun(#rdivide,bsxfun(#minus,A,B),C);
It will automatically expand the arrays of size [1 M] to be compatible with the one of size [N M], then perform the necessary array operations on them, returning an array of size [N M].
If your B and C arrays are of size [K M], then it's a bit more difficult. You didn't specify what the output should be shaped, but in the most general case you can compute "(A-B)/C" for every row of B and C and collect these matrices in an array of size [K N M]:
A = bsxfun(#rdivide,bsxfun(#minus,permute(A,[3 1 2]),permute(B,[1 3 2])),permute(C,[1 3 2]));
where A is transformed to an array of size [1 N M], and both B and C are transformed to size [K 1 M]. Depending on the size of your arrays along the various dimensions, you might benefit from putting M in front (since that's the dimension along which you're subtracting, but I'm not sure.
Unless you need raw speed, I would prefer a more explicit approach:
N = size(A, 1);
easy = (A-repmat(B, N, 1)) ./ repmat(C, N, 1);
repmat copies the first argument, the number of second argument times vertically (in rows), and they number of third argument times in columns. So, in this case, B is turned into N x M by replicating the vector N times vertically only.
For the more general case, where B & C are K x M, and N/K is an integer:
rowReps = size(A, 1)/size(B, 1);
notMuchHarder= (A - repmat(B, rowReps , 1) ./ repmat(C, rowReps, 1);

How to do a fast matrix multiplication for each column of two matrices without for loops?

I have two matrices A and B for which I want to do a multiplication for each of their columns to produce a new matrix. The first thing cross my mind is
A = rand(4,3);
B = rand(4,3);
for J=1:SIZE(A,2)
for jj=1:size(B,2)
C(:,:,m) = A(:,j)*B(:,jj)' ;
m = m+1 ;
end
end
But I don't want to use for loops which makes it slow. Is there any way?
I am going to use the matrices of third dimension of C, the ones which are built by multiplication of columns of A and B, Is it better to first build the C and then use its 3rd dimension matrices in each loop or just do the multiplication in each loop?
One approach with bsxfun -
N1 = size(A,1);
N2 = size(B,1);
C = reshape(bsxfun(#times,permute(A,[1 4 3 2]),permute(B,[4 1 2 3])),N1,N2,[])
You could avoid going to the 4th dimension as listed next, but it's still marginally slower than the earlier 4D approach -
C = reshape(bsxfun(#times,permute(A,[1 3 2]),B(:).'),N1,N2,[])
As an alternative to Divakar's answer, you can generate all 4-fold combinations of row and column indices of the two matrices (with ndgrid) and then compute the products:
[m, p] = size(A);
[n, q] = size(B);
[mm, nn, qq, pp] = ndgrid(1:m, 1:n, 1:q, 1:p);
C = reshape(A(mm+(pp-1)*m).*B(nn+(qq-1)*n), m, n, p*q);

Matlab d-dimensional multipication table?

I'm new to Matlab and I'm trying to solve a problem that involves creating a d dimensional multiplication table where each edge goes from 1 to n. The problem statement says that inputting d = 0 should return the number 1 and d = 1 should return a column vector with the elements 1 to n.
Ideally, I would just create a matrix of 1 to n along d dimensions and then iterate through for each element setting it equal to the product of the indices, but I don't know how to create the d dimensional matrix.
Can anyone help me with this problem?
You can create the table with repeated use of bsxfun. At each iteration, the vector 1,2,...,n is shifted to a new dimension and multiplied (with singleton expansion) by the previous result.
%// Data
d = 3;
n = 10;
%// Computations
vector = (1:n).'; %// first dimension: column vector
result = 1; %// initialization
for n = 1:d
result = bsxfun(#times, result, vector); %// new dimension
vector = shiftdim(vector,-1); %// shift to the next dimension
end