how to multiply 2D slices of two 3D matrices with each other in Matlab - 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

Related

stacking rows of 2 matrices on top of each other consecutively

I have two matrices, each with about ten rows. I am trying to stack the rows on top of each other consecutively. For example I have matrices A and B, and I have made a for loop to make it repeat the processes of stacking their rows. The problem now is that when I run the script, it only does it for the first row and doesnt continue on. The code is written below
A = [1 2 3 4 5 6 7 8 9 10];
B= [11 12 13 14 15 16 171 18 19 20];
for i2= 1:10
l= A(i2,1);
p= B(i2,1);
for i4= 1:10
i4 = [l;p] ;
end
end
% so the answer will be
% i4 = [1 11 2 12 3 13 4 14 5 15 6 16 7 17 8 18 9 19 10 20]
Please I need some help
I haven't got matlab to test this but:
new = []
for i= 1:10
l= A(i,:);
p= B(i,:);
for j= 1:10
new(end+1) =[l(j),p(j)] ;
end
end
There is surely a nicer way but this should work.
From:
https://stackoverflow.com/a/17766565/7252268
A = [1 2 3 4 5 6 7 8 9 10];
B= [11 12 13 14 15 16 171 18 19 20];
i4 = zeros(size(A,1), size(A,2)+size(B,2));
i4(:,1:2:end) = A;
i4(:,2:2:end) = B;
Alternatively to the solution of Ekin Inceleme you can use
i4 = reshape([A.' B.'].', 1, 2*size(A,2));
providing that A and B are equally sized. However, this one here is not so easy to read.
You don't need any loops!
just try this:
i4 = [A,B];

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.

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

How to reshape and interleave matrix elements?

Having the values of time sequence, I would like to reshape it into a nx4 matrix [X y], for the purpose of using these values as input and output values for machine learning algorithm.
X(i) is a 1x3 input vector and y is output scalar value.
The algorithm takes as an input every 2nd sequence value (3 values) in order to predict the 4th value.
To give a practical example, let's say we have a sequence
[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
The [X y] matrix should be the following:
[1 3 5 7; 2 4 6 8; 9 11 13 15; 10 12 14 16]
To get every second row I wrote the following code:
vec1 = timeSeries(1:2:end);
XyVec1 = reshape(vec1,4,[])'
similarly it could be written to get even numbers:
vec2 = timeSeries(2:2:end);
XyVec2 = reshape(vec2,5,[])'
The thing that I don't know how to do is to interleave matrix vec1 and vec2 rows to get
[vec(1,:); vec2(1,:);vec1(2,:), vec2(2,:)...]
Does anyone know how to interleave the rows of two (or more) matrices?
Try
result = zeros(size(vec1,1)+size(vec2,1),size(vec1,2));
result(1:2:end,:) = vec1;
result(2:2:end,:) = vec2;
Reuse matlab indexing facilities ot insert elements in correct rows
Sample octave mock-up: http://ideone.com/RVgmYA
There is this one-liner option
result = kron(vec1, [1;0]) + kron(vec2, [0;1]);
However, #Joel Falcou is faster. Having set the input vectors as
vec1 = rand(1000,1000);
vec2 = -rand(1000,1000);
it gives
Elapsed time is 0.007620 seconds. (indexing)
Elapsed time is 0.054607 seconds. (kron)
Good luck :) figuring out what's going on with those reshape(), permutes():
a = [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16];
reshape(permute(reshape(a,2,4,[]),[2,1,3]),4,[])'
the result
ans =
1 3 5 7
2 4 6 8
9 11 13 15
10 12 14 16
To interleave the vectors as mentioned in the end of your question you can use
reshape([vec1, vec2]', 4, [])'
for
vec1 =
1 3 5 7
9 11 13 15
vec2 =
2 4 6 8
10 12 14 16
it returns
>> reshape([vec1, vec2]', 4, [])'
ans =
1 3 5 7
2 4 6 8
9 11 13 15
10 12 14 16