public void CalculateNormMethodTest() { // N(-8+3x) in Z[x]/(x^3+15x^2+29x+8) var polynomial = new Polynomial(new BigInteger[] { 8, 29, 15, 1 }); var normCalculator = new FirstDegreeElementsNormCalculator(polynomial, 3); var actual = normCalculator.CalculateNorm(-8); var expected = -5696; Assert.AreEqual(expected, actual); }
void InitSieve(BigInteger[] rationalElements, BigInteger[] norms, BigInteger b, SieveOptions options) { var a = options.LowerBound; var normCalculator = new FirstDegreeElementsNormCalculator(options.Polynomial, b); for (var i = 0; i < rationalElements.Length; i++) { rationalElements[i] = a + b * options.IntegerRoot; norms[i] = normCalculator.CalculateNorm(a); a++; } }
public List <Pair> Sieve(long pairsCount, SieveOptions options) { var result = new List <Pair>(); var intervalLength = (int)(options.UpperBound - options.LowerBound); var fudge = 0.7; var smoothTester = new SmoothTester(); for (int b = 1; true; b++) { var norm = new FirstDegreeElementsNormCalculator(options.Polynomial, b); var rationalSmoothBound = fudge * BigInteger.Log(b * options.IntegerRoot); var rationalElements = new double[intervalLength]; var algebraicElements = new double[intervalLength]; RationalSieve(rationalElements, b, options); AlgebraicSieve(algebraicElements, b, options); if (b % 2 == 0) { for (int i = (options.LowerBound % 2 == 0?1:0); i < intervalLength; i += 2) { if (rationalElements[i] >= rationalSmoothBound) { var firstComponent = options.LowerBound + i; var secondComponent = b; var algebraicSmoothBound = fudge * BigInteger.Log(BigInteger.Abs(norm.CalculateNorm(firstComponent))); if (algebraicElements[i] >= algebraicSmoothBound) { if (BigInteger.GreatestCommonDivisor(firstComponent, secondComponent) != 1) { continue; } if (smoothTester.IsSmoothOverRationalFactorbase(firstComponent, secondComponent, options.IntegerRoot, options.RationalFactorbase)) { if (smoothTester.IsSmoothOverAlgebraicFactorbase(firstComponent, secondComponent, options.Polynomial, options.AlgebraicFactorbase)) { result.Add(new Pair(firstComponent, secondComponent)); } } } } } } else { for (int i = 0; i < intervalLength; i++) { if (rationalElements[i] >= rationalSmoothBound) { var firstComponent = options.LowerBound + i; var secondComponent = b; var algebraicSmoothBound = fudge * BigInteger.Log(BigInteger.Abs(norm.CalculateNorm(firstComponent))); if (algebraicElements[i] >= algebraicSmoothBound) { if (BigInteger.GreatestCommonDivisor(firstComponent, secondComponent) != 1) { continue; } if (smoothTester.IsSmoothOverRationalFactorbase(firstComponent, secondComponent, options.IntegerRoot, options.RationalFactorbase)) { if (smoothTester.IsSmoothOverAlgebraicFactorbase(firstComponent, secondComponent, options.Polynomial, options.AlgebraicFactorbase)) { result.Add(new Pair(firstComponent, secondComponent)); } } } } } } Console.Write("\r{0}/{1} [b={2}] ", result.Count, pairsCount, b); if (result.Count >= pairsCount) { break; } } Console.WriteLine(); Console.WriteLine(); return(result); }