public static IEnumerator<BigInteger> Create(IPrimes primes) { for (int index = 0; true; ++index) { yield return primes[index]; } }
/// <summary> /// Factorise a number by trial division /// </summary> /// <param name="primes">prime number generator</param> /// <param name="n">number to factorise</param> public PrimeFactorisation(IPrimes primes, BigInteger n) { FactorsAndPowers = new List<FactorAndPower>(); IEnumerator<BigInteger> e = PrimesEnumerator.Create(primes); e.MoveNext(); var currentPrimeCandidate = e.Current; var residue = n; BigInteger factorToSave = -1; int powerToSave = 0; while(residue > 1) { // Look for a prime divisor BigInteger primeDivisor = 0; if (residue % currentPrimeCandidate == 0) { primeDivisor = currentPrimeCandidate; } else if (currentPrimeCandidate * currentPrimeCandidate > residue) { primeDivisor = residue; } else { // get the next prime to try e.MoveNext(); currentPrimeCandidate = e.Current; continue; } // Divisor found: update data // See if it's a new prime if (primeDivisor != factorToSave) { // New prime: write the term for any previous prime out and start again if (factorToSave > 0) { FactorsAndPowers.Add(new FactorAndPower(factor: factorToSave, power: powerToSave)); } factorToSave = primeDivisor; powerToSave = 1; } else { powerToSave++; // same as last prime: keep track of powers } residue /= primeDivisor; } // while: residue > 1 (we still have factoring to do) // We are at the end so write final term out FactorsAndPowers.Add(new FactorAndPower(factor: factorToSave, power: powerToSave)); }
public AliquotChainLink(IPrimes p, BigInteger n) { Current = n; try { Factorisation = new PrimeFactorisation(p, Current); Successor = Factorisation.SumAllProperDivisors(); } catch(Exception e) { Exception = e; } }
static void Test(IPrimes primeFinder) { var count = 1000000000; Stopwatch sw = Stopwatch.StartNew(); var primes = primeFinder.Primes(count); sw.Stop(); //Debug.WriteLine(String.Join(",", primes)); #if DEBUG //Debug.WriteLine(string.Join(",", primes)); Debug.WriteLine("Time used for {2} by {1} (rounded): {0}ms", sw.ElapsedMilliseconds, primeFinder.GetType().Name, count); #endif Console.WriteLine("Time used for {2} by {1} (rounded): {0}ms", sw.ElapsedMilliseconds, primeFinder.GetType().Name, count); }
public void Setup() { _primes = new Primes(); }
public static AliquotDatabase Create( IPrimes p, int dbLimit, Progress<ProgressEventArgs> progressIndicator = null, CancellationToken? maybeCancellationToken = null) { var creationProperties = new Dictionary<string, string>(); creationProperties["Create.ChainStartLimit"] = dbLimit.ToString(); BigInteger upperLimit = BigInteger.Parse("1000000000000000"); // 10^15 Utilities.LogLine("AliquotDatabase: Create to {0}, Successor Limit {1} ({2} digits)", dbLimit, upperLimit, upperLimit.ToString().Length); creationProperties["Create.UpperLimit"] = upperLimit.ToString(); var links = new Dictionary<BigInteger, AliquotChainLink>(); DateTime dtStart = DateTime.UtcNow; int progress = 0; // Set up a parallel run across the collection var range = Enumerable.Range(1, dbLimit); var parOpts = new ParallelOptions(); parOpts.CancellationToken = maybeCancellationToken.Value; // We *could* set this, but really .NET should be able to figure it out! // parOpts.MaxDegreeOfParallelism = System.Environment.ProcessorCount; Parallel.ForEach(range, (i) => { // Build the chain onwards from this number BigInteger n = i; while (n > 1 && n < upperLimit) { // Get the new link var s = new AliquotChainLink(p, n); // Abandon if we would go above the limit if (s.Successor > upperLimit) { break; } // Synchronize on the links collection since this is in parallel lock(links) { // We exit if we are joining an existing chain if (links.ContainsKey(n)) { break; } // It's a new link - add it to the database links[n] = s; } // Go to next element in chain n = s.Successor; } // Indicate progress int newProgress = (int)(100.0 * i / dbLimit); if (newProgress > progress) { if(maybeCancellationToken.HasValue) { maybeCancellationToken.Value.ThrowIfCancellationRequested(); } double s = (DateTime.UtcNow - dtStart).TotalSeconds; double expected = s * (dbLimit - i) / i; ProgressEventArgs.RaiseEvent(progressIndicator, newProgress, "ADB: i {0} Time Used (min) {1:N} Estimated time Left (min) {2:N}".FormatWith(i, s / 60.0, expected / 60.0)); progress = newProgress; } } ); creationProperties["Create.FinishTimeUtc"] = DateTime.UtcNow.ToString(); creationProperties["Create.Seconds"] = (DateTime.UtcNow - dtStart).TotalSeconds.ToString("N2"); return new AliquotDatabase(links, creationProperties); }
public HomeController(INumberListMultiplier numberListMultiplier, IPrimes primes) { _numberListMultiplier = numberListMultiplier; _primes = primes; }