Improving performance of Matlab code
I have a matrix A (MxN) and need to create a matrix B (MxNxN) using A so B(:,1,1) = A(:,1)
that ,, B(:,2,2) = A(:,2)
..., B(:,N,N) = A(:,N)
. I am currently using
B = zeros(size(A,1), size(A,2), size(A,2));
for i=1:size(B,3)
B(:,i,i) = A(:,i);
end
Can repmat
any other method be used to make this code faster than it is now?
source to share
This can be done using "partial" linear indexing in the last two dimensions B
, as shown below:
[M, N] = size(A);
B = zeros(M, N, N);
B(:, 1:N+1:N^2) = A;
source to share
Here's a way bsxfun
and shiftdim
:
m = 3;
n = 4;
A = rand(m,n); % example data
C = bsxfun(@times,A,shiftdim(eye(n),-1));
shiftdim
is used to map an N-by-N identity matrix to a 1-by-N-by-N array, which is then multiplied by A
and actually replicated along the first dimension. This approach should be both efficient and quick. Compared to the loop version for
:
B = zeros(size(A,1), size(A,2), size(A,2));
for i=1:size(B,3)
B(:,i,i) = A(:,i);
end
Then it isequal(B,C)
returns 1
.
source to share
If I understand correctly what you want to do, this should do the trick (you will need to replace 4
and 5
in my example with M
or N
):
>> A = rand(4, 5)
A =
0.8147 0.6324 0.9575 0.9572 0.4218
0.9058 0.0975 0.9649 0.4854 0.9157
0.1270 0.2785 0.1576 0.8003 0.7922
0.9134 0.5469 0.9706 0.1419 0.9595
>> B = permute(reshape(repmat(A, 1, 5), 4, 5, 5), [1 3 2]) ;
>> C = permute(reshape(repmat(eye(5, 5), 1, 4), 5, 5, 4), [3 1 2]) ;
>> T = C .* B
>> squeeze(T(1, :, :))
ans =
0.8147 0 0 0 0
0 0.6324 0 0 0
0 0 0.9575 0 0
0 0 0 0.9572 0
0 0 0 0 0.4218
Note. I haven't tested the above code in MATLAB, I only tested it with numpy
, but this should do what you want. Below is an example in python
using numpy
:
>>> import numpy
>>> import numpy.matlib as matlib
>>> A = numpy.random.rand(4, 5)
>>> A
array([[ 0.44172719, 0.32698936, 0.53422512, 0.39081766, 0.09870158],
[ 0.65483718, 0.50364349, 0.74913438, 0.87151756, 0.71811372],
[ 0.54355853, 0.44174294, 0.61738783, 0.74293526, 0.1598779 ],
[ 0.77675639, 0.204072 , 0.69584264, 0.04263266, 0.24350847]])
>>> B = matlib.repmat(A, 1, 5).reshape((4, 5, 5))
>>> B
array([[[ 0.44172719, 0.32698936, 0.53422512, 0.39081766, 0.09870158],
[ 0.44172719, 0.32698936, 0.53422512, 0.39081766, 0.09870158],
[ 0.44172719, 0.32698936, 0.53422512, 0.39081766, 0.09870158],
[ 0.44172719, 0.32698936, 0.53422512, 0.39081766, 0.09870158],
[ 0.44172719, 0.32698936, 0.53422512, 0.39081766, 0.09870158]],
[[ 0.65483718, 0.50364349, 0.74913438, 0.87151756, 0.71811372],
[ 0.65483718, 0.50364349, 0.74913438, 0.87151756, 0.71811372],
[ 0.65483718, 0.50364349, 0.74913438, 0.87151756, 0.71811372],
[ 0.65483718, 0.50364349, 0.74913438, 0.87151756, 0.71811372],
[ 0.65483718, 0.50364349, 0.74913438, 0.87151756, 0.71811372]],
[[ 0.54355853, 0.44174294, 0.61738783, 0.74293526, 0.1598779 ],
[ 0.54355853, 0.44174294, 0.61738783, 0.74293526, 0.1598779 ],
[ 0.54355853, 0.44174294, 0.61738783, 0.74293526, 0.1598779 ],
[ 0.54355853, 0.44174294, 0.61738783, 0.74293526, 0.1598779 ],
[ 0.54355853, 0.44174294, 0.61738783, 0.74293526, 0.1598779 ]],
[[ 0.77675639, 0.204072 , 0.69584264, 0.04263266, 0.24350847],
[ 0.77675639, 0.204072 , 0.69584264, 0.04263266, 0.24350847],
[ 0.77675639, 0.204072 , 0.69584264, 0.04263266, 0.24350847],
[ 0.77675639, 0.204072 , 0.69584264, 0.04263266, 0.24350847],
[ 0.77675639, 0.204072 , 0.69584264, 0.04263266, 0.24350847]]])
>>> C = matlib.repmat(numpy.identity(5), 4, 1).reshape(4, 5, 5) * B
>>> C
array([[[ 0.44172719, 0. , 0. , 0. , 0. ],
[ 0. , 0.32698936, 0. , 0. , 0. ],
[ 0. , 0. , 0.53422512, 0. , 0. ],
[ 0. , 0. , 0. , 0.39081766, 0. ],
[ 0. , 0. , 0. , 0. , 0.09870158]],
[[ 0.65483718, 0. , 0. , 0. , 0. ],
[ 0. , 0.50364349, 0. , 0. , 0. ],
[ 0. , 0. , 0.74913438, 0. , 0. ],
[ 0. , 0. , 0. , 0.87151756, 0. ],
[ 0. , 0. , 0. , 0. , 0.71811372]],
[[ 0.54355853, 0. , 0. , 0. , 0. ],
[ 0. , 0.44174294, 0. , 0. , 0. ],
[ 0. , 0. , 0.61738783, 0. , 0. ],
[ 0. , 0. , 0. , 0.74293526, 0. ],
[ 0. , 0. , 0. , 0. , 0.1598779 ]],
[[ 0.77675639, 0. , 0. , 0. , 0. ],
[ 0. , 0.204072 , 0. , 0. , 0. ],
[ 0. , 0. , 0.69584264, 0. , 0. ],
[ 0. , 0. , 0. , 0.04263266, 0. ],
[ 0. , 0. , 0. , 0. , 0.24350847]]])
source to share