private static IEnumerable <FieldElement[]> PlaceErrors(GaloisField field, int codewordLength, IReadOnlyList <int> errorsPositions, IList <int> noiseValue, int currentErrorPosition) { if (currentErrorPosition == errorsPositions.Count) { var additiveNoise = Enumerable.Repeat(field.Zero(), codewordLength).ToArray(); for (var i = 0; i < errorsPositions.Count; i++) { additiveNoise[errorsPositions[i]] = field.CreateElement(noiseValue[i]); } yield return(additiveNoise); yield break; } for (var i = noiseValue[currentErrorPosition]; i < field.Order; i++) { noiseValue[currentErrorPosition] = i; foreach (var additiveNoise in PlaceErrors(field, codewordLength, errorsPositions, noiseValue, currentErrorPosition + 1)) { yield return(additiveNoise); } } noiseValue[currentErrorPosition] = 1; }
internal StandardReedSolomonCode( GaloisField field, int codewordLength, int informationWordLength, IDecoder decoder, IListDecoder listDecoder) { Field = field; CodewordLength = codewordLength; InformationWordLength = informationWordLength; CodeDistance = CodewordLength - InformationWordLength + 1; _decoder = decoder; _listDecoder = listDecoder; _preparedPoints = Enumerable.Range(0, CodewordLength) .Select(x => Field.CreateElement(Field.GetGeneratingElementPower(x))) .ToArray(); _maxListDecodingRadius = (int)Math.Ceiling(CodewordLength - Math.Sqrt(CodewordLength * (CodewordLength - CodeDistance)) - 1); }
static BiVariablePolynomialTests() { Gf5 = new PrimeOrderField(5); var polynomialForEvoluation = new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(1, 1)] = Gf5.CreateElement(2), [new Tuple <int, int>(0, 1)] = Gf5.One(), [new Tuple <int, int>(2, 0)] = Gf5.One(), [new Tuple <int, int>(1, 0)] = Gf5.One(), [new Tuple <int, int>(0, 0)] = Gf5.CreateElement(4) }; EvaluateTestsData = new TheoryData <EvaluationTestCase> { new EvaluationTestCase { Polynomial = polynomialForEvoluation, XValue = Gf5.One(), YValue = Gf5.CreateElement(3), Expected = Gf5.Zero() }, new EvaluationTestCase { Polynomial = polynomialForEvoluation, XValue = Gf5.CreateElement(2), YValue = new FieldElement(Gf5, 4), Expected = Gf5.Zero() }, new EvaluationTestCase { Polynomial = polynomialForEvoluation, XValue = Gf5.CreateElement(3), YValue = Gf5.CreateElement(2), Expected = Gf5.Zero() }, new EvaluationTestCase { Polynomial = polynomialForEvoluation, XValue = Gf5.CreateElement(2), YValue = Gf5.CreateElement(3), Expected = Gf5.Zero() }, }; AddTestsData = new TheoryData <BinaryOperationTestCase> { new BinaryOperationTestCase { FirstOperand = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(2), [Tuple.Create(1, 0)] = Gf5.CreateElement(3) }, SecondOperand = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(3), [Tuple.Create(0, 1)] = Gf5.CreateElement(4) }, Expected = new BiVariablePolynomial(Gf5) { [Tuple.Create(1, 0)] = Gf5.CreateElement(3), [Tuple.Create(0, 1)] = Gf5.CreateElement(4) } }, new BinaryOperationTestCase { FirstOperand = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(2), [Tuple.Create(1, 0)] = Gf5.CreateElement(3), [Tuple.Create(0, 1)] = Gf5.CreateElement(4) }, SecondOperand = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 1)] = Gf5.CreateElement(4), [Tuple.Create(0, 0)] = Gf5.CreateElement(4), [Tuple.Create(1, 0)] = Gf5.CreateElement(4) }, Expected = new BiVariablePolynomial(Gf5) { [Tuple.Create(1, 0)] = Gf5.CreateElement(2), [Tuple.Create(0, 1)] = Gf5.CreateElement(3), [Tuple.Create(0, 0)] = Gf5.One() } } }; SubtractTestsData = new TheoryData <BinaryOperationTestCase> { new BinaryOperationTestCase { FirstOperand = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(2), [Tuple.Create(1, 0)] = Gf5.CreateElement(3) }, SecondOperand = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(3), [Tuple.Create(0, 1)] = Gf5.CreateElement(4) }, Expected = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(4), [Tuple.Create(1, 0)] = Gf5.CreateElement(3), [Tuple.Create(0, 1)] = Gf5.One() } }, new BinaryOperationTestCase { FirstOperand = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(2), [Tuple.Create(1, 0)] = Gf5.CreateElement(3), [Tuple.Create(0, 1)] = Gf5.CreateElement(4) }, SecondOperand = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(4), [Tuple.Create(1, 0)] = Gf5.CreateElement(4), [Tuple.Create(0, 1)] = Gf5.CreateElement(4) }, Expected = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(3), [Tuple.Create(1, 0)] = Gf5.CreateElement(4) } } }; MultiplyPolynomialsTestsData = new TheoryData <BinaryOperationTestCase> { new BinaryOperationTestCase { FirstOperand = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(2), [Tuple.Create(1, 0)] = Gf5.CreateElement(3) }, SecondOperand = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(3), [Tuple.Create(0, 1)] = Gf5.CreateElement(4) }, Expected = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.One(), [Tuple.Create(1, 0)] = Gf5.CreateElement(4), [Tuple.Create(0, 1)] = Gf5.CreateElement(3), [Tuple.Create(1, 1)] = Gf5.CreateElement(2) } }, new BinaryOperationTestCase { FirstOperand = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(2), [Tuple.Create(1, 0)] = Gf5.CreateElement(3), [Tuple.Create(0, 1)] = Gf5.CreateElement(4) }, SecondOperand = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(4), [Tuple.Create(1, 0)] = Gf5.One(), [Tuple.Create(0, 1)] = Gf5.CreateElement(2) }, Expected = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(3), [Tuple.Create(1, 0)] = Gf5.CreateElement(4), [Tuple.Create(2, 0)] = Gf5.CreateElement(3), [Tuple.Create(0, 2)] = Gf5.CreateElement(3) } }, new BinaryOperationTestCase { FirstOperand = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(2), [Tuple.Create(1, 0)] = Gf5.CreateElement(3), [Tuple.Create(0, 1)] = Gf5.CreateElement(4) }, SecondOperand = new BiVariablePolynomial(Gf5), Expected = new BiVariablePolynomial(Gf5) } }; var polynomialForMultiplication = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(3), [Tuple.Create(1, 0)] = Gf5.CreateElement(2), [Tuple.Create(0, 1)] = Gf5.CreateElement(4), [Tuple.Create(1, 1)] = Gf5.One() }; MultiplyByFieldElementTestsData = new TheoryData <MultiplicationByFieldElementTestCase> { new MultiplicationByFieldElementTestCase { Polynomial = polynomialForMultiplication, Multiplier = Gf5.Zero(), Expected = new BiVariablePolynomial(Gf5) }, new MultiplicationByFieldElementTestCase { Polynomial = polynomialForMultiplication, Multiplier = Gf5.CreateElement(2), Expected = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.One(), [Tuple.Create(1, 0)] = Gf5.CreateElement(4), [Tuple.Create(0, 1)] = Gf5.CreateElement(3), [Tuple.Create(1, 1)] = Gf5.CreateElement(2) } } }; SubstitutionTestsData = new TheoryData <SubstitutionTestCase> { new SubstitutionTestCase { Polynomial = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.One(), [Tuple.Create(1, 0)] = Gf5.CreateElement(3), [Tuple.Create(0, 1)] = Gf5.CreateElement(2) }, XSubstitution = new BiVariablePolynomial(Gf5) { [Tuple.Create(1, 0)] = Gf5.One() }, YSubstitution = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(3), [Tuple.Create(1, 1)] = Gf5.One() }, Expected = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(2), [Tuple.Create(1, 0)] = Gf5.CreateElement(3), [Tuple.Create(1, 1)] = Gf5.CreateElement(2) } }, new SubstitutionTestCase { Polynomial = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.One(), [Tuple.Create(1, 0)] = Gf5.CreateElement(2), [Tuple.Create(2, 0)] = Gf5.One(), [Tuple.Create(0, 1)] = Gf5.CreateElement(3), [Tuple.Create(1, 1)] = Gf5.One() }, XSubstitution = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.One(), [Tuple.Create(1, 0)] = Gf5.One() }, YSubstitution = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(2), [Tuple.Create(1, 1)] = Gf5.One() }, Expected = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(2), [Tuple.Create(1, 0)] = Gf5.One(), [Tuple.Create(2, 0)] = Gf5.One(), [Tuple.Create(1, 1)] = Gf5.CreateElement(4), [Tuple.Create(2, 1)] = Gf5.One() } }, new SubstitutionTestCase { Polynomial = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.One(), [Tuple.Create(1, 0)] = Gf5.CreateElement(3), [Tuple.Create(0, 1)] = Gf5.CreateElement(2) }, XSubstitution = new BiVariablePolynomial(Gf5), YSubstitution = new BiVariablePolynomial(Gf5), Expected = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.One() } } }; DivideByXDegreeTestsData = new TheoryData <DivideByXDegreeTestCase> { new DivideByXDegreeTestCase { Polynomial = new BiVariablePolynomial(Gf5) { [Tuple.Create(1, 0)] = Gf5.CreateElement(2), [Tuple.Create(2, 0)] = Gf5.One(), [Tuple.Create(1, 1)] = Gf5.CreateElement(3) }, Expected = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(2), [Tuple.Create(1, 0)] = Gf5.One(), [Tuple.Create(0, 1)] = Gf5.CreateElement(3) } }, new DivideByXDegreeTestCase { Polynomial = new BiVariablePolynomial(Gf5) { [Tuple.Create(1, 0)] = Gf5.CreateElement(2), [Tuple.Create(2, 0)] = Gf5.One(), [Tuple.Create(0, 1)] = Gf5.CreateElement(3) }, Expected = new BiVariablePolynomial(Gf5) { [Tuple.Create(1, 0)] = Gf5.CreateElement(2), [Tuple.Create(2, 0)] = Gf5.One(), [Tuple.Create(0, 1)] = Gf5.CreateElement(3) } }, new DivideByXDegreeTestCase { Polynomial = new BiVariablePolynomial(Gf5), Expected = new BiVariablePolynomial(Gf5) } }; EvaluateXTestsData = new TheoryData <PartialEvaluationTestCase> { new PartialEvaluationTestCase { Polynomial = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(3), [Tuple.Create(1, 0)] = Gf5.CreateElement(2), [Tuple.Create(0, 1)] = Gf5.One() }, VariableValue = Gf5.One(), Expected = new Polynomial(Gf5, 0, 1) }, new PartialEvaluationTestCase { Polynomial = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(3), [Tuple.Create(1, 0)] = Gf5.CreateElement(2), [Tuple.Create(1, 1)] = Gf5.One() }, VariableValue = Gf5.Zero(), Expected = new Polynomial(Gf5, 3) }, new PartialEvaluationTestCase { Polynomial = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(2), [Tuple.Create(1, 0)] = Gf5.CreateElement(3), [Tuple.Create(2, 0)] = Gf5.CreateElement(2), [Tuple.Create(0, 1)] = Gf5.One(), [Tuple.Create(1, 1)] = Gf5.One(), [Tuple.Create(0, 2)] = Gf5.One() }, VariableValue = Gf5.CreateElement(3), Expected = new Polynomial(Gf5, 4, 4, 1) } }; EvaluateYTestsData = new TheoryData <PartialEvaluationTestCase> { new PartialEvaluationTestCase { Polynomial = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(3), [Tuple.Create(1, 0)] = Gf5.One(), [Tuple.Create(0, 1)] = Gf5.CreateElement(2) }, VariableValue = Gf5.One(), Expected = new Polynomial(Gf5, 0, 1) }, new PartialEvaluationTestCase { Polynomial = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(3), [Tuple.Create(0, 1)] = Gf5.CreateElement(2), [Tuple.Create(1, 1)] = Gf5.One() }, VariableValue = Gf5.Zero(), Expected = new Polynomial(Gf5, 3) }, new PartialEvaluationTestCase { Polynomial = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(2), [Tuple.Create(1, 0)] = Gf5.CreateElement(3), [Tuple.Create(2, 0)] = Gf5.CreateElement(2), [Tuple.Create(0, 1)] = Gf5.One(), [Tuple.Create(1, 1)] = Gf5.One(), [Tuple.Create(0, 2)] = Gf5.One() }, VariableValue = Gf5.CreateElement(2), Expected = new Polynomial(Gf5, 3, 0, 2) } }; HasseDerivativeCalculationTestsData = new TheoryData <HasseDerivativeCalculationTestCase> { new HasseDerivativeCalculationTestCase { Polynomial = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(2), [Tuple.Create(1, 0)] = Gf5.CreateElement(2), [Tuple.Create(0, 1)] = Gf5.CreateElement(2), [Tuple.Create(2, 0)] = Gf5.One(), [Tuple.Create(0, 2)] = Gf5.One() }, R = 1, S = 1, XValue = Gf5.One(), YValue = Gf5.One(), Expected = Gf5.Zero() }, new HasseDerivativeCalculationTestCase { Polynomial = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(2), [Tuple.Create(1, 0)] = Gf5.CreateElement(2), [Tuple.Create(0, 1)] = Gf5.CreateElement(2), [Tuple.Create(2, 2)] = Gf5.One() }, R = 1, S = 1, XValue = Gf5.One(), YValue = Gf5.One(), Expected = new FieldElement(Gf5, 4) }, new HasseDerivativeCalculationTestCase { Polynomial = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(2), [Tuple.Create(1, 0)] = Gf5.CreateElement(2), [Tuple.Create(0, 1)] = Gf5.CreateElement(2), [Tuple.Create(2, 2)] = Gf5.One() }, R = 2, S = 1, XValue = Gf5.One(), YValue = Gf5.One(), Expected = Gf5.CreateElement(2) } }; }