eminem
Parse Matrix Market files in C++
|
Parse a matrix from a Matrix Market file. More...
#include <Parser.hpp>
Public Member Functions | |
Parser (std::unique_ptr< Input_ > input, const ParserOptions &options) | |
const MatrixDetails & | get_banner () const |
Index | get_nrows () const |
Index | get_ncols () const |
Index | get_nlines () const |
void | scan_preamble () |
template<typename Type_ = int, class Store_ > | |
bool | scan_integer (Store_ store) |
template<typename Type_ = double, class Store_ > | |
bool | scan_real (Store_ &&store) |
template<typename Type_ = double, class Store_ > | |
bool | scan_double (Store_ store) |
template<typename Type_ = double, class Store_ > | |
bool | scan_complex (Store_ store) |
template<typename Type_ = bool, class Store_ > | |
bool | scan_pattern (Store_ store) |
Parse a matrix from a Matrix Market file.
Input_ | Class for the source of input bytes, satisfying the byteme::PerByteInterface instance. |
This parses a Matrix Market file according to the specification described at https://math.nist.gov/MatrixMarket/reports/MMformat.ps.gz. It is expected that users call scan_preamble()
to determine the field type (see eminem::Field
for supported values), after which they may call one of scan_integer()
, scan_real()
, etc. to parse the rest of the file. An error will be thrown upon detecting a non-compliant file.
As the Matrix Market specification is somewhat vague in parts, we apply the following refinements:
Index
type occurs in scan_preamble()
. An error is also thrown if the row/column indices in any data line exceed the number of rows/columns in the preamble, or if the observed number of data lines exceeds the expected number for coordinate matrices/vectors.+
or -
sign. Leading zeros are ignored and will not be interpreted as octal. An error is thrown if overflow of the Type_
type occurs in scan_integer()
.Real data values should follow one of the following formats:
(sign)[digit sequence](exponent)
(sign)[digit sequence].(exponent)
(sign).[digit sequence](exponent)
(sign)[digit sequence].[digit sequence](exponent)
The digit sequence should contain one or mor digits, possibly containing leading zeros that will be ignored. The sign is optional and should be either +
or -
. The exponent is optional should have the form e(sign)[digit sequence]
or E(sign)[digit sequence]
, where the sign is again optional. We also support case-insensitive matches to inf
, infinity
or nan
. This will be converted to their corresponding IEEE special values if they are available for the provided Type_
in scan_real()
, otherwise an error is thrown. For non-special values, no additional checks for overflow are applied. If IEEE arithmetic is available, overflow will manifest as infinities, otherwise they will be undefined behavior.
No validation is performed to determine whether coordinates are consistent with non-general symmetries. Similarly, we do not check for the existence of multiple lines with the same row/column indices in coordinate matrices/vectors.
|
inline |
input | Source of input bytes, typically a byteme::PerByteInterface instance. |
options | Further options. |
|
inline |
Retrieve the Matrix Market banner, containing information about the data format and type. This should only be called after scan_preamble()
.
|
inline |
Get the number of rows in the matrix. This should only be called after scan_preamble()
. If the object type is Object::VECTOR
, the number of rows is equal to the length of the vector.
|
inline |
Get the number of columns in the matrix. This should only be called after scan_preamble()
. If the object type is Object::VECTOR
, the number of columns is set to 1.
|
inline |
Get the number of non-zero lines in the coordinate format. This should only be called after scan_preamble()
. If the object type is Object::ARRAY
, the number of lines is defined as the product of the number of rows and columns.
|
inline |
Scan the preamble from the Matrix Market file, including the banner and the size line. This should only be called once.
|
inline |
Scan the file for integer lines, assuming that the field in the banner is Field::INTEGER
.
Type_ | Type to represent the integer. |
Store_ | Function to process each line. |
store | Function with the signature void(Index row, Index column, Type_ value) , which is passed the corresponding values at each line. Both row and column will be 1-based indices; for Object::VECTOR , column will be set to 1. Alternatively, this may return bool , where a false indicates that the scanning should terminate early and a true indicates that the scanning should continue. |
store
returning false
.
|
inline |
Scan the file for real lines, assuming that the field in the banner is Field::REAL
.
Type_ | Type to represent the real value. |
Store_ | Function to process each line. |
store | Function with the signature void(Index row, Index column, Type_ value) , which is passed the corresponding values at each line. Both row and column will be 1-based indices; for Object::VECTOR , column will be set to 1. Alternatively, this function may return bool , where a false indicates that the scanning should terminate early and a true indicates that the scanning should continue. |
store
returning false
.
|
inline |
Scan the file for double-precision lines, assuming that the field in the banner is Field::DOUBLE
. This is just an alias for scan_real()
.
Type_ | Type to represent the double-precision value. |
Store_ | Function to process each line. |
store | Function with the signature void(Index row, Index column, Type_ value) , which is passed the corresponding values at each line. Both row and column will be 1-based indices; for Object::VECTOR , column will be set to 1. Alternatively, this function may return bool , where a false indicates that the scanning should terminate early and a true indicates that the scanning should continue. |
store
returning false
.
|
inline |
Scan the file for complex lines, assuming that the field in the banner is Field::COMPLEX
.
Type_ | Type to represent the real and imaginary parts of the complex value. |
Store_ | Function to process each line. |
store | Function with the signature void(Index row, Index column, std::complex<Type_> value) , which is passed the corresponding values at each line. Both row and column will be 1-based indices; for Object::VECTOR , column will be set to 1. Alternatively, this function may return bool , where a false indicates that the scanning should terminate early and a true indicates that the scanning should continue. |
store
returning false
.
|
inline |
Scan the file for pattern lines, assuming that the field in the banner is Field::PATTERN
. This function only works when the format field is set to Format::COORDINATE
.
Type_ | Type to represent the presence of a non-zero entry. |
Store_ | Function to process each line. |
store | Function with the signature void(Index row, Index column, Type_ value) , which is passed the corresponding values at each line. Both row and column will be 1-based indices; for Object::VECTOR , column will be set to 1. value will always be true and can be ignored; it is only required here for consistency with the other methods. Alternatively, this function may return bool , where a false indicates that the scanning should terminate early and a true indicates that the scanning should continue. |
store
returning false
.