Skip to content

Commit

Permalink
test: many extended interval arithmetic unit tests (#31)
Browse files Browse the repository at this point in the history
* fix: change cargo test profile to get correct times in benchmark

* test: all add and mul tests on critical intervals

* wip: planning more domain tests

* fix: `is_zero` and `is_one` check for empty intervals

* test: checker tests for EIF

* fix: `abs` interval calculation

* test: interval `neg`, `abs`, and some concrete intervals for `exp` and `log`

* fix: negative cases for interval `sqrt`

* test: interval `sqrt` tests

* fix: `log` on negative intervals

* fix: let `log` work for non-negative input

* test: tests up to interval `sub`

* test: interval `mul` tests

* refactor: neater `is_zero` and `is_one`

* style: no prints in tests

* test: interval `min` and `max`

* feat: interval macros

* test: more `div` interval tests

* feat: macros for all intervals

* style: do not name all intervals

* fix: be careful with `0 ^ 0`

* fix: `I ^ [0, 0] = [1, 1]`

* test: many tests for interval `pow`
  • Loading branch information
ramonfmir committed Apr 24, 2024
1 parent c2f77e4 commit 46087d0
Show file tree
Hide file tree
Showing 3 changed files with 1,540 additions and 357 deletions.
7 changes: 6 additions & 1 deletion egg-pre-dcp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,12 @@ intervals-good = "0.1.1"

[profile.test]
debug = true
opt-level = 1
lto = "fat"
codegen-units = 1
opt-level = 3
debug-assertions = false
overflow-checks = false
incremental = false

[profile.release]
debug = true
Expand Down
94 changes: 72 additions & 22 deletions egg-pre-dcp/src/domain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,45 @@ impl Domain {
}
}

#[macro_export]
macro_rules! CC {
($a:expr, $b:expr) => { Domain::make_cc(domain::make_float($a), domain::make_float($b)) };
}

#[macro_export]
macro_rules! CO {
($a:expr, $b:expr) => { Domain::make_co(domain::make_float($a), domain::make_float($b)) };
}

#[macro_export]
macro_rules! CI {
($a:expr) => { Domain::make_ci(domain::make_float($a)) };
}

#[macro_export]
macro_rules! OC {
($a:expr, $b:expr) => { Domain::make_oc(domain::make_float($a), domain::make_float($b)) };
}

#[macro_export]
macro_rules! OO {
($a:expr, $b:expr) => { Domain::make_oo(domain::make_float($a), domain::make_float($b)) };
}

#[macro_export]
macro_rules! OI {
($b:expr) => { Domain::make_oi(domain::make_float($b)) };
}

#[macro_export]
macro_rules! IC {
($b:expr) => { Domain::make_ic(domain::make_float($b)) };
}

#[macro_export]
macro_rules! IO {
($b:expr) => { Domain::make_io(domain::make_float($b)) };
}

impl PartialOrd for Domain {
fn partial_cmp(&self, other: &Domain) -> Option<Ordering> {
Expand Down Expand Up @@ -339,7 +378,7 @@ pub fn zero_dom() -> Domain {
}

pub fn is_zero(d: &Domain) -> bool {
d.subseteq(&zero_dom())
d.eq(&zero_dom())
}

pub fn option_is_zero(d: Option<&Domain>) -> bool {
Expand All @@ -351,7 +390,7 @@ pub fn one_dom() -> Domain {
}

pub fn is_one(d: &Domain) -> bool {
d.subseteq(&one_dom())
d.eq(&one_dom())
}

pub fn option_is_one(d: Option<&Domain>) -> bool {
Expand All @@ -362,6 +401,22 @@ pub fn free_dom() -> Domain {
Domain::make_ii()
}

pub fn empty_dom() -> Domain {
Domain::make_oo(zero(), zero())
}

pub fn pos_dom() -> Domain {
Domain::make_oi(zero())
}

pub fn is_pos(d: &Domain) -> bool {
d.subseteq(&pos_dom())
}

pub fn option_is_pos(d: Option<&Domain>) -> bool {
d.map_or(false, is_pos)
}

pub fn nonneg_dom() -> Domain {
Domain::make_ci(zero())
}
Expand All @@ -386,18 +441,6 @@ pub fn option_is_nonpos(d: Option<&Domain>) -> bool {
d.map_or(false, is_nonpos)
}

pub fn pos_dom() -> Domain {
Domain::make_oi(zero())
}

pub fn is_pos(d: &Domain) -> bool {
d.subseteq(&pos_dom())
}

pub fn option_is_pos(d: Option<&Domain>) -> bool {
d.map_or(false, is_pos)
}

pub fn neg_dom() -> Domain {
Domain::make_io(neg_zero())
}
Expand Down Expand Up @@ -475,11 +518,11 @@ pub fn abs(d: &Domain) -> Domain {
Domain::make_from_endpoints(-b, -a, r, l)
} else {
if a_abs < b_abs {
Domain::make_from_endpoints(zero(), b, false, r)
Domain::make_from_endpoints(zero(), b_abs, false, r)
} else if b_abs < a_abs {
Domain::make_from_endpoints(zero(), a, false, l)
Domain::make_from_endpoints(zero(), a_abs, false, l)
} else {
Domain::make_from_endpoints(zero(), a, false, l && r)
Domain::make_from_endpoints(zero(), a_abs, false, l && r)
}
}
} else {
Expand All @@ -492,15 +535,23 @@ pub fn option_abs(d_o: Option<Domain>) -> Option<Domain> {
}

pub fn sqrt(d: &Domain) -> Domain {
Domain::make(d.interval.sqrt(), d.lo_open, d.hi_open)
if is_nonneg(d) {
Domain::make(d.interval.sqrt(), d.lo_open, d.hi_open)
} else {
free_dom()
}
}

pub fn option_sqrt(d_o: Option<Domain>) -> Option<Domain> {
execute_unary(d_o, sqrt)
}

pub fn log(d: &Domain) -> Domain {
Domain::make(d.interval.ln(), d.lo_open, d.hi_open)
if is_nonneg(d) {
Domain::make(d.interval.ln(), d.lo_open, d.hi_open)
} else {
free_dom()
}
}

pub fn option_log(d_o: Option<Domain>) -> Option<Domain> {
Expand Down Expand Up @@ -638,7 +689,6 @@ fn perform_mult(
}

// For multiplication, opennes of endpoints depends on the values.
// NOTE(RFM): For the case splitting part, c.f. with `classify`.
pub fn mul(d1: &Domain, d2: &Domain) -> Domain {
let d1_pos = is_pos(d1);
let d1_neg = is_neg(d1);
Expand Down Expand Up @@ -845,11 +895,11 @@ pub fn pow(d1: &Domain, d2: &Domain) -> Domain {
Some(f) => {
if ((f as u32) as f64) == f {
let n = f as u32;
if n == 0 && does_not_contain_zero(d1) {
if n == 0 {
return Domain::make_singleton(1.0);
} else if n == 1 {
return d1.clone();
} else if n % 2 == 0 {
} else if n > 0 && n % 2 == 0 {
let d = abs(d1);
let lo = d.lo_float();
let hi = d.hi_float();
Expand Down
Loading

0 comments on commit 46087d0

Please sign in to comment.