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;
       }
 }
Beispiel #4
0
        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;
 }