gevtushenko / matrix_reader

C++ reader for matrix market format
MIT License
3 stars 1 forks source link

Complex support #2

Open cauachagas opened 3 years ago

cauachagas commented 3 years ago

I'm trying to open a complex .mtx file, but without success. I tried to add the following codes

L84 - matrix_market_reader.h

  const std::complex<double> *get_cpx_data () const
  {
    if (meta.matrix_data_type == data_type::complex)
      return reinterpret_cast<const std::complex<double> *> (get_data ());
    throw std::runtime_error ("Accessing non cpx matrix as cpx");
  }

https://github.com/senior-zero/matrix_reader/blob/e031bb88878022b9ab0dda2c66b19e1f6bc616d0/include/matrix_market_reader.h#L84

L191 - matrix_market_reader.cpp

    else if (meta.matrix_data_type == matrix_class::data_type::complex)
      cpx_data.reset (new complex<double>[meta.non_zero_count]);

https://github.com/senior-zero/matrix_reader/blob/e031bb88878022b9ab0dda2c66b19e1f6bc616d0/src/matrix_market_reader.cpp#L191

L201 - matrix_market_reader.cpp

    else if (cpx_data)
      return read_lines (is, cpx_data);

https://github.com/senior-zero/matrix_reader/blob/e031bb88878022b9ab0dda2c66b19e1f6bc616d0/src/matrix_market_reader.cpp#L201

229 - matrix_market_reader.cpp

  unique_ptr<complex<double>[]> cpx_data;

https://github.com/senior-zero/matrix_reader/blob/e031bb88878022b9ab0dda2c66b19e1f6bc616d0/src/matrix_market_reader.cpp#L229

Test

TEST(matrix_market_reader, sparse_complex_general)
{
  const unsigned int target_nz = 4;
  const string mm_file_content =
      "%%MatrixMarket matrix coordinate complex general\n"
      "%----------------------------------------------\n"
      "% Multi line comment \n"
      "2 2 4\n"
      "1 1 1 0\n"
      "1 2 2 0\n"
      "2 1 3 0\n"
      "2 2 4 0\n";
  istringstream iss (mm_file_content);

  matrix_market::reader reader (iss);
  ASSERT_TRUE (reader);
  ASSERT_EQ (reader.matrix ().meta.non_zero_count, target_nz);

  auto col_ids = reader.matrix ().get_col_ids ();
  auto row_ids = reader.matrix ().get_row_ids ();
  auto data    = reader.matrix ().get_cpx_data ();

  for (unsigned int i = 0; i < target_nz; i++)
  {
    ASSERT_EQ (row_ids[i], i / 2);
    ASSERT_EQ (col_ids[i], i % 2);
    ASSERT_EQ (data[i], complex<double> (i + 1, 0));
    cout << data[i] << endl;
  }
}

TEST(matrix_market_reader, sparse_complex_general2)
{
  const unsigned int target_nz = 4;
  const string mm_file_content =
      "%%MatrixMarket matrix coordinate complex general\n"
      "%----------------------------------------------\n"
      "% Multi line comment \n"
      "2 2 4\n"
      "1 1 1 1\n"
      "1 2 2 2\n"
      "2 1 3 3\n"
      "2 2 4 4\n";
  istringstream iss (mm_file_content);

  matrix_market::reader reader (iss);
  ASSERT_TRUE (reader);
  ASSERT_EQ (reader.matrix ().meta.non_zero_count, target_nz);

  auto col_ids = reader.matrix ().get_col_ids ();
  auto row_ids = reader.matrix ().get_row_ids ();
  auto data    = reader.matrix ().get_cpx_data ();

  for (unsigned int i = 0; i < target_nz; i++)
  {
    ASSERT_EQ (row_ids[i], i / 2);
    ASSERT_EQ (col_ids[i], i % 2);
    ASSERT_EQ (data[i], complex<double> (i + 1, i + 1));
  }
}

Result

[==========] Running 4 tests from 1 test suite.
[----------] Global test environment set-up.
[----------] 4 tests from matrix_market_reader
[ RUN      ] matrix_market_reader.empty_sparse
[       OK ] matrix_market_reader.empty_sparse (0 ms)
[ RUN      ] matrix_market_reader.sparse
[       OK ] matrix_market_reader.sparse (0 ms)
[ RUN      ] matrix_market_reader.sparse_complex_general
(1,0)
(2,0)
(3,0)
(4,0)
[       OK ] matrix_market_reader.sparse_complex_general (0 ms)
[ RUN      ] matrix_market_reader.sparse_complex_general2
~/sparse/MatrixMarket/matrix_reader/tests/matrix_market_test.cpp:120: Failure
Expected equality of these values:
  data[i]
    Which is: (1,0)
  std::complex<double> (i + 1, i + 1)
    Which is: (1,1)
[  FAILED  ] matrix_market_reader.sparse_complex_general2 (0 ms)
[----------] 4 tests from matrix_market_reader (0 ms total)

[----------] Global test environment tear-down
[==========] 4 tests from 1 test suite ran. (0 ms total)
[  PASSED  ] 3 tests.
[  FAILED  ] 1 test, listed below:
[  FAILED  ] matrix_market_reader.sparse_complex_general2

 1 FAILED TEST

You can see that the code only reads the real part (test 1). When added to the imaginary part, the test fails (test 2). I don't have that much experience with C ++ to know where it is wrong.

gevtushenko commented 3 years ago

The issue with the complex type support is in the read_lines function. istringstream doesn't parse "1 2" as a complex number in izz >> data[nz]. You can add a branch for complex numbers to read lines function (like this one). Or you can wait for a while and I'll add complex matrices support.