FindAFactor 3.6.0__tar.gz → 3.6.2__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,6 @@
1
1
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2
2
  //
3
- // (C) Daniel Strano and the Qrack contributors 2017-2024. All rights reserved.
3
+ // (C) Daniel Strano and the Qrack contributors 2017-2025. All rights reserved.
4
4
  //
5
5
  // "A quantum-inspired Monte Carlo integer factoring algorithm"
6
6
  //
@@ -721,28 +721,6 @@ inline BigInteger modExp(BigInteger base, BigInteger exp, const BigInteger &mod)
721
721
  return result;
722
722
  }
723
723
 
724
- // Compute the prime factorization modulo 2
725
- boost::dynamic_bitset<size_t> factorizationVector(BigInteger num, const std::vector<BigInteger> &primes) {
726
- boost::dynamic_bitset<size_t> vec(primes.size(), false);
727
- for (size_t i = 0U; i < primes.size(); ++i) {
728
- bool count = false;
729
- const BigInteger &p = primes[i];
730
- while (!(num % p)) {
731
- num /= p;
732
- count = !count;
733
- }
734
- vec[i] = count;
735
- if (num == 1U) {
736
- break;
737
- }
738
- }
739
- if (num != 1U) {
740
- return boost::dynamic_bitset<size_t>();
741
- }
742
-
743
- return vec;
744
- }
745
-
746
724
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
747
725
  // WRITTEN WITH ELARA (GPT) ABOVE //
748
726
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -751,6 +729,8 @@ struct Factorizer {
751
729
  std::mutex batchMutex;
752
730
  std::mutex smoothNumberMapMutex;
753
731
  std::default_random_engine rng;
732
+ std::mt19937_64 gen;
733
+ std::uniform_int_distribution<size_t> dis;
754
734
  BigInteger toFactorSqr;
755
735
  BigInteger toFactor;
756
736
  BigInteger toFactorSqrt;
@@ -758,22 +738,27 @@ struct Factorizer {
758
738
  BigInteger batchNumber;
759
739
  BigInteger batchOffset;
760
740
  BigInteger batchTotal;
741
+ BigInteger wheelRadius;
761
742
  size_t wheelEntryCount;
762
743
  size_t smoothPartsLimit;
763
744
  size_t rowOffset;
764
745
  bool isIncomplete;
765
746
  std::vector<BigInteger> primes;
747
+ std::vector<BigInteger> sqrPrimes;
766
748
  ForwardFn forwardFn;
767
749
  std::vector<BigInteger> smoothNumberKeys;
768
750
  std::vector<boost::dynamic_bitset<size_t>> smoothNumberValues;
769
751
 
770
752
  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,
771
753
  const std::vector<BigInteger> &p, ForwardFn fn)
772
- : rng({}), toFactorSqr(tfsqr), toFactor(tf), toFactorSqrt(tfsqrt), batchRange(range), batchNumber(0U), batchOffset(nodeId * range), batchTotal(nodeCount * range),
773
- wheelEntryCount(w), smoothPartsLimit(spl), rowOffset(p.size()), isIncomplete(true), primes(p), forwardFn(fn)
754
+ : 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
+ wheelRadius(1U), wheelEntryCount(w), smoothPartsLimit(spl), rowOffset(p.size()), isIncomplete(true), primes(p), forwardFn(fn)
774
756
  {
775
757
  for (size_t i = 0U; i < primes.size(); ++i) {
776
- smoothNumberKeys.push_back(primes[i]);
758
+ const BigInteger& p = primes[i];
759
+ wheelRadius *= p;
760
+ sqrPrimes.push_back(p * p);
761
+ smoothNumberKeys.push_back(p);
777
762
  smoothNumberValues.emplace_back(primes.size(), false);
778
763
  smoothNumberValues.back()[i] = true;
779
764
  }
@@ -841,12 +826,39 @@ struct Factorizer {
841
826
  return 1U;
842
827
  }
843
828
 
829
+ // Compute the prime factorization modulo 2
830
+ 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);
835
+ if (factor == 1U) {
836
+ break;
837
+ }
838
+ num /= factor;
839
+ for (size_t pi = 0U; pi < primes.size(); ++pi) {
840
+ if (!(factor % primes[pi])) {
841
+ vec[pi] = !vec[pi];
842
+ }
843
+ }
844
+ if (num == 1U) {
845
+ break;
846
+ }
847
+ } while (factor != 1U);
848
+
849
+ if (num != 1U) {
850
+ return boost::dynamic_bitset<size_t>();
851
+ }
852
+
853
+ return vec;
854
+ }
855
+
844
856
  void makeSmoothNumbers(std::vector<BigInteger> *semiSmoothParts, bool isGaussElim) {
845
857
  // Factorize all "smooth parts."
846
858
  std::vector<BigInteger> smoothParts;
847
859
  std::map<BigInteger, boost::dynamic_bitset<size_t>> smoothPartsMap;
848
860
  for (const BigInteger &n : (*semiSmoothParts)) {
849
- const boost::dynamic_bitset<size_t> fv = factorizationVector(n, primes);
861
+ const boost::dynamic_bitset<size_t> fv = factorizationVector(n);
850
862
  if (fv.size()) {
851
863
  smoothPartsMap[n] = fv;
852
864
  smoothParts.push_back(n);
@@ -894,8 +906,7 @@ struct Factorizer {
894
906
  auto mColIt = smoothNumberValues.begin();
895
907
  auto nColIt = smoothNumberKeys.begin();
896
908
  const size_t rows = smoothNumberValues.size();
897
- const size_t cols = mColIt->size();
898
- for (size_t col = 0U; col < cols; ++col) {
909
+ for (size_t col = 0U; col < primes.size(); ++col) {
899
910
  auto mRowIt = mColIt;
900
911
  auto nRowIt = nColIt;
901
912
 
@@ -953,6 +964,32 @@ struct Factorizer {
953
964
  }
954
965
  }
955
966
 
967
+ BigInteger checkPerfectSquare(BigInteger perfectSquare) {
968
+ while (perfectSquare < toFactorSqr) {
969
+ // Compute x and y
970
+ const BigInteger x = perfectSquare % toFactor;
971
+ const BigInteger y = modExp(x, toFactor >> 1U, toFactor);
972
+
973
+ // Check congruence of squares
974
+ BigInteger factor = gcd(toFactor, x + y);
975
+ if ((factor != 1U) && (factor != toFactor)) {
976
+ return factor;
977
+ }
978
+
979
+ if (x != y) {
980
+ // Try x - y as well
981
+ factor = gcd(toFactor, x - y);
982
+ if ((factor != 1U) && (factor != toFactor)) {
983
+ return factor;
984
+ }
985
+ }
986
+
987
+ perfectSquare *= sqrPrimes[dis(gen)];
988
+ }
989
+
990
+ return 1U;
991
+ }
992
+
956
993
  // Find duplicate rows
957
994
  BigInteger findDuplicateRows(const BigInteger &target) {
958
995
  // Check for linear dependencies and find a congruence of squares
@@ -987,25 +1024,7 @@ struct Factorizer {
987
1024
  toStrike.insert(i);
988
1025
  }
989
1026
 
990
- // Compute x and y
991
- const BigInteger x = (iInt * jInt) % target;
992
- const BigInteger y = modExp(x, target >> 1U, target);
993
-
994
- // Check congruence of squares
995
- BigInteger factor = gcd(target, x + y);
996
- if ((factor != 1U) && (factor != target)) {
997
- std::lock_guard<std::mutex> lock(rowMutex);
998
- result = factor;
999
-
1000
- return true;
1001
- }
1002
-
1003
- if (x == y) {
1004
- continue;
1005
- }
1006
-
1007
- // Try x - y as well
1008
- factor = gcd(target, x - y);
1027
+ const BigInteger factor = checkPerfectSquare(this->smoothNumberKeys[i]);
1009
1028
  if ((factor != 1U) && (factor != target)) {
1010
1029
  std::lock_guard<std::mutex> lock(rowMutex);
1011
1030
  result = factor;
@@ -1047,27 +1066,8 @@ struct Factorizer {
1047
1066
  const size_t rowCount = smoothNumberKeys.size();
1048
1067
  for (size_t i = primes.size(); (i < rowCount) && (result == 1U); ++i) {
1049
1068
  dispatch.dispatch([this, &target, i, &result, &rowMutex]() -> bool {
1050
- const BigInteger& iInt = this->smoothNumberKeys[i];
1051
-
1052
- // Compute x and y
1053
- const BigInteger x = iInt % target;
1054
- const BigInteger y = modExp(x, target >> 1U, target);
1055
-
1056
- // Check congruence of squares
1057
- BigInteger factor = gcd(target, x + y);
1058
- if ((factor != 1U) && (factor != target)) {
1059
- std::lock_guard<std::mutex> lock(rowMutex);
1060
- result = factor;
1069
+ const BigInteger factor = checkPerfectSquare(this->smoothNumberKeys[i]);
1061
1070
 
1062
- return true;
1063
- }
1064
-
1065
- if (x == y) {
1066
- return false;
1067
- }
1068
-
1069
- // Try x - y as well
1070
- factor = gcd(target, x - y);
1071
1071
  if ((factor != 1U) && (factor != target)) {
1072
1072
  std::lock_guard<std::mutex> lock(rowMutex);
1073
1073
  result = factor;
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: FindAFactor
3
- Version: 3.6.0
3
+ Version: 3.6.2
4
4
  Summary: Find any nontrivial factor of a number
5
5
  Home-page: https://github.com/vm6502q/FindAFactor
6
6
  Author: Dan Strano
@@ -23,7 +23,7 @@ Requires-Dist: pybind11
23
23
  Find any nontrivial factor of a number
24
24
 
25
25
  ## Copyright and license
26
- (c) Daniel Strano and the Qrack contributors 2017-2024. All rights reserved.
26
+ (c) Daniel Strano and the Qrack contributors 2017-2025. All rights reserved.
27
27
 
28
28
  ## Installation
29
29
  From PyPi:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: FindAFactor
3
- Version: 3.6.0
3
+ Version: 3.6.2
4
4
  Summary: Find any nontrivial factor of a number
5
5
  Home-page: https://github.com/vm6502q/FindAFactor
6
6
  Author: Dan Strano
@@ -23,7 +23,7 @@ Requires-Dist: pybind11
23
23
  Find any nontrivial factor of a number
24
24
 
25
25
  ## Copyright and license
26
- (c) Daniel Strano and the Qrack contributors 2017-2024. All rights reserved.
26
+ (c) Daniel Strano and the Qrack contributors 2017-2025. All rights reserved.
27
27
 
28
28
  ## Installation
29
29
  From PyPi:
@@ -2,7 +2,7 @@
2
2
  Find any nontrivial factor of a number
3
3
 
4
4
  ## Copyright and license
5
- (c) Daniel Strano and the Qrack contributors 2017-2024. All rights reserved.
5
+ (c) Daniel Strano and the Qrack contributors 2017-2025. All rights reserved.
6
6
 
7
7
  ## Installation
8
8
  From PyPi:
@@ -7,7 +7,7 @@ except ImportError:
7
7
  import setuptools
8
8
  from distutils.core import setup, Extension
9
9
 
10
- cpp_args = ['-std=c++17', '-lpthread']
10
+ cpp_args = ['-std=c++17', '-lpthread', '-O3']
11
11
 
12
12
  README_PATH = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'README.md')
13
13
  with open(README_PATH) as readme_file:
@@ -26,7 +26,7 @@ ext_modules = [
26
26
 
27
27
  setup(
28
28
  name='FindAFactor',
29
- version='3.6.0',
29
+ version='3.6.2',
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