FindAFactor 3.6.6__tar.gz → 3.6.8__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
@@ -189,7 +189,7 @@ inline size_t backward3(const size_t &n) { return (size_t)((~(~n | 1U)) / 3U) +
189
189
  constexpr unsigned char wheel5[8U] = {1U, 7U, 11U, 13U, 17U, 19U, 23U, 29U};
190
190
 
191
191
  // Make this NOT a multiple of 2, 3, or 5.
192
- size_t forward5(const size_t &p) { return wheel5[p % 8U] + (p / 8U) * 30U; }
192
+ size_t forward5(const size_t &p) { return wheel5[p & 7U] + (p >> 3U) * 30U; }
193
193
 
194
194
  size_t backward5(const size_t &n) { return std::distance(wheel5, std::lower_bound(wheel5, wheel5 + 8U, (size_t)(n % 30U))) + 8U * (size_t)(n / 30U) + 1U; }
195
195
 
@@ -486,7 +486,7 @@ inline BigInteger _forward3(const BigInteger &p) { return (p << 1U) + (~(~p | 1U
486
486
 
487
487
  inline BigInteger _backward3(const BigInteger &n) { return ((~(~n | 1U)) / 3U) + 1U; }
488
488
 
489
- BigInteger _forward5(const BigInteger &p) { return wheel5[(size_t)(p % 8U)] + (p / 8U) * 30U; }
489
+ BigInteger _forward5(const BigInteger &p) { return wheel5[(size_t)(p & 7U)] + (p >> 3U) * 30U; }
490
490
 
491
491
  BigInteger _backward5(const BigInteger &n) { return std::distance(wheel5, std::lower_bound(wheel5, wheel5 + 8U, (size_t)(n % 30U))) + 8U * (n / 30U) + 1U; }
492
492
 
@@ -682,7 +682,7 @@ bool isMultiple(const BigInteger &p, const std::vector<size_t> &knownPrimes) {
682
682
 
683
683
  boost::dynamic_bitset<size_t> wheel_inc(std::vector<size_t> primes) {
684
684
  BigInteger radius = 1U;
685
- for (const BigInteger &i : primes) {
685
+ for (const size_t &i : primes) {
686
686
  radius *= i;
687
687
  }
688
688
  const size_t prime = primes.back();
@@ -769,7 +769,6 @@ struct Factorizer {
769
769
  size_t rowOffset;
770
770
  bool isIncomplete;
771
771
  std::vector<size_t> primes;
772
- std::vector<size_t> sqrPrimes;
773
772
  ForwardFn forwardFn;
774
773
  std::vector<BigInteger> smoothNumberKeys;
775
774
  std::vector<boost::dynamic_bitset<size_t>> smoothNumberValues;
@@ -782,7 +781,6 @@ struct Factorizer {
782
781
  for (size_t i = 0U; i < primes.size(); ++i) {
783
782
  const size_t& p = primes[i];
784
783
  wheelRadius *= p;
785
- sqrPrimes.push_back(p * p);
786
784
  smoothNumberKeys.push_back(p);
787
785
  smoothNumberValues.emplace_back(primes.size(), 0);
788
786
  smoothNumberValues.back()[i] = true;
@@ -875,7 +873,7 @@ struct Factorizer {
875
873
  if (num == 1U) {
876
874
  return vec;
877
875
  }
878
- };
876
+ }
879
877
  if (num != 1U) {
880
878
  return boost::dynamic_bitset<size_t>();
881
879
  }
@@ -995,26 +993,24 @@ struct Factorizer {
995
993
  }
996
994
 
997
995
  BigInteger checkPerfectSquare(BigInteger perfectSquare) {
998
- while (perfectSquare < toFactorSqr) {
999
- // Compute x and y
1000
- const BigInteger x = perfectSquare % toFactor;
1001
- const BigInteger y = modExp(x, toFactor >> 1U, toFactor);
1002
-
1003
- // Check congruence of squares
1004
- BigInteger factor = gcd(toFactor, x + y);
1005
- if ((factor != 1U) && (factor != toFactor)) {
1006
- return factor;
1007
- }
996
+ // Compute x and y
997
+ const BigInteger x = perfectSquare % toFactor;
998
+ const BigInteger y = modExp(x, toFactor >> 1U, toFactor);
999
+
1000
+ // Check congruence of squares
1001
+ BigInteger factor = gcd(toFactor, x + y);
1002
+ if ((factor != 1U) && (factor != toFactor)) {
1003
+ return factor;
1004
+ }
1008
1005
 
1009
- if (x != y) {
1010
- // Try x - y as well
1011
- factor = gcd(toFactor, x - y);
1012
- if ((factor != 1U) && (factor != toFactor)) {
1013
- return factor;
1014
- }
1015
- }
1006
+ if (x == y) {
1007
+ return 1U;
1008
+ }
1016
1009
 
1017
- perfectSquare *= sqrPrimes[dis(gen)];
1010
+ // Try x - y as well
1011
+ factor = gcd(toFactor, x - y);
1012
+ if ((factor != 1U) && (factor != toFactor)) {
1013
+ return factor;
1018
1014
  }
1019
1015
 
1020
1016
  return 1U;
@@ -1198,10 +1194,11 @@ std::string find_a_factor(const std::string &toFactorStr, const bool &isConOfSqr
1198
1194
  const size_t maxPrimeCount = std::min(primes.size(), smoothPrimeCount);
1199
1195
  std::vector<size_t> smoothPrimes;
1200
1196
  for (size_t primeId = 0U; (primeId < primes.size()) && (smoothPrimes.size() < maxPrimeCount); ++primeId) {
1201
- const size_t residue = (size_t)(toFactor % primes[primeId]);
1197
+ const size_t p = primes[primeId];
1198
+ const size_t residue = (size_t)(toFactor % p);
1202
1199
  const size_t sr = _sqrt(residue);
1203
1200
  if ((sr * sr) == residue) {
1204
- smoothPrimes.push_back(primes[primeId]);
1201
+ smoothPrimes.push_back(p);
1205
1202
  }
1206
1203
  }
1207
1204
  if (smoothPrimes.size() < maxPrimeCount) {
@@ -1231,8 +1228,6 @@ std::string find_a_factor(const std::string &toFactorStr, const bool &isConOfSqr
1231
1228
 
1232
1229
  // Range per parallel node
1233
1230
  const BigInteger nodeRange = (((backward(SMALLEST_WHEEL)(fullMaxBase) + nodeCount - 1U) / nodeCount) + wheelEntryCount - 1U) / wheelEntryCount;
1234
- // This is used by all threads:
1235
- std::vector<std::vector<BigInteger>> semiSmoothParts(CpuCount);
1236
1231
  // This manages the work of all threads.
1237
1232
  Factorizer worker(toFactor * toFactor, toFactor, fullMaxBase,
1238
1233
  nodeRange, nodeCount, nodeId,
@@ -1269,7 +1264,7 @@ std::string find_a_factor(const std::string &toFactorStr, const bool &isConOfSqr
1269
1264
  return boost::lexical_cast<std::string>(result);
1270
1265
  }
1271
1266
 
1272
- const auto smoothNumberFn = [&inc_seqs, &wheelEntryCount, &semiSmoothParts, &worker, &isGaussElim] (unsigned cpu) {
1267
+ const auto smoothNumberFn = [&inc_seqs, &wheelEntryCount, &batchSizeMultiplier, &worker, &isGaussElim] {
1273
1268
  // inc_seq needs to be independent per thread.
1274
1269
  std::vector<boost::dynamic_bitset<size_t>> inc_seqs_clone;
1275
1270
  inc_seqs_clone.reserve(inc_seqs.size());
@@ -1278,10 +1273,11 @@ std::string find_a_factor(const std::string &toFactorStr, const bool &isConOfSqr
1278
1273
  }
1279
1274
 
1280
1275
  // Different collections per thread;
1281
- semiSmoothParts.reserve(wheelEntryCount << 1U);
1276
+ std::vector<BigInteger> semiSmoothParts;
1277
+ semiSmoothParts.reserve((size_t)((wheelEntryCount << 1U) * batchSizeMultiplier));
1282
1278
 
1283
1279
  // While brute-forcing, use the "exhaust" to feed "smooth" number generation and check conguence of squares.
1284
- return worker.smoothCongruences(&inc_seqs_clone, &(semiSmoothParts[cpu]), isGaussElim);
1280
+ return worker.smoothCongruences(&inc_seqs_clone, &semiSmoothParts, isGaussElim);
1285
1281
  };
1286
1282
 
1287
1283
  std::vector<std::future<BigInteger>> futures;
@@ -1289,7 +1285,7 @@ std::string find_a_factor(const std::string &toFactorStr, const bool &isConOfSqr
1289
1285
 
1290
1286
  do {
1291
1287
  for (unsigned cpu = 0U; cpu < CpuCount; ++cpu) {
1292
- futures.push_back(std::async(std::launch::async, smoothNumberFn, cpu));
1288
+ futures.push_back(std::async(std::launch::async, smoothNumberFn));
1293
1289
  }
1294
1290
 
1295
1291
  for (unsigned cpu = 0U; cpu < futures.size(); ++cpu) {
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: FindAFactor
3
- Version: 3.6.6
3
+ Version: 3.6.8
4
4
  Summary: Find any nontrivial factor of a number
5
5
  Home-page: https://github.com/vm6502q/FindAFactor
6
6
  Author: Dan Strano
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: FindAFactor
3
- Version: 3.6.6
3
+ Version: 3.6.8
4
4
  Summary: Find any nontrivial factor of a number
5
5
  Home-page: https://github.com/vm6502q/FindAFactor
6
6
  Author: Dan Strano
@@ -26,7 +26,7 @@ ext_modules = [
26
26
 
27
27
  setup(
28
28
  name='FindAFactor',
29
- version='3.6.6',
29
+ version='3.6.8',
30
30
  author='Dan Strano',
31
31
  author_email='dan@unitary.fund',
32
32
  description='Find any nontrivial factor of a number',
File without changes
File without changes
File without changes