Dado que la cuestión está etiquetada C++, voy a contribuir una respuesta que muestra cómo acceder a/manipulación de matrices columna-principal se puede hacer usando Boost.Multiarray (que pueden ser útiles a los demás que se enfrentan a un problema similar). Considero que Boost es una extensión de la biblioteca estándar de C++. No dude en ignorar esta respuesta si no le gusta/use Boost. :-)
#include <algorithm>
#include <iostream>
#include <boost/multi_array.hpp>
// Prints the contents of a matrix to standard output
template <class M> void printMatrix(const M& matrix)
{
int height = matrix.shape()[0];
int width = matrix.shape()[1];
for (int row=0; row<height; ++row)
{
for (int col=0; col<width; ++col)
{
std::cout << matrix[row][col] << " ";
}
std::cout << "\n";
}
}
int main()
{
// Source matrix data is in column-major format in memory,
// with data starting at bottom-left corner.
double data[] =
{
3, 7, 11,
2, 6, 10,
1, 5, 9,
0, 4, 8
};
int width=4, height=3;
// Store rows, then columns (column-major)
int ordering[] = {0,1};
// Store rows in descending order (flips Y axis)
bool ascending[] = {true,false};
// Create a multi_array that references the existing data,
// with custom storage specifications.
typedef boost::multi_array_ref<double, 2> Matrix;
typedef boost::general_storage_order<2> Storage;
Matrix matrix(
data,
boost::extents[height][width],
Storage(ordering, ascending)
);
// Access source data as if it's row major
printMatrix(matrix);
std::cout << "\n";
// Transpose source data to an actual row-major matrix
// boost::multi_array is row-major by default
boost::multi_array<double, 2> matrix2(boost::extents[height][width]);
std::copy(matrix.begin(), matrix.end(), matrix2.begin());
printMatrix(matrix2);
}
Salida:
0 1 2 3
4 5 6 7
8 9 10 11
0 1 2 3
4 5 6 7
8 9 10 11
Como se puede ver, puede dejar los datos de origen en su formato de columna principal, y utilizar boost::multi_array_ref
con las especificaciones de almacenamiento personalizados para manipular los datos directamente (como si fuera fila mayor) usando la notación matrix[row][col]
.
Si la matriz va a ser atravesada a menudo en forma de hileras principales, entonces podría ser mejor transponerla a una matriz real principal de filas, como se muestra en la última parte de mi ejemplo.
Una solución fácil es escribir una clase de matriz que comprenda el concepto. La llamada justa cambia el orden de la fila. Los datos subyacentes no necesitan ser movidos, la interfaz simplemente intercambia los parámetros de acceso. –
@Martin: boost :: multi_array ya es compatible con esto. ¿Por qué todos ignoran esa maravillosa biblioteca? Síndrome de no inventado aquí? :-) –
@Emile: Obviamente use la herramienta correcta en el código de producción. Pero esta no es una pregunta sobre las bibliotecas. Es una pregunta sobre técnicas y agilidad de código. El OP obviamente está tratando de entender algunos de los conceptos más básicos del lenguaje que no intentan comprender toda la plethera de las bibliotecas disponibles. –