switch rs to use Rc instead of impractical clones

This commit is contained in:
Henry Schimke
2022-08-31 17:07:43 -05:00
parent 56559f4888
commit 5ce745950e
2 changed files with 32 additions and 29 deletions

View File

@@ -19,6 +19,8 @@
//import org.junit.Assert; //import org.junit.Assert;
//import org.junit.Test; //import org.junit.Test;
use std::rc::Rc;
use super::{GenericGF, GenericGFPoly}; use super::{GenericGF, GenericGFPoly};
/** /**
@@ -29,11 +31,11 @@ use super::{GenericGF, GenericGFPoly};
#[test] #[test]
fn testPolynomialString() { fn testPolynomialString() {
let FIELD = super::get_predefined_genericgf(super::PredefinedGenericGF::QrCodeField256); let FIELD = Rc::new(super::get_predefined_genericgf(super::PredefinedGenericGF::QrCodeField256));
let fz = super::GenericGFPoly::new(FIELD.clone(), &vec![0; 1]).unwrap(); let fz = super::GenericGFPoly::new(FIELD.clone(), &vec![0; 1]).unwrap();
assert_eq!("0", fz.getZero().to_string()); assert_eq!("0", fz.getZero().to_string());
let n1mono = FIELD.buildMonomial(0, -1); let n1mono = GenericGF::buildMonomial(FIELD.clone(), 0, -1);
assert_eq!("-1", n1mono.to_string()); assert_eq!("-1", n1mono.to_string());
let p = GenericGFPoly::new(FIELD.clone(), &vec![3, 0, -2, 1, 1]).unwrap(); let p = GenericGFPoly::new(FIELD.clone(), &vec![3, 0, -2, 1, 1]).unwrap();
assert_eq!("a^25x^4 - ax^2 + x + 1", p.to_string()); assert_eq!("a^25x^4 - ax^2 + x + 1", p.to_string());
@@ -43,19 +45,19 @@ fn testPolynomialString() {
#[test] #[test]
fn testZero() { fn testZero() {
let FIELD = super::get_predefined_genericgf(super::PredefinedGenericGF::QrCodeField256); let FIELD = Rc::new(super::get_predefined_genericgf(super::PredefinedGenericGF::QrCodeField256));
let fz = super::GenericGFPoly::new(FIELD.clone(), &vec![0; 1]).unwrap(); let fz = super::GenericGFPoly::new(FIELD.clone(), &vec![0; 1]).unwrap();
assert_eq!(fz.getZero(), FIELD.buildMonomial(1, 0)); assert_eq!(fz.getZero(), GenericGF::buildMonomial(FIELD.clone(), 1, 0));
assert_eq!( assert_eq!(
fz.getZero(), fz.getZero(),
FIELD.buildMonomial(1, 2).multiply_with_scalar(0) GenericGF::buildMonomial(FIELD.clone(), 1, 2).multiply_with_scalar(0)
); );
} }
#[test] #[test]
fn testEvaluate() { fn testEvaluate() {
let FIELD = super::get_predefined_genericgf(super::PredefinedGenericGF::QrCodeField256); let FIELD = Rc::new(super::get_predefined_genericgf(super::PredefinedGenericGF::QrCodeField256));
assert_eq!(3, FIELD.buildMonomial(0, 3).evaluateAt(0)); assert_eq!(3, GenericGF::buildMonomial(FIELD.clone(), 0, 3).evaluateAt(0));
} }

View File

@@ -1,4 +1,4 @@
use std::fmt; use std::{fmt, rc::Rc};
use crate::Exceptions; use crate::Exceptions;
use std::hash::Hash; use std::hash::Hash;
@@ -172,13 +172,13 @@ impl GenericGF {
/** /**
* @return the monomial representing coefficient * x^degree * @return the monomial representing coefficient * x^degree
*/ */
pub fn buildMonomial(&self, degree: usize, coefficient: i32) -> GenericGFPoly { pub fn buildMonomial(source: Rc<Self>, degree: usize, coefficient: i32) -> GenericGFPoly {
if coefficient == 0 { if coefficient == 0 {
return GenericGFPoly::new(self.clone(), &vec![0]).unwrap(); return GenericGFPoly::new(source.clone(), &vec![0]).unwrap();
} }
let mut coefficients = vec![0; degree + 1]; let mut coefficients = vec![0; degree + 1];
coefficients[0] = coefficient; coefficients[0] = coefficient;
return GenericGFPoly::new(self.clone(), &coefficients).unwrap(); return GenericGFPoly::new(source.clone(), &coefficients).unwrap();
} }
/** /**
@@ -282,7 +282,7 @@ impl fmt::Display for GenericGF {
*/ */
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct GenericGFPoly { pub struct GenericGFPoly {
field: GenericGF, field: Rc<GenericGF>,
coefficients: Vec<i32>, coefficients: Vec<i32>,
} }
@@ -303,7 +303,7 @@ impl GenericGFPoly {
* or if leading coefficient is 0 and this is not a * or if leading coefficient is 0 and this is not a
* constant polynomial (that is, it is not the monomial "0") * constant polynomial (that is, it is not the monomial "0")
*/ */
pub fn new(field: GenericGF, coefficients: &Vec<i32>) -> Result<Self, Exceptions> { pub fn new(field: Rc<GenericGF>, coefficients: &Vec<i32>) -> Result<Self, Exceptions> {
if coefficients.len() == 0 { if coefficients.len() == 0 {
return Err(Exceptions::IllegalArgumentException( return Err(Exceptions::IllegalArgumentException(
"coefficients.len()".to_owned(), "coefficients.len()".to_owned(),
@@ -312,19 +312,19 @@ impl GenericGFPoly {
Ok(Self { Ok(Self {
field: field, field: field,
coefficients: { coefficients: {
let coefficientsLength = coefficients.len(); let coefficients_length = coefficients.len();
if coefficientsLength > 1 && coefficients[0] == 0 { if coefficients_length > 1 && coefficients[0] == 0 {
// Leading term must be non-zero for anything except the constant polynomial "0" // Leading term must be non-zero for anything except the constant polynomial "0"
let mut firstNonZero = 1; let mut first_non_zero = 1;
while firstNonZero < coefficientsLength && coefficients[firstNonZero] == 0 { while first_non_zero < coefficients_length && coefficients[first_non_zero] == 0 {
firstNonZero += 1; first_non_zero += 1;
} }
if firstNonZero == coefficientsLength { if first_non_zero == coefficients_length {
vec![0] vec![0]
} else { } else {
let mut new_coefficients = vec![0; coefficientsLength - firstNonZero]; let mut new_coefficients = vec![0; coefficients_length - first_non_zero];
let l = new_coefficients.len() - 1; let l = new_coefficients.len() - 1;
new_coefficients[0..=l].clone_from_slice(&coefficients[firstNonZero..]); new_coefficients[0..=l].clone_from_slice(&coefficients[first_non_zero..]);
// System.arraycopy(coefficients, // System.arraycopy(coefficients,
// firstNonZero, // firstNonZero,
// this.coefficients, // this.coefficients,
@@ -551,7 +551,7 @@ impl GenericGFPoly {
inverse_denominator_leading_term, inverse_denominator_leading_term,
); );
let term = other.multiply_by_monomial(degree_difference, scale)?; let term = other.multiply_by_monomial(degree_difference, scale)?;
let iteration_quotient = self.field.buildMonomial(degree_difference, scale); let iteration_quotient = GenericGF::buildMonomial(self.field.clone(), degree_difference, scale);
quotient = quotient.addOrSubtract(&iteration_quotient)?; quotient = quotient.addOrSubtract(&iteration_quotient)?;
remainder = remainder.addOrSubtract(&term)?; remainder = remainder.addOrSubtract(&term)?;
} }
@@ -648,12 +648,12 @@ impl fmt::Display for GenericGFPoly {
* @author sanfordsquires * @author sanfordsquires
*/ */
pub struct ReedSolomonDecoder { pub struct ReedSolomonDecoder {
field: GenericGF, field: Rc<GenericGF>,
} }
impl ReedSolomonDecoder { impl ReedSolomonDecoder {
pub fn new(field: GenericGF) -> Self { pub fn new(field: GenericGF) -> Self {
Self { field: field } Self { field: Rc::new(field) }
} }
/** /**
@@ -695,7 +695,7 @@ impl ReedSolomonDecoder {
} }
}; };
let sigmaOmega = self.runEuclideanAlgorithm( let sigmaOmega = self.runEuclideanAlgorithm(
&self.field.buildMonomial(twoS.try_into().unwrap(), 1), &GenericGF::buildMonomial(self.field.clone(), twoS.try_into().unwrap(), 1),
&syndrome, &syndrome,
twoS.try_into().unwrap(), twoS.try_into().unwrap(),
)?; )?;
@@ -772,7 +772,7 @@ impl ReedSolomonDecoder {
let scale = self let scale = self
.field .field
.multiply(r.getCoefficient(r.getDegree()), dltInverse); .multiply(r.getCoefficient(r.getDegree()), dltInverse);
q = match q.addOrSubtract(&self.field.buildMonomial(degreeDiff, scale)) { q = match q.addOrSubtract(&GenericGF::buildMonomial(self.field.clone(), degreeDiff, scale)) {
Ok(res) => res, Ok(res) => res,
Err(err) => { Err(err) => {
return Err(Exceptions::ReedSolomonException( return Err(Exceptions::ReedSolomonException(
@@ -951,15 +951,16 @@ impl ReedSolomonDecoder {
* @author William Rucklidge * @author William Rucklidge
*/ */
pub struct ReedSolomonEncoder { pub struct ReedSolomonEncoder {
field: GenericGF, field: Rc<GenericGF>,
cachedGenerators: Vec<GenericGFPoly>, cachedGenerators: Vec<GenericGFPoly>,
} }
impl ReedSolomonEncoder { impl ReedSolomonEncoder {
pub fn new(field: GenericGF) -> Self { pub fn new(field: GenericGF) -> Self {
let n = Rc::new(field);
Self { Self {
cachedGenerators: vec![GenericGFPoly::new(field.clone(), &vec![1]).unwrap()], cachedGenerators: vec![GenericGFPoly::new(n.clone(), &vec![1]).unwrap()],
field: field, field: n,
} }
} }