Albert Nestler
Albert Nestler

Reputation: 29

Optimizing matlab code which uses repmat

In some part of my code, I have used repmat for a very large vector

vecO=repmat(vec,1,9);
fi = repmat(vecO',1,400)-A;

vec is a 1 by 400 matrix and 'A' is a 3600 by 400 matrix. I think there should be a way less time-consuming than using repmat but I don't know what is the method. Does anyone have any idea?

Upvotes: 0

Views: 97

Answers (2)

Steve
Steve

Reputation: 1587

Here is a template test to use, including mikkola's answer:

vec = rand(1,400);
A = rand(3600,400);
n_expts = 1000;
format long
disp(version);

% Warm up
for ii = 1:n_expts
    vec0 = repmat(vec,1,9);
    res1 = repmat(vec0',1,400)-A;
    res3 = bsxfun(@minus, vec0.', A);
end

tic
for ii = 1:n_expts
    vec0 = repmat(vec, 1, 9);
    res1 = repmat(vec0.', 1, 400) - A;
end
fprintf('Time taken with 2 repmats: ')
disp(toc/n_expts)

tic
for ii = 1:n_expts
    res2 = repmat(vec.', 9, 400) - A;
end
fprintf('Time taken with 1 repmat and transpose: ')
disp(toc/n_expts)

tic
for ii = 1:n_expts
    res3 = bsxfun(@minus, vec0.', A);
end
fprintf('Time taken with bsxfun: ')
disp(toc/n_expts)

% Check that all the fi are the same
dres1 = max(max(abs(res1 - res2)));
dres2 = max(max(abs(res1 - res3)));
tol = eps;
if (dres1 > eps) | (dres2 > eps)
    fprintf('Difference in output matrices');
end

With results

8.3.0.532 (R2014a)
Time taken with 2 repmats:    0.004027661867427

Time taken with 1 repmat and transpose:    0.004034170491803

Time taken with bsxfun:    0.003970521454027

Upvotes: 0

mikkola
mikkola

Reputation: 3476

Seems like your result (in your question fi) is supposed to contain the difference of vec0 with each column of A. This means that instead of using repmat to expand vec0 to the same size as A (by generating 400 replicates of it), you can apply an element-wise operation to two arrays with implicit expansion using bsxfun. Using this function will not make copies of vec0 but should achieve the same result. The first argument specifies the function to apply to the two arrays, here it is simply minus.

result = bsxfun(@minus, vec0.', A);

Upvotes: 1

Related Questions