math_rs/matrix/float/
parser.rs1use crate::{
2 matrix::traits::{Matrix, Parseable, Serializable},
3 result::{MathError, Result},
4};
5
6use super::MatrixF32;
7
8impl Parseable for MatrixF32 {
9 fn parse(input: &str, tolerance: f32) -> Result<Self> {
10 parse_matrix(input, tolerance)
11 }
12}
13
14impl Serializable for MatrixF32 {
15 fn serialize(&self) -> String {
16 serialize_matrix(self)
17 }
18}
19
20pub fn parse_matrix(input: &str, tolerance: f32) -> Result<MatrixF32> {
21 let mut matrix = vec![];
22 let processed_input = input.trim().split_whitespace().collect::<String>();
23 let inner = processed_input
24 .trim_start_matches('{')
25 .trim_end_matches('}')
26 .trim();
27 for row_str in inner.split("},{") {
28 let row = row_str
29 .split(',')
30 .map(|s| -> Result<f32> {
31 s.parse().map_err(|_| {
32 MathError::MatrixError(format!("Could not parse matrix due to parsing error",))
33 })
34 })
35 .collect::<Result<Vec<f32>>>()?;
36 matrix.push(row);
37 }
38 MatrixF32::new(matrix, tolerance)
39}
40
41pub fn serialize_matrix(matrix: &MatrixF32) -> String {
42 let mut result = String::new();
43 let push_row = |res: &mut String, row_number: usize| {
44 res.push('{');
45 for j in 0..matrix.columns() - 1 {
46 res.push_str(matrix.get(row_number, j).unwrap().to_string().as_str());
48 res.push_str(", ")
49 }
50 res.push_str(
51 matrix
52 .get(row_number, matrix.columns() - 1)
53 .unwrap()
54 .to_string()
55 .as_str(),
56 );
57 res.push('}');
58 };
59
60 result.push('{');
61 for i in 0..matrix.rows() - 1 {
62 push_row(&mut result, i);
63 result.push_str(", ");
64 }
65 push_row(&mut result, matrix.rows() - 1);
66
67 result.push('}');
68 result
69}
70
71#[cfg(test)]
72mod test {
73
74 use std::str::FromStr;
75
76 use super::{serialize_matrix, MatrixF32};
77
78 const TOLERANCE: f32 = 1E-12;
79
80 #[test]
81 fn parse_2x2() {
82 let matrix = MatrixF32::from_str("{{1,2},{2,3}}")
83 .expect("Should have been able to parse this matrix");
84
85 println!("{matrix}");
86 pretty_assertions::assert_eq!(
87 matrix,
88 MatrixF32::new(vec![vec![1.0, 2.0], vec![2.0, 3.0]], TOLERANCE)
89 .expect("Should've been able to built this matrix")
90 )
91 }
92
93 #[test]
94 fn parse_3x5() {
95 let matrix = MatrixF32::from_str("{{1,2,3,4,5}, {5,4,3,2,1}, {0,0,0,0,0}}")
96 .expect("Should have been able to parse this matrix");
97 println!("{matrix}");
98 pretty_assertions::assert_eq!(
99 matrix,
100 MatrixF32::new(
101 vec![
102 vec![1.0, 2.0, 3.0, 4.0, 5.0],
103 vec![5.0, 4.0, 3.0, 2.0, 1.0],
104 vec![0.0, 0.0, 0.0, 0.0, 0.0]
105 ],
106 TOLERANCE
107 )
108 .expect("Should've been able to built this matrix")
109 )
110 }
111
112 #[test]
113 fn serialize_2x2() {
114 let matrix = MatrixF32::new(vec![vec![1.1, 1.1], vec![1.1, 1.1]], TOLERANCE).unwrap();
115 pretty_assertions::assert_str_eq!("{{1.1, 1.1}, {1.1, 1.1}}", serialize_matrix(&matrix))
116 }
117}