MATLAB - resizing matrix using matrix multiplication and not the RESIZE command - matlab

For a specific problem, I need to design the resizing of a matrix process using multiplication of matrices alone.
Given a matrix of A of dimensions (a*b,1) where a and b are integers, I need to find a way to resize A to dimensions (a,b) like this:
M*A*N = resize(A,a,b)
where dim(M) = (a,a*b) and dim(N) = (1,b). It doesn't have to be two matrices but I don't think it is possible any other way.

If you can't use reshape or vec2mat, you need to do your manipulation for each element of A separately.
There is no such M and N that you are searching for.
Suppose:
resh_A = M*A*N;
Let's study one row of this equation. Assume one row of M*A :
temp_i = M(i, :) * A;
Since M(i, :) is 1 x a*b and A is a*b x 1; temp_i whould be a 1 x 1 matrix.
Now temp_i * N should result in the ith row of your result (or resh_A).
Thus resh_A will look like:
(note N is 1 x b)
temp_1 * N % row1
temp_2 * N % row2
temp_3 * N % row3
...
which is not a general matrix (it's a matrix with rank 1).

Related

Matlab: multiplying rows of a matrix by vector elements

Let v be a row vector (1 x n matrix) and M be a n x m matrix.
I use the following piece of code to create a "weighted vector" (I hope the comments explain what it's supposed to be doing):
weighted_M = bsxfun(#times,v',M);
%creates a matrix with the i-th row of M being weighted (multiplied) by the i-th element of v
weighted_v = sum(weighted_M);
%sums the columns of weighted_M
Now the actual question: I have to do the same calculation for a lot of input vectors v. So instead I would like to input a matrix V that contains the vectors v as rows and output a matrix that contains the weighted vectors as rows. Is there any way to do this without using for loops?
If V is of size [k,n] and M is of size [n,m], and you're looking for the k weighted vectors, then you might simply need
weighted_vs = V*M;
an element of which is equal to
weighted_vs_ij = (V*M)ij = sum_l V_il * M_lj
First you multiply each row of M with a corresponding element of V (V_il * M_lj above for a fix i), then sum up as a function of the first index.
The result are the k weighted row vectors, each of length m.

Sum over blocks in a 3D matrix - MATLAB

For a 3N by 3N by 3N matrix A, I would like to derive a N by N by N matrix B whose entries come from summation over blocks in A.
For example, B(1,1,1) = sum of all elements of A(1:3,1:3,1:3).
Basically, A is kind of a high resolution matrix and B is a low resolution matrix from summing over entries in A.
If memory is not a concern, you can use a "labelling" approach: build a 3-component label to group the elements of A, and use that label as the first input argument to accumarray to do the sum. The label uses integers from 1 to N, so the result of accumarray already has the desired shape (NxNxN).
N = 5;
F = 3; %// block size per dimension
A = rand(15,15,15); %// example data. Size FN x FN x FN
[ii jj kk] = ind2sub(size(A), 1:numel(A));
label = ceil([ii.' jj.' kk.']/F);
result = accumarray(label, A(:));
reshape + sum based approach and as such has to be pretty efficient -
sumrows = sum(reshape(A,3,[]),1); %// Sum along rows
sumcols = sum(reshape(sumrows,N,3,[]),2); %// Sum along cols
B = reshape(sum(reshape(sumcols,N*N,3,[]),2),N,N,N); %// Sum along 3rd dim
If you are crazy about one-liners, here's that combining all steps into one -
B = reshape(sum(reshape(sum(reshape(sum(reshape(A,3,[]),1),N,3,[]),2),N*N,3,[]),2),N,N,N);
For a 2D matrix, this would work:
B = reshape(sum(im2col(A, [3 3], 'distinct')), [N N]);
NB: You need the image processing toolbox.
But for 3D matrices, I don't know of any built-in function equivalent to im2col. You might have to use a loop. Left as an exercise to the reader ;)

Matrix representation for point-wise operation

I have the following expression to implement in MATLAB:
(A*u).*(B*v)
Where A and B are matrices N x N and u and v column vectors N x 1.
For some reason, not really important at the moment, I want to represent it in the form C(A,u,b)*v for some matrix N x N originated by A,u and B.
How can I do that?
I tried to do something like using the following matrix
C = spdiags( A*u,0,N,N)*B
But it seems that the result is not really what I need.
How about
C1 = bsxfun(#times, A*u,B) * v

Multiply two matrices in Matlab to obtain 3-dimensional matrix

I have two sparse matrices in Matlab, A and B,
and I want to compute a three-dimensional matrix C such that
C(i,j,k) = A(i,j) * B(j,k)
can I do this without a loop?
(Side question: Is there a name for this operation?)
Edit:
Seems my question has already been asked (just for full matrices):
Create a 3-dim matrix from two 2-dim matrices
For full matrices:
You can do it using bsxfun and shiftdim:
C = bsxfun(#times, A, shiftdim(B,-1))
Explanation: Let A be of size M x N and B of size N x P. Applying shiftdim(B,-1) gives a 1 x N x P array. bsxfun implicitly replicates A along the third dimension and shiftdim(B,-1) along the first to compute the desired element-wise product.
Another possibility, usually less efficient than bsxfun, is to repeat the arrays explicity along the desired dimensions, using repmat:
C = repmat(A, [1 1 size(B,2)]) .* repmat(shiftdim(B,-1), [size(A,1) 1 1])
For sparse matrices:
The result cannot be sparse, as sparse ND-arrays are not supported.. But you can do the computations with sparse A and B using linear indexing:
ind1 = repmat(1:numel(A),1,size(B,2));
ind2 = repmat(1:numel(B),size(A,1),1);
ind2 = ind2(:).';
C = NaN([size(A,1),size(A,2),size(B,2)]); %// preallocate with appropriate shape
C(:) = full(A(ind1).*B(ind2)); %// need to use full if C is to be 3D
Answer to your side question: the name for this operation is a hash join.

Multiplying matrices in a cell array

Suppose you have an N x 1 cell array where each constituent cell is an m x m matrix. I would like the matrix product (i.e. not entry-by-entry multiplication) of these matrices, so if E_i is the ith matrix in the cell array. I would like to compute E_1 * E_2 * ... * E_N. Any ideas for a vectorized approach to this?
The most direct way is to do this (where p is your answer and cellarray is your cell array). * is the matrix multiplication while .* is the element-by-element multiplication you wish to avoid.
p = 1;
for i = 1:N,
p = p*cellarray{i};
end
I don't think this can be vectorized since the iterations aren't independent of each other. A multiplication at some step is dependent on all the multiplications prior to it.