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.Test;
use std::rc::Rc;
use super::{GenericGF, GenericGFPoly};
/**
@@ -29,11 +31,11 @@ use super::{GenericGF, GenericGFPoly};
#[test]
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();
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());
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());
@@ -43,19 +45,19 @@ fn testPolynomialString() {
#[test]
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();
assert_eq!(fz.getZero(), FIELD.buildMonomial(1, 0));
assert_eq!(fz.getZero(), GenericGF::buildMonomial(FIELD.clone(), 1, 0));
assert_eq!(
fz.getZero(),
FIELD.buildMonomial(1, 2).multiply_with_scalar(0)
GenericGF::buildMonomial(FIELD.clone(), 1, 2).multiply_with_scalar(0)
);
}
#[test]
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 std::hash::Hash;
@@ -172,13 +172,13 @@ impl GenericGF {
/**
* @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 {
return GenericGFPoly::new(self.clone(), &vec![0]).unwrap();
return GenericGFPoly::new(source.clone(), &vec![0]).unwrap();
}
let mut coefficients = vec![0; degree + 1];
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)]
pub struct GenericGFPoly {
field: GenericGF,
field: Rc<GenericGF>,
coefficients: Vec<i32>,
}
@@ -303,7 +303,7 @@ impl GenericGFPoly {
* or if leading coefficient is 0 and this is not a
* 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 {
return Err(Exceptions::IllegalArgumentException(
"coefficients.len()".to_owned(),
@@ -312,19 +312,19 @@ impl GenericGFPoly {
Ok(Self {
field: field,
coefficients: {
let coefficientsLength = coefficients.len();
if coefficientsLength > 1 && coefficients[0] == 0 {
let coefficients_length = coefficients.len();
if coefficients_length > 1 && coefficients[0] == 0 {
// Leading term must be non-zero for anything except the constant polynomial "0"
let mut firstNonZero = 1;
while firstNonZero < coefficientsLength && coefficients[firstNonZero] == 0 {
firstNonZero += 1;
let mut first_non_zero = 1;
while first_non_zero < coefficients_length && coefficients[first_non_zero] == 0 {
first_non_zero += 1;
}
if firstNonZero == coefficientsLength {
if first_non_zero == coefficients_length {
vec![0]
} 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;
new_coefficients[0..=l].clone_from_slice(&coefficients[firstNonZero..]);
new_coefficients[0..=l].clone_from_slice(&coefficients[first_non_zero..]);
// System.arraycopy(coefficients,
// firstNonZero,
// this.coefficients,
@@ -551,7 +551,7 @@ impl GenericGFPoly {
inverse_denominator_leading_term,
);
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)?;
remainder = remainder.addOrSubtract(&term)?;
}
@@ -648,12 +648,12 @@ impl fmt::Display for GenericGFPoly {
* @author sanfordsquires
*/
pub struct ReedSolomonDecoder {
field: GenericGF,
field: Rc<GenericGF>,
}
impl ReedSolomonDecoder {
pub fn new(field: GenericGF) -> Self {
Self { field: field }
Self { field: Rc::new(field) }
}
/**
@@ -695,7 +695,7 @@ impl ReedSolomonDecoder {
}
};
let sigmaOmega = self.runEuclideanAlgorithm(
&self.field.buildMonomial(twoS.try_into().unwrap(), 1),
&GenericGF::buildMonomial(self.field.clone(), twoS.try_into().unwrap(), 1),
&syndrome,
twoS.try_into().unwrap(),
)?;
@@ -772,7 +772,7 @@ impl ReedSolomonDecoder {
let scale = self
.field
.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,
Err(err) => {
return Err(Exceptions::ReedSolomonException(
@@ -951,15 +951,16 @@ impl ReedSolomonDecoder {
* @author William Rucklidge
*/
pub struct ReedSolomonEncoder {
field: GenericGF,
field: Rc<GenericGF>,
cachedGenerators: Vec<GenericGFPoly>,
}
impl ReedSolomonEncoder {
pub fn new(field: GenericGF) -> Self {
let n = Rc::new(field);
Self {
cachedGenerators: vec![GenericGFPoly::new(field.clone(), &vec![1]).unwrap()],
field: field,
cachedGenerators: vec![GenericGFPoly::new(n.clone(), &vec![1]).unwrap()],
field: n,
}
}