@@ -892,41 +892,38 @@ struct Factorizer {
892892 for (size_t col = 0U ; col < primes.size (); ++col) {
893893 auto mRowIt = mColIt ;
894894 auto nRowIt = nColIt;
895+ const size_t colPlus1 = col + 1U ;
895896
896897 // Look for a pivot row in this column
897- for (size_t row = col ; row < rows; ++row) {
898+ for (size_t row = colPlus1 ; row < rows; ++row) {
898899 if ((*mRowIt )[col]) {
899900 // Swapping matrix rows corresponds
900901 // with swapping factorized numbers.
901- if (row != col) {
902- std::swap (*mColIt , *mRowIt );
903- std::swap (*nColIt, *nRowIt);
904- }
902+ std::swap (*mColIt , *mRowIt );
903+ std::swap (*nColIt, *nRowIt);
905904 // Mark this column as having a pivot.
906905 result.marks [col] = true ;
907906 break ;
908907 }
909- ++nRowIt;
910908 ++mRowIt ;
909+ ++nRowIt;
911910 }
912911
913912 if (result.marks [col]) {
914913 // Pivot found, now eliminate entries in this column
915914 const boost::dynamic_bitset<size_t > &cm = *mColIt ;
916915 const BigInteger &cn = *nColIt;
917- mRowIt = smoothNumberValues.begin ();
918- nRowIt = smoothNumberKeys.begin ();
919-
920- for (unsigned cpu = 0U ; (cpu < CpuCount) && (cpu < rows); ++cpu) {
921- dispatch.dispatch ([cpu, &cpuCount, &col, &rows, &cm, &cn, nRowIt, mRowIt ]() -> bool {
922- auto mrIt = mRowIt ;
923- auto nrIt = nRowIt;
916+ const size_t maxLcv = std::min (colPlus1 + CpuCount, rows);
917+ for (unsigned cpu = colPlus1; cpu < maxLcv; ++cpu) {
918+ dispatch.dispatch ([cpu, &cpuCount, &col, &rows, &cm, &cn, mRowIt , nRowIt]() -> bool {
924919 // Notice that each thread updates rows with space increments of cpuCount,
925920 // based on the same unchanged outer-loop row, and this covers the inner-loop set.
921+ auto mrIt = mRowIt ;
922+ auto nrIt = nRowIt;
926923 for (size_t row = cpu; ; row += cpuCount) {
927924 boost::dynamic_bitset<size_t > &rm = *mrIt;
928925 BigInteger &rn = *nrIt;
929- if ((row != col) && rm[col]) {
926+ if (rm[col]) {
930927 // XOR-ing factorization rows
931928 // is like multiplying the numbers.
932929 rm ^= cm;
@@ -937,8 +934,8 @@ struct Factorizer {
937934 return false ;
938935 }
939936 // Every row advance is staggered according to cpuCount.
940- std::advance (nrIt, cpuCount);
941937 std::advance (mrIt, cpuCount);
938+ std::advance (nrIt, cpuCount);
942939 }
943940 return false ;
944941 });
@@ -969,7 +966,7 @@ struct Factorizer {
969966 }
970967
971968 if (result.solutionColumns .empty ()) {
972- throw std::runtime_error (" No solution found. Need more smooth numbers." );
969+ throw std::runtime_error (" Gaussian elimination found no solution. Produce and retain more smooth numbers." );
973970 }
974971
975972 return result;
@@ -984,6 +981,7 @@ struct Factorizer {
984981 if (smoothNumberKeys.empty ()) {
985982 throw std::runtime_error (" No smooth numbers found. Sieve more." );
986983 }
984+
987985 GaussianEliminationResult result = gaussianElimination ();
988986 for (size_t i = 0U ; i < result.solutionColumns .size (); ++i) {
989987 const BigInteger factor = solveCongruence (findDependentRows (result, i));
@@ -994,7 +992,7 @@ struct Factorizer {
994992
995993 // Depending on row count, a successful result should be nearly guaranteed,
996994 // but we default to no solution.
997- return 1U ;
995+ throw std::runtime_error ( " No solution produced a congruence of squares. " ) ;
998996 }
999997
1000998 // Produce a smooth number with its factorization vector.
0 commit comments