Subtract column from a matrix

In matlab it is easy to subtract number from column or row. I want to subtract column [n x 1] from a matrix [n x m]. Is it possible to doit without for loop? When I wrote it just with '-', there was dimension mismatch error. Thanks.

 Respuesta aceptada

Image Analyst
Image Analyst el 25 de Sept. de 2014
You could use repmat() to create an array of the same size:
out = inputArray - repmat(columnVector, [1, m]);

6 comentarios

Mikhail
Mikhail el 25 de Sept. de 2014
Yea, seems like this is the fastest way. I think this must work faster, then for loop. Thanks.
Guillaume
Guillaume el 25 de Sept. de 2014
Editada: Guillaume el 25 de Sept. de 2014
No, bsxfun is faster and this is the exact purpose of it.
Image Analyst
Image Analyst el 25 de Sept. de 2014
Not always.
inputArray = rand(100,100);
columnVector = rand(100, 1);
tic
out = bsxfun(@minus, inputArray, columnVector);
toc
tic;
out = inputArray - repmat(columnVector, [1, 100]);
toc
Elapsed time is 0.000508 seconds.
Elapsed time is 0.000357 seconds.
José-Luis
José-Luis el 25 de Sept. de 2014
Editada: José-Luis el 25 de Sept. de 2014
To continue with the one-upping: When it is that fast, unless you are doing it many many times, it doesn't really matter.
Just did a quick test:
ii = [10 100 200 300 400 500 1000 2000 5000 7500 10000 20000]
a = [ii' ii'];
cnt = 0;
for sz = ii
sz
cnt = cnt + 1;
inputArray = rand(sz);
columnVector = rand(sz, 1);
tic
bsxfun(@minus, inputArray, columnVector);
out(1) = toc;
tic;
inputArray - repmat(columnVector, [1, sz]);
out(2) = toc;
a(cnt,:) = out;
end
plot(ii,a);
legend({'bsxfun','repmat'});
ylabel('Elapsed time (s)')
xlabel('Array size')
That results in:
Titus Edelhofer
Titus Edelhofer el 26 de Sept. de 2014
Nice comparison!
One aspect has not been mentioned yet: for larger matrices/vectors the memoryfriendliness of bsxfun compared to repmat (which blows up the memory usage significantly).
Titus
Image Analyst
Image Analyst el 26 de Sept. de 2014
Good point. This can be done by adding these lines into the loop:
memoryUsed = memory;
fprintf('Memory used by MATLAB = %d bytes.\n', memoryUsed.MemUsedMATLAB)

Iniciar sesión para comentar.

Más respuestas (1)

Guillaume
Guillaume el 25 de Sept. de 2014
Editada: Guillaume el 25 de Sept. de 2014
Use bsxfun, it will expands singleton dimensions:
n = 10; m = 20;
matrix = rand(n, m);
column = rand(n, 1);
bsxfun(@minus, matrix, column)

Categorías

Más información sobre Matrices and Arrays en Centro de ayuda y File Exchange.

Productos

Etiquetas

Preguntada:

el 25 de Sept. de 2014

Comentada:

el 26 de Sept. de 2014

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by