export to file directly; add a new trait for export
This commit is contained in:
parent
d511e372de
commit
8904c01c7b
@ -1,10 +1,9 @@
|
||||
//! Implementation of matrix market io code.
|
||||
//!
|
||||
//! See the [website](https://math.nist.gov/MatrixMarket/formats.html) or the [paper](https://www.researchgate.net/publication/2630533_The_Matrix_Market_Exchange_Formats_Initial_Design) for more details about matrix market.
|
||||
use crate::CooMatrix;
|
||||
use crate::SparseFormatError;
|
||||
use crate::SparseFormatErrorKind;
|
||||
use matrixcompare_core::SparseAccess;
|
||||
use crate::{CooMatrix, CscMatrix, CsrMatrix};
|
||||
use nalgebra::Complex;
|
||||
use pest::iterators::Pairs;
|
||||
use pest::Parser;
|
||||
@ -513,6 +512,17 @@ mod internal {
|
||||
/// Convert the data to string
|
||||
fn to_matrixmarket_string(&self) -> String;
|
||||
}
|
||||
|
||||
pub trait SupportedMatrixMarketExport<T: SupportedMatrixMarketScalar> {
|
||||
/// iterate over triplets
|
||||
fn triplet_iter(&self) -> Box<dyn Iterator<Item = (usize, usize, &T)> + '_>;
|
||||
/// number of rows
|
||||
fn nrows(&self) -> usize;
|
||||
/// number of columns
|
||||
fn ncols(&self) -> usize;
|
||||
/// number of non-zeros
|
||||
fn nnz(&self) -> usize;
|
||||
}
|
||||
}
|
||||
|
||||
/// A marker trait for supported matrix market scalars.
|
||||
@ -754,6 +764,46 @@ mm_complex_impl!(f64);
|
||||
|
||||
mm_pattern_impl!(());
|
||||
|
||||
/// A marker trait for supported sparse matrix types.
|
||||
///
|
||||
/// This is a sealed trait; it cannot be implemented by external crates. This is done in order to prevent leaking
|
||||
/// some of the implementation details we currently rely on. We may relax this restriction in the future.
|
||||
pub trait MatrixMarketExport<T: MatrixMarketScalar>:
|
||||
internal::SupportedMatrixMarketExport<T>
|
||||
{
|
||||
}
|
||||
|
||||
macro_rules! mm_matrix_impl {
|
||||
($T_MATRIX:ty) => {
|
||||
impl<T: MatrixMarketScalar> MatrixMarketExport<T> for $T_MATRIX {}
|
||||
|
||||
impl<T: internal::SupportedMatrixMarketScalar> internal::SupportedMatrixMarketExport<T>
|
||||
for $T_MATRIX
|
||||
{
|
||||
#[inline]
|
||||
fn triplet_iter(&self) -> Box<dyn Iterator<Item = (usize, usize, &T)> + '_> {
|
||||
Box::new(self.triplet_iter())
|
||||
}
|
||||
#[inline]
|
||||
fn nrows(&self) -> usize {
|
||||
self.nrows()
|
||||
}
|
||||
#[inline]
|
||||
fn ncols(&self) -> usize {
|
||||
self.ncols()
|
||||
}
|
||||
#[inline]
|
||||
fn nnz(&self) -> usize {
|
||||
self.nnz()
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
mm_matrix_impl!(CooMatrix<T>);
|
||||
mm_matrix_impl!(CsrMatrix<T>);
|
||||
mm_matrix_impl!(CscMatrix<T>);
|
||||
|
||||
#[derive(Parser)]
|
||||
#[grammar = "io/matrix_market.pest"]
|
||||
struct MatrixMarketParser;
|
||||
@ -1391,23 +1441,29 @@ fn next_dense_coordinate(
|
||||
/// let generated_matrixmarket = load_coo_from_matrix_market_str::<i32>(&generated_matrixmarket_string).unwrap();
|
||||
/// assert_matrix_eq!(matrix,generated_matrixmarket);
|
||||
/// ```
|
||||
pub fn write_to_matrix_market_str<T: MatrixMarketScalar, S: SparseAccess<T>>(
|
||||
pub fn write_to_matrix_market_str<T: MatrixMarketScalar, S: MatrixMarketExport<T>>(
|
||||
sparse_matrix: &S,
|
||||
) -> String {
|
||||
let mut matrixmarket_string = String::new();
|
||||
|
||||
// write header
|
||||
matrixmarket_string.push_str("%%matrixmarket matrix coordinate ");
|
||||
matrixmarket_string.push_str(T::typename());
|
||||
matrixmarket_string.push_str(" general\n% matrixmarket file generated by nalgebra-sparse.\n");
|
||||
matrixmarket_string.push_str(" general\n");
|
||||
|
||||
//write comment
|
||||
matrixmarket_string.push_str("% matrixmarket file generated by nalgebra-sparse.\n");
|
||||
|
||||
// write shape information
|
||||
matrixmarket_string.push_str(&sparse_matrix.rows().to_string());
|
||||
matrixmarket_string.push_str(&sparse_matrix.nrows().to_string());
|
||||
matrixmarket_string.push(' ');
|
||||
matrixmarket_string.push_str(&sparse_matrix.cols().to_string());
|
||||
matrixmarket_string.push_str(&sparse_matrix.ncols().to_string());
|
||||
matrixmarket_string.push(' ');
|
||||
matrixmarket_string.push_str(&sparse_matrix.nnz().to_string());
|
||||
matrixmarket_string.push('\n');
|
||||
|
||||
for (r, c, d) in sparse_matrix.fetch_triplets() {
|
||||
//write triplets
|
||||
for (r, c, d) in sparse_matrix.triplet_iter() {
|
||||
matrixmarket_string.push_str(&(r + 1).to_string());
|
||||
matrixmarket_string.push_str(" ");
|
||||
matrixmarket_string.push_str(&(c + 1).to_string());
|
||||
@ -1415,7 +1471,6 @@ pub fn write_to_matrix_market_str<T: MatrixMarketScalar, S: SparseAccess<T>>(
|
||||
matrixmarket_string.push_str(&d.to_matrixmarket_string());
|
||||
matrixmarket_string.push_str("\n");
|
||||
}
|
||||
|
||||
matrixmarket_string
|
||||
}
|
||||
|
||||
@ -1442,15 +1497,49 @@ pub fn write_to_matrix_market_str<T: MatrixMarketScalar, S: SparseAccess<T>>(
|
||||
/// let matrix = load_coo_from_matrix_market_str::<i32>(&str).unwrap();
|
||||
/// let res = write_to_matrix_market_file(&matrix,"path/to/matrix.mtx");
|
||||
/// if res.is_err(){
|
||||
/// // do something
|
||||
/// // do something
|
||||
/// }
|
||||
/// ```
|
||||
pub fn write_to_matrix_market_file<T: MatrixMarketScalar, S: SparseAccess<T>, P: AsRef<Path>>(
|
||||
matrix: &S,
|
||||
pub fn write_to_matrix_market_file<
|
||||
T: MatrixMarketScalar,
|
||||
S: MatrixMarketExport<T>,
|
||||
P: AsRef<Path>,
|
||||
>(
|
||||
sparse_matrix: &S,
|
||||
path: P,
|
||||
) -> Result<(), MatrixMarketError> {
|
||||
let matrixmarket_string = write_to_matrix_market_str(matrix);
|
||||
// The code is basically the same as write_to_matrix_market_str, but write the matrix into file instead.
|
||||
let mut file = File::create(path)?;
|
||||
write!(file, "{}", matrixmarket_string)?;
|
||||
|
||||
// write header
|
||||
write!(
|
||||
file,
|
||||
"%%matrixmarket matrix coordinate {} general\n",
|
||||
T::typename()
|
||||
)?;
|
||||
|
||||
// write comments
|
||||
write!(file, "% matrixmarket file generated by nalgebra-sparse.\n",)?;
|
||||
|
||||
// write shape information
|
||||
write!(
|
||||
file,
|
||||
"{} {} {}\n",
|
||||
sparse_matrix.nrows(),
|
||||
sparse_matrix.ncols(),
|
||||
sparse_matrix.nnz()
|
||||
)?;
|
||||
|
||||
// write triplets
|
||||
for (r, c, d) in sparse_matrix.triplet_iter() {
|
||||
write!(
|
||||
file,
|
||||
"{} {} {}\n",
|
||||
r + 1,
|
||||
c + 1,
|
||||
d.to_matrixmarket_string()
|
||||
)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -33,6 +33,7 @@
|
||||
|
||||
pub use self::matrix_market::{
|
||||
load_coo_from_matrix_market_file, load_coo_from_matrix_market_str, write_to_matrix_market_file,
|
||||
write_to_matrix_market_str, MatrixMarketError, MatrixMarketErrorKind, MatrixMarketScalar,
|
||||
write_to_matrix_market_str, MatrixMarketError, MatrixMarketErrorKind, MatrixMarketExport,
|
||||
MatrixMarketScalar,
|
||||
};
|
||||
mod matrix_market;
|
||||
|
Loading…
Reference in New Issue
Block a user