From d32e0d34836a881ac8f2797ce788a2e173c91e12 Mon Sep 17 00:00:00 2001 From: Eliel <46634774+elielnfinic@users.noreply.github.com> Date: Tue, 19 Mar 2024 12:56:28 +0200 Subject: [PATCH] Implementing divide, truediv, mod for polynomial struct --- .../src/linear_multiiplication.rs | 2 +- baby-stark/src/field.rs | 14 ++- baby-stark/src/main.rs | 2 +- baby-stark/src/polynomial.rs | 108 +++++++++++++++--- 4 files changed, 109 insertions(+), 17 deletions(-) diff --git a/baby-stark-math-lib/src/linear_multiiplication.rs b/baby-stark-math-lib/src/linear_multiiplication.rs index a181507..56c4ac4 100644 --- a/baby-stark-math-lib/src/linear_multiiplication.rs +++ b/baby-stark-math-lib/src/linear_multiiplication.rs @@ -2,4 +2,4 @@ pub fn vector_scalar_multiplication(vector : Vec, scalar : i128) -> Vec>() -} \ No newline at end of file +} diff --git a/baby-stark/src/field.rs b/baby-stark/src/field.rs index d3ffc9b..bd0892c 100644 --- a/baby-stark/src/field.rs +++ b/baby-stark/src/field.rs @@ -43,6 +43,7 @@ impl FieldElement{ } } + // TO BE IMPLEMENTED pub fn __truediv__(self, right : FieldElement) -> FieldElement{ FieldElement::new() } @@ -59,7 +60,8 @@ impl FieldElement{ let acc = FieldElement::from(1, self.field.clone()); let val = FieldElement::from(self.value, self.field); - // TBD + // TBD + } @@ -182,6 +184,16 @@ impl Field{ } +pub fn vector_multiplication_field_scalar ( vector : &Vec, scalar : i128) -> Vec{ + let mut res : Vec = vec![]; + for field_element in vector.iter() { + res.push(FieldElement::from(field_element.value * scalar, vector.get(0).unwrap().field)); + } + + res +} + + #[cfg(test)] mod tests{ use super::*; diff --git a/baby-stark/src/main.rs b/baby-stark/src/main.rs index b77c32a..0f2d861 100644 --- a/baby-stark/src/main.rs +++ b/baby-stark/src/main.rs @@ -3,7 +3,7 @@ use baby_stark_math_lib; use crate::field::FieldElement; mod field; -// mod polynomial; +mod polynomial; fn main() { println!("Hello, world!"); diff --git a/baby-stark/src/polynomial.rs b/baby-stark/src/polynomial.rs index 290dfaf..b9e5042 100644 --- a/baby-stark/src/polynomial.rs +++ b/baby-stark/src/polynomial.rs @@ -1,9 +1,16 @@ use baby_stark_math_lib::linear_multiiplication::vector_scalar_multiplication; +use core::num; use std::cmp::max; -use crate::field::{self, FieldElement}; +use crate::field::{self, vector_multiplication_field_scalar, FieldElement}; -#[derive(Debug)] +pub fn multi_poly_and_scalar(poly : Polynomial, scalar : i128) -> Polynomial{ + Polynomial{ + coeficients : vector_multiplication_field_scalar(&poly.coeficients, scalar) + } +} + +#[derive(Debug, Clone)] pub struct Polynomial { coeficients: Vec, } @@ -42,17 +49,22 @@ impl Polynomial { ) } + // TO FIX : ADD RETURN ELEMENT pub fn __add__(self, other: Polynomial) -> Polynomial { - if self.degree() == -1 { + if self.clone().degree() == -1 { return other; - } else if other.degree() == -1 { + } else if other.clone().degree() == -1 { return self; } - let field = self.coeficients.get(0).unwrap().field; + // let field = self.coeficients.get(0).unwrap().field; - let zero_vec = [field.zero(); 10].to_vec(); - let largest_vec = max(self.coeficients.len(), other.coeficients.len()); - let coeffs = vector_scalar_multiplication(zero_vec, largest_vec as i128); + // let zero_vec = [field.zero(); 10].to_vec(); + // let largest_vec = max(self.coeficients.len(), other.coeficients.len()); + // // let coeffs = vector_scalar_multiplication(zero_vec, largest_vec as i128); + + Polynomial{ + coeficients : vec![] + } } pub fn __sub__(self, other: Polynomial) -> Polynomial { @@ -73,16 +85,16 @@ impl Polynomial { } pub fn __eq__(self, other: Polynomial) -> bool { - if self.degree() != other.degree() { + if self.clone().degree() != other.clone().degree() { return false; } - if self.degree() == -1 { + if self.clone().degree() == -1 { return true; } - self.coeficients + self.clone().coeficients .iter() .zip(other.coeficients.iter()) - .all(|(a, b)| a == b) + .all(|(a, b)| (*a).__eq__(*b)) } pub fn __neq__(self, other: Polynomial) -> bool { @@ -96,7 +108,75 @@ impl Polynomial { return false; } - pub fn leading_coefficient(self) { - self.coeficients[self.degree()] + // TO BE FIXED + pub fn leading_coefficient(self) -> FieldElement{ + // self.coeficients[self.degree()] + self.coeficients[0_usize] + } + + pub fn divide(numerator : Polynomial, denominator : Polynomial) -> Option<(Polynomial, Polynomial)>{ + if denominator.clone().degree() == -1 { + return None; + } + + if numerator.clone().degree() < denominator.clone().degree() { + return Some((Polynomial::from(vec![]), numerator)); + } + + let field = denominator.clone().coeficients.get(0).unwrap().field; + let mut remainder = Polynomial::from(numerator.coeficients.clone()); + + let mut quotient_coefficients : Vec = vec![]; + + let degree_diff = numerator.clone().degree() - denominator.clone().degree() + 1; + + for i in 0 .. degree_diff { + quotient_coefficients.push(field.zero()); + } + + for i in 0 .. degree_diff { + if remainder.clone().degree() < denominator.clone().degree() { + break; + } + + let coefficent = remainder.clone().leading_coefficient().__truediv__(denominator.clone().leading_coefficient()); + let shift = remainder.clone().degree() - denominator.clone().degree(); + + let poly_product = multi_poly_and_scalar(Polynomial::from(vec![field.clone().zero()]), shift); + + let subsctractee = (poly_product.__add__(Polynomial::from(vec![coefficent]))).__mul__(denominator.clone()); + + quotient_coefficients[shift as usize] = coefficent; + + remainder = remainder.__sub__(subsctractee) + } + + let quotient = Polynomial::from(quotient_coefficients); + + Some((quotient, remainder)) + } + + pub fn __truediv__(self, other : Polynomial) -> Result { + if other.clone().is_zero() { + return Err("CANT_DIVIDE_BY_0".to_string()); + } + let divide_result = Polynomial::divide(self, other); + match divide_result { + Some(divide_result) => Ok(divide_result.0), + None => Err("COULD_NOT_DIVIDE".to_string()) + } + } + + pub fn __mod__(self, other : Polynomial) -> Result { + let divide_result = Polynomial::divide(self, other); + match divide_result { + Some(divide_result) => Ok(divide_result.1), + None => Err("COULD_NOT_GET_MODULO".to_string()) + } + } + + pub fn __xor__(self, exponent : i128) -> Polynomial { + // TBD + Polynomial::from(vec![FieldElement::new()]) } }