0

I have a Matrix market(.mtx) file. I want a sparse matrix conversion from the matrix market file. Can anyone suggest a way to convert matrix market format to 2 dimensional matrix in c++?

I have tried a matlab approach in converting the matrix market to sparse matrix online. But, I don't succeed in it. It would be of great help if I get a solution in c++. As it helps my project.

saichand
  • 1,165
  • 1
  • 10
  • 25
  • You have to show you've some effort yourself. Post your own attempt at writing this cide in C++ and someone will help you fix the problems. I think you're very unlikely to get someone to just write the code for you. That's not how it works round here. – john Jul 17 '19 at 12:39
  • Apart from anything else it's not clear what you mean by a 2 dimensional matrix. There's lots of different ways you can have a 2d matrix in C++, so if you show your own code it will be clear to everyone what you are aiming for. – john Jul 17 '19 at 12:40
  • I wanted a matrix market format conversion in general, nothing specific to the code I'm using. that is the reason I've not posted any code. sorry, if you didn't get my question. I have put effort in trying to convert using matlab online. but it could not support the size of the matrix file I was uploading. So I wanted a different approach. I got the answer from Sumit Jha (below). Thank you. – saichand Jul 17 '19 at 13:59

4 Answers4

4

There could be several ways to read .mtx data. I just parsed the file and filled the matrix with data. Please find code snippet below :

std::ifstream file("filaname.mtx");
int num_row, num_col, num_lines;

// Ignore comments headers
while (file.peek() == '%') file.ignore(2048, '\n');

// Read number of rows and columns
file >> num_row>> num_col >> num_lines;

// Create 2D array and fill with zeros
double* matrix;              
matrix = new double[num_row * num_col];      
std::fill(matrix, matrix + num_row *num_col, 0.);.

// fill the matrix with data
for (int l = 0; l < num_lines; l++)
{
    double data;
    int row, col;
    file >> row >> col >> data;
    matrix[(row -1) + (col -1) * num_row] = data;
}

file.close();

I hope it helps.

Sumit Jha
  • 1,601
  • 11
  • 18
1

Without more information on your code or goals, it's difficult to say exactly what would would work best. If you're using this format, I'd suggest something similar to this.

Open the file in a std::ifstream, and then get lines one at a time into a std::string with std::getline() for processing. If you know the line has values you want, I would also recommend converting it to std::stringstream so you can use the >> operator to extract values.

  1. Given that the header of a Matrux market file begins with '%%', std::string::find() lets you determine whether the line you've read is the header. You can convert to stringstream and parse strings out to get information about the file, like "matrix coordinate real general" or others, if you care about these.
  2. Each comment begins with '%' - if you find this character at the beginning of your string, you can ignore it and read the next one.
  3. The first non-comment line is 3 numbers: rows, columns, and entries. Parse these with a stringstream; you'll use them to allocate memory for your array. Once you have the dimensions, This question and its answers describe some good ways to dynamically allocate the space you need.
  4. Each subsequent line describes the coordinates and value of an array entry. You can read the first two numbers and use these as indices to your 2D array, and then use the third number as the entry at that point.

Or, you could switch to C, which has a library dedicated to Matrix Market I/O.

Nick Reed
  • 4,989
  • 4
  • 17
  • 37
0

The National Institute of Standards and Technology provides C code that can do the file operations you are looking for. It also has examples of read and write operations in C. Since C code is compatible with C++ you can use this code in the project you are working on. https://math.nist.gov/MatrixMarket/mmio-c.html

Bilal Shafi
  • 115
  • 2
  • 13
0

The fast_matrix_market library has a loader that will do exactly what you need:

std::ifstream file("filename.mtx");
std::vector<double> matrix;
int64_t nrows, ncols; // the file's dimensions saved here

fast_matrix_market::read_matrix_market_array(
                file,
                nrows, ncols,
                matrix,
                fast_matrix_market::row_major);

That will work with both sparse and dense MatrixMarket files.

Adam
  • 16,808
  • 7
  • 52
  • 98