@@ -764,6 +764,7 @@ struct Factorizer {
764764 std::vector<uint16_t > primes;
765765 ForwardFn forwardFn;
766766 std::map<BigInteger, boost::dynamic_bitset<size_t >> smoothNumberMap;
767+ std::unordered_map<boost::dynamic_bitset<size_t >, BigInteger> hashMap;
767768
768769 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,
769770 const std::vector<uint16_t > &p, ForwardFn fn)
@@ -879,75 +880,73 @@ struct Factorizer {
879880 // WRITTEN BY ELARA (GPT) BELOW //
880881 // /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
881882
882- // Find factor via Gaussian elimination
883+ // Find duplicate rows
883884 BigInteger findFactor (const BigInteger &target) {
884- // Check for linear dependencies and find a congruence of squares
885- std::mutex rowMutex ;
885+ std::mutex toStrikeMtx;
886+ std::mutex hashMapMtx ;
886887 BigInteger result = 1U ;
887888 std::set<BigInteger> toStrike;
888- auto iIt = smoothNumberMap.begin ();
889- const size_t rowCount = smoothNumberMap.size ();
890- const size_t rowCountMin1 = rowCount - 1U ;
891- for (size_t i = 0U ; (i < rowCountMin1) && (result == 1U ); ++i) {
892- dispatch.dispatch ([&target, i, iIt, &rowCount, &result, &toStrike, &rowMutex]() -> bool {
893- boost::dynamic_bitset<size_t > &iRow = iIt->second ;
894- auto jIt = iIt;
895- for (size_t j = i + 1U ; j < rowCount; ++j) {
896- ++jIt;
897-
898- boost::dynamic_bitset<size_t > &jRow = jIt->second ;
899- if (iRow != jRow) {
900- continue ;
889+ auto rIt = smoothNumberMap.begin ();
890+ std::advance (rIt, hashMap.size ());
891+ for (size_t row = hashMap.size (); (row < smoothNumberMap.size ()) && (result == 1U ); ++row) {
892+ dispatch.dispatch ([this , &target, row, rIt, &toStrikeMtx, &hashMapMtx, &toStrike, &result] {
893+ const auto & binaryRow = rIt->second ;
894+ // Check if the row already exists in the map
895+ BigInteger duplicateRow;
896+ // For lock_guard scope
897+ if (true ) {
898+ std::lock_guard<std::mutex> lock (hashMapMtx);
899+ const auto found = this ->hashMap .find (binaryRow);
900+ if (found == this ->hashMap .end ()) {
901+ this ->hashMap [binaryRow] = row;
902+
903+ return false ;
901904 }
905+ duplicateRow = found->second ;
906+ }
902907
903- if (true ) {
904- std::lock_guard<std::mutex> lock (rowMutex);
905- toStrike.insert (jIt->first );
906- }
907-
908- // Compute x and y
909- const BigInteger x = (iIt->first * jIt->first ) % target;
910- const BigInteger y = modExp (x, target >> 1U , target);
911-
912- // Check congruence of squares
913- BigInteger factor = gcd (target, x + y);
914- if ((factor != 1U ) && (factor != target)) {
915- std::lock_guard<std::mutex> lock (rowMutex);
916- result = factor;
908+ // Compute x and y
909+ const BigInteger x = (rIt->first * duplicateRow) % target;
910+ const BigInteger y = modExp (x, target >> 1U , target);
917911
918- return true ;
919- }
912+ // Check congruence of squares
913+ BigInteger factor = gcd (target, x + y);
914+ if ((factor != 1U ) && (factor != target)) {
915+ std::lock_guard<std::mutex> lock (toStrikeMtx);
916+ result = factor;
920917
921- if (x == y) {
922- continue ;
923- }
918+ return true ;
919+ }
924920
921+ if (x != y) {
925922 // Try x - y as well
926923 factor = gcd (target, x - y);
927924 if ((factor != 1U ) && (factor != target)) {
928- std::lock_guard<std::mutex> lock (rowMutex );
925+ std::lock_guard<std::mutex> lock (toStrikeMtx );
929926 result = factor;
930927
931928 return true ;
932929 }
933930 }
934931
932+ if (rIt->first < duplicateRow) {
933+ std::lock_guard<std::mutex> lock (toStrikeMtx);
934+ toStrike.insert (duplicateRow);
935+ } else {
936+ std::lock_guard<std::mutex> lock (toStrikeMtx);
937+ toStrike.insert (rIt->first );
938+ }
939+
935940 return false ;
936941 });
937- ++iIt ;
942+ ++rIt ;
938943 }
939944 dispatch.finish ();
940945
941- if (result != 1U ) {
942- return result;
943- }
944-
945946 // These numbers have been tried already:
946947 for (const BigInteger& i : toStrike) {
947948 smoothNumberMap.erase (i);
948949 }
949-
950- return 1U ; // No factor found
951950 }
952951
953952 // /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
0 commit comments