Merger of Multiple matrices using Matlab/Octave - matlab

Assuming we have 3 matrices, A, B and C, all are of the same size 256x256. It is known that last 20% of columns of Matrix A is identical to first 20% of Matrix B and last 10% of Matrix B is identical to first 10% of Matrix C. So in these cases since we know the overlapping amount, I do not need to compare the 3 matrices, but i want to join them at the overlap.
Taking a smaller Matrix as an example here are the 3 Matrices
A = [1 2 3 4 ; 5 6 7 8; 9 10 11 12];
B = [3 4 13 14; 7 8 15 16; 11 12 17 18];
C = [14 19 20 21; 16 22 23 24; 18 25 26 27];
So I would like my output to be
D = [1 2 3 4 13 14 19 20 21
5 6 7 8 15 16 22 23 24
9 10 11 12 17 18 25 26 27
I hope this might explain it better. I am extremely new to matlab. I tried using matrix shift, but we have only circular shift available.
Concatenation does not work because it just joins the 3 matrices. What would be the best way to overlay these 3 matrices together ?

Make proper use of matrix indexing and concatenation
For your example
D = [A B(:,3) C];
For a 256x256 Matrix and your concatenation conditions:
D = [A B(:, 0.2*256+1 : 0.9*256) C]
Since 256/10 is no integer you may adjust the index values

Related

Vectorising a Matlab code to pick specific indices of a matrix

I have a matrix A in Matlab of dimension Nx(N-1), e.g.
N=5;
A=[1 2 3 4;
5 6 7 8;
9 10 11 12;
13 14 15 16;
17 18 19 20];
I want to rearrange the elements of A in a certain way. Specifically I want to create a matrix B of dimension (N-1)xN such that:
for i=1,...,N,
B(:,i) collects
1) the first i-1 elements of the i-1th column of A and
2) the last N-i elements of the ith column of A.
Notice that for i=1 the i-1th column of A does not exist and therefore 1) is skipped; similarly, for i=N theith column of A does not exist and therefore 2) is skipped.
In the example above
B=[5 1 2 3 4
9 10 6 7 8
13 14 15 11 12
17 18 19 20 16];
This code does what I want. I am asking your help to vectorise it in an efficient way.
B=zeros(N-1,N);
for i=1:N
if i>1 && i<N
step1=A(1:i-1,i-1);
step2=A(i+1:N,i);
B(:,i)=[step1;step2];
elseif i==1
B(:,i)=A(i+1:N,i);
elseif i==N
B(:,i)=A(1:i-1,i-1);
end
end
Extract the lower and upper triangular matrices of A. Then reassemble them with a "diagonal shift":
u = triu(A);
l = tril(A,-1);
B = padarray(u(1:end-1,:),[0 1],'pre') + padarray(l(2:end,:),[0 1],'post');
Another valid approach using logical indexing combined with tril and triu:
B = zeros(size(A'));
B(tril(true(size(B)))) = A(tril(true(size(A)), -1));
B(triu(true(size(B)), 1)) = A(triu(true(size(A))));
Result:
>> B
B =
5 1 2 3 4
9 10 6 7 8
13 14 15 11 12
17 18 19 20 16

How to efficiently reshape one column matrix to many specific length columns by moving specific interval

The input is an N-by-1 matrix. I need to reshape it to L-by-M matrix. The following is an example.
Input:
b =
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Set length = 18, Output:
X =
1 2 3
2 3 4
3 4 5
4 5 6
5 6 7
6 7 8
7 8 9
8 9 10
9 10 11
10 11 12
11 12 13
12 13 14
13 14 15
14 15 16
15 16 17
16 17 18
17 18 19
18 19 20
Because I have a very big matrix, using a loop to reshape is very inefficient. How can I improve the reshape speed?
Your example output matrix X is the perfect matrix to index a vector of length N to get what you want. It's also very easy to create using bsxfun:
N = 20;
b = rand(N,1);
M = 3; %// number of columns
L = N-M; %// Note that N-M is an upper limit for L!
idx = bsxfun(#plus, (0:L)', 1:M)
X = b(idx)
That's exactly what im2col (from the Image Processing Toolbox) does:
b = (1:20).'; %'// example data
L = 18; % // desired length of sliding blocks
x = im2col(b, [L 1]); % // result
I'd use horzcat. For example:
function X = reshaper(b,len)
diff = length(b) - len + 1;
X = b(1:len);
for i=2:diff
X = horzcat(X,b(i:len+(i-1)));
end
You could probably remove the for loop with some further thought.

how to multiply 2D slices of two 3D matrices with each other in Matlab

I have two 3D matrices A(kl,1,r) and B(1,rs,r). kl=rs.
I need to get a new matrix C(kl,rs,r) which should have the product of column vector of A(kl,1) by the row vector of B(1,rs) for every page r without for loop
C=zeros(size(A,1),size(B,2),r);
for rr=1:size(A,3)
dummy=squeeze(A(:,:,rr))*squeeze(B(:,:,rr))';
C(:,:,rr)=dummy;
end
can anyone help with that? :)
Using bsxfun, you could do that directly in one line
out = bsxfun(#times, A, B);
Sample Inputs:
>> A
A(:,:,1) =
6
10
3
A(:,:,2) =
2
2
1
>> B
B(:,:,1) =
5 5 4
B(:,:,2) =
8 7 8
Results:
out(:,:,1) =
30 30 24
50 50 40
15 15 12
out(:,:,2) =
16 14 16
16 14 16
8 7 8

Multiply 2D Matrix with vector to span third dimension - MATLAB

As I am trying to multiply a m x n Matrix with a p-dimensional vector, I am stumbling across some difficulties.
Trying to avoid for loops, here is what I am looking to achieve
enter code here
M = [1 2 3; p = [1;2;3]
4 5 6;
7 8 9]
I want to obtain a 3x3x3 matrix, where the slices in third dimension are simply the entries of M multiplied by the respective entry in p.
Help is much appreciated
You can use bsxfun with permute for a vectorized (no-loop) approach like so -
out = bsxfun(#times,M,permute(p(:),[3 2 1]))
You would end up with -
out(:,:,1) =
1 2 3
4 5 6
7 8 9
out(:,:,2) =
2 4 6
8 10 12
14 16 18
out(:,:,3) =
3 6 9
12 15 18
21 24 27
With matrix-multiplication -
out = permute(reshape(reshape(M.',[],1)*p(:).',[size(M) numel(p)]),[2 1 3])

Extracting values along a row, column or diagonal of a 2D matrix

I have a 2 dimensional matrix and I want to get the data along a particular line. Similar to what 'Slice' does to a 3D matrix. Is there a a way to do a similar thing on a 2D matrix.
Thanks in advance.
Extracting all values of a column or a line:
>> M = magic(4)
M =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
>> particular_row = 3;
>> M(particular_row,:)
ans =
9 7 6 12
>> particular_column = 2;
>> M(:,particular_column)
ans =
2
11
7
14
Extracting values along a diagonal:
What if I want to get the data along any direction say along a line joining matrix index (1,1) to (4,4) of a 5x5 matrix?
I'd use linear indexing and the sub2ind function for this task. Demo:
(1,1) to (4,4):
>> M = magic(5)
M =
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
>> M(sub2ind(size(M), 1:4, 1:4))
ans =
17 5 13 21
Another example: (1,2) to (3,4):
M(sub2ind(size(M), 1:3, 2:4))
ans =
24 7 20