1use binius_field::field::FieldOps;
7
8use crate::multilinear::hypercube::{Hypercube, OneCube};
9
10#[inline]
22pub fn extrapolate_line<F: FieldOps>(x0: F, x1: F, z: F) -> F {
23 OneCube::extrapolate_line(x0, x1, z)
25}
26
27#[cfg(test)]
28mod tests {
29 use binius_field::{Field, Random, field::FieldOps};
30 use rand::prelude::*;
31
32 use super::*;
33 use crate::test_utils::{B128, Packed128b};
34
35 type P = Packed128b;
36 type F = B128;
37
38 #[test]
39 fn extrapolate_line_reads_the_endpoints_at_zero_and_one() {
40 let mut rng = StdRng::seed_from_u64(0);
41
42 let x0 = F::random(&mut rng);
47 let x1 = F::random(&mut rng);
48 assert_eq!(extrapolate_line(x0, x1, F::ZERO), x0);
49 assert_eq!(extrapolate_line(x0, x1, F::ONE), x1);
50
51 let x0_packed = P::random(&mut rng);
53 let x1_packed = P::random(&mut rng);
54 assert_eq!(extrapolate_line(x0_packed, x1_packed, P::zero()), x0_packed);
55 assert_eq!(extrapolate_line(x0_packed, x1_packed, P::one()), x1_packed);
56 }
57
58 #[test]
59 fn extrapolate_line_matches_the_closed_form() {
60 let mut rng = StdRng::seed_from_u64(0);
61
62 for _ in 0..10 {
65 let x0 = F::random(&mut rng);
66 let x1 = F::random(&mut rng);
67 let z = F::from(rng.next_u64() as u128);
68 assert_eq!(extrapolate_line(x0, x1, z), x0 + (x1 - x0) * z);
69 }
70 }
71}