Skip to content

Commit

Permalink
MVPoly: implement degree + tests
Browse files Browse the repository at this point in the history
  • Loading branch information
dannywillems committed Aug 28, 2024
1 parent 293d74e commit 317da6a
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 0 deletions.
31 changes: 31 additions & 0 deletions mvpoly/src/prime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,37 @@ impl<F: PrimeField, const N: usize, const D: usize> Dense<F, N, D> {
D
}

pub fn is_constant(&self) -> bool {
self.coeff.iter().skip(1).all(|c| c.is_zero())
}

/// Returns the degree of the polynomial.
///
/// The degree of the polynomial is the maximum degree of the monomials
/// that have a non-zero coefficient.
///
/// # Safety
///
/// The zero polynomial as a degree equals to 0, as the degree of the
/// constant polynomials. We do use the `unsafe` keyword to warn the user
/// for this specific case.
pub unsafe fn degree(&self) -> usize {
if self.is_constant() {
return 0;
}
let mut prime_gen = PrimeNumberGenerator::new();
self.coeff.iter().enumerate().fold(1, |acc, (i, c)| {
if *c != F::zero() {
let decomposition_of_i =
naive_prime_factors(self.normalized_indices[i], &mut prime_gen);
let monomial_degree = decomposition_of_i.iter().fold(0, |acc, (_, d)| acc + d);
acc.max(monomial_degree)
} else {
acc
}
})
}

/// Output example for N = 2 and D = 2:
/// ```text
/// - 0 -> 1
Expand Down
43 changes: 43 additions & 0 deletions mvpoly/tests/prime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use kimchi::circuits::{
};
use mina_curves::pasta::Fp;
use mvpoly::{prime::Dense, utils::PrimeNumberGenerator};
use rand::Rng;

#[test]
fn test_vector_space_dimension() {
Expand Down Expand Up @@ -620,3 +621,45 @@ fn test_from_expr_ec_addition() {
assert_eq!(eval, exp_eval);
}
}

#[test]
fn test_degree_with_coeffs() {
let p = Dense::<Fp, 4, 5>::from_coeffs(vec![
Fp::from(2_u32),
Fp::from(3_u32),
Fp::from(4_u32),
Fp::from(5_u32),
Fp::from(6_u32),
Fp::from(7_u32),
]);
let degree = unsafe { p.degree() };
assert_eq!(degree, 2);
}

#[test]
fn test_degree_constant() {
let mut rng = o1_utils::tests::make_test_rng(None);
let c = Fp::rand(&mut rng);
let p = Dense::<Fp, 4, 5>::from(c);
let degree = unsafe { p.degree() };
assert_eq!(degree, 0);

let p = Dense::<Fp, 4, 5>::zero();
let degree = unsafe { p.degree() };
assert_eq!(degree, 0);
}

#[test]
fn test_degree_random_degree() {
let mut rng = o1_utils::tests::make_test_rng(None);
let max_degree: usize = rng.gen_range(1..5);
let p: Dense<Fp, 4, 5> = unsafe { Dense::random(&mut rng, Some(max_degree)) };
let degree = unsafe { p.degree() };
assert!(degree <= max_degree);

let max_degree: usize = rng.gen_range(1..20);
// univariate
let p = unsafe { Dense::<Fp, 1, 20>::random(&mut rng, Some(max_degree)) };
let degree = unsafe { p.degree() };
assert!(degree <= max_degree);
}

0 comments on commit 317da6a

Please sign in to comment.