Skip to content

Commit 4368e14

Browse files
committed
c?ul: faster walk_1() for a set at a time
1 parent 1369ed0 commit 4368e14

File tree

1 file changed

+101
-0
lines changed

1 file changed

+101
-0
lines changed

coul.c

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1766,6 +1766,7 @@ void walk_v(t_level *cur_level, mpz_t start) {
17661766
fail("TODO: walk_v.end > 2^64");
17671767
}
17681768

1769+
/* test the case where v_i has all divisors accounted for */
17691770
void walk_1(t_level *cur_level, uint vi) {
17701771
#ifdef SQONLY
17711772
if (!cur_level->have_square)
@@ -1836,6 +1837,101 @@ void walk_1(t_level *cur_level, uint vi) {
18361837
return;
18371838
}
18381839

1840+
/* test a set of cases where v_i will have all divisors accounted for */
1841+
void walk_1_set(t_level *cur_level, uint vi, ulong plow, ulong phigh, uint x) {
1842+
#ifdef SQONLY
1843+
if (!cur_level->have_square)
1844+
return;
1845+
#endif
1846+
if (minp && cur_level->maxp <= minp)
1847+
plow = minp;
1848+
1849+
uint t[k];
1850+
uint need_prime[k];
1851+
uint need_square[k];
1852+
uint need_other[k];
1853+
uint npc = 0, nqc = 0, noc = 0;
1854+
for (uint vj = 0; vj < k; ++vj) {
1855+
if (vi == vj)
1856+
continue;
1857+
t_value *vjp = &value[vj];
1858+
t_allocation *ajp = (vjp->vlevel) ? &vjp->alloc[vjp->vlevel - 1] : NULL;
1859+
t[vj] = ajp ? ajp->t : n;
1860+
if (t[vj] == 1)
1861+
fail("should never see multiple values with t==1");
1862+
if (t[vj] == 2)
1863+
need_prime[npc++] = vj;
1864+
else if (t[vj] & 1)
1865+
need_prime[npc++] = vj;
1866+
else
1867+
need_other[noc++] = vj;
1868+
}
1869+
1870+
level_setp(cur_level, plow);
1871+
t_value *vip = &value[vi];
1872+
t_allocation *aip = vip->vlevel ? &vip->alloc[vip->vlevel - 1] : NULL;
1873+
while (1) {
1874+
ulong p = prime_iterator_next(&cur_level->piter);
1875+
if (p > phigh)
1876+
break;
1877+
if (need_work) {
1878+
/* temporarily make this prime power visible to diag code */
1879+
t_allocation *a2ip = &vip->alloc[vip->vlevel++];
1880+
a2ip->p = p;
1881+
a2ip->x = x;
1882+
diag_plain();
1883+
--vip->vlevel;
1884+
}
1885+
mpz_ui_pow_ui(Z(w1_v), p, x - 1);
1886+
if (aip)
1887+
mpz_mul(Z(w1_v), Z(w1_v), aip->q);
1888+
mpz_sub_ui(Z(w1_v), Z(w1_v), TYPE_OFFSET(vi));
1889+
1890+
if (mpz_cmp(Z(w1_v), min) < 0)
1891+
break;
1892+
++countw;
1893+
1894+
for (uint vj = 0; vj < k; ++vj) {
1895+
t_value *vjp = &value[vj];
1896+
t_allocation *ajp = (vjp->vlevel) ? &vjp->alloc[vjp->vlevel - 1]
1897+
: NULL;
1898+
mpz_add_ui(Z(w1_j), Z(w1_v), TYPE_OFFSET(vj));
1899+
if (ajp) {
1900+
mpz_fdiv_qr(Z(w1_j), Z(w1_r), Z(w1_j), ajp->q);
1901+
if (mpz_sgn(Z(w1_r)) != 0)
1902+
goto reject_this_one;
1903+
mpz_gcd(Z(w1_r), Z(w1_j), ajp->q);
1904+
if (mpz_cmp(Z(w1_r), Z(zone)) != 0)
1905+
goto reject_this_one;
1906+
}
1907+
mpz_set(wv_o[vj], Z(w1_j));
1908+
}
1909+
++countwi;
1910+
for (uint i = 0; i < npc; ++i)
1911+
if (!_GMP_is_prob_prime(wv_o[need_prime[i]]))
1912+
goto reject_this_one;
1913+
for (uint i = 0; i < nqc; ++i)
1914+
if (!is_taux(wv_o[need_square[i]], t[need_square[i]], 1))
1915+
goto reject_this_one;
1916+
oc_t = t;
1917+
qsort(need_other, noc, sizeof(uint), &other_comparator);
1918+
#ifdef PARALLEL
1919+
if (!test_1multi(need_other, noc, t))
1920+
goto reject_this_one;
1921+
#else
1922+
for (uint i = 0; i < noc; ++i)
1923+
if (!is_taux(wv_o[need_other[i]], t[need_other[i]], 1))
1924+
goto reject_this_one;
1925+
#endif
1926+
candidate(Z(w1_v));
1927+
if (improve_max)
1928+
return;
1929+
reject_this_one:
1930+
;
1931+
}
1932+
return;
1933+
}
1934+
18391935
/* When some v_j is known to be of the form m.z^g, we keep a running set
18401936
* of possible values of z: z == ((rq + i)/q_j)^{ 1/g } mod aq/q_j.
18411937
* If no such residues exist, this returns FALSE to signal that this
@@ -2878,6 +2974,11 @@ e_pux prep_unforced_x(t_level *prev, t_level *cur, ulong p, bool forced) {
28782974
return PUX_ALL_DONE;
28792975
} else if (limp < p + 1)
28802976
return PUX_SKIP_THIS_X; /* nothing to do here */
2977+
if (nextt == 1) {
2978+
walk_1_set(cur, vi, p, limp, x);
2979+
return PUX_SKIP_THIS_X;
2980+
}
2981+
28812982
mpz_add_ui(Z(r_walk), max, vi);
28822983
#ifdef LARGE_MIN
28832984
mpz_sub(Z(r_walk), Z(r_walk), min);

0 commit comments

Comments
 (0)