
En informática, el orden por filas y el orden por columnas son métodos para almacenar matrices multidimensionales en almacenamiento lineal, como la memoria de acceso aleatorio .
La diferencia entre los órdenes radica en qué elementos de una matriz son contiguos en la memoria. En el orden por filas, los elementos consecutivos de una fila se encuentran uno al lado del otro, mientras que lo mismo ocurre con los elementos consecutivos de una columna en el orden por columnas. Si bien los términos aluden a las filas y columnas de una matriz bidimensional, los órdenes pueden generalizarse a matrices de cualquier dimensión, teniendo en cuenta que los términos "por filas" y "por columnas" son equivalentes a los órdenes lexicográfico y colexicográfico , respectivamente. Las matrices, que comúnmente se representan como colecciones de vectores fila o columna, se almacenan efectivamente como vectores consecutivos o componentes de vectores consecutivos mediante este enfoque. Estas formas de almacenar datos se denominan AoS y SoA, respectivamente.
La disposición de los datos es fundamental para transferir correctamente matrices entre programas escritos en distintos lenguajes de programación. También es importante para el rendimiento al recorrer una matriz, ya que las CPU modernas procesan los datos secuenciales de forma más eficiente que los no secuenciales. Esto se debe principalmente al almacenamiento en caché de la CPU , que aprovecha la localidad espacial de referencia . [ 1 ] Además, el acceso contiguo permite utilizar instrucciones SIMD que operan sobre vectores de datos. En algunos soportes, como el almacenamiento de datos en cinta magnética , el acceso secuencial es mucho más rápido que el acceso no secuencial.
Explicación y ejemplo
Los términos ordenación por filas y por columnas provienen de la terminología relacionada con la ordenación de objetos. Una forma general de ordenar objetos con muchos atributos es agruparlos y ordenarlos primero por un atributo y luego, dentro de cada grupo, agruparlos y ordenarlos por otro atributo, y así sucesivamente. Si interviene más de un atributo en la ordenación, el primero se denomina principal y el último secundario . Si intervienen dos atributos, basta con nombrar solo el principal.
En el caso de los arreglos, los atributos son los índices a lo largo de cada dimensión. Para las matrices en notación matemática, el primer índice indica la fila y el segundo indica la columna , por ejemplo, dada una matriz, la entradaestá en su primera fila y segunda columna. Esta convención se traslada a la sintaxis de los lenguajes de programación, [ 2 ] aunque a menudo con índices que comienzan en 0 en lugar de 1. [ 3 ]
Aunque la fila se indica con el primer índice y la columna con el segundo , esto no implica ningún orden de agrupación entre las dimensiones. Por lo tanto, la elección de cómo agrupar y ordenar los índices, ya sea por filas o por columnas, es una cuestión de convención. La misma terminología se puede aplicar a matrices de dimensiones aún mayores. La agrupación por filas comienza desde el índice más a la izquierda y la agrupación por columnas desde el índice más a la derecha , lo que da lugar a órdenes lexicográficos y colexicográficos (o colex) , respectivamente.
Por ejemplo, la matriz
podría almacenarse de dos maneras posibles:
Los lenguajes de programación manejan esto de diferentes maneras. En C , los arreglos multidimensionales se almacenan en orden de filas principales, y los índices del arreglo se escriben en orden de filas primero (orden de acceso lexicográfico):
Por otro lado, en Fortran , los arreglos se almacenan en orden de columnas, mientras que los índices de los arreglos todavía se escriben en orden de filas (orden de acceso colexicográfico):
Nótese cómo el uso de A[i][j]con indexación de varios pasos como en C, en contraposición a una notación neutral como A(i,j)como en Fortran, implica casi inevitablemente un orden por filas por razones sintácticas, por así decirlo, porque se puede reescribir como (A[i])[j], e A[i]incluso la parte de la fila se puede asignar a una variable intermedia que luego se indexa en una expresión separada. (No se deben asumir otras implicaciones; por ejemplo, Fortran no es de orden por columnas simplemente por su notación, e incluso la implicación anterior podría eludirse intencionalmente en un nuevo lenguaje).
Para usar el orden de columnas en un entorno de filas, o viceversa, por cualquier motivo, una solución consiste en asignar roles no convencionales a los índices (usando el primer índice para la columna y el segundo para la fila), y otra en eludir la sintaxis del lenguaje calculando explícitamente las posiciones en una matriz unidimensional. Por supuesto, desviarse de la convención probablemente conlleva un coste que aumenta con el grado de interacción necesaria con las características convencionales del lenguaje y otro código, no solo en forma de mayor vulnerabilidad a errores (olvidar invertir también el orden de multiplicación de matrices, volver a la convención durante el mantenimiento del código, etc.), sino también en forma de tener que reorganizar activamente los elementos, todo lo cual debe sopesarse frente a cualquier propósito original, como aumentar el rendimiento. Se prefiere ejecutar el bucle fila por fila en lenguajes de filas como C y viceversa para lenguajes de columnas.
Lenguajes de programación y bibliotecas
Los lenguajes de programación o sus bibliotecas estándar que admiten matrices multidimensionales suelen tener un orden de almacenamiento nativo por filas o por columnas para estas matrices.
El orden de filas se utiliza en C / C++ / Objective-C (para matrices de estilo C), PL/I , [ 4 ] Pascal , [ 5 ] Speakeasy , [ 6 ] y SAS . [ 7 ]
El orden de columnas principales se utiliza en Fortran , [ 8 ] [ 9 ] IDL , [ 8 ] MATLAB , [ 9 ] GNU Octave , Julia , [ 10 ] S , S-PLUS , [ 11 ] R , [ 12 ] Scilab , [ 13 ] Yorick y Rasdaman . [ 14 ]
Ni orden por filas ni orden por columnas
Una alternativa típica para el almacenamiento de matrices densas es el uso de vectores Iliffe , que normalmente almacenan punteros a elementos en la misma fila de forma contigua (como el orden de filas principales), pero no las filas en sí. Se utilizan en (ordenados por antigüedad): Java , [ 15 ] C# / CLI / .Net , Scala , [ 16 ] y Swift .
Aún menos denso es usar listas de listas, por ejemplo, en Python , [ 17 ] y en el lenguaje Wolfram de Wolfram Mathematica . [ 18 ]
Un enfoque alternativo utiliza tablas de tablas, por ejemplo, en Lua . [ 19 ]
Bibliotecas externas
Las bibliotecas externas también pueden ofrecer compatibilidad con matrices multidimensionales e incluso admitir ordenaciones arbitrarias, donde cada dimensión tiene un valor de paso, y el orden por filas o por columnas son solo dos posibles interpretaciones resultantes.
El orden por filas es el predeterminado en NumPy [ 20 ] (para Python).
El orden por columnas es el predeterminado en Eigen [ 21 ] y Armadillo (ambos para C++).
Un caso especial sería OpenGL (y OpenGL ES ) para el procesamiento de gráficos. Dado que "los tratamientos matemáticos recientes del álgebra lineal y campos relacionados invariablemente tratan los vectores como columnas", el diseñador Mark Segal decidió sustituir esto por la convención en el predecesor IRIS GL , que era escribir vectores como filas; para compatibilidad, las matrices de transformación seguirían almacenándose en orden vector-mayor (fila-mayor) en lugar de orden coordenada-mayor (columna-mayor), y luego usó el truco "[para] decir que las matrices en OpenGL se almacenan en orden columna-mayor". [ 22 ] Esto realmente solo era relevante para la presentación, porque la multiplicación de matrices se basaba en la pila y aún podía interpretarse como postmultiplicación, pero, peor aún, la realidad se filtró a través de la API basada en C porque se accedería a los elementos individuales como M[vector][coordinate]o, efectivamente, M[column][row], lo que desafortunadamente confundió la convención que el diseñador buscaba adoptar, y esto incluso se conservó en el lenguaje de sombreado de OpenGL que se agregó posteriormente (aunque esto también hace posible acceder a las coordenadas por nombre en su lugar, p. ej., M[vector].y). Como resultado, muchos desarrolladores ahora simplemente declararán que tener la columna como primer índice es la definición de orden de columnas, aunque claramente este no es el caso con un lenguaje de orden de columnas real como Fortran.
Torch (para Lua) cambió el orden predeterminado de columna principal [ 23 ] a fila principal [ 24 ] .
Transposición
Dado que la transposición de matrices consiste en intercambiar los índices de una matriz , una matriz almacenada en orden de filas pero leída en orden de columnas (o viceversa) aparecerá transpuesta. Como realizar esta reorganización en memoria suele ser una operación costosa, algunos sistemas ofrecen opciones para especificar que las matrices individuales se almacenen transpuestas. El programador debe entonces decidir si reorganizar o no los elementos en memoria, en función de su uso real (incluida la cantidad de veces que la matriz se reutiliza en un cálculo).
Por ejemplo, a las funciones de los subprogramas básicos de álgebra lineal se les pasan indicadores que señalan qué matrices se transponen. [ 25 ]
Cálculo de direcciones en general
El concepto se generaliza a matrices con más de dos dimensiones.
Para un d -dimensionalmatriz con dimensiones N k ( k =1... d ), un elemento dado de esta matriz se especifica mediante una tuplade índices d (basados en cero).
En orden de filas, la última dimensión es contigua, por lo que el desplazamiento de memoria de este elemento viene dado por:
En orden de columnas, la primera dimensión es contigua, por lo que el desplazamiento de memoria de este elemento viene dado por: donde el producto vacío es el elemento identidad multiplicativo , es decir,.
Para un orden dado, el paso en la dimensión k viene dado por el valor de multiplicación entre paréntesis antes del índice n k en las sumas del lado derecho anteriores.
En términos más generales, hay d! posibles órdenes para una matriz dada, una para cada permutación de dimensiones (siendo el orden por filas y el orden por columnas solo 2 casos especiales), aunque las listas de valores de paso no son necesariamente permutaciones entre sí, por ejemplo, en el ejemplo de 2 por 3 anterior, los pasos son (3,1) para el orden por filas y (1,2) para el orden por columnas.
Véase también
- Matriz (estructura de datos)
- Comparación de lenguajes de programación (array)
- Origen del índice , otra diferencia entre los tipos de matrices en los distintos lenguajes de programación.
- Representación matricial
- El orden de Morton , otra forma de mapear datos multidimensionales a un índice unidimensional, resulta útil en estructuras de datos de árbol.
- Formato CSR , una técnica para almacenar matrices dispersas en memoria.
- Vectorización (matemáticas) , el equivalente a convertir una matriz en el vector columna principal correspondiente.
Referencias
- ↑ "Memoria caché" . Peter Lars Dordal . Consultado el 10 de abril de 2021 .
- ↑ "Matrices y E/S formateadas" . Tutorial de FORTRAN . Consultado el 19 de noviembre de 2016 .
- ↑ "Por qué la numeración debería comenzar en cero" . Archivo EW Dijkstra . Consultado el 2 de febrero de 2017 .
- ↑ "Language Reference Version 4 Release 3" (PDF) . IBM . Consultado el 13 de noviembre de 2017.
Los valores iniciales especificados para una matriz se asignan a los elementos sucesivos de la matriz en orden de filas (el subíndice final varía más rápidamente).
- ↑ "ISO/IEC 7185:1990(E)" (PDF) .
Un tipo de matriz que especifica una secuencia de dos o más tipos de índice será una notación abreviada para un tipo de matriz especificado para tener como su tipo de índice el primer tipo de índice en la secuencia y para tener un tipo de componente que es un tipo de matriz que especifica la secuencia de tipos de índice sin el primer tipo de índice en la secuencia y que especifica el mismo tipo de componente que la especificación original.
- ↑ Cohen, S.; Vincent, CM (1971-05-01). Introducción a SPEAKEASY (Informe). Laboratorio Nacional Argonne, IL (EE. UU.).
- ↑ "SAS® 9.4 Language Reference: Concepts, Sixth Edition" (PDF) . SAS Institute Inc. 6 de septiembre de 2017. pág. 573. Consultado el 18 de noviembre de 2017.
De derecha a izquierda, la dimensión más a la derecha representa las columnas; la siguiente dimensión representa las filas. [...] SAS coloca las variables en una matriz multidimensional llenando todas las filas en orden, comenzando en la esquina superior izquierda de la matriz (conocido como orden por filas).
- 1 2 "Columnas, filas y mayoría de matrices" . www.nv5geospatialsoftware.com . Consultado el 31 de julio de 2024 .
- 1 2 Documentación de MATLAB, Almacenamiento de datos de MATLAB (obtenido de Mathworks.co.uk, enero de 2014).
- ↑ "Matrices multidimensionales" . Julia . Consultado el 9 de noviembre de 2020 .
- ↑ Spiegelhalter et al. (2003 , p. 17) : Spiegelhalter, David ; Thomas, Andrew; Best, Nicky ; Lunn, Dave (enero de 2003), "Formato de datos: formato S-Plus", Manual de usuario de WinBUGS (PDF) (versión 1.4 ), Cambridge, Reino Unido: Unidad de Bioestadística del MRC, Instituto de Salud Pública, archivado del original (PDF) el 18 de mayo de 2003.
- ↑ Introducción a R , Sección 5.1: Arreglos (consultado en marzo de 2010).
- ↑ "FFT con datos multidimensionales" . Scilab Wiki . Consultado el 25 de noviembre de 2017.
Debido a que Scilab almacena matrices en formato de columna principal, los elementos de una columna son adyacentes (es decir, una separación de 1) en formato lineal.
- ↑ "Representación interna de matrices en rasdaman" . rasdaman.org . Consultado el 30 de marzo de 2025 .
- ↑ "Especificación del lenguaje Java" . Oracle . Consultado el 13 de febrero de 2016 .
- ↑ "object Array" . Biblioteca estándar de Scala . Consultado el 1 de mayo de 2016 .
- ↑ "La biblioteca estándar de Python: 8. Tipos de datos" . Consultado el 18 de noviembre de 2017 .
- ↑ "Vectores y matrices" . Wolfram . Consultado el 12 de noviembre de 2017 .
- ↑ "11.2 – Matrices y arreglos multidimensionales" . Consultado el 6 de febrero de 2016 .
- ↑ "El arreglo N-dimensional (ndarray)" . SciPy.org . Consultado el 3 de abril de 2016 .
- ↑ "Eigen: Órdenes de almacenamiento" . eigen.tuxfamily.org . Consultado el 23/11/2017 .
Si no se especifica el orden de almacenamiento, Eigen almacena la entrada por defecto en orden de columnas.
- ↑ "Vectores columna vs. vectores fila" . Consultado el 12 de noviembre de 2017 .
- ↑ "Tensor" . Consultado el 6 de febrero de 2016 .
- ↑ "Tensor" . Manual de referencia del paquete Torch . Consultado el 8 de mayo de 2016 .
- ↑ "BLAS (Subprogramas básicos de álgebra lineal)" . Consultado el 16 de mayo de 2015 .
Fuentes
- Donald E. Knuth, El arte de la programación informática Volumen 1: Algoritmos fundamentales , tercera edición, sección 2.2.6 (Addison-Wesley: Nueva York, 1997).
- Matrices