FindAFactor 3.6.4__tar.gz → 3.6.6__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
@@ -149,33 +149,58 @@ BigInteger sqrt(const BigInteger &toTest) {
149
149
  return ans;
150
150
  }
151
151
 
152
+ size_t _sqrt(const size_t &toTest) {
153
+ // Otherwise, find b = sqrt(b^2).
154
+ size_t start = 1U, end = toTest >> 1U, ans = 0U;
155
+ do {
156
+ const size_t mid = (start + end) >> 1U;
157
+
158
+ // If toTest is a perfect square
159
+ const size_t sqr = mid * mid;
160
+ if (sqr == toTest) {
161
+ return mid;
162
+ }
163
+
164
+ if (sqr < toTest) {
165
+ // Since we need floor, we update answer when mid*mid is smaller than p, and move closer to sqrt(p).
166
+ start = mid + 1U;
167
+ ans = mid;
168
+ } else {
169
+ // If mid*mid is greater than p
170
+ end = mid - 1U;
171
+ }
172
+ } while (start <= end);
173
+
174
+ return ans;
175
+ }
176
+
152
177
  // We are multiplying out the first distinct primes, below.
153
178
 
154
179
  // Make this NOT a multiple of 2.
155
- inline BigInteger forward2(const size_t &p) { return (p << 1U) | 1U; }
180
+ inline size_t forward2(const size_t &p) { return (p << 1U) | 1U; }
156
181
 
157
- inline size_t backward2(const BigInteger &p) { return (size_t)(p >> 1U); }
182
+ inline size_t backward2(const size_t &p) { return (size_t)(p >> 1U); }
158
183
 
159
184
  // Make this NOT a multiple of 2 or 3.
160
- inline BigInteger forward3(const size_t &p) { return (p << 1U) + (~(~p | 1U)) - 1U; }
185
+ inline size_t forward3(const size_t &p) { return (p << 1U) + (~(~p | 1U)) - 1U; }
161
186
 
162
- inline size_t backward3(const BigInteger &n) { return (size_t)((~(~n | 1U)) / 3U) + 1U; }
187
+ inline size_t backward3(const size_t &n) { return (size_t)((~(~n | 1U)) / 3U) + 1U; }
163
188
 
164
189
  constexpr unsigned char wheel5[8U] = {1U, 7U, 11U, 13U, 17U, 19U, 23U, 29U};
165
190
 
166
191
  // Make this NOT a multiple of 2, 3, or 5.
167
- BigInteger forward5(const size_t &p) { return wheel5[p % 8U] + (p / 8U) * 30U; }
192
+ size_t forward5(const size_t &p) { return wheel5[p % 8U] + (p / 8U) * 30U; }
168
193
 
169
- size_t backward5(const BigInteger &n) { return std::distance(wheel5, std::lower_bound(wheel5, wheel5 + 8U, (size_t)(n % 30U))) + 8U * (size_t)(n / 30U) + 1U; }
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; }
170
195
 
171
196
  constexpr unsigned char wheel7[48U] = {1U, 11U, 13U, 17U, 19U, 23U, 29U, 31U, 37U, 41U, 43U, 47U, 53U, 59U, 61U, 67U,
172
197
  71U, 73U, 79U, 83U, 89U, 97U, 101U, 103U, 107U, 109U, 113U, 121U, 127U, 131U, 137U, 139U,
173
198
  143U, 149U, 151U, 157U, 163U, 167U, 169U, 173U, 179U, 181U, 187U, 191U, 193U, 197U, 199U, 209U};
174
199
 
175
200
  // Make this NOT a multiple of 2, 3, 5, or 7.
176
- BigInteger forward7(const size_t &p) { return wheel7[p % 48U] + (p / 48U) * 210U; }
201
+ size_t forward7(const size_t &p) { return wheel7[p % 48U] + (p / 48U) * 210U; }
177
202
 
178
- size_t backward7(const BigInteger &n) { return std::distance(wheel7, std::lower_bound(wheel7, wheel7 + 48U, (size_t)(n % 210U))) + 48U * (size_t)(n / 210U) + 1U; }
203
+ size_t backward7(const size_t &n) { return std::distance(wheel7, std::lower_bound(wheel7, wheel7 + 48U, (size_t)(n % 210U))) + 48U * (size_t)(n / 210U) + 1U; }
179
204
 
180
205
  constexpr unsigned short wheel11[480U] = {
181
206
  1U, 13U, 17U, 19U, 23U, 29U, 31U, 37U, 41U, 43U, 47U, 53U, 59U, 61U, 67U, 71U, 73U, 79U, 83U, 89U, 97U, 101U, 103U, 107U,
@@ -200,9 +225,9 @@ constexpr unsigned short wheel11[480U] = {
200
225
  2203U, 2207U, 2209U, 2213U, 2221U, 2227U, 2231U, 2237U, 2239U, 2243U, 2249U, 2251U, 2257U, 2263U, 2267U, 2269U, 2273U, 2279U, 2281U, 2287U, 2291U, 2293U, 2297U, 2309U};
201
226
 
202
227
  // Make this NOT a multiple of 2, 3, 5, 7, or 11.
203
- BigInteger forward11(const size_t &p) { return wheel11[p % 480U] + (p / 480U) * 2310U; }
228
+ size_t forward11(const size_t &p) { return wheel11[p % 480U] + (p / 480U) * 2310U; }
204
229
 
205
- size_t backward11(const BigInteger &n) { return std::distance(wheel11, std::lower_bound(wheel11, wheel11 + 480U, (size_t)(n % 2310U))) + 480U * (size_t)(n / 2310U) + 1U; }
230
+ size_t backward11(const size_t &n) { return std::distance(wheel11, std::lower_bound(wheel11, wheel11 + 480U, (size_t)(n % 2310U))) + 480U * (size_t)(n / 2310U) + 1U; }
206
231
 
207
232
  constexpr unsigned short wheel13[5760U] =
208
233
  {
@@ -449,9 +474,9 @@ constexpr unsigned short wheel13[5760U] =
449
474
  };
450
475
 
451
476
  // Make this NOT a multiple of 2, 3, 5, 7, 11, or 13.
452
- BigInteger forward13(const size_t &p) { return wheel13[p % 5760U] + (p / 5760U) * 30030U; }
477
+ size_t forward13(const size_t &p) { return wheel13[p % 5760U] + (p / 5760U) * 30030U; }
453
478
 
454
- size_t backward13(const BigInteger &n) { return std::distance(wheel13, std::lower_bound(wheel13, wheel13 + 5760U, (size_t)(n % 30030U))) + 5760U * (size_t)(n / 30030U) + 1U; }
479
+ size_t backward13(const size_t &n) { return std::distance(wheel13, std::lower_bound(wheel13, wheel13 + 5760U, (size_t)(n % 30030U))) + 5760U * (size_t)(n / 30030U) + 1U; }
455
480
 
456
481
  inline BigInteger _forward2(const BigInteger &p) { return (p << 1U) | 1U; }
457
482
 
@@ -543,15 +568,15 @@ inline size_t GetWheel5and7Increment(unsigned short &wheel5, unsigned long long
543
568
  return wheelIncrement;
544
569
  }
545
570
 
546
- std::vector<BigInteger> SieveOfEratosthenes(const BigInteger &n) {
547
- std::vector<BigInteger> knownPrimes = {2U, 3U, 5U, 7U};
571
+ std::vector<size_t> SieveOfEratosthenes(const size_t &n) {
572
+ std::vector<size_t> knownPrimes = {2U, 3U, 5U, 7U};
548
573
  if (n < 2U) {
549
- return std::vector<BigInteger>();
574
+ return std::vector<size_t>();
550
575
  }
551
576
 
552
577
  if (n < (knownPrimes.back() + 2U)) {
553
578
  const auto highestPrimeIt = std::upper_bound(knownPrimes.begin(), knownPrimes.end(), n);
554
- return std::vector<BigInteger>(knownPrimes.begin(), highestPrimeIt);
579
+ return std::vector<size_t>(knownPrimes.begin(), highestPrimeIt);
555
580
  }
556
581
 
557
582
  knownPrimes.reserve((size_t)(((double)n) / log((double)n)));
@@ -576,7 +601,7 @@ std::vector<BigInteger> SieveOfEratosthenes(const BigInteger &n) {
576
601
  for (;;) {
577
602
  o += GetWheel5and7Increment(wheel5, wheel7);
578
603
 
579
- const BigInteger p = forward3(o);
604
+ const size_t p = forward3(o);
580
605
  if ((p * p) > n) {
581
606
  break;
582
607
  }
@@ -590,9 +615,9 @@ std::vector<BigInteger> SieveOfEratosthenes(const BigInteger &n) {
590
615
  // We are skipping multiples of 2, 3, and 5
591
616
  // for space complexity, for 4/15 the bits.
592
617
  // More are skipped by the wheel for time.
593
- const BigInteger p2 = p << 1U;
594
- const BigInteger p4 = p << 2U;
595
- BigInteger i = p * p;
618
+ const size_t p2 = p << 1U;
619
+ const size_t p4 = p << 2U;
620
+ size_t i = p * p;
596
621
 
597
622
  // "p" already definitely not a multiple of 3.
598
623
  // Its remainder when divided by 3 can be 1 or 2.
@@ -628,7 +653,7 @@ std::vector<BigInteger> SieveOfEratosthenes(const BigInteger &n) {
628
653
  }
629
654
 
630
655
  for (;;) {
631
- const BigInteger p = forward3(o);
656
+ const size_t p = forward3(o);
632
657
  if (p > n) {
633
658
  break;
634
659
  }
@@ -645,8 +670,8 @@ std::vector<BigInteger> SieveOfEratosthenes(const BigInteger &n) {
645
670
  return knownPrimes;
646
671
  }
647
672
 
648
- bool isMultiple(const BigInteger &p, const std::vector<BigInteger> &knownPrimes) {
649
- for (const BigInteger &prime : knownPrimes) {
673
+ bool isMultiple(const BigInteger &p, const std::vector<size_t> &knownPrimes) {
674
+ for (const size_t &prime : knownPrimes) {
650
675
  if (!(p % prime)) {
651
676
  return true;
652
677
  }
@@ -655,12 +680,12 @@ bool isMultiple(const BigInteger &p, const std::vector<BigInteger> &knownPrimes)
655
680
  return false;
656
681
  }
657
682
 
658
- boost::dynamic_bitset<size_t> wheel_inc(std::vector<BigInteger> primes) {
683
+ boost::dynamic_bitset<size_t> wheel_inc(std::vector<size_t> primes) {
659
684
  BigInteger radius = 1U;
660
685
  for (const BigInteger &i : primes) {
661
686
  radius *= i;
662
687
  }
663
- const BigInteger prime = primes.back();
688
+ const size_t prime = primes.back();
664
689
  primes.pop_back();
665
690
  boost::dynamic_bitset<size_t> o;
666
691
  for (BigInteger i = 1U; i <= radius; ++i) {
@@ -673,10 +698,10 @@ boost::dynamic_bitset<size_t> wheel_inc(std::vector<BigInteger> primes) {
673
698
  return o;
674
699
  }
675
700
 
676
- std::vector<boost::dynamic_bitset<size_t>> wheel_gen(const std::vector<BigInteger> &primes) {
701
+ std::vector<boost::dynamic_bitset<size_t>> wheel_gen(const std::vector<size_t> &primes) {
677
702
  std::vector<boost::dynamic_bitset<size_t>> output;
678
- std::vector<BigInteger> wheelPrimes;
679
- for (const BigInteger &p : primes) {
703
+ std::vector<size_t> wheelPrimes;
704
+ for (const size_t &p : primes) {
680
705
  wheelPrimes.push_back(p);
681
706
  output.push_back(wheel_inc(wheelPrimes));
682
707
  }
@@ -743,23 +768,23 @@ struct Factorizer {
743
768
  size_t smoothPartsLimit;
744
769
  size_t rowOffset;
745
770
  bool isIncomplete;
746
- std::vector<BigInteger> primes;
747
- std::vector<BigInteger> sqrPrimes;
771
+ std::vector<size_t> primes;
772
+ std::vector<size_t> sqrPrimes;
748
773
  ForwardFn forwardFn;
749
774
  std::vector<BigInteger> smoothNumberKeys;
750
775
  std::vector<boost::dynamic_bitset<size_t>> smoothNumberValues;
751
776
 
752
777
  Factorizer(const BigInteger &tfsqr, const BigInteger &tf, const BigInteger &tfsqrt, const BigInteger &range, size_t nodeCount, size_t nodeId, size_t w, size_t spl,
753
- const std::vector<BigInteger> &p, ForwardFn fn)
778
+ const std::vector<size_t> &p, ForwardFn fn)
754
779
  : rng({}), gen(rng()), dis(0U, p.size() - 1U), toFactorSqr(tfsqr), toFactor(tf), toFactorSqrt(tfsqrt), batchRange(range), batchNumber(0U), batchOffset(nodeId * range), batchTotal(nodeCount * range),
755
780
  wheelRadius(1U), wheelEntryCount(w), smoothPartsLimit(spl), rowOffset(p.size()), isIncomplete(true), primes(p), forwardFn(fn)
756
781
  {
757
782
  for (size_t i = 0U; i < primes.size(); ++i) {
758
- const BigInteger& p = primes[i];
783
+ const size_t& p = primes[i];
759
784
  wheelRadius *= p;
760
785
  sqrPrimes.push_back(p * p);
761
786
  smoothNumberKeys.push_back(p);
762
- smoothNumberValues.emplace_back(primes.size(), false);
787
+ smoothNumberValues.emplace_back(primes.size(), 0);
763
788
  smoothNumberValues.back()[i] = true;
764
789
  }
765
790
  }
@@ -828,32 +853,29 @@ struct Factorizer {
828
853
 
829
854
  // Compute the prime factorization modulo 2
830
855
  boost::dynamic_bitset<size_t> factorizationVector(BigInteger num) {
831
- boost::dynamic_bitset<size_t> vec(primes.size(), false);
832
- BigInteger factor = 1U;
833
- do {
834
- factor = gcd(num, wheelRadius);
856
+ boost::dynamic_bitset<size_t> vec(primes.size(), 0);
857
+ while (true) {
858
+ BigInteger factor = gcd(num, wheelRadius);
835
859
  if (factor == 1U) {
836
860
  break;
837
861
  }
838
862
  num /= factor;
839
863
  // Remove smooth primes from factor
840
864
  for (size_t pi = 0U; pi < primes.size(); ++pi) {
841
- const BigInteger& p = primes[pi];
842
- if (!(factor % p)) {
843
- factor /= p;
844
- vec[pi] = !vec[pi];
845
- if (factor == 1U) {
846
- break;
847
- }
865
+ const size_t& p = primes[pi];
866
+ if (factor % p) {
867
+ continue;
868
+ }
869
+ factor /= p;
870
+ vec[pi] = !vec[pi];
871
+ if (factor == 1U) {
872
+ break;
848
873
  }
849
874
  }
850
875
  if (num == 1U) {
851
- break;
876
+ return vec;
852
877
  }
853
- // Since we removed smooth primes,
854
- // factor == 1U if the number is smooth.
855
- } while (factor == 1U);
856
-
878
+ };
857
879
  if (num != 1U) {
858
880
  return boost::dynamic_bitset<size_t>();
859
881
  }
@@ -882,7 +904,7 @@ struct Factorizer {
882
904
 
883
905
  // Now that smooth parts have been shuffled, just multiply down the list until they are larger than square root of toFactor.
884
906
  BigInteger smoothNumber = 1U;
885
- boost::dynamic_bitset<size_t> fv(primes.size(), false);
907
+ boost::dynamic_bitset<size_t> fv(primes.size(), 0);
886
908
  for (size_t spi = 0U; spi < smoothParts.size(); ++spi) {
887
909
  const BigInteger &sp = smoothParts[spi];
888
910
  // This multiplies together the factorizations of the smooth parts
@@ -900,7 +922,7 @@ struct Factorizer {
900
922
  }
901
923
  // Reset "smoothNumber" and its factorization vector.
902
924
  smoothNumber = 1U;
903
- fv = boost::dynamic_bitset<size_t>(primes.size(), false);
925
+ fv = boost::dynamic_bitset<size_t>(primes.size(), 0);
904
926
  }
905
927
  }
906
928
 
@@ -1130,10 +1152,10 @@ std::string find_a_factor(const std::string &toFactorStr, const bool &isConOfSqr
1130
1152
  }
1131
1153
 
1132
1154
  // We only need to try trial division about as high as would be necessary for 4096 bits of semiprime.
1133
- const BigInteger primeCeiling = (trialDivisionLevel < fullMaxBase) ? (BigInteger)trialDivisionLevel : fullMaxBase;
1155
+ const size_t primeCeiling = (trialDivisionLevel < fullMaxBase) ? trialDivisionLevel : (size_t)fullMaxBase;
1134
1156
  BigInteger result = 1U;
1135
1157
  // This uses very little memory and time, to find primes.
1136
- std::vector<BigInteger> primes = SieveOfEratosthenes(primeCeiling);
1158
+ std::vector<size_t> primes = SieveOfEratosthenes(primeCeiling);
1137
1159
  // "it" is the end-of-list iterator for a list up-to-and-including wheelFactorizationLevel.
1138
1160
  const auto itw = std::upper_bound(primes.begin(), primes.end(), wheelFactorizationLevel);
1139
1161
  const auto itg = std::upper_bound(primes.begin(), primes.end(), gearFactorizationLevel);
@@ -1145,7 +1167,7 @@ std::string find_a_factor(const std::string &toFactorStr, const bool &isConOfSqr
1145
1167
  dispatch.dispatch([&toFactor, &primes, &result, &trialDivisionMutex, primeIndex]() -> bool {
1146
1168
  const size_t maxLcv = std::min(primeIndex + 64U, primes.size());
1147
1169
  for (size_t pi = primeIndex; pi < maxLcv; ++pi) {
1148
- const BigInteger& currentPrime = primes[pi];
1170
+ const size_t& currentPrime = primes[pi];
1149
1171
  if (!(toFactor % currentPrime)) {
1150
1172
  std::lock_guard<std::mutex> lock(trialDivisionMutex);
1151
1173
  result = currentPrime;
@@ -1162,8 +1184,8 @@ std::string find_a_factor(const std::string &toFactorStr, const bool &isConOfSqr
1162
1184
  }
1163
1185
 
1164
1186
  // Set up wheel factorization (or "gear" factorization)
1165
- std::vector<BigInteger> gearFactorizationPrimes(primes.begin(), itg);
1166
- std::vector<BigInteger> wheelFactorizationPrimes(primes.begin(), itw);
1187
+ std::vector<size_t> gearFactorizationPrimes(primes.begin(), itg);
1188
+ std::vector<size_t> wheelFactorizationPrimes(primes.begin(), itw);
1167
1189
  // Keep as many "smooth" primes as bits in number to factor.
1168
1190
  const size_t toFactorBits = (size_t)log2(toFactor);
1169
1191
  size_t smoothPrimeCount = (size_t)(smoothnessBoundMultiplier * toFactorBits);
@@ -1174,10 +1196,10 @@ std::string find_a_factor(const std::string &toFactorStr, const bool &isConOfSqr
1174
1196
  // Primes are only present in range above wheel factorization level
1175
1197
  primes.erase(primes.begin(), itg);
1176
1198
  const size_t maxPrimeCount = std::min(primes.size(), smoothPrimeCount);
1177
- std::vector<BigInteger> smoothPrimes;
1199
+ std::vector<size_t> smoothPrimes;
1178
1200
  for (size_t primeId = 0U; (primeId < primes.size()) && (smoothPrimes.size() < maxPrimeCount); ++primeId) {
1179
- const BigInteger residue = toFactor % primes[primeId];
1180
- const BigInteger sr = sqrt(residue);
1201
+ const size_t residue = (size_t)(toFactor % primes[primeId]);
1202
+ const size_t sr = _sqrt(residue);
1181
1203
  if ((sr * sr) == residue) {
1182
1204
  smoothPrimes.push_back(primes[primeId]);
1183
1205
  }
@@ -1187,7 +1209,7 @@ std::string find_a_factor(const std::string &toFactorStr, const bool &isConOfSqr
1187
1209
  }
1188
1210
  // From 1, this is a period for wheel factorization
1189
1211
  size_t biggestWheel = 1ULL;
1190
- for (const BigInteger &wp : gearFactorizationPrimes) {
1212
+ for (const size_t &wp : gearFactorizationPrimes) {
1191
1213
  biggestWheel *= (size_t)wp;
1192
1214
  }
1193
1215
  // Wheel entry count per largest "gear" scales our brute-force range.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: FindAFactor
3
- Version: 3.6.4
3
+ Version: 3.6.6
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.4
3
+ Version: 3.6.6
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.4',
29
+ version='3.6.6',
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