1#[cfg(any(
7 all(
8 not(feature = "exactarithmetic"),
9 not(feature = "approximatearithmetic")
10 ),
11 all(feature = "exactarithmetic", feature = "approximatearithmetic")
12))]
13pub type FractionMatrix = super::fraction_matrix_enum::FractionMatrixEnum;
14
15#[cfg(all(not(feature = "exactarithmetic"), feature = "approximatearithmetic"))]
16pub type FractionMatrix = super::fraction_matrix_f64::FractionMatrixF64;
17
18#[cfg(all(feature = "exactarithmetic", not(feature = "approximatearithmetic")))]
19pub type FractionMatrix = super::fraction_matrix_exact::FractionMatrixExact;
20
21#[macro_export]
24macro_rules! push_columns {
25 ($zero:expr, $number_of_columns_to_add:expr, $values:expr, $number_of_rows:expr, $number_of_columns:expr) => {
26 for row in (0..$number_of_rows).rev() {
27 $values.splice(
28 row * $number_of_columns + $number_of_columns
29 ..row * $number_of_columns + $number_of_columns,
30 vec![$zero; $number_of_columns_to_add],
31 );
32 }
33 };
34}
35
36#[macro_export]
37macro_rules! pop_front_columns {
38 ($number_of_columns_to_remove:expr, $values:expr, $number_of_rows:expr, $number_of_columns:expr) => {
39 for row in (0..$number_of_rows).rev() {
40 $values.drain(
41 row * $number_of_columns..row * $number_of_columns + $number_of_columns_to_remove,
42 );
43 }
44 };
45}
46
47#[cfg(test)]
49mod tests {
50
51 use crate::{
52 Inversion,
53 Zero,
54 ebi_matrix::EbiMatrix,
55 f, f0,
56 fraction::fraction::Fraction,
57 matrix::fraction_matrix::FractionMatrix,
58 };
59
60 #[test]
61 fn fraction_matrix() {
62 let m: FractionMatrix = vec![vec![f!(1, 4), f!(2, 5), f!(8, 3)]].try_into().unwrap();
63 assert_eq!(m, m);
64 }
65
66 #[test]
67 fn fraction_matrix_empty() {
68 let m = vec![vec![]];
69 let m: FractionMatrix = m.try_into().unwrap();
70 assert_eq!(m.number_of_rows(), 1);
71 assert_eq!(m.number_of_columns(), 0);
72 }
73
74 #[test]
75 fn fraction_matrix_get() {
76 let m: FractionMatrix = vec![vec![f!(1, 4), f!(2, 5), f!(8, 3)]].try_into().unwrap();
77
78 assert!(m.get(10, 10).is_none());
79
80 assert_eq!(m.get(0, 0).unwrap(), f!(1, 4));
81 }
82
83 #[test]
84 #[should_panic]
85 fn fraction_matrix_incomplete() {
86 let _: FractionMatrix = vec![vec![f!(1, 4), f!(2, 5)], vec![f!(8, 3)]]
87 .try_into()
88 .unwrap();
89 }
90
91 #[test]
92 fn fraction_matrix_pop_front() {
93 let mut m1: FractionMatrix = vec![vec![f!(1, 4), f!(2, 5), f!(8, 3)]].try_into().unwrap();
94
95 m1.pop_front_columns(1);
96
97 let m3: FractionMatrix = vec![vec![f!(2, 5), f!(8, 3)]].try_into().unwrap();
98
99 assert_eq!(m1, m3);
103 }
104
105 #[test]
106 fn fraction_matrix_push_columns() {
107 let mut m1: FractionMatrix = vec![vec![f!(1, 4), f!(2, 5), f!(8, 3)]].try_into().unwrap();
108
109 m1.push_columns(1);
110
111 let m3: FractionMatrix = vec![vec![f!(1, 4), f!(2, 5), f!(8, 3), f0!()]]
112 .try_into()
113 .unwrap();
114
115 assert_eq!(m1, m3);
119 }
120
121 #[test]
122 fn fraction_matrix_inverse() {
123 let mut m1: FractionMatrix = vec![
124 vec![1.into(), 0.into(), 0.into(), 0.into()],
125 vec![0.into(), 1.into(), 0.into(), Fraction::from((-3, 5))],
126 vec![0.into(), Fraction::from((-3, 4)), 1.into(), 0.into()],
127 vec![0.into(), 0.into(), 0.into(), 1.into()],
128 ]
129 .try_into()
130 .unwrap();
131
132 let mut m2: FractionMatrix = vec![
133 vec![1.into(), 0.into(), 0.into(), 0.into()],
134 vec![0.into(), 1.into(), 0.into(), Fraction::from((3, 5))],
135 vec![
136 0.into(),
137 Fraction::from((3, 4)),
138 1.into(),
139 Fraction::from((9, 20)),
140 ],
141 vec![0.into(), 0.into(), 0.into(), 1.into()],
142 ]
143 .try_into()
144 .unwrap();
145
146 m1 = m1.invert().unwrap();
147
148 println!("{}", m1);
149 println!("{}", m2);
150
151 assert!(m1.eq(&mut m2));
152 }
153
154 #[test]
155 fn display_empty() {
156 let m = FractionMatrix::new(0, 0);
157 let _ = format!("{}", m);
158
159 let m = FractionMatrix::new(1, 0);
160 let _ = format!("{}", m);
161
162 let m = FractionMatrix::new(0, 1);
163 let _ = format!("{}", m);
164 }
165
166 #[test]
167 fn to_vec_empty() {
168 let m = FractionMatrix::new(0, 0);
169 let u: Vec<Vec<Fraction>> = vec![];
170 assert_eq!(m.to_vec(), u);
171
172 let m = FractionMatrix::new(1, 0);
173 let u: Vec<Vec<Fraction>> = vec![vec![]];
174 assert_eq!(m.to_vec(), u);
175
176 let m = FractionMatrix::new(0, 1);
177 let u: Vec<Vec<Fraction>> = vec![];
178 assert_eq!(m.to_vec(), u);
179 }
180}