use ::num::complex;
use un_algebra::tests::*;
use un_algebra::prelude::*;
#[derive(Copy, Clone, Debug, PartialEq)]
struct Complex(complex::Complex<f64>);
impl Complex {
pub fn new(re: f64, im: f64) -> Self {
Self(complex::Complex::new(re, im))
}
}
impl NumEq for Complex {
type Eps = f64;
fn num_eq(&self, other: &Self, eps: &Self::Eps) -> bool {
let re = self.0.re.num_eq(&other.0.re, eps);
let im = self.0.im.num_eq(&other.0.im, eps);
re && im
}
}
impl AddMagma for Complex {
fn add(&self, other: &Self) -> Self {
Self(self.0 + other.0)
}
}
impl AddSemigroup for Complex {}
impl AddMonoid for Complex {
fn zero() -> Self {
Self::new(0.0, 0.0)
}
}
impl AddGroup for Complex {
fn negate(&self) -> Self {
Self(-self.0)
}
}
impl AddComGroup for Complex {}
impl MulMagma for Complex {
fn mul(&self, other: &Self) -> Self {
Self(self.0 * other.0)
}
}
impl MulSemigroup for Complex {}
impl MulMonoid for Complex {
fn one() -> Self {
Self::new(1.0, 0.0)
}
}
impl MulGroup for Complex {
fn is_invertible(&self) -> bool {
!self.is_zero()
}
fn invert(&self) -> Self {
Self(self.0.inv())
}
}
impl MulComGroup for Complex {}
impl Ring for Complex {}
impl ComRing for Complex {}
impl Field for Complex {
fn invert(&self) -> Self {
Self(self.0.inv())
}
}
fn cx() -> impl Strategy<Value = Complex> {
let ranges = (-1.0e10_f64..1.0e10, -1.0e10_f64..1.0e10);
ranges.prop_map(|(re, im)| Complex::new(re, im))
}
#[cfg(test)]
proptest! {
#![proptest_config(config::standard())]
#[test]
fn add_closure([w, z] in [cx(), cx()]) {
prop_assert!(NumAddMagmaLaws::num_closure(&w, &z, &F64_EPS))
}
#[test]
fn mul_closure([w, z] in [cx(), cx()]) {
prop_assert!(NumMulMagmaLaws::num_closure(&w, &z, &F64_EPS))
}
#[test]
fn mul_associative([v, w, z] in [cx(), cx(), cx()]) {
prop_assert!(NumMulSemigroupLaws::num_associativity(&v, &w, &z, &(F64_EPS * 1e5)))
}
#[test]
fn add_associative([v, w, z] in [cx(), cx(), cx()]) {
prop_assert!(NumAddSemigroupLaws::num_associativity(&v, &w, &z, &(F64_EPS * 1e5)))
}
#[test]
fn left_add_identity(z in cx()) {
prop_assert!(NumAddMonoidLaws::num_left_identity(&z, &F64_EPS))
}
#[test]
fn right_add_identity(z in cx()) {
prop_assert!(NumAddMonoidLaws::num_left_identity(&z, &F64_EPS))
}
#[test]
fn left_mul_identity(z in cx()) {
prop_assert!(NumMulMonoidLaws::num_left_identity(&z, &F64_EPS))
}
#[test]
fn right_mul_identity(z in cx()) {
prop_assert!(NumMulMonoidLaws::num_right_identity(&z, &F64_EPS))
}
#[test]
fn left_add_inverse(z in cx()) {
prop_assert!(NumAddGroupLaws::num_left_inverse(&z, &F64_EPS))
}
#[test]
fn right_add_inverse(z in cx()) {
prop_assert!(NumAddGroupLaws::num_right_inverse(&z, &F64_EPS))
}
#[test]
fn left_mul_inverse(z in cx()) {
prop_assume!(MulGroup::is_invertible(&z));
prop_assert!(NumMulGroupLaws::num_left_inverse(&z, &(F64_EPS * 1e3)))
}
#[test]
fn right_inverse(z in cx()) {
prop_assume!(MulGroup::is_invertible(&z));
prop_assert!(NumMulGroupLaws::num_right_inverse(&z, &F64_EPS))
}
#[test]
fn add_commute([w, z] in [cx(), cx()]) {
prop_assert!(NumAddComGroupLaws::num_commutivity(&w, &z, &F64_EPS))
}
#[test]
fn mul_commute([w, z] in [cx(), cx()]) {
prop_assert!(NumMulComGroupLaws::num_commutivity(&w, &z, &F64_EPS))
}
#[test]
fn left_distributivity([u, v, w] in [cx(), cx(), cx()]) {
prop_assert!(NumRingLaws::num_left_distributivity(&u, &v, &w, &(F64_EPS * 1e5)))
}
#[test]
fn right_distributivity([u, v, w] in [cx(), cx(), cx()]) {
prop_assert!(NumRingLaws::num_right_distributivity(&u, &v, &w, &(F64_EPS * 1e5)))
}
#[test]
fn left_absorption(x in cx()) {
prop_assert!(NumRingLaws::num_left_absorption(&x, &F64_EPS))
}
#[test]
fn right_absorption(x in cx()) {
prop_assert!(NumRingLaws::num_right_absorption(&x, &F64_EPS))
}
#[test]
fn left_negation((w, z) in (cx(), cx())) {
prop_assert!(NumRingLaws::num_left_negation(&w, &z, &F64_EPS))
}
#[test]
fn right_negation((w, z) in (cx(), cx())) {
prop_assert!(NumRingLaws::num_right_negation(&w, &z, &F64_EPS))
}
#[test]
fn mul_commutivity((x, y) in (cx(), cx())) {
prop_assert!(NumComRingLaws::num_commutivity(&x, &y, &F64_EPS))
}
#[test]
fn field_left_inverse(z in cx()) {
prop_assume!(Field::is_invertible(&z));
prop_assert!(NumFieldLaws::num_left_inverse(&z, &F64_EPS))
}
#[test]
fn field_right_inverse(z in cx()) {
prop_assume!(Field::is_invertible(&z));
prop_assert!(NumFieldLaws::num_right_inverse(&z, &F64_EPS))
}
#[test]
fn zero_cancellation((w, z) in (cx(), cx())) {
prop_assert!(NumFieldLaws::num_zero_cancellation(&w, &z, &F64_EPS))
}
#[test]
fn add_cancellation((v, w, z) in (cx(), cx(), cx())) {
prop_assert!(NumFieldLaws::num_add_cancellation(&v, &w, &z, &F64_EPS))
}
#[test]
fn mul_cancellation((v, w, z) in (cx(), cx(), cx())) {
prop_assert!(NumFieldLaws::num_mul_cancellation(&v, &w, &z, &F64_EPS))
}
}
fn main() {
}