#[cfg(any(
all(
not(feature = "exactarithmetic"),
not(feature = "approximatearithmetic")
),
all(feature = "exactarithmetic", feature = "approximatearithmetic")
))]
pub type FractionMatrix = super::fraction_matrix_enum::FractionMatrixEnum;
#[cfg(all(not(feature = "exactarithmetic"), feature = "approximatearithmetic"))]
pub type FractionMatrix = super::fraction_matrix_f64::FractionMatrixF64;
#[cfg(all(feature = "exactarithmetic", not(feature = "approximatearithmetic")))]
pub type FractionMatrix = super::fraction_matrix_exact::FractionMatrixExact;
#[macro_export]
macro_rules! push_columns {
($zero:expr, $number_of_columns_to_add:expr, $values:expr, $number_of_rows:expr, $number_of_columns:expr) => {
for row in (0..$number_of_rows).rev() {
$values.splice(
row * $number_of_columns + $number_of_columns
..row * $number_of_columns + $number_of_columns,
vec![$zero; $number_of_columns_to_add],
);
}
};
}
#[macro_export]
macro_rules! pop_front_columns {
($number_of_columns_to_remove:expr, $values:expr, $number_of_rows:expr, $number_of_columns:expr) => {
for row in (0..$number_of_rows).rev() {
$values.drain(
row * $number_of_columns..row * $number_of_columns + $number_of_columns_to_remove,
);
}
};
}
#[cfg(test)]
mod tests {
use crate::{
Inversion,
Zero,
ebi_matrix::EbiMatrix,
f, f0,
fraction::fraction::Fraction,
matrix::fraction_matrix::FractionMatrix,
};
#[test]
fn fraction_matrix() {
let m: FractionMatrix = vec![vec![f!(1, 4), f!(2, 5), f!(8, 3)]].try_into().unwrap();
assert_eq!(m, m);
}
#[test]
fn fraction_matrix_empty() {
let m = vec![vec![]];
let m: FractionMatrix = m.try_into().unwrap();
assert_eq!(m.number_of_rows(), 1);
assert_eq!(m.number_of_columns(), 0);
}
#[test]
fn fraction_matrix_get() {
let m: FractionMatrix = vec![vec![f!(1, 4), f!(2, 5), f!(8, 3)]].try_into().unwrap();
assert!(m.get(10, 10).is_none());
assert_eq!(m.get(0, 0).unwrap(), f!(1, 4));
}
#[test]
#[should_panic]
fn fraction_matrix_incomplete() {
let _: FractionMatrix = vec![vec![f!(1, 4), f!(2, 5)], vec![f!(8, 3)]]
.try_into()
.unwrap();
}
#[test]
fn fraction_matrix_pop_front() {
let mut m1: FractionMatrix = vec![vec![f!(1, 4), f!(2, 5), f!(8, 3)]].try_into().unwrap();
m1.pop_front_columns(1);
let m3: FractionMatrix = vec![vec![f!(2, 5), f!(8, 3)]].try_into().unwrap();
assert_eq!(m1, m3);
}
#[test]
fn fraction_matrix_push_columns() {
let mut m1: FractionMatrix = vec![vec![f!(1, 4), f!(2, 5), f!(8, 3)]].try_into().unwrap();
m1.push_columns(1);
let m3: FractionMatrix = vec![vec![f!(1, 4), f!(2, 5), f!(8, 3), f0!()]]
.try_into()
.unwrap();
assert_eq!(m1, m3);
}
#[test]
fn fraction_matrix_inverse() {
let mut m1: FractionMatrix = vec![
vec![1.into(), 0.into(), 0.into(), 0.into()],
vec![0.into(), 1.into(), 0.into(), Fraction::from((-3, 5))],
vec![0.into(), Fraction::from((-3, 4)), 1.into(), 0.into()],
vec![0.into(), 0.into(), 0.into(), 1.into()],
]
.try_into()
.unwrap();
let mut m2: FractionMatrix = vec![
vec![1.into(), 0.into(), 0.into(), 0.into()],
vec![0.into(), 1.into(), 0.into(), Fraction::from((3, 5))],
vec![
0.into(),
Fraction::from((3, 4)),
1.into(),
Fraction::from((9, 20)),
],
vec![0.into(), 0.into(), 0.into(), 1.into()],
]
.try_into()
.unwrap();
m1 = m1.invert().unwrap();
println!("{}", m1);
println!("{}", m2);
assert!(m1.eq(&mut m2));
}
#[test]
fn display_empty() {
let m = FractionMatrix::new(0, 0);
let _ = format!("{}", m);
let m = FractionMatrix::new(1, 0);
let _ = format!("{}", m);
let m = FractionMatrix::new(0, 1);
let _ = format!("{}", m);
}
#[test]
fn to_vec_empty() {
let m = FractionMatrix::new(0, 0);
let u: Vec<Vec<Fraction>> = vec![];
assert_eq!(m.to_vec(), u);
let m = FractionMatrix::new(1, 0);
let u: Vec<Vec<Fraction>> = vec![vec![]];
assert_eq!(m.to_vec(), u);
let m = FractionMatrix::new(0, 1);
let u: Vec<Vec<Fraction>> = vec![];
assert_eq!(m.to_vec(), u);
}
}