Since the question is tagged C++, I'll contribute an answer that shows how accessing / manipulating column-major matrices can be done using Boost.Multiarray (it may be useful to others who face a similar problem). I consider Boost to be an extension to the C++ standard library. Feel free to ignore this answer if you don't like/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);
}
Output:
0 1 2 3
4 5 6 7
8 9 10 11
0 1 2 3
4 5 6 7
8 9 10 11
As you can see, you can leave the source data in its column-major format, and use boost::multi_array_ref
with custom storage specifications to manipulate the data directly (as if it were row-major) using the matrix[row][col]
notation.
If the matrix is going to be traversed often in row-major fashion, then it might be better to transpose it to an actual row-major matrix, as shown in the last part of my example.