Mi pregunta: Me he dado cuenta de que muchas buenas respuestas a las preguntas de Matlab sobre SO utilizan con frecuencia la función bsxfun. ¿Por qué?
Motivación: en la documentación de Matlab para bsxfun, se proporciona el siguiente ejemplo:
A = magic(5);
A = bsxfun(@minus, A, mean(A))
Por supuesto, podríamos hacer la misma operación usando:
A = A - (ones(size(A, 1), 1) * mean(A));
Y, de hecho, una simple prueba de velocidad demuestra que el segundo método es aproximadamente un 20% más rápido. Entonces, ¿por qué usar el primer método? Supongo que hay algunas circunstancias en las que el uso bsxfunserá mucho más rápido que el enfoque "manual". Me interesaría mucho ver un ejemplo de tal situación y una explicación de por qué es más rápido.
Además, un elemento final para esta pregunta, nuevamente de la documentación de Matlab para bsxfun: "C = bsxfun (fun, A, B) aplica la operación binaria elemento por elemento especificada por la función de diversión de manejo a las matrices A y B, con singleton expansión habilitada ". ¿Qué significa la frase "con la expansión singleton habilitada"?

tic...toclas líneas, la velocidad del código dependerá de tener que leer las funciones en la memoria.timeitfunción en el enlace que usted / angainor / Dan proporciona.Respuestas:
Hay tres razones por las que uso
bsxfun( documentación , enlace del blog )bsxfunes más rápido querepmat(ver abajo)bsxfunrequiere menos escribirbsxfun, como usaraccumarray, me hace sentir bien con mi comprensión de Matlab.bsxfunreplicará las matrices de entrada a lo largo de sus "dimensiones singleton", es decir, las dimensiones a lo largo de las cuales el tamaño de la matriz es 1, de modo que coincidan con el tamaño de la dimensión correspondiente de la otra matriz. Esto es lo que se llama "expansión singleton". Por otro lado, las dimensiones de singleton son las que se eliminarán si llamasqueeze.Es posible que para problemas muy pequeños, el
repmatenfoque sea más rápido, pero con ese tamaño de matriz, ambas operaciones son tan rápidas que probablemente no harán ninguna diferencia en términos de rendimiento general. Hay dos razones importantes para quebsxfunsea más rápido: (1) el cálculo se realiza en código compilado, lo que significa que la replicación real de la matriz nunca ocurre, y (2)bsxfunes una de las funciones de Matlab multiproceso.He realizado una comparación de velocidad entre
repmatybsxfuncon R2012b en mi portátil bastante rápido.Para mí,
bsxfunes aproximadamente 3 veces más rápido querepmat. La diferencia se hace más pronunciada si las matrices se hacen más grandesEl salto en tiempo de ejecución
repmatocurre alrededor de un tamaño de matriz de 1Mb, que podría tener algo que ver con el tamaño de la memoria caché de mi procesador,bsxfunno es un salto tan malo, ya que solo necesita asignar la matriz de salida.A continuación encontrará el código que usé para el tiempo:
fuente
En mi caso, lo uso
bsxfunporque me evita pensar en los problemas de columna o fila.Para escribir su ejemplo:
Tengo que resolver varios problemas:
1)
size(A,1)osize(A,2)2)
ones(sizes(A,1),1)oones(1,sizes(A,1))3)
ones(size(A, 1), 1) * mean(A)omean(A)*ones(size(A, 1), 1)4)
mean(A)omean(A,2)Cuando lo uso
bsxfun, solo tengo que resolver el último:a)
mean(A)omean(A,2)Puede pensar que es flojo o algo así, pero cuando lo uso
bsxfun, tengo menos errores y programo más rápido .Además, es más corto, lo que mejora la velocidad de escritura y la legibilidad .
fuente
Pregunta muy interesante! Recientemente me topé con tal situación al responder esta pregunta. Considere el siguiente código que calcula los índices de una ventana deslizante de tamaño 3 a través de un vector
a:¡En este caso
bsxfunes casi dos veces más rápido! Es útil y rápido porque evita la asignación explícita de memoria. para las matricesidx0yidx1, guardándolas en la memoria, y luego volviéndolas a leer solo para agregarlas. Dado que el ancho de banda de la memoria es un activo valioso y, a menudo, el cuello de botella en las arquitecturas de hoy en día, desea usarlo sabiamente y disminuir los requisitos de memoria de su código para mejorar el rendimiento.bsxfunle permite hacer exactamente eso: crear una matriz basada en la aplicación de un operador arbitrario a todos los pares de elementos de dos vectores, en lugar de operar explícitamente en dos matrices obtenidas al replicar los vectores. Esa es la expansión singleton . También puede considerarlo como el producto externo de BLAS:Multiplica dos vectores para obtener una matriz. Solo que el producto externo solo realiza la multiplicación y
bsxfunpuede aplicar operadores arbitrarios. Como nota al margen, es muy interesante ver quebsxfunes tan rápido como el producto externo BLAS. Y generalmente se considera que BLAS ofrece el rendimiento.Editar Gracias al comentario de Dan, aquí hay un gran artículo de Loren que habla exactamente de eso.
fuente
bsxfuncon un buen ejemplo.A partir de R2016b, Matlab admite la expansión implícita para una amplia variedad de operadores, por lo que en la mayoría de los casos ya no es necesario usar
bsxfun:Hay una discusión detallada de Expansión implícita y su desempeño en el blog de Loren. Para citar a Steve Eddins de MathWorks:
fuente
Las cosas no siempre son consistentes con los 3 métodos comunes: la
repmatexpulsión por indexación ybsxfun. Se vuelve más interesante cuando aumenta aún más el tamaño del vector. Ver trama:bsxfunen realidad se vuelve un poco más lento que los otros dos en algún momento, pero lo que me sorprendió es que si aumenta el tamaño del vector aún más (> 13E6 elementos de salida), bsxfun de repente se vuelve más rápido en aproximadamente 3x. Sus velocidades parecen saltar en pasos y el orden no siempre es consistente. Supongo que también podría depender del tamaño del procesador / memoria, pero en general creo que me quedaríabsxfunsiempre que sea posible.fuente