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.
|
//! 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.
|
//! 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::SparseFormatError;
|
||||||
use crate::SparseFormatErrorKind;
|
use crate::SparseFormatErrorKind;
|
||||||
use matrixcompare_core::SparseAccess;
|
use crate::{CooMatrix, CscMatrix, CsrMatrix};
|
||||||
use nalgebra::Complex;
|
use nalgebra::Complex;
|
||||||
use pest::iterators::Pairs;
|
use pest::iterators::Pairs;
|
||||||
use pest::Parser;
|
use pest::Parser;
|
||||||
|
@ -513,6 +512,17 @@ mod internal {
|
||||||
/// Convert the data to string
|
/// Convert the data to string
|
||||||
fn to_matrixmarket_string(&self) -> 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.
|
/// A marker trait for supported matrix market scalars.
|
||||||
|
@ -754,6 +764,46 @@ mm_complex_impl!(f64);
|
||||||
|
|
||||||
mm_pattern_impl!(());
|
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)]
|
#[derive(Parser)]
|
||||||
#[grammar = "io/matrix_market.pest"]
|
#[grammar = "io/matrix_market.pest"]
|
||||||
struct MatrixMarketParser;
|
struct MatrixMarketParser;
|
||||||
|
@ -1391,23 +1441,29 @@ fn next_dense_coordinate(
|
||||||
/// let generated_matrixmarket = load_coo_from_matrix_market_str::<i32>(&generated_matrixmarket_string).unwrap();
|
/// let generated_matrixmarket = load_coo_from_matrix_market_str::<i32>(&generated_matrixmarket_string).unwrap();
|
||||||
/// assert_matrix_eq!(matrix,generated_matrixmarket);
|
/// 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,
|
sparse_matrix: &S,
|
||||||
) -> String {
|
) -> String {
|
||||||
let mut matrixmarket_string = String::new();
|
let mut matrixmarket_string = String::new();
|
||||||
|
|
||||||
// write header
|
// write header
|
||||||
matrixmarket_string.push_str("%%matrixmarket matrix coordinate ");
|
matrixmarket_string.push_str("%%matrixmarket matrix coordinate ");
|
||||||
matrixmarket_string.push_str(T::typename());
|
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
|
// 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(' ');
|
||||||
matrixmarket_string.push_str(&sparse_matrix.cols().to_string());
|
matrixmarket_string.push_str(&sparse_matrix.ncols().to_string());
|
||||||
matrixmarket_string.push(' ');
|
matrixmarket_string.push(' ');
|
||||||
matrixmarket_string.push_str(&sparse_matrix.nnz().to_string());
|
matrixmarket_string.push_str(&sparse_matrix.nnz().to_string());
|
||||||
matrixmarket_string.push('\n');
|
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(&(r + 1).to_string());
|
||||||
matrixmarket_string.push_str(" ");
|
matrixmarket_string.push_str(" ");
|
||||||
matrixmarket_string.push_str(&(c + 1).to_string());
|
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(&d.to_matrixmarket_string());
|
||||||
matrixmarket_string.push_str("\n");
|
matrixmarket_string.push_str("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
matrixmarket_string
|
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 matrix = load_coo_from_matrix_market_str::<i32>(&str).unwrap();
|
||||||
/// let res = write_to_matrix_market_file(&matrix,"path/to/matrix.mtx");
|
/// let res = write_to_matrix_market_file(&matrix,"path/to/matrix.mtx");
|
||||||
/// if res.is_err(){
|
/// if res.is_err(){
|
||||||
/// // do something
|
/// // do something
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn write_to_matrix_market_file<T: MatrixMarketScalar, S: SparseAccess<T>, P: AsRef<Path>>(
|
pub fn write_to_matrix_market_file<
|
||||||
matrix: &S,
|
T: MatrixMarketScalar,
|
||||||
|
S: MatrixMarketExport<T>,
|
||||||
|
P: AsRef<Path>,
|
||||||
|
>(
|
||||||
|
sparse_matrix: &S,
|
||||||
path: P,
|
path: P,
|
||||||
) -> Result<(), MatrixMarketError> {
|
) -> 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)?;
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
|
|
||||||
pub use self::matrix_market::{
|
pub use self::matrix_market::{
|
||||||
load_coo_from_matrix_market_file, load_coo_from_matrix_market_str, write_to_matrix_market_file,
|
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;
|
mod matrix_market;
|
||||||
|
|
Loading…
Reference in New Issue