internal void MakeBaseNumbers() { try { MakeYBaseToPrimesArray(); if( Worker.CancellationPending ) return; Integer YTop = new Integer(); Integer Y = new Integer(); Integer XSquared = new Integer(); Integer Test = new Integer(); YTop.SetToZero(); uint XSquaredBitLength = 1; ExponentVectorNumber ExpNumber = new ExponentVectorNumber( IntMath ); uint Loops = 0; uint BSmoothCount = 0; uint BSmoothTestsCount = 0; uint IncrementYBy = 0; while( true ) { if( Worker.CancellationPending ) return; Loops++; if( (Loops & 0xF) == 0 ) { Worker.ReportProgress( 0, " " ); Worker.ReportProgress( 0, "Loops: " + Loops.ToString( "N0" )); Worker.ReportProgress( 0, "BSmoothCount: " + BSmoothCount.ToString( "N0" )); Worker.ReportProgress( 0, "BSmoothTestsCount: " + BSmoothTestsCount.ToString( "N0" )); if( BSmoothTestsCount != 0 ) { double TestsRatio = (double)BSmoothCount / (double)BSmoothTestsCount; Worker.ReportProgress( 0, "TestsRatio: " + TestsRatio.ToString( "N3" )); } } /* if( (Loops & 0xFFFFF) == 0 ) { // Use Task Manager to tweak the CPU Utilization if you want // it be below 100 percent. Thread.Sleep( 1 ); } */ // About 98 percent of the time it is running IncrementBy(). IncrementYBy += IncrementConst; uint BitLength = IncrementBy(); const uint SomeOptimumBitLength = 2; if( BitLength < SomeOptimumBitLength ) continue; // This BitLength has to do with how many small factors you want // in the number. But it doesn't limit your factor base at all. // You can still have any size prime in your factor base (up to // IntegerMath.PrimeArrayLength). Compare the size of // YBaseToPrimesArrayLast to IntegerMath.PrimeArrayLength. BSmoothTestsCount++; YTop.AddULong( IncrementYBy ); IncrementYBy = 0; Y.Copy( ProductSqrRoot ); Y.Add( YTop ); XSquared.Copy( Y ); IntMath.DoSquare( XSquared ); if( XSquared.ParamIsGreater( Product )) throw( new Exception( "Bug. XSquared.ParamIsGreater( Product )." )); IntMath.Subtract( XSquared, Product ); XSquaredBitLength = (uint)(XSquared.GetIndex() * 32); uint TopDigit = (uint)XSquared.GetD( XSquared.GetIndex()); uint TopLength = GetBitLength( TopDigit ); XSquaredBitLength += TopLength; if( XSquaredBitLength == 0 ) XSquaredBitLength = 1; // if( ItIsTheAnswerAlready( XSquared )) It's too unlikely. // QuadResCombinatorics could run in parallel to check for that, // and it would be way ahead of this. GetOneMainFactor(); if( OneMainFactor.IsEqual( XSquared )) { MakeFastExpNumber( ExpNumber ); } else { if( OneMainFactor.IsZero()) throw( new Exception( "OneMainFactor.IsZero()." )); IntMath.Divide( XSquared, OneMainFactor, Quotient, Remainder ); ExpNumber.SetFromTraditionalInteger( Quotient ); ExpNumber.Multiply( ExpOneMainFactor ); ExpNumber.GetTraditionalInteger( Test ); if( !Test.IsEqual( XSquared )) throw( new Exception( "!Test.IsEqual( XSquared )." )); } if( ExpNumber.IsBSmooth()) { BSmoothCount++; string DelimS = IntMath.ToString10( Y ) + "\t" + ExpNumber.ToDelimString(); Worker.ReportProgress( 1, DelimS ); if( (BSmoothCount & 0x3F) == 0 ) { Worker.ReportProgress( 0, " " ); Worker.ReportProgress( 0, "BitLength: " + BitLength.ToString()); Worker.ReportProgress( 0, "XSquaredBitLength: " + XSquaredBitLength.ToString()); Worker.ReportProgress( 0, ExpNumber.ToString() ); // What should BSmoothLimit be? // (Since FactorDictionary.cs will reduce the final factor base.) if( BSmoothCount > BSmoothLimit ) { Worker.ReportProgress( 0, "Found enough to make the matrix." ); Worker.ReportProgress( 0, "BSmoothCount: " + BSmoothCount.ToString( "N0" )); Worker.ReportProgress( 0, "BSmoothLimit: " + BSmoothLimit.ToString( "N0" )); Worker.ReportProgress( 0, "Seconds: " + StartTime.GetSecondsToNow().ToString( "N1" )); double Seconds = StartTime.GetSecondsToNow(); int Minutes = (int)Seconds / 60; int Hours = Minutes / 60; Minutes = Minutes % 60; Seconds = Seconds % 60; string ShowS = "Hours: " + Hours.ToString( "N0" ) + " Minutes: " + Minutes.ToString( "N0" ) + " Seconds: " + Seconds.ToString( "N0" ); Worker.ReportProgress( 0, ShowS ); return; } } } } } catch( Exception Except ) { throw( new Exception( "Exception in MakeBaseNumbers():\r\n" + Except.Message )); } }
private bool GetFactors( Integer Y, ExponentVectorNumber XExp ) { Integer XRoot = new Integer(); Integer X = new Integer(); Integer XwithY = new Integer(); Integer Gcd = new Integer(); XExp.GetTraditionalInteger( X ); if( !IntMath.SquareRoot( X, XRoot )) throw( new Exception( "Bug. X should have an exact square root." )); XwithY.Copy( Y ); XwithY.Add( XRoot ); IntMath.GreatestCommonDivisor( Product, XwithY, Gcd ); if( !Gcd.IsOne()) { if( !Gcd.IsEqual( Product )) { SolutionP.Copy( Gcd ); IntMath.Divide( Product, SolutionP, Quotient, Remainder ); if( !Remainder.IsZero()) throw( new Exception( "The Remainder with SolutionP can't be zero." )); SolutionQ.Copy( Quotient ); MForm.ShowStatus( "SolutionP: " + IntMath.ToString10( SolutionP )); MForm.ShowStatus( "SolutionQ: " + IntMath.ToString10( SolutionQ )); return true; } else { MForm.ShowStatus( "GCD was Product." ); } } else { MForm.ShowStatus( "GCD was one." ); } MForm.ShowStatus( "XRoot: " + IntMath.ToString10( XRoot )); MForm.ShowStatus( "Y: " + IntMath.ToString10( Y )); XwithY.Copy( Y ); if( Y.ParamIsGreater( XRoot )) throw( new Exception( "This can't be right. XRoot is bigger than Y." )); IntMath.Subtract( Y, XRoot ); IntMath.GreatestCommonDivisor( Product, XwithY, Gcd ); if( !Gcd.IsOne()) { if( !Gcd.IsEqual( Product )) { SolutionP.Copy( Gcd ); IntMath.Divide( Product, SolutionP, Quotient, Remainder ); if( !Remainder.IsZero()) throw( new Exception( "The Remainder with SolutionP can't be zero." )); SolutionQ.Copy( Quotient ); MForm.ShowStatus( "SolutionP: " + IntMath.ToString10( SolutionP )); MForm.ShowStatus( "SolutionQ: " + IntMath.ToString10( SolutionQ )); return true; } else { MForm.ShowStatus( "GCD was Product." ); } } else { MForm.ShowStatus( "GCD was one." ); } return false; }