use spirix::*;
#[cfg(test)]
mod undefined_creation {
use super::*;
#[test]
fn test_division_by_zero() {
let one = ScalarF5E3::from(1);
let zero = ScalarF5E3::ZERO;
let result = one / zero;
assert!(result.is_infinite());
assert!(!result.is_normal());
assert!(!result.is_finite());
assert!(!result.is_zero());
}
#[test]
fn test_zero_to_zero_power() {
let zero = ScalarF5E3::ZERO;
let result = zero.pow(zero);
assert_eq!(result, ScalarF5E3::ONE);
}
#[test]
fn test_square_root_of_negative() {
let negative = ScalarF5E3::from(-4);
let result = negative.sqrt();
assert!(result.is_undefined());
}
#[test]
fn test_logarithm_of_negative() {
let negative = ScalarF5E3::from(-2);
let result = negative.ln();
assert!(result.is_undefined());
}
#[test]
fn test_logarithm_of_zero() {
let zero = ScalarF5E3::ZERO;
let result = zero.ln();
assert!(result.is_infinite());
}
#[test]
fn test_invalid_inverse_trig() {
let too_large = ScalarF5E3::from(2.0);
let asin_result = too_large.asin();
let acos_result = too_large.acos();
assert!(asin_result.is_undefined());
assert!(acos_result.is_undefined());
let too_small = ScalarF5E3::from(-2.0);
let asin_result2 = too_small.asin();
let acos_result2 = too_small.acos();
assert!(asin_result2.is_undefined());
assert!(acos_result2.is_undefined());
}
#[test]
fn test_negative_base_fractional_power() {
let negative_base = ScalarF5E3::from(-2);
let fractional_exp = ScalarF5E3::from(0.5); let result = negative_base.pow(fractional_exp);
assert!(result.is_undefined());
}
}
#[cfg(test)]
mod undefined_propagation {
use super::*;
#[test]
fn test_arithmetic_propagation() {
let undefined = ScalarF5E3::ZERO / ScalarF5E3::ZERO;
assert!(undefined.is_undefined());
let normal = ScalarF5E3::from(42);
assert!((undefined + normal).is_undefined());
assert!((normal + undefined).is_undefined());
assert!((undefined - normal).is_undefined());
assert!((normal - undefined).is_undefined());
assert!((undefined * normal).is_undefined());
assert!((normal * undefined).is_undefined());
assert!((undefined / normal).is_undefined());
assert!((normal / undefined).is_undefined());
}
#[test]
fn test_function_propagation() {
let undefined = ScalarF5E3::from(-1).sqrt(); assert!(undefined.is_undefined());
assert!(undefined.sin().is_undefined());
assert!(undefined.cos().is_undefined());
assert!(undefined.tan().is_undefined());
assert!(undefined.exp().is_undefined());
assert!(undefined.ln().is_undefined());
assert!(undefined.lb().is_undefined());
assert!(undefined.square().is_undefined());
assert!(undefined.sqrt().is_undefined());
assert!(undefined.reciprocal().is_undefined());
let normal = ScalarF5E3::from(2);
assert!(undefined.pow(normal).is_undefined());
assert!(normal.pow(undefined).is_undefined());
}
#[test]
fn test_comparison_with_undefined() {
let undefined = ScalarF5E3::from(0) / ScalarF5E3::ZERO;
let normal = ScalarF5E3::from(5);
assert!(undefined.is_undefined());
let min_result = undefined.min(normal);
let max_result = undefined.max(normal);
assert!(min_result.is_undefined() || min_result == normal);
assert!(max_result.is_undefined() || max_result == normal);
let clamp_result = undefined.clamp(ScalarF5E3::from(1), ScalarF5E3::from(10));
assert!(clamp_result.is_undefined());
}
#[test]
fn test_undefined_chaining() {
let start = ScalarF5E3::from(-1);
let step1 = start.sqrt(); assert!(step1.is_undefined());
let step2 = step1.exp(); let step3 = step2 + ScalarF5E3::PI; let step4 = step3.sin(); let step5 = step4 * ScalarF5E3::from(100);
assert!(step2.is_undefined());
assert!(step3.is_undefined());
assert!(step4.is_undefined());
assert!(step5.is_undefined());
}
}
#[cfg(test)]
mod complex_undefined {
use super::*;
#[test]
fn test_complex_with_undefined_components() {
let z1 = CircleF5E3::from((f32::NAN, 2.0));
assert!(z1.is_undefined());
let z2 = CircleF5E3::from((3.0, f32::NAN));
assert!(z2.is_undefined());
let z3 = CircleF5E3::from((f32::NAN, f32::NAN));
assert!(z3.is_undefined());
}
#[test]
fn test_complex_operations_with_undefined() {
let undefined_complex = CircleF5E3::from((f32::NAN, 1.0));
let normal_complex = CircleF5E3::from((2.0, 3.0));
assert!(undefined_complex.is_undefined());
assert!(normal_complex.is_normal());
assert!((undefined_complex + normal_complex).is_undefined());
assert!((normal_complex + undefined_complex).is_undefined());
assert!((undefined_complex - normal_complex).is_undefined());
assert!((undefined_complex * normal_complex).is_undefined());
}
#[test]
fn test_complex_undefined_propagation() {
let undefined_complex = CircleF5E3::from((f32::NAN, f32::NAN));
assert!(undefined_complex.is_undefined());
let step1 = undefined_complex * CircleF5E3::POS_I;
let step2 = step1.conjugate();
let step3 = step2 + CircleF5E3::from((5.0, -3.0));
assert!(step1.is_undefined());
assert!(step2.is_undefined());
assert!(step3.is_undefined());
}
}
#[cfg(test)]
mod undefined_across_types {
use super::*;
macro_rules! test_undefined_for_type {
($scalar_type:ident) => {
let undefined = $scalar_type::ZERO / $scalar_type::ZERO;
assert!(undefined.is_undefined());
let normal = $scalar_type::from(42);
assert!((undefined + normal).is_undefined());
assert!((undefined * normal).is_undefined());
assert!((normal - undefined).is_undefined());
assert!(undefined.sin().is_undefined());
assert!(undefined.exp().is_undefined());
assert!(undefined.sqrt().is_undefined());
assert!(($scalar_type::from(-1).sqrt()).is_undefined());
assert!(($scalar_type::from(-1).ln()).is_undefined());
};
}
macro_rules! test_complex_undefined_for_type {
($circle_type:ident) => {
let undefined_complex = $circle_type::from((f32::NAN, f32::NAN));
assert!(undefined_complex.is_undefined());
let normal = $circle_type::from((2.0, 3.0));
assert!((undefined_complex + normal).is_undefined());
assert!((undefined_complex * normal).is_undefined());
};
}
#[test]
fn test_undefined_propagation_all_scalar_types() {
test_undefined_for_type!(ScalarF3E3);
test_undefined_for_type!(ScalarF5E3);
test_undefined_for_type!(ScalarF7E7);
test_undefined_for_type!(ScalarF3E7);
test_undefined_for_type!(ScalarF7E3);
}
#[test]
fn test_undefined_propagation_all_circle_types() {
test_complex_undefined_for_type!(CircleF3E3);
test_complex_undefined_for_type!(CircleF5E3);
test_complex_undefined_for_type!(CircleF7E7);
test_complex_undefined_for_type!(CircleF3E7);
test_complex_undefined_for_type!(CircleF7E3);
}
#[test]
fn test_undefined_conversion_between_types() {
let undefined_f3e3 = ScalarF3E3::from(f32::NAN);
assert!(undefined_f3e3.is_undefined());
let as_f5e3 = ScalarF5E3::from(f32::NAN);
let as_f7e7 = ScalarF7E7::from(f32::NAN);
assert!(as_f5e3.is_undefined());
assert!(as_f7e7.is_undefined());
let undefined_circle_f3e3 = CircleF3E3::from((f32::NAN, 1.0));
assert!(undefined_circle_f3e3.is_undefined());
}
}
#[cfg(test)]
mod undefined_special_cases {
use super::*;
#[test]
fn test_undefined_with_escaped_values() {
let exploded: ScalarF5E3 = ScalarF5E3::MAX * 2.0;
let vanished: ScalarF5E3 = ScalarF5E3::MIN_POS / 1000.0;
let undefined = ScalarF5E3::ZERO / ScalarF5E3::ZERO;
assert!(exploded.exploded());
assert!(vanished.vanished());
assert!(undefined.is_undefined());
let undefined_plus_exploded = undefined + exploded;
let undefined_plus_vanished = undefined + vanished;
let exploded_plus_undefined = exploded + undefined;
assert!(undefined_plus_exploded.is_undefined());
assert!(undefined_plus_vanished.is_undefined());
assert!(exploded_plus_undefined.is_undefined());
}
#[test]
fn test_double_undefined_operations() {
let undefined1 = ScalarF5E3::ZERO / ScalarF5E3::ZERO;
let undefined2 = ScalarF5E3::from(-1).sqrt();
assert!(undefined1.is_undefined());
assert!(undefined2.is_undefined());
assert!((undefined1 + undefined2).is_undefined());
assert!((undefined1 - undefined2).is_undefined());
assert!((undefined1 * undefined2).is_undefined());
assert!((undefined1 / undefined2).is_undefined());
assert!(undefined1.pow(undefined2).is_undefined());
}
#[test]
fn test_undefined_edge_cases() {
let large_exp = ScalarF5E3::from(1000);
let small_base = ScalarF5E3::from(0.1);
let result = small_base.pow(large_exp);
assert!(result.vanished() || result.is_undefined() || result.is_normal());
let modulo_result = ScalarF5E3::from(5) % ScalarF5E3::ZERO;
assert!(modulo_result.is_zero());
let zero_power_neg = ScalarF5E3::ZERO.pow(ScalarF5E3::from(-1));
assert!(zero_power_neg.is_undefined());
}
}