Пример #1
0
        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);
        }
Пример #2
0
        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();
        }
Пример #3
0
        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()));
            }
        }
Пример #4
0
        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;
                }
            }
        }