protected static bool[] GetVector(CountDictionary primeFactorizationDict, BigInteger maxValue) { int primeIndex = PrimeFactory.GetIndexFromValue(maxValue); bool[] result = new bool[primeIndex]; if (primeFactorizationDict.Any()) { foreach (KeyValuePair <BigInteger, BigInteger> kvp in primeFactorizationDict) { if (kvp.Key > maxValue) { continue; } if (kvp.Key == -1) { continue; } if (kvp.Value % 2 == 0) { continue; } int index = PrimeFactory.GetIndexFromValue(kvp.Key); result[index] = true; } } return(result); }
private void PrintCurrentCounts() { int smoothRelation_CurrentTarget = _gnfs.CurrentRelationsProgress.SmoothRelations_TargetQuantity; int smoothRelations_CurrentCount = _gnfs.CurrentRelationsProgress.SmoothRelations.Count; int smoothRelation_SavedCounter = _gnfs.CurrentRelationsProgress.SmoothRelationsCounter; BigInteger rationalBase_Max = _gnfs.PrimeFactorBase.RationalFactorBaseMax; BigInteger algebraicBase_Max = _gnfs.PrimeFactorBase.AlgebraicFactorBaseMax; BigInteger quadraticBase_Max = _gnfs.PrimeFactorBase.QuadraticFactorBaseMax; int rationalBase_Size = PrimeFactory.GetIndexFromValue(rationalBase_Max); int algebraicBase_Size = PrimeFactory.GetIndexFromValue(algebraicBase_Max); int quadraticBase_Size = PrimeFactory.GetIndexFromValue(quadraticBase_Max); int rationalFactorPair_Count = _gnfs.RationalFactorPairCollection.Count; int algebraicFactorPair_Count = _gnfs.AlgebraicFactorPairCollection.Count; int quadraticFactorPair_Count = _gnfs.QuadraticFactorPairCollection.Count; int smoothRelation_RequiredBeforeMatrixStep = _gnfs.CurrentRelationsProgress.SmoothRelationsRequiredForMatrixStep; Logging.LogMessage(); Logging.LogMessage($"Required smooth relations found before beginning matrix step: {smoothRelation_RequiredBeforeMatrixStep}"); Logging.LogMessage($"Smooth relations target value: {smoothRelation_CurrentTarget}"); Logging.LogMessage(); Logging.LogMessage($"Smooth relations currently loaded count: {smoothRelations_CurrentCount}"); Logging.LogMessage($"Smooth relations saved counter: {smoothRelation_SavedCounter}"); Logging.LogMessage(); Logging.LogMessage($"quadraticFactorPair_Count: {quadraticFactorPair_Count}"); Logging.LogMessage($"PrimeIndxOf(quadraticBase_Max): {PrimeFactory.GetIndexFromValue(quadraticBase_Max)}"); Logging.LogMessage(); }
public GaussianMatrix(GNFS gnfs, List <Relation> rels) { _gnfs = gnfs; relationMatrixTuple = new List <Tuple <Relation, bool[]> >(); eliminationStep = false; freeCols = new bool[0]; M = new List <bool[]>(); int maxRelationsToSelect = PrimeFactory.GetIndexFromValue(_gnfs.PrimeFactorBase.RationalFactorBaseMax) + PrimeFactory.GetIndexFromValue(_gnfs.PrimeFactorBase.AlgebraicFactorBaseMax) + _gnfs.QuadraticFactorPairCollection.Count + 3; relations = rels; List <GaussianRow> relationsAsRows = new List <GaussianRow>(); foreach (Relation rel in relations) { GaussianRow row = new GaussianRow(_gnfs, rel); relationsAsRows.Add(row); } //List<GaussianRow> orderedRows = relationsAsRows.OrderBy(row1 => row1.LastIndexOfAlgebraic).ThenBy(row2 => row2.LastIndexOfQuadratic).ToList(); List <GaussianRow> selectedRows = relationsAsRows.Take(maxRelationsToSelect).ToList(); int maxIndexRat = selectedRows.Select(row => row.LastIndexOfRational).Max(); int maxIndexAlg = selectedRows.Select(row => row.LastIndexOfAlgebraic).Max(); int maxIndexQua = selectedRows.Select(row => row.LastIndexOfQuadratic).Max(); foreach (GaussianRow row in selectedRows) { row.ResizeRationalPart(maxIndexRat); row.ResizeAlgebraicPart(maxIndexAlg); row.ResizeQuadraticPart(maxIndexQua); } GaussianRow exampleRow = selectedRows.First(); int newLength = exampleRow.GetBoolArray().Length; newLength++; selectedRows = selectedRows.Take(newLength).ToList(); foreach (GaussianRow row in selectedRows) { relationMatrixTuple.Add(new Tuple <Relation, bool[]>(row.SourceRelation, row.GetBoolArray())); } }
public static void GaussianSolve(CancellationToken cancelToken, GNFS gnfs) { Serialization.Save.Relations.Smooth.Append(gnfs); // Persist any relations not already persisted to disk // Because some operations clear this collection after persisting unsaved relations (to keep memory usage light)... // We completely reload the entire relations collection from disk. // This ensure that all the smooth relations are available for the matrix solving step. Serialization.Load.Relations.Smooth(ref gnfs); List <Relation> smoothRelations = gnfs.CurrentRelationsProgress.SmoothRelations.ToList(); int smoothCount = smoothRelations.Count; int maxRelationsToSelect = PrimeFactory.GetIndexFromValue(gnfs.PrimeFactorBase.RationalFactorBaseMax) + PrimeFactory.GetIndexFromValue(gnfs.PrimeFactorBase.AlgebraicFactorBaseMax) + gnfs.QuadraticFactorPairCollection.Count + 3; gnfs.LogFunction($"Total relations: {smoothCount}"); gnfs.LogFunction($"MaxRelationsToSelect: {maxRelationsToSelect}"); gnfs.LogFunction($"Total / Max = {smoothCount / maxRelationsToSelect}"); while (smoothRelations.Count >= maxRelationsToSelect) { // Randomly select n relations from smoothRelations List <Relation> selectedRelations = new List <Relation>(); while ( selectedRelations.Count < maxRelationsToSelect || selectedRelations.Count % 2 != 0 // Force number of relations to be even ) { int randomIndex = StaticRandom.Next(0, smoothRelations.Count); selectedRelations.Add(smoothRelations[randomIndex]); smoothRelations.RemoveAt(randomIndex); } GaussianMatrix gaussianReduction = new GaussianMatrix(gnfs, selectedRelations); gaussianReduction.TransposeAppend(); gaussianReduction.Elimination(); int number = 1; int solutionCount = gaussianReduction.FreeVariables.Count(b => b) - 1; List <List <Relation> > solution = new List <List <Relation> >(); while (number <= solutionCount) { List <Relation> relations = gaussianReduction.GetSolutionSet(number); number++; BigInteger algebraic = relations.Select(rel => rel.AlgebraicNorm).Product(); BigInteger rational = relations.Select(rel => rel.RationalNorm).Product(); CountDictionary algCountDict = new CountDictionary(); foreach (var rel in relations) { algCountDict.Combine(rel.AlgebraicFactorization); } bool isAlgebraicSquare = algebraic.IsSquare(); bool isRationalSquare = rational.IsSquare(); gnfs.LogFunction("---"); gnfs.LogFunction($"Relations count: {relations.Count}"); gnfs.LogFunction($"(a,b) pairs: {string.Join(" ", relations.Select(rel => $"({rel.A},{rel.B})"))}"); gnfs.LogFunction($"Rational ∏(a+mb): IsSquare? {isRationalSquare} : {rational}"); gnfs.LogFunction($"Algebraic ∏ƒ(a/b): IsSquare? {isAlgebraicSquare} : {algebraic}"); gnfs.LogFunction($"Algebraic (factorization): {algCountDict.FormatStringAsFactorization()}"); if (isAlgebraicSquare && isRationalSquare) { solution.Add(relations); gnfs.CurrentRelationsProgress.AddFreeRelationSolution(relations); } if (cancelToken.IsCancellationRequested) { break; } } if (cancelToken.IsCancellationRequested) { break; } } }