use std::io::Write trait when export to matrix market

This commit is contained in:
Hantao Hui 2022-02-13 21:16:16 +01:00
parent 8904c01c7b
commit 9e0dfd14de
1 changed files with 61 additions and 80 deletions

View File

@ -508,9 +508,9 @@ mod internal {
/// When matrix is a Hermitian matrix, it will convert itself to its conjugate. /// When matrix is a Hermitian matrix, it will convert itself to its conjugate.
fn conjugate(self) -> Result<Self, MatrixMarketError>; fn conjugate(self) -> Result<Self, MatrixMarketError>;
/// Returns the name of SupportedMatrixMarketScalar, used when write the matrix /// Returns the name of SupportedMatrixMarketScalar, used when write the matrix
fn typename() -> &'static str; fn typename() -> &'static [u8];
/// Convert the data to string /// Convert the data to bytes
fn to_matrixmarket_string(&self) -> String; fn to_matrixmarket_bytes(&self) -> Vec<u8>;
} }
pub trait SupportedMatrixMarketExport<T: SupportedMatrixMarketScalar> { pub trait SupportedMatrixMarketExport<T: SupportedMatrixMarketScalar> {
@ -574,12 +574,12 @@ macro_rules! mm_int_impl {
Ok(-self) Ok(-self)
} }
#[inline] #[inline]
fn typename() -> &'static str { fn typename() -> &'static [u8] {
"integer" b"integer"
} }
#[inline] #[inline]
fn to_matrixmarket_string(&self) -> String { fn to_matrixmarket_bytes(&self) -> Vec<u8> {
self.to_string() self.to_string().into_bytes()
} }
} }
}; };
@ -627,12 +627,12 @@ macro_rules! mm_real_impl {
Ok(-self) Ok(-self)
} }
#[inline] #[inline]
fn typename() -> &'static str { fn typename() -> &'static [u8] {
"real" b"real"
} }
#[inline] #[inline]
fn to_matrixmarket_string(&self) -> String { fn to_matrixmarket_bytes(&self) -> Vec<u8> {
self.to_string() self.to_string().into_bytes()
} }
} }
}; };
@ -681,12 +681,12 @@ macro_rules! mm_complex_impl {
Ok(-self) Ok(-self)
} }
#[inline] #[inline]
fn typename() -> &'static str { fn typename() -> &'static [u8] {
"complex" b"complex"
} }
#[inline] #[inline]
fn to_matrixmarket_string(&self) -> String { fn to_matrixmarket_bytes(&self) -> Vec<u8> {
self.re.to_string() + " " + &self.im.to_string() (self.re.to_string() + " " + &self.im.to_string()).into_bytes()
} }
} }
}; };
@ -738,13 +738,12 @@ macro_rules! mm_pattern_impl {
)) ))
} }
#[inline] #[inline]
fn typename() -> &'static str { fn typename() -> &'static [u8] {
"pattern" b"pattern"
} }
#[inline] #[inline]
fn to_matrixmarket_string(&self) -> String { fn to_matrixmarket_bytes(&self) -> Vec<u8> {
// pattern type will return an empty string Vec::<u8>::new()
String::new()
} }
} }
}; };
@ -1444,34 +1443,14 @@ fn next_dense_coordinate(
pub fn write_to_matrix_market_str<T: MatrixMarketScalar, S: MatrixMarketExport<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 bytes = Vec::<u8>::new();
// This will call impl<A: Allocator> Write for Vec<u8, A>
// write header // The vector will grow as needed.
matrixmarket_string.push_str("%%matrixmarket matrix coordinate "); // So, unwrap here won't cause any issue.
matrixmarket_string.push_str(T::typename()); write_to_matrix_market(&mut bytes, sparse_matrix).unwrap();
matrixmarket_string.push_str(" general\n"); // safety issue is because 'from_utf8_unchecked' does not check that the bytes passed to it are valid UTF-8.
// Since 'bytes' created here is valid UTF-8 data, so it will not cause any problem.
//write comment unsafe { String::from_utf8_unchecked(bytes) }
matrixmarket_string.push_str("% matrixmarket file generated by nalgebra-sparse.\n");
// write shape information
matrixmarket_string.push_str(&sparse_matrix.nrows().to_string());
matrixmarket_string.push(' ');
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');
//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());
matrixmarket_string.push_str(" ");
matrixmarket_string.push_str(&d.to_matrixmarket_string());
matrixmarket_string.push_str("\n");
}
matrixmarket_string
} }
/// Write a sparse matrix into Matrix Market format file. /// Write a sparse matrix into Matrix Market format file.
@ -1508,38 +1487,40 @@ pub fn write_to_matrix_market_file<
sparse_matrix: &S, sparse_matrix: &S,
path: P, path: P,
) -> Result<(), MatrixMarketError> { ) -> Result<(), MatrixMarketError> {
// 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_to_matrix_market(&mut file, sparse_matrix)?;
// write header Ok(())
write!( }
file,
"%%matrixmarket matrix coordinate {} general\n", /// low level implementation of writing sparse matrix into any [std::io::Write] object
T::typename() fn write_to_matrix_market<T: MatrixMarketScalar, S: MatrixMarketExport<T>, W: Write>(
)?; w: &mut W,
sparse_matrix: &S,
// write comments ) -> Result<(), MatrixMarketError> {
write!(file, "% matrixmarket file generated by nalgebra-sparse.\n",)?; // write header
w.write_all(b"%%matrixmarket matrix coordinate ")?;
// write shape information w.write_all(T::typename())?;
write!( w.write_all(b" general\n")?;
file,
"{} {} {}\n", //write comment
sparse_matrix.nrows(), w.write_all(b"% matrixmarket file generated by nalgebra-sparse.\n")?;
sparse_matrix.ncols(),
sparse_matrix.nnz() // write shape information
)?; w.write_all(sparse_matrix.nrows().to_string().as_bytes())?;
w.write_all(b" ")?;
// write triplets w.write_all(sparse_matrix.ncols().to_string().as_bytes())?;
for (r, c, d) in sparse_matrix.triplet_iter() { w.write_all(b" ")?;
write!( w.write_all(sparse_matrix.nnz().to_string().as_bytes())?;
file, w.write_all(b"\n")?;
"{} {} {}\n",
r + 1, //write triplets
c + 1, for (r, c, d) in sparse_matrix.triplet_iter() {
d.to_matrixmarket_string() w.write_all((r + 1).to_string().as_bytes())?;
)?; w.write_all(b" ")?;
} w.write_all((c + 1).to_string().as_bytes())?;
w.write_all(b" ")?;
w.write_all(&d.to_matrixmarket_bytes())?;
w.write_all(b"\n")?;
}
Ok(()) Ok(())
} }