Skip to content

Commit

Permalink
fixup! Replace HasDomain to enable multi-argument edge case and dom…
Browse files Browse the repository at this point in the history
…ain tests
  • Loading branch information
tgross35 committed Jan 16, 2025
1 parent e930f6f commit 2ba42ee
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 19 deletions.
38 changes: 20 additions & 18 deletions crates/libm-test/src/domain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ impl<F: Float> Domain<F> {
const STRICTLY_POSITIVE: Self =
Self { start: Bound::Excluded(F::ZERO), end: Bound::Unbounded, check_points: None };

const fn into_prim_f<I>(self) -> EitherPrim<Self, Domain<I>> {
/// Wrap in the float variant of [`EitherPrim`].
const fn into_prim_float<I>(self) -> EitherPrim<Self, Domain<I>> {
EitherPrim::Float(self)
}
}
Expand All @@ -89,7 +90,8 @@ impl<I: Int> Domain<I> {
const UNBOUNDED_INT: Self =
Self { start: Bound::Unbounded, end: Bound::Unbounded, check_points: None };

const fn into_prim_i<F>(self) -> EitherPrim<Domain<F>, Self> {
/// Wrap in the int variant of [`EitherPrim`].
const fn into_prim_int<F>(self) -> EitherPrim<Domain<F>, Self> {
EitherPrim::Int(self)
}
}
Expand All @@ -99,65 +101,65 @@ impl<F: Float, I: Int> EitherPrim<Domain<F>, Domain<I>> {
/// x ∈ ℝ
const UNBOUNDED1: [Self; 1] =
[Domain { start: Bound::Unbounded, end: Bound::Unbounded, check_points: None }
.into_prim_f()];
.into_prim_float()];

/// {x1, x2} ∈ ℝ
const UNBOUNDED2: [Self; 2] =
[Domain::UNBOUNDED.into_prim_f(), Domain::UNBOUNDED.into_prim_f()];
[Domain::UNBOUNDED.into_prim_float(), Domain::UNBOUNDED.into_prim_float()];

/// {x1, x2, x3} ∈ ℝ
const UNBOUNDED3: [Self; 3] = [
Domain::UNBOUNDED.into_prim_f(),
Domain::UNBOUNDED.into_prim_f(),
Domain::UNBOUNDED.into_prim_f(),
Domain::UNBOUNDED.into_prim_float(),
Domain::UNBOUNDED.into_prim_float(),
Domain::UNBOUNDED.into_prim_float(),
];

/// {x1, x2} ∈ ℝ, one float and one int
const UNBOUNDED_F_I: [Self; 2] =
[Domain::UNBOUNDED.into_prim_f(), Domain::UNBOUNDED_INT.into_prim_i()];
[Domain::UNBOUNDED.into_prim_float(), Domain::UNBOUNDED_INT.into_prim_int()];

/// x ∈ ℝ >= 0
const POSITIVE: [Self; 1] = [Domain::POSITIVE.into_prim_f()];
const POSITIVE: [Self; 1] = [Domain::POSITIVE.into_prim_float()];

/// x ∈ ℝ > 0
const STRICTLY_POSITIVE: [Self; 1] = [Domain::STRICTLY_POSITIVE.into_prim_f()];
const STRICTLY_POSITIVE: [Self; 1] = [Domain::STRICTLY_POSITIVE.into_prim_float()];

/// Used for versions of `asin` and `acos`.
const INVERSE_TRIG_PERIODIC: [Self; 1] = [Domain {
start: Bound::Included(F::NEG_ONE),
end: Bound::Included(F::ONE),
check_points: None,
}
.into_prim_f()];
.into_prim_float()];

/// Domain for `acosh`
const ACOSH: [Self; 1] =
[Domain { start: Bound::Included(F::ONE), end: Bound::Unbounded, check_points: None }
.into_prim_f()];
.into_prim_float()];

/// Domain for `atanh`
const ATANH: [Self; 1] = [Domain {
start: Bound::Excluded(F::NEG_ONE),
end: Bound::Excluded(F::ONE),
check_points: None,
}
.into_prim_f()];
.into_prim_float()];

/// Domain for `sin`, `cos`, and `tan`
const TRIG: [Self; 1] = [Domain {
// TODO
// Trig functions have special behavior at fractions of π.
check_points: Some(|| Box::new([-F::PI, -F::FRAC_PI_2, F::FRAC_PI_2, F::PI].into_iter())),
..Domain::UNBOUNDED
}
.into_prim_f()];
.into_prim_float()];

/// Domain for `log` in various bases
const LOG: [Self; 1] = Self::STRICTLY_POSITIVE;

/// Domain for `log1p` i.e. `log(1 + x)`
const LOG1P: [Self; 1] =
[Domain { start: Bound::Excluded(F::NEG_ONE), end: Bound::Unbounded, check_points: None }
.into_prim_f()];
.into_prim_float()];

/// Domain for `sqrt`
const SQRT: [Self; 1] = Self::POSITIVE;
Expand All @@ -177,7 +179,7 @@ impl<F: Float, I: Int> EitherPrim<Domain<F>, Domain<I>> {
// Whether or not gamma is defined for negative numbers is implementation dependent
..Domain::UNBOUNDED
}
.into_prim_f()];
.into_prim_float()];

/// Domain for `loggamma`
const LGAMMA: [Self; 1] = Self::STRICTLY_POSITIVE;
Expand All @@ -186,7 +188,7 @@ impl<F: Float, I: Int> EitherPrim<Domain<F>, Domain<I>> {
// FIXME: the domain should provide some sort of "reasonable range" so we don't actually test
// the entire system unbounded.
const BESSEL_N: [Self; 2] =
[Domain::UNBOUNDED_INT.into_prim_i(), Domain::UNBOUNDED.into_prim_f()];
[Domain::UNBOUNDED_INT.into_prim_int(), Domain::UNBOUNDED.into_prim_float()];
}

/// Get the domain for a given function.
Expand Down
11 changes: 10 additions & 1 deletion crates/libm-test/src/run_cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,16 @@ pub fn check_near_count(ctx: &CheckCtx) -> u64 {
GeneratorKind::EdgeCases,
"check_near_count is intended for edge case tests"
);
if cfg!(optimizations_enabled) { 100 } else { 10 }
if cfg!(optimizations_enabled) {
// Taper based on the number of inputs.
match ctx.input_count() {
1 | 2 => 100,
3 => 50,
x => panic!("unexpected argument count {x}"),
}
} else {
10
}
}

/// Check whether extensive actions should be run or skipped.
Expand Down

0 comments on commit 2ba42ee

Please sign in to comment.