Algorithmically construct block matrices (matlab) - matlab

Let Matrices = [A B C D] be a set of square matrices. I want to construct
H = [A B C D;
B A B C;
C B A B;
D C B A]
If all I was interested in was the 4 by 4 case, then this would be enough. However, I want to construct the analogous matrix when Matrices = [A B C D E F] etc. What code could I write to do this?

This can be done as follows:
Concatenate the matrices into a 3D array;
Build the basic with numbers instead of matrices using toeplitz;
Extend this structure so that using linear indexing into the 3D array produces the desired result.
N = 2; % matrix size
M = 3; % number of matrices
matrices = arrayfun(#(x) {randi(9,N)}, 1:M); % input matrices
matrices_3D = cat(3, matrices{:}); % concatenate the matrices along the third dim
ind1 = repmat(reshape(1:N^2, N, N), M, M); % linear indices within each matrix
ind2 = (repelem(toeplitz(1:M), N, N)-1)*N^2; % linear indices to select the matrices
result = matrices_3D(ind1 + ind2); % build result
Example run:
>> celldisp(matrices)
matrices{1} =
1 4
2 6
matrices{2} =
6 4
5 9
matrices{3} =
5 4
6 5
>> result
result =
1 4 6 4 5 4
2 6 5 9 6 5
6 4 1 4 6 4
5 9 2 6 5 9
5 4 6 4 1 4
6 5 5 9 2 6

Related

Turning matrix diagonals to columns

I am looking for a matrix operation of the form: B = M*A*N where A is some general square matrix and M and N are the matrices I want to find.
Such that the columns of B are the diagonals of A. The first column the main diagonal, the second the diagonal shifted by 1 from the main and so on.
e.g. In MATLAB syntax:
A = [1, 2, 3
4, 5, 6
7, 8, 9]
and
B = [1, 2, 3
5, 6, 4
9, 7, 8]
Edit:
It seems a pure linear algebra solution doesn't exist. So I'll be more precise about what I was trying to do:
For some vector v of size 1 x m. Then define C = repmat(v,m,1). My matrix is A = C-C.';.
Therefore, A is essentially all differences of values in v but I'm only interested in the difference up to some distance between values.
Those are the diagonals of A; but m is so large that the construction of such m x m matrices causes out-of-memory issues.
I'm looking for a way to extract those diagonals in a way that is as efficient as possible (in MATLAB).
Thanks!
If you're not actually looking for a linear algebra solution, then I would argue that constructing three additional matrices the same size as A using two matrix multiplications is very inefficient in both time and space complexity. I'm not sure it's even possible to find a matrix solution, given my limited knowledge of linear algebra, but even if it is it's sure to be messy.
Since you say you only need the values along some diagonals, I'd construct only those diagonals using diag:
A = [1 2 3;
4 5 6;
7 8 9];
m = size(A, 1); % assume A is square
k = 1; % let's get the k'th diagonal
kdiag = [diag(A, k); diag(A, k-m)];
kdiag =
2
6
7
Diagonal 0 is the main diagonal, diagonal m-1 (for an mxm matrix) is the last. So if you wanted all of B you could easily loop:
B = zeros(size(A));
for k = 0:m-1
B(:,k+1) = [diag(A, k); diag(A, k-m)];
end
B =
1 2 3
5 6 4
9 7 8
From the comments:
For v some vector of size 1xm. Then B=repmat(v,m,1). My matrix is A=B-B.'; A is essentially all differences of values in v but I'm only interested in the difference up to some distance between values.
Let's say
m = 4;
v = [1 3 7 11];
If you construct the entire matrix,
B = repmat(v, m, 1);
A = B - B.';
A =
0 2 6 10
-2 0 4 8
-6 -4 0 4
-10 -8 -4 0
The main diagonal is zeros, so that's not very interesting. The next diagonal, which I'll call k = 1 is
[2 4 4 -10].'
You can construct this diagonal without constructing A or even B by shifting the elements of v:
k = 1;
diag1 = circshift(v, m-k, 2) - v;
diag1 =
2 4 4 -10
The main diagonal is given by k = 0, the last diagonal by k = m-1.
You can do this using the function toeplitz to create column indices for the reshuffling, then convert those to a linear index to use for reordering A, like so:
>> A = [1 2 3; 4 5 6; 7 8 9]
A =
1 2 3
4 5 6
7 8 9
>> n = size(A, 1);
>> index = repmat((1:n).', 1, n)+n*(toeplitz([1 n:-1:2], 1:n)-1);
>> B = zeros(n);
>> B(index) = A
B =
1 2 3
5 6 4
9 7 8
This will generalize to any size square matrix A.

MATLAB: Forming an array of matrices and do operations with respect to each matrix "element"

I have an array of matrix m such that
m1 = [1 2;3 4];
m2 = [2 7; 8 9];
m3 = [9 7; 8 91];
m = [m1 m2 m3]
m =
1 2 2 7 9 7
3 4 8 9 8 91
I also have a vector
v = [1 2 3];
such that i want the operations between v and m result in h such that
h = [1*m1 2*m2 3*m3] = [h1 h2 h3];
I imagine I have to do this in 3-dimensional array for h, which is a 3d array. Or maybe there are better ways.
Let A be a simple 2 by 2 matrix, rand(2,2).
From h i want to extract h1 h2 and h3 out(or better not doing any extraction) and perform operations to A such that
1.
h1*A*h1'
h2*A*h2'
h3*A*h3'
and
2.
h1*h1', h2*h2', h3*h3'.
Why i want to do this in array is because i have a lot of matrix mi so I want to avoid for loop by vectorization.
From what i could understand from the question, i suppose element-wise multiplication would be better choice. You would just have to use proper concatenation and repeatation of matrices.
m1 = [1 2; 3 4];
m2 = [2 7; 8 9];
m3 = [9 7; 8 91];
% Concatenate to create 3D matrix
m = cat(3,m1,m2,m3);
v = [1 2 3];
% Create similar 3D matrix
v1 = cat(3,ones(size(m1))*v(1),ones(size(m2))*v(2),ones(size(m3))*v(3));
% Simple element wise multiplication
h = m.*v1;
% Creating a repeated 3D matrix A, repetation is along third dimension
A = repmat(rand(2,2),[1 1 3]);
% Outputs
op_1 = h.*A.*permute(h,[2 1 3]);
op_2 = h.*permute(h,[2 1 3]);

Sort the first N elements of a vector in MATLAB

I would like to sort the first N elements of a vector that has more elements.
For example:
A = [3 2 5 1 8 9 2 1 9];
If N = 5, the output should be:
B = [1 2 3 5 8 9 2 1 9];
I would also like to have a vector of indices v, so that B = A(v).
How can I do this?
[B, v] = sort(A(1:N));
B = [B, A(N+1:end)]; % sorted vector
v = [v, N+1:numel(A)]; % index vector

How can i insert 2d random numbers into a given 2d matrix in matlab

I want to insert random numbers into a given 2D matrix in MATLAB. For example
if
A = [1 2 3;
4 5 6;
7 8 9];
and if B is a matrix which is uniformly distributed matrix, then I want a new matrix merging this two matrices (A & B), like
new matrix
C = [1 0.653 2 2.55 3;
4 4.3 5 5.4 6;
7 7.6 8 8.09 9]
How could I write MATLAB code for that?
If you've already got B and assuming that A is an n-by-m matrix and B is an n-by-m-1 matrix:
[n,m] = size(A);
C = zeros(n,2*m-1);
C(:,1:2:end) = A;
C(:,2:2:end) = B; % end-1 is not necessary since 2*m-1 is an odd number but if you prefer for readability then you can do C(:,2:2:end-1) = B
You could create B like this (depends on the limits of B which are not clear from your question)
B = A(:,1:end-1) + rand(n,m-1)*2 - 1

Creating a vector out of a matrix

I have a 10x10 matrix (called A) and I'd like to make a 1x100 vector (called B) out of the rows of A. And I'm not sure if there is a fast way to program this in MATLAB.
Transpose A and read out the elements linearly:
At = A.'; %' transpose to read across A
B = At(:).'; %' (:) creates column vector, transpose with .'
Short example:
>> A=magic(3)
A =
8 1 6
3 5 7
4 9 2
>> At = A.';
>> B = At(:).'
B =
8 1 6 3 5 7 4 9 2