matlab - suma - ¿Cómo restar un vector de cada fila de una matriz?
vectores y matrices matematicas (2)
Posible duplicado:
¿Cómo puedo dividir cada fila de una matriz por una fila fija?
Estoy buscando una forma elegante de restar el mismo vector de cada fila de una matriz. Aquí hay una manera no elegante de hacerlo.
a = [1 2 3];
b = rand(7,3);
c(:,1) = b(:,1) - a(1);
c(:,2) = b(:,2) - a(2);
c(:,3) = b(:,3) - a(3);
Además, la manera elegante no puede ser más lenta que este método.
He intentado
c = b-repmat(a,size(b,1),1);
y parece más lento.
EDITAR: El ganador es este método.
c(:,1) = b(:,1) - a(1);
c(:,2) = b(:,2) - a(2);
c(:,3) = b(:,3) - a(3);
EDITAR: Más métodos y resultados de tic toc:
n = 1e6;
m = 3;
iter = 100;
a = rand(1,m);
b = rand(n,m);
tic
c = zeros(size(b));
for i = 1:iter
c(:,1) = b(:,1) - a(1);
c(:,2) = b(:,2) - a(2);
c(:,3) = b(:,3) - a(3);
end
toc
tic
c = zeros(size(b));
for i = 1:iter
c(:,1) = b(:,1) - a(1);
c(:,2) = b(:,2) - a(2);
c(:,3) = b(:,3) - a(3);
end
toc
tic
c = zeros(size(b));
for i = 1:iter
for j = 1:3
c(:,j) = b(:,j) - a(j);
end
end
toc
tic
for i = 1:iter
c = b-repmat(a,size(b,1),1);
end
toc
tic
for i = 1:iter
c = bsxfun(@minus,b,a);
end
toc
tic
c = zeros(size(b));
for i = 1:iter
for j = 1:size(b,1)
c(j,:) = b(j,:) - a;
end
end
toc
resultados
Elapsed time is 0.622730 seconds.
Elapsed time is 0.627321 seconds.
Elapsed time is 0.713384 seconds.
Elapsed time is 2.621642 seconds.
Elapsed time is 1.323490 seconds.
Elapsed time is 17.269901 seconds.
Aquí está mi contribución:
c = b - ones(size(b))*diag(a)
Ahora apresúrate a probarlo:
tic
for i = 1:10000
c = zeros(size(b));
b = rand(7,3);
c = b - ones(size(b))*diag(a);
end
toc
El resultado:
Elapsed time is 0.099979 seconds.
No es tan rápido, pero está limpio.
Solo hay tres respuestas obvias, y usted dio dos de ellas en su pregunta.
El tercero es por fila,
c(1,:) = b(1,:) - a; %...
pero espero que sea más lento que el procesamiento por columna para matrices grandes, ya que accede a elementos que están fuera del orden de la memoria.
Si convierte el procesamiento por columna en un bucle for
en un archivo o subfunción * .m, ¿es aún más rápido que la versión repmat
?
Otra cosa que puedes probar es la velocidad: intenta preasignar c
.
c = zeros(size(b));
c(:,1) = b(:,1) - a(1); %...