#!/bin/bash
# run_all.sh.txt (a bash script; the archive accepts only certain file types, hence .txt): rerun every numerical certificate behind the paper (Theorem 1 at 18, Theorem 2 at 14, Theorem 3 at 9)
# from this supplement, then compare with expected/ and with the bounds stated in the paper (compare.py).
#
# Usage:   PY=<python with mpmath, numpy and python-flint> bash run_all.sh.txt [OUTDIR]
# Default: PY = python3; OUTDIR = ./out. Single-threaded; each script runs at nice 10 if `nice` is available.
# The code tree is first copied into OUTDIR, and every script runs from its copy there, because some scripts read and write files next
# to themselves (third/t2_check/*.py read ../js_cert/; cert_S3P_K18.py writes its .out beside itself).
# Tested: Python 3.14.4, mpmath 1.3.0, numpy 2.5.2, python-flint 0.9.0 on Linux (see REPRODUCTION.md for wall times).
set -u
HERE="$(cd "$(dirname "$0")" && pwd)"
OUT="$(mkdir -p "${1:-$HERE/out}" && cd "${1:-$HERE/out}" && pwd)"
PY="${PY:-python3}"
export OMP_NUM_THREADS=1 OPENBLAS_NUM_THREADS=1 MKL_NUM_THREADS=1 PYTHONDONTWRITEBYTECODE=1
NICE=""; command -v nice >/dev/null && NICE="nice -n 10"
for d in author second third audit; do cp -rp "$HERE/$d" "$OUT/"; done
echo "# run_all.sh.txt started $(date -u '+%Y-%m-%d %H:%M:%S UTC'); $($PY -c 'import sys, mpmath, numpy, flint; print("python", sys.version.split()[0], "mpmath", mpmath.__version__, "numpy", numpy.__version__, "python-flint", flint.__version__)')"
now() {  # a monotonic clock in seconds (the wall clock can step on some virtual machines)
  if [ -r /proc/uptime ]; then cut -d' ' -f1 /proc/uptime; else date +%s; fi
}
run() {  # run OUTFILE CMD...: stdout and stderr to OUTFILE, report exit status and elapsed time
  local name=$1; shift; local t0; t0=$(now)
  $NICE "$@" > "$name" 2>&1; local rc=$?
  echo "${PWD#$OUT/}/$name: exit $rc, $(awk -v a="$t0" -v b="$(now)" 'BEGIN { printf "%.1f", b - a }') s"
}
# 1. author/ (mpmath iv): the rows of Lemma 7 and two values in remarks; the f/F enclosures of Appendix B (python-flint)
cd "$OUT/author"
run cert_C3s_v7.out            "$PY" cert_C3s_v7.py
run fF_enclose.out             "$PY" fF_enclose.py
# 2. second/ (Arb via python-flint): Lemmas 7, 10 and 16 and the grids of Theorem 2 (the grid scripts import ../author/cert_qrh_range.py)
cd "$OUT/second"
run cert_C3_e1800.out          "$PY" cert_C3.py 1800 4e18 0.2 18
run cert_C3_e350.out           "$PY" cert_C3.py 350 4e18 0.2 13 14 16
run cert_C3_e62.out            "$PY" cert_C3.py 62 4e18 0.2 9
run cert_C4.out                "$PY" cert_C4.py 2736.86 1800 0.02 0.02 17 18
run cert_S4_H400.out           "$PY" cert_S4.py 400 0.01 17 18
run cert_qrhB3_K14_low.out     "$PY" cert_qrhB3.py 14 350 51046 1.01 0.05 200
run cert_qrhB3p_K14_top.out    "$PY" cert_qrhB3p.py 14 51046 159011874857757 1.05 0.05 200
# 3. third/ (mpmath iv): the (I4') certificate, the certificate of record for Lemma 16, and the GRH pieces
cd "$OUT/third/js_cert"
run tp_bound.stdout            "$PY" tp_bound.py              # writes tp_bound.out
run js_cert.out                "$PY" js_cert.py               # reads tp_bound.out, writes js_cert.json
cd "$OUT/third/t2_check"
run cert_S3P_K18.stdout        "$PY" cert_S3P_K18.py           # reads ../js_cert/js_cert.json and tp_bound.out, writes cert_S3P_K18.out
run c3_grh.out                 "$PY" c3_grh.py
run cert_grh_sieve.out         "$PY" cert_grh_sieve.py         # reads ../js_cert/tp_bound.out
# 4. audit/ (Arb): an independent audit of the (I4') certificate. audit_js.py also reruns a historical chain from ./original_js_uniform.py
cd "$OUT/audit"
cp js_uniform.py original_js_uniform.py
run audit_js.out               "$PY" audit_js.py
# 5. audit/t2v6/ (Arb): independent audits of Lemmas 7, 10, 16, 23 and 25, of Theorem 2's grids, and of the float cell weights.
#    audit_v6.py reads the grid parameters from frozen/second/ (copies of second/'s grid files taken for the audit); the others
#    write their JSON into resume1/.
cd "$OUT/audit/t2v6"
mkdir -p resume1
run audit_c4.out               "$PY" -B audit_c4.py
run audit_s4.out               "$PY" -B audit_s4.py
run audit_grh9.out             "$PY" -B audit_grh9.py
run audit_v6.out               "$PY" -B audit_v6.py
run check_float_cells.out      "$PY" -B check_float_cells.py   # imports audit_v6; also writes numpy_convolve_source.txt (version-dependent)
echo "# runs finished $(date -u '+%Y-%m-%d %H:%M:%S UTC')"
"$PY" "$HERE/compare.py" "$HERE/expected" "$OUT"
