Skip to content

pcoul options

Hugo van der Sanden edited this page Oct 17, 2026 · 5 revisions

This page lists every command-line option of pcoul. The README gives a shorter introduction with examples; D(n,k) calculation explains the method, and the terms used here.

It describes the code on the master branch as of 2026-10-14 (commit 028e0b3). The same options apply to pcaul and pcrul, except where noted.

Options marked (calibrate2 branch only) exist only in builds of the experimental calibrate2 branch, which adds the automatic choice of options by estimated cost; they describe that branch as rebased onto master 116f8d2.

Synopsis

pcoul [options] <n> <k>

<n> and <k> come after all options: the search is for $D(n,k)$, the least $v$ such that $\tau(v+i) = n$ for every $0 \le i &lt; k$. $k$ may be at most 66. The code is aimed at $n$ up to a few thousand; much larger $n$ may need a lot of memory and a long start-up time.

  • For odd $n$, only $D(n,1)$ exists; for pcaul the same seems to hold, but it is not proven; for pcrul odd $n$ are normal.

Options start with -, and take their value directly after the option letter(s), with no space: -x1000, not -x 1000. An argument -- ends the options.

Where an option can take a large number, it can usually be written in exponential notation without a decimal point: 13e6 means 13000000.

Search range

  • -x<max>, -x<min>:<max>: search for solutions $v$ with $min &lt; v \le max$. -x<max> and -x:<max> mean -x0:<max>. This option is required: there is no default maximum, and min >= max is refused.
  • -X: report every solution up to the maximum. By default each solution found lowers the maximum, so that only improvements are reported. Under -X the same solution may be reported more than once. The best solution found is still reported at the end.

Shape of the search

These options change how the work is done, but not which values are covered: a full run with any of them gives the same answer.

  • -g<gain>, -g<antigain>:<gain>: set the gain for the walk-or-recurse decision to $gain / antigain$ (default 1). A higher gain means more recursion and shorter walks. Choosing it well can make a large difference to the run time.
  • -G<gain>, -G<antigain>:<gain>: as -g, but only for the decision when a square is available. By default the same value as -g.
  • -f<p>: treat every prime up to $p$ as forced at every position, rather than letting it be allocated later as an unforced prime. In pcoul, when $n \equiv 2 \pmod 4$ this already happens for every forced prime, and -f has no effect. See "Forced primes and batches" on the calculation page.
  • -F<p>, -F: treat every prime $p$ and above as unforceable. -F alone means -F1. -F<n> with $n \le 2$ has known bugs in release 20261014, fixed afterwards.
  • -j<s>: the strategy for choosing the next position to allocate at, from -j0 to -j4. The default is -j1 when $n$ has at least two distinct odd prime factors, otherwise -j0. See "Strategies" on the calculation page.
  • -js<i>,<i>,...: allocate at the positions in the order given, then walk. This is expected to be useful only with -b.
  • -jp: wait for a complete batch before solving a Pell equation (see "Squares" on the calculation page). This makes -a list those batches, and lets -b run one; it also changes the batch ids.
  • -ix: ignore hard-coded exceptions, do the normal search instead. These cases have a mathematical proof described in the code comments, but a search will simply fail to find a solution in any range. (Added after release 20261014.)
  • -W<P>: for each batch, first sweep all the cases that allocate an unforced prime above $P$, then continue as if -p<P> had been given. A well-chosen value can give a large speedup.
  • -WW<P>: do only the sweep of -W<P> for each batch, and skip the rest. Unlike the other options in this section, this is a partial search (see below): it covers only the cases that allocate an unforced prime above $P$.
  • -Wx<list>: as -W, with a separate threshold for each power (see "Prime limits" below).
  • -P<P>: cap the prime limit used in the walk-or-recurse decision at $P$. If a run is split by prime ranges (for example -p100, -p100:200, -p200:300), give all parts the same -P100 so that the decisions are made in the same way, and the parts together test the same cases as a single -p300 -P100 run.
  • -h<t>: test roughness for remaining tau of at least $t$, so that such values are resolved by trial factorization where possible. This is a tuning option; it is expected to be replaced by something automatic.
  • -c<m>: before the search, work out for every modulus up to $m$ which residues of $v$ cannot be a solution, and reject those values during walks. -cp<p> skips moduli with a prime factor above $p$; -cr<r> drops moduli that reject too small a proportion of residues; -cc<c> combines moduli into chunks of size $c$. These are experimental.
  • -k<B> (calibrate2 branch only): applies to each batch that leaves exactly one position needing a square. Each other position whose remaining tau is $2 \pmod 4$ then needs exactly one more prime to an odd power, allowing a fast Pell solution. With this option it first tries every $p^1$ with $p \le B$ that way, and every higher odd power of any $p$. The normal recursion then continues knowing that prime exceeds $B$, lowering the limit on every other prime allocated at the same position; and it leaves the position needing the square to the walk rather than allocating there. A position with tau 6 left is passed over where another has a larger multiple of 6 left: its one prime squared has too high a limit to be allocated before the other position's last, so nothing is allocated there at all (nor by -W), and the walks cover it. A batch that STRATEGY_6X (the special strategy for "2z^2" two places after a power of 2) can take is left to it, unless the search under -k is estimated to cost less. In a batch -k applies to, -j4 and -js allocate no $p^{2^z-1}$. Requires $k \le 64$. Default is not to do this.
  • -K<c> (calibrate2 branch only): with -k, the $c$ positions with tau 6 left that have most allocated are not passed over, which can pay with -W where few positions are left.
  • -ka (calibrate2 branch only): choose the bound of -k for each batch it applies to by estimated cost, along with the bound of -W and the count of -K unless those are given; -ka cannot be combined with -k<B>, and implies -ja1. Each choice is estimated by following the search of the batch in the abstract under -ja1. A batch is left without -k if it would take under 10ms to walk whole, or if no choice is estimated to cost less than that walk. The cost of walking a root is taken from the cost table (see below), for a walk of the batch with the tau that would then be left at each position, if the table has rows for each tau to be tested; else it is a fixed guess. The choice is shown on a line for the batch (203), as [k=<bound>] ([k=0] if -k is not to apply), [W=<bound>] if a sweep was chosen, [K=<count>], [est=<seconds>], and [rootus=<microseconds>] for the cost per root of walking the batch whole, if that came from the cost table. It is also logged with each progress line (in 316), and a recovered run continues the batch with what was logged rather than choosing again. With -a the choices are listed without running anything.
  • -ja1 (calibrate2 branch only, experimental): automate the transition from recursion to walking by estimated cost: walking now is weighed against recursing one more level with every resulting case walked, using the cost of a walk per iteration learnt during the run. That covers every loop where no square is fixed, unless a flip may follow (tau $2q^2$ for an odd prime $q$); and with one square fixed, every loop in a batch that -k applies to. The gain (-g) then applies only to what is left.
  • -ja2 (calibrate2 branch only, experimental): as -ja1, and also choose the next position to allocate at by estimated cost, instead of by the strategy, in the same places, wherever the node is not too cheap for the choice to pay: walking now is weighed against recursing over each eligible position, with every resulting case walked. The strategy remains the choice where the costs cannot be estimated (when a flip may follow). Not supported with -js. The estimates are corrected as the run proceeds by the costs measured for the choices made. Since the choices then depend on costs learnt during the run, progress lines (315) mark each position chosen against the strategy, so that recovery can reproduce it.
  • With either level, what -ja has learnt is logged before each progress line (316), and a recovered run carries on from it.

Cost table (calibrate2 branch only)

The costs -ja and -ka use are counted rather than timed, so that identical runs make identical choices, whatever else the machine is doing: walk iterations, primes tried and tests made are each charged their cost from a cost table (made by multibench-table). A default table is built into pcoul from the file timings; set the environment variable $COST_TABLE to the path of another to use that instead (rather than editing timings and rebuilding). Since only the relative costs matter, a table made on one machine should serve on others. With -dT, pcoul notes in the log each section of the table made by a different build of divrep or MPU::GMP.

Partial searches

These options restrict the search to part of the space. A run using any of them is not a proof of the least value, even when it reports one in the same way (200 f(n, k) = ...): it shows only that the value is an upper bound, and that there is nothing smaller in the part searched. They are useful for finding a first upper bound quickly, or for splitting a search into parts.

  • -p<max>, -p<min>:<max>: allocate only primes up to $max$, and skip any case that does not allocate at least one prime above $min$. Currently -p<max> must be used for no minimum: -p:<max> is refused. The minimum takes effect only when a walk is reached; the maximum applies only to unforced primes unless -fr is given.
  • -fr: apply the -p maximum (and any -px maxima) to forced primes too.
  • -px<list>: per-power overrides of the -p limits (see "Prime limits" below).
  • -m<mod>=<val>: search only $v \equiv val \pmod{mod}$. -m<mod>!<val> excludes that residue class instead. Either may be given several times. These only reject allocations that are inconsistent with the condition; they do not choose allocations to satisfy it.
  • -b<id>, -b<min>:<max>: run only the given batch, or range of batches, using the ids that -a shows with the same options; either end of the range may be left out. A run of every batch, in parts, covers the same ground as a single run.
  • -I<pattern>: force the given allocations into place, and search only below them. The pattern has the form of a progress line (305), such as -I'2^5 3^2 2 . 2^2.3'.

Prime limits

The values of -p and -W can be given as a power, such as -p100^2: this limits the allocated power $p^e$ to at most $100^2$, rather than limiting the prime $p$ whatever its power.

The extended forms -px, -Wx give a comma-separated list of p^e entries, each setting the limit for one power $e$ (where $e + 1$ must divide $n$); a limit of 0 means no limit. So -p100 -px1^5,0^11 allows $p \le 100$ for most powers, no $p^5$ at all, and any $p^{11}$.

Batches

  • -a: list the valid batches, without searching them. Each is shown with its id (for -b) and its LCM, as a guide to its cost: a batch with a larger LCM leaves fewer values to test, and is usually quicker.
  • -a<bits>: the same, with a combination of these bits:
    • 1: list the batches (as plain -a).
    • 2: write the list as CSV on standard output, with a column for each position, the LCM of the allocated prime powers, and counts of the remaining tau values. (Currently the ids in this format are one higher than those -a shows and -b uses.)
    • 4: also list the batches that are normally handled at once rather than counted: those that fully determine a value, and (without -jp) those that lead to a Pell equation. This ignores the minimum of -x. The ids then differ from those of a normal run, so cannot be used with -b.
  • In the calibrate2 branch only, a batch that fixes exactly one square is also shown with the number rc of residues, modulo the LCM, of that square's root.
  • -ap (calibrate2 branch only): as -a, and after each batch that fixes exactly one square, show on a line (205) what the batch is estimated to cost: under -k, with the bounds -ka chose or those given, the total in seconds and what it is made of (the pass, the sweep of -W and the rest of the search, with the nodes and the roots expected in all); under STRATEGY_6X, where that can take the batch (6x); and walked whole, which the search can always do, and may improve on by far. A last line (205) gives the total for the batches estimated under -k, or else under STRATEGY_6X, and the number of each kind. So -ap with -ka shows what its choices rest on, and with -k, -W and -K what those would cost instead.

When redirecting the output of -a to a file, also give -Ls0, so that progress lines do not get mixed into it.

Logging and recovery

Note that progress logging occurs only at certain points in the program. Currently there are no such points within the factorization code, so a long factorization may delay progress updates for an indeterminate time.

  • -r<path>: write progress to the log file at <path>, by default every 600 seconds (see -Lf). If the file already exists the run first reads it, and continues from the last point it records; it must be given the same options as the original run. Without -r, progress is shown only on the terminal.
  • -R: with -r, do not read the existing log: start from the beginning, and append to it.
  • -Lf<s>: write progress to the log at most every $s$ seconds (default 600). On recovery, at most this much work is lost.
  • -Ls<s>: show progress on the terminal every $s$ seconds (default 1). -Ls0 shows none.
  • -Ld<s>: stop after about $s$ seconds. This is checked only when a progress line is due, so has no effect with -Ls0. It writes a final 301 line to the log, after which the log is treated as finished; to continue the run later, remove that line.
  • -o, -o<bits>: when all factorization methods have failed for some value, log it and carry on, instead of stopping. With <bits>, values of more than that many bits are logged without trying the slowest methods (QS and beyond), so that they can be factorized separately.
  • -s<seed>: seed for the random number generator, used at least for ECM factorization (default 1, so that runs are reproducible).
  • -v: show progress in the terminal window title as well, using VT100 escape sequences.
  • -y<type>: fail unless the program is of the given type (o for pcoul, a for pcaul, r for pcrul). Used by the harness.

Debugging

These are mainly for development and testing.

  • -d: show a progress line at every step, each on a new line, but only one line for each walk. -d -d: also show every step of each walk.
  • -dw<c>, -dW<c>: as -d and -d -d; with a count $c$, stop after $c$ lines.
  • -dL<c>: write every progress line to the log as well; with a count $c$, stop after $c$ lines. Stopping writes a final 301 line, as for -Ld.
  • -db: show each batch as it is started; -dB: show every batch, even those not otherwise shown.
  • -df: show the prepared forced-prime batches.
  • -dx: show the $p^x$ constraints.
  • -dt: show the target tau at each position.
  • -dc, -dC: show the modular constraints (-dC shows more detail).
  • -dm: track and show some internal statistics, and imply -dl.
  • -dl: at the end of the run, report extra lines used by the automated harness: a 500 line if no solution was found, else the factorization of each value of the best one (211 lines).
  • -dT (calibrate2 branch only): note in the log each section of the cost table made by a different build of divrep or MPU::GMP.
  • -dv<bits> (calibrate2 branch only): in a build with VERBOSE=1, select instrumentation, as the sum of: 1 for a trace of the recursion, walks and factoring tests to standard output; 2 for records of each gate decision, recursion loop and walk (and more) to the file named by $GATE_STATS (default gate_stats.log); 4 to add, with 2, the time spent in each stage of a walk's tests; 8, 16 and 32 for records of -ja2's choices, of test preparations and of the run's counted costs, to the same file. See trace.h and trace.c. The default is none, and the build is then only a few percent slower than a normal one. The same build runs the benchmarks behind the cost tables of multibench-table (see bench.c).

Clone this wiki locally