Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
393 commits
Select commit Hold shift + click to select a range
945c8f7
feat(system): System can hold and evaluate blocks
ofloveandhate Jun 13, 2026
57ec051
feat(mhom): evaluate the MHom start system via a products-of-linears …
ofloveandhate Jun 13, 2026
433354c
feat(system): BlendBlock over Systems; add it to the Block variant
ofloveandhate Jun 13, 2026
f32301f
fix(test): qualify Mat/Vec in products-of-linears test
ofloveandhate Jun 13, 2026
620dbcd
feat(mhom): solve multihomogeneous systems end-to-end via the block h…
ofloveandhate Jun 13, 2026
c064a88
Merge pull request #17 from ofloveandhate/feature/unify_rng_seeding
ofloveandhate Jun 13, 2026
0446772
feat(python): bind the multihomogeneous ZeroDim solver to Python
ofloveandhate Jun 13, 2026
27da280
fix(amp): block-composed System evaluations return at working precision
ofloveandhate Jun 13, 2026
a3862c5
docs(tutorials): all-solutions and eigenvalues-by-homotopy
ofloveandhate Jun 13, 2026
a5050b2
feat(linalg): express conditions over vectors and matrices of variables
ofloveandhate Jun 13, 2026
ddcc0f6
Merge remote-tracking branch 'origin/develop' into feature/infer_star…
ofloveandhate Jun 13, 2026
d0b771d
feat(blocks): LinearFormsBlock — affine linear forms M x + b as an ev…
ofloveandhate Jun 13, 2026
36eb0a7
fix(mhom): support projective variable groups in start-point generation
ofloveandhate Jun 13, 2026
dbfc009
feat(blocks): boost serialization of the evaluation-block variant
ofloveandhate Jun 13, 2026
5998cde
feat(python): construct LinearFormsBlock from Python (linalg.add_line…
ofloveandhate Jun 13, 2026
29606fd
refactor(mhom): generate start coefficients directly; retire LinearPr…
ofloveandhate Jun 13, 2026
6c82704
feat(linalg): add_linear — constant-coefficient linear forms as a Lin…
ofloveandhate Jun 13, 2026
5afe606
feat(python): unified System.add(*objects) builder
ofloveandhate Jun 13, 2026
d6b6c02
feat(system): PolynomialBlock foundation (fold step 1a, behavior-pres…
ofloveandhate Jun 13, 2026
1699a12
feat(system): PolynomialBlock accessors + simplify + SLP-deriv fix (f…
ofloveandhate Jun 13, 2026
fd7f2bb
refactor(system)!: fold the classic polynomial path into the Polynomi…
ofloveandhate Jun 14, 2026
e487e68
feat(system): block-aware Degrees() (+ DegreeBound guard) with a degr…
ofloveandhate Jun 14, 2026
2305c17
test(python): degrees of the linear-algebra evaluation paths
ofloveandhate Jun 14, 2026
f937d4c
ci(windows): opt out of the MSVC STL1000 compiler-version gate
ofloveandhate Jun 14, 2026
386e949
feat(system): homogenization-aware blocks — structured blocks survive…
ofloveandhate Jun 14, 2026
90f8f31
test(mhom): fold accuracy into the gamma-retry so a fragile fixed-dou…
ofloveandhate Jun 14, 2026
6efff5a
test(mhom): solve the end-to-end MHom check with AMP instead of fixed…
ofloveandhate Jun 14, 2026
1f704aa
test(mhom): mark fixed-double MHom variants best-effort (non-strict x…
ofloveandhate Jun 14, 2026
90870cb
test(mhom): kill the gamma-retry storms that ballooned Windows CI
ofloveandhate Jun 14, 2026
3a24ffb
test(zerodim): end-to-end user-homotopy parameter solve from a given …
ofloveandhate Jun 14, 2026
1d4fcd1
feat(python): user-homotopy ZeroDim — solve from your homotopy + your…
ofloveandhate Jun 14, 2026
9210d60
test(mhom): fixed-double MHom smoke tolerates a tracking failure on a…
ofloveandhate Jun 14, 2026
dbdbc95
feat(python): coefficient_parameter_homotopy helper + parameter-homot…
ofloveandhate Jun 14, 2026
87f8f8c
docs(tutorial): a real point on every component — Hauenstein on the T…
ofloveandhate Jun 14, 2026
670f766
fix(mpi)!: distributed ZeroDim was silently wrong — broadcast the hom…
ofloveandhate Jun 14, 2026
b8abc6d
feat(nag): compute solution metadata (finite/real/singular) matching …
ofloveandhate Jun 14, 2026
5e7957a
docs(adr): ADRs 0015-0017 — metadata classification, distributed-seed…
ofloveandhate Jun 14, 2026
62db64c
docs(tutorial): solving at scale (#5) — distributed cyclic + eigenval…
ofloveandhate Jun 14, 2026
606cd94
test(ci)!: stop the 6-hour Windows hang — bound every test, kill the …
ofloveandhate Jun 14, 2026
4c79dc7
docs(adr): ADR-0018 — bound every test with a timeout; pin seeds, ski…
ofloveandhate Jun 14, 2026
38ed425
feat(parser): read CondNumThreshold in the classic PostProcessing parser
ofloveandhate Jun 14, 2026
ea87fb0
docs(adr): ADR-0015 — CondNumThreshold parser follow-up resolved
ofloveandhate Jun 14, 2026
bd4308c
probe(amp): Step-0 escalation instrumentation harness
ofloveandhate Jun 14, 2026
f0ddb12
feat(system): scoped System::ExpandToFunctionTree() + correctness tests
ofloveandhate Jun 15, 2026
13cb4be
test(amp): verify J-inverse estimate + real-homotopy block==function-…
ofloveandhate Jun 15, 2026
29991c3
probe(amp): condition-number trajectory observer + projective start-p…
ofloveandhate Jun 15, 2026
dbe52d3
probe(amp): catch a spiking trajectory -- escalation is spurious, not…
ofloveandhate Jun 15, 2026
4e0a570
fix(amp)+probe: precision-decrease threshold 10->5 (B1 StepsForIncrea…
ofloveandhate Jun 15, 2026
5018fb5
probe(amp): bounded trace + pinned spike config; empirical chain conf…
ofloveandhate Jun 15, 2026
4eac45a
probe(seed): determinism diagnostic -- it is NOT an RNG seeding problem
ofloveandhate Jun 15, 2026
1efff22
feat(rng): collision-free deterministic seeding + fixed AMP probe vector
ofloveandhate Jun 15, 2026
c17760a
fix(repro): clear mpfr constant cache at each solve boundary
ofloveandhate Jun 15, 2026
258f31a
docs(amp): document A/B confirmation that the regenerated probe vecto…
ofloveandhate Jun 15, 2026
62774d8
probe(amp): pin the escalation driver to size_proportion (not ||J^-1||)
ofloveandhate Jun 15, 2026
9cfc06b
fix(amp)!: default predictor Euler -> RKF45 (perf + stable size_propo…
ofloveandhate Jun 15, 2026
c2057e3
fix(amp): correct Euler/non-error-estimate size_proportion (drop spur…
ofloveandhate Jun 15, 2026
4bcc052
fix(amp): faithful port of Bertini 1's AMP2_update (step credit + mar…
ofloveandhate Jun 15, 2026
22720ca
build: omit -g from Release builds (ADR-0019)
ofloveandhate Jun 15, 2026
be03a30
chore(amp): remove escalation probe instrumentation; unskip MHom tests
ofloveandhate Jun 15, 2026
a09c249
feat(linalg): expose products-of-linears block + user-authored blend …
ofloveandhate Jun 16, 2026
4b76840
docs(tutorial): author your own product-of-linears start system
ofloveandhate Jun 16, 2026
18b36d8
docs(tracking): fix stale doctest in tracking_nonsingular tutorial
ofloveandhate Jun 16, 2026
51e9093
docs(adr): ADR-0020 structured-block start systems need a blend homotopy
ofloveandhate Jun 16, 2026
8092c01
docs: clear all pre-existing Sphinx warnings
ofloveandhate Jun 16, 2026
e908e81
feat(nag_algorithm): friendly ZeroDim() factory over the 18 bound sol…
ofloveandhate Jun 16, 2026
42cffba
fix(nag_algorithm): blend structured starts in coefficient_parameter_…
ofloveandhate Jun 16, 2026
4fb05ea
test(linalg): products-of-linears block survives a deep-copy clone ro…
ofloveandhate Jun 16, 2026
12f264d
test(linalg): products-of-linears authoring works multi-group and pro…
ofloveandhate Jun 16, 2026
637fb8e
docs(adr): ADR-0020 — coefficient_parameter_homotopy hardened; author…
ofloveandhate Jun 16, 2026
574ddb5
fix(patch): zero the patch's own Jacobian rows (uninitialized-memory …
ofloveandhate Jun 16, 2026
c2a1c59
feat(core): is_block_v enforces the full evaluation-block contract
ofloveandhate Jun 16, 2026
2575589
feat(bindings): VariableGroup (and the list converters) accept any it…
ofloveandhate Jun 16, 2026
8f579e3
test(mhom): fixed-double MHom solves -- assert the roots, drop the fa…
ofloveandhate Jun 16, 2026
904db54
docs(linalg): numpy/pandas-style Examples + how to spell exact non-in…
ofloveandhate Jun 16, 2026
427568d
docs(nag_algorithm): Examples section for the ZeroDim factory
ofloveandhate Jun 16, 2026
af7a68b
ci: raise Linux build parallelism to 4; opt into Node 24; fix conda d…
ofloveandhate Jun 16, 2026
a5d8c10
fix(nag_algorithm): ZeroDim infers the start system from variable groups
ofloveandhate Jun 16, 2026
8bad6c8
docs(adr): ADR-0021 — a block (and the patch) must fully define its o…
ofloveandhate Jun 16, 2026
1783ae7
Merge pull request #18 from ofloveandhate/feature/infer_start_system_…
ofloveandhate Jun 16, 2026
b8d8094
bump version to 3.0.0.
ofloveandhate Jun 16, 2026
c18f1e5
shoulda been 3.0.0.dev1. also updated the readme
ofloveandhate Jun 16, 2026
ef47611
📝 added missing submodules etc to detailed docs
ofloveandhate Jun 17, 2026
86a75da
📝 reorder tutorials to create scaffolding
ofloveandhate Jun 17, 2026
388c4bc
📝 improved manual-run endgame tutorial
ofloveandhate Jun 17, 2026
e5b3b6d
📝 Added a note about installation
ofloveandhate Jun 17, 2026
7b37df0
📝 fixed a lie in opening paragraph
ofloveandhate Jun 17, 2026
219995e
feat(system): randomize overdetermined systems via a first-class Rand…
ofloveandhate Jun 17, 2026
c65fa6c
Merge pull request #20 from ofloveandhate/feature/docs_improvements_2026
ofloveandhate Jun 17, 2026
4d31415
fix(nag_algorithm): detect and re-track crossed paths at the endgame …
ofloveandhate Jun 16, 2026
d0210e1
refactor(nag_algorithm): unify per-path execution behind shared bodies
ofloveandhate Jun 17, 2026
9bb66f3
refactor(nag_algorithm): serial Solve uses the speculative-full-path …
ofloveandhate Jun 17, 2026
c798cb2
feat(nag_algorithm): distributed solve uses the speculative-full-path…
ofloveandhate Jun 17, 2026
9fe5db2
fix(function_tree): compute pi from the authoritative MPFR constant, …
ofloveandhate Jun 17, 2026
42fe796
feat(nag_algorithm): broadcast rank 0's authoritative systems in dist…
ofloveandhate Jun 17, 2026
664d9dc
feat(nag_algorithm): rank 0 computes start points and ships them to w…
ofloveandhate Jun 17, 2026
ff8c4b5
fix(trackers): refresh the condition-number probe once per path, via …
ofloveandhate Jun 17, 2026
36bbf1a
build: skip the deprecated MPI C++ bindings (MPICH_SKIP_MPICXX / OMPI…
ofloveandhate Jun 17, 2026
448e507
build: route every <mpi.h> include through a guard header (skip MPI C…
ofloveandhate Jun 17, 2026
ec1ba4d
docs: document random/sympy_bridge/config submodules; fix napoleon wa…
ofloveandhate Jun 17, 2026
df9515d
feat(system): moving-row homotopies — blend only the moving rows, eva…
ofloveandhate Jun 17, 2026
fbe6271
feat(python): enable pickling for System, multiprecision numbers, con…
ofloveandhate Jun 17, 2026
22ba548
feat(system): human-facing block-by-block printing (terse placeholder…
ofloveandhate Jun 17, 2026
61a927c
Merge pull request #21 from ofloveandhate/feature/more_fixes_another_…
ofloveandhate Jun 17, 2026
4f543e5
Merge remote-tracking branch 'origin/develop' into feature/randomization
ofloveandhate Jun 17, 2026
b1d809c
docs(adr): renumber randomization/moving ADRs to 0025/0026 after #21 …
ofloveandhate Jun 18, 2026
ac32af2
test(crossed-paths): raise the cyclic-5 timeout 360->900s for the man…
ofloveandhate Jun 18, 2026
afa4bea
test(crossed_paths): deterministic planted cubic crossing, no seed se…
ofloveandhate Jun 18, 2026
f10bd9f
fix(config): explicit __copy__/__deepcopy__ so configs deep-copy corr…
ofloveandhate Jun 18, 2026
3ff66df
Merge pull request #19 from ofloveandhate/feature/randomization
ofloveandhate Jun 18, 2026
00f8bea
dev version bump
ofloveandhate Jun 18, 2026
d1ce539
fixed name of tutorial
ofloveandhate Jun 18, 2026
c1c6282
fixed subtitle
ofloveandhate Jun 18, 2026
7c8599f
removed a bunch of cruft
ofloveandhate Jun 18, 2026
2b60bd1
Merge pull request #22 from ofloveandhate/feature/moredocs
ofloveandhate Jun 18, 2026
6589927
feat(python): expose step diagnostics on trackers (stepsize, delta_t,…
ofloveandhate Jun 18, 2026
f16e3fe
docs(observer): document the event-lifetime contract (#255 point 4)
ofloveandhate Jun 18, 2026
c9873d5
refactor(observer): return-value unsubscribe + deferred mutation (#25…
ofloveandhate Jun 18, 2026
fa272af
feat(python): path-collecting meta-observer for visualizing tracked p…
ofloveandhate Jun 18, 2026
8b3fbb1
docs(tutorial): observers and path-data visualization, with a plot
ofloveandhate Jun 18, 2026
83b874e
refactor(observer): CRTP TypedObserver replaces per-observer dynamic_…
ofloveandhate Jun 18, 2026
308d968
feat(observer): co-owned observer lifetimes + incompatible-attach gua…
ofloveandhate Jun 18, 2026
2b3bddb
rename(python): observer base Abstract -> CustomObserver
ofloveandhate Jun 18, 2026
6442468
feat(python): precision-agnostic event handles + string-named Callbac…
ofloveandhate Jun 18, 2026
66ddacd
feat(nag): ZeroDim emits lifecycle events on the AnyZeroDim base
ofloveandhate Jun 18, 2026
2511e47
feat(python): expose ZeroDim observability + nag observers (CustomObs…
ofloveandhate Jun 18, 2026
2a3a9ef
feat(python): SolutionPathCollector — whole solution paths (incl. end…
ofloveandhate Jun 18, 2026
87ca83e
docs(tutorial): use an explicit 1:1 data aspect ratio for the paths plot
ofloveandhate Jun 18, 2026
2479d7a
docs(tutorial): add a 3-D cyclic-3 example, paths coloured by conditi…
ofloveandhate Jun 18, 2026
6ed9f04
docs(tutorial): seed all examples, add singular-endgame (Griewank-Osb…
ofloveandhate Jun 18, 2026
9f89971
rename(nag): PathBeginning -> PathStarted (mirrors AlgorithmStarted)
ofloveandhate Jun 18, 2026
827a11b
Merge pull request #23 from ofloveandhate/feature/observer_party
ofloveandhate Jun 19, 2026
a2d0724
docs(tutorial): add a 'build your own A-attaches-B observer' section
ofloveandhate Jun 19, 2026
9640d53
docs(doctest): execute real_points.rst code blocks; headless matplotlib
ofloveandhate Jun 19, 2026
560fab3
docs(doctest): execute all_solutions.rst and parameter_homotopy.rst b…
ofloveandhate Jun 19, 2026
cc24503
docs(doctest): execute user_product_of_linears.rst blocks
ofloveandhate Jun 19, 2026
daaebea
docs(doctest): execute evaluation_cyclic.rst blocks
ofloveandhate Jun 19, 2026
b7184d0
docs(doctest): fix and execute manual_endgame_usage.rst (it had bit-r…
ofloveandhate Jun 19, 2026
95b2a8e
docs(doctest): execute eigenvalues_by_homotopy.rst blocks
ofloveandhate Jun 19, 2026
1e78ef8
docs(doctest): execute the narrative blocks in tracking_nonsingular.rst
ofloveandhate Jun 19, 2026
193bd2f
docs(doctest): execute observers_and_path_data.rst code blocks
ofloveandhate Jun 19, 2026
5ad57d9
test(docs): run the literalinclude'd example scripts serially
ofloveandhate Jun 19, 2026
c73a9a3
ci: matplotlib for doctest build; skip example-script test without mp…
ofloveandhate Jun 19, 2026
9f8db73
test(docs): resolve bertini via inherited sys.path, not the source tree
ofloveandhate Jun 21, 2026
b59e456
test(docs): gate the heavy crossed_paths.py example behind an opt-in …
ofloveandhate Jun 21, 2026
6c25362
refactor(system): remove the JacobianNode derivative eval strategy (R…
ofloveandhate Jun 21, 2026
83288e7
refactor(function_tree): functional Node::Simplified() (Rung 1a, part 1)
ofloveandhate Jun 21, 2026
7ea8c64
refactor(function_tree): remove in-place Eliminate*/ReduceDepth (Rung…
ofloveandhate Jun 21, 2026
259e4e4
refactor(function_tree): functional Homogenized() (Rung 1b)
ofloveandhate Jun 21, 2026
a6766bd
test(homogenization): use functional Homogenized() (Rung 1b follow-up)
ofloveandhate Jun 21, 2026
bef6932
feat(function_tree): structural hash + equality on Node (Rung 2)
ofloveandhate Jun 21, 2026
07d6ac6
feat(function_tree): hash-consing intern table; route every Make thro…
ofloveandhate Jun 21, 2026
5c00c05
feat(function_tree): variables canonical by name (Rung 3b)
ofloveandhate Jun 21, 2026
01dc4ff
feat(function_tree): canonical operand-order machinery, pluggable mon…
ofloveandhate Jun 21, 2026
2727152
fix(parser): unary minus binds one factor, not the whole expression
ofloveandhate Jun 21, 2026
6724796
feat(function_tree): canonicalize operand order by default (Rung 3c, …
ofloveandhate Jun 21, 2026
b429e73
docs: drop workflow 'Rung N' / 'decision #N' references from code com…
ofloveandhate Jun 21, 2026
02cd824
feat(python): expose canonicalization controls + printing/opt-out tests
ofloveandhate Jun 21, 2026
556d931
docs: drop a stray 'Rung 3a' reference from node.hpp Intern() comment
ofloveandhate Jun 21, 2026
7308055
feat(function_tree): restore like-factor and like-term combining in S…
ofloveandhate Jun 21, 2026
461bec8
test(slp): CSE benchmark + NumMemorySlots accessor
ofloveandhate Jun 21, 2026
349c937
test(slp): oracle asserting the SLP agrees with the tree-walk evaluator
ofloveandhate Jun 21, 2026
1d8ee4e
docs(tutorial): canonical ordering and the opt-out
ofloveandhate Jun 21, 2026
942f7f1
refactor(system): make the SLP the sole evaluator; remove EvalMethod:…
ofloveandhate Jun 21, 2026
a052de3
feat(eval): evaluate a bare expression with no System, f.eval(x=2, y=5)
ofloveandhate Jun 22, 2026
0edbc04
refactor(total_degree): read random constants via Rational::Value, no…
ofloveandhate Jun 22, 2026
1bb8e17
refactor(blend_block): evaluate coefficients via a cached System, not…
ofloveandhate Jun 22, 2026
6314580
docs(adr): SLPs belong to output-sets; Program/Memory split + freeze-…
ofloveandhate Jun 22, 2026
d578a26
perf(slp): freeze-set tape partition — skip constant prologue on poin…
ofloveandhate Jun 22, 2026
6b83721
refactor(slp): compiler wires outputs from bare roots, not Function m…
ofloveandhate Jun 22, 2026
8ac65cd
refactor(parse): eager-bind classic functions; System no longer needs…
ofloveandhate Jun 22, 2026
fd93dbf
refactor(system): store functions as bare Nd, not Function; cut funct…
ofloveandhate Jun 22, 2026
6c6d3df
fix(parse): route the Python parser binding through the canonical C++…
ofloveandhate Jun 22, 2026
fe4351a
docs(adr): named-node taxonomy — NameHolder, 3 named kinds, NamedExpr…
ofloveandhate Jun 22, 2026
fd95e66
refactor(function_tree): rename the Named name-storage mixin to NameH…
ofloveandhate Jun 22, 2026
a9396f2
feat(function_tree): introduce immutable NamedExpression — Named(expr…
ofloveandhate Jun 22, 2026
7997ed9
feat(function_tree): generic Find<T> (sympy-style); GatherVariables i…
ofloveandhate Jun 22, 2026
b357311
refactor(function_tree): delete the dead node::Jacobian (and with it …
ofloveandhate Jun 22, 2026
c26ea38
feat(parse): subfunctions become immutable NamedExpressions; no stora…
ofloveandhate Jun 22, 2026
a1dad9d
docs(adr): record implementation status + F/E renumbering in ADR-0027…
ofloveandhate Jun 22, 2026
f9ea025
refactor(slp): split StraightLineProgram into immutable SLPProgram + …
ofloveandhate Jun 22, 2026
3bb82fb
refactor(slp): bake constants as exact node-free recipes, not node po…
ofloveandhate Jun 22, 2026
2bbac1f
refactor(system): route the path value through a stored buffer, not t…
ofloveandhate Jun 22, 2026
4cc4c66
refactor(system): stop the per-thread eval path writing node state (E…
ofloveandhate Jun 22, 2026
614088c
refactor(parse): eager-bind function/constant/parameter to NamedExpre…
ofloveandhate Jun 22, 2026
a5a17d3
refactor(system): Clone shares DAG + Program, isolates Memory; delete…
ofloveandhate Jun 22, 2026
6e307b0
docs: record E1 (Program/Memory split) as done in ADR-0027 + roadmap;…
ofloveandhate Jun 22, 2026
710ae4c
refactor(function_tree): delete Function and Handle; NamedExpression …
ofloveandhate Jun 22, 2026
b8593eb
docs: drop work-stage labels (E1/"stage N") from code and test comments
ofloveandhate Jun 22, 2026
4beeff9
perf(eval): memoize the compiled program for f.eval on the node, reti…
ofloveandhate Jun 22, 2026
7085596
merge: Track F (delete Function/Handle; NamedExpression is the sole r…
ofloveandhate Jun 22, 2026
171be01
Merge pull request #24 from ofloveandhate/feature/documentation_impro…
ofloveandhate Jun 22, 2026
dd981af
refactor: remove two production node-eval consumers ahead of deleting…
ofloveandhate Jun 22, 2026
b336658
refactor: delete FixVariable / RemoveVariable (vestigial), removing t…
ofloveandhate Jun 22, 2026
b449e1f
test: replace the node-level eval/diff matrices with focused SLP-eval…
ofloveandhate Jun 22, 2026
0c6c488
test: migrate C++ node-eval verification to the SLP path (EvalAt helper)
ofloveandhate Jun 23, 2026
1e55a2e
test(python): move function_tree_test off node eval; consolidate oper…
ofloveandhate Jun 23, 2026
3030854
test(python): migrate remaining node-eval tests to the SLP; add node.…
ofloveandhate Jun 23, 2026
0f1ecb5
refactor: delete node-level evaluation -- the SLP is now the only eva…
ofloveandhate Jun 23, 2026
2140a97
refactor: remove the dead auto-simplify machinery
ofloveandhate Jun 23, 2026
f4fb29a
Merge remote-tracking branch 'origin/develop' into feature/eliminate_…
ofloveandhate Jun 23, 2026
c9e8baa
fix(example): solve cyclic-n with adaptive precision; use named succe…
ofloveandhate Jun 23, 2026
bd42e14
fix(docs): tracking_nonsingular uses the bare add_function (F-track r…
ofloveandhate Jun 23, 2026
86e0ecc
docs(tutorial): add "When double precision is not enough" (adaptive p…
ofloveandhate Jun 23, 2026
cd2b725
feat(nag): SolveReport -- an end-of-zero-dim-solve diagnostic summary
ofloveandhate Jun 23, 2026
be3a63d
docs(dogfood): use solver.report() in solve_cyclic.py and the precisi…
ofloveandhate Jun 23, 2026
2d1ae93
feat(nag): filtered solution accessors (finite/real/nonsingular/singu…
ofloveandhate Jun 23, 2026
0b88542
docs(dogfood): use the filtered solution accessors across the tutorials
ofloveandhate Jun 23, 2026
eec36ab
fix(test): repair two stale-masked C++ test regressions (red CI on a …
ofloveandhate Jun 23, 2026
78c3da8
Merge pull request #25 from ofloveandhate/feature/eliminate_duplicate…
ofloveandhate Jun 23, 2026
9639a24
fix(test): give the adaptive solve_cyclic example test a 600s budget …
ofloveandhate Jun 23, 2026
426ae33
fix(test): override the global 180s pytest-timeout for the adaptive s…
ofloveandhate Jun 23, 2026
20cfb88
fix(docs): reset default_precision per-document in the doctest build
ofloveandhate Jun 23, 2026
8ea5e5e
docs(dogfood): eigenvalues_by_homotopy reads eigenpairs from finite_s…
ofloveandhate Jun 23, 2026
0f8d3b7
fix(nag): uniform ambient precision for fixed-multiple solves; defaul…
ofloveandhate Jun 23, 2026
2c0c052
fix(example): gate solve_cyclic on num_failed, not all_paths_resolved…
ofloveandhate Jun 23, 2026
cf34837
feat(io): classic-format writer (INPUT section) -- the inverse of the…
ofloveandhate Jun 23, 2026
c78def4
feat(io): emit a full Bertini 1 classic input file (CONFIG + INPUT); …
ofloveandhate Jun 23, 2026
5465ebd
feat(io): emit the full step-size cadence in the classic writer (cont…
ofloveandhate Jun 23, 2026
b999429
feat(io,python): algorithm-level solver.to_classic_input(system)
ofloveandhate Jun 23, 2026
37ad76d
fix(system): concatenate copies the patch from the patched operand; d…
ofloveandhate Jun 23, 2026
612762f
fix(random): RandomUnit returns modulus 1; gamma is a max-precision u…
ofloveandhate Jun 23, 2026
0dc7d06
Merge branch 'feature/bertini1_emitter' into fix/ci_fallout
ofloveandhate Jun 23, 2026
b160693
Merge branch 'fix/gamma_norm_one' into fix/ci_fallout
ofloveandhate Jun 23, 2026
a93bc1b
docs(adr): record gamma generation + fixed-multiple precision decisio…
ofloveandhate Jun 23, 2026
3c3d3d8
test(zero_dim): cross-software cyclic-5 regression against a Bertini-…
ofloveandhate Jun 23, 2026
fea2666
Merge pull request #26 from ofloveandhate/fix/ci_fallout
ofloveandhate Jun 23, 2026
3398b3c
feat(config): update() accepts a string for every numeric field unifo…
ofloveandhate Jun 23, 2026
11ab84c
refactor(config): prefix RegenerationConfig's slice-moving tolerances…
ofloveandhate Jun 23, 2026
b376cc6
refactor(config): de-template ZeroDimConfig; one precision-agnostic c…
ofloveandhate Jun 23, 2026
d6d8c6d
feat(config): owner.update(**fields) -- set config fields by name, au…
ofloveandhate Jun 23, 2026
914815f
feat(config): get_settings()/set_settings() -- carry a whole config b…
ofloveandhate Jun 23, 2026
b155814
docs(tutorials): add "carrying settings across solves" and "precision…
ofloveandhate Jun 23, 2026
fdb8589
Merge pull request #28 from ofloveandhate/feature/config_ux
ofloveandhate Jun 24, 2026
dac8bbb
Merge pull request #27 from ofloveandhate/followup/adrs_and_cyclic5_o…
ofloveandhate Jun 24, 2026
38a1b91
feat(precision): FixedPrecisionConfig.precision sets a fixed-multiple…
ofloveandhate Jun 24, 2026
6f23419
Merge pull request #29 from ofloveandhate/feature/fixed_precision_config
ofloveandhate Jun 24, 2026
446b36c
chore: bump version to 3.0.0.dev3
ofloveandhate Jun 24, 2026
4504c46
docs: correct CLAUDE.md version-tracking line (pyproject.toml only; _…
ofloveandhate Jun 24, 2026
71f3893
feat(python): ZeroDim solution-access ergonomics — all_solutions, inf…
ofloveandhate Jun 24, 2026
3c2e0d4
fix(nag_algorithm): friendly error when a solver is passed to user_ho…
ofloveandhate Jun 24, 2026
906a7e7
Merge pull request #31 from ofloveandhate/fix/258-user-homotopy-solve…
ofloveandhate Jun 24, 2026
26b7898
docs(tutorial): add "database of solutions" — pandas filtering + plot…
ofloveandhate Jun 24, 2026
b87e39c
fix(python): to_dataframe must copy coordinates (eigenpy view aliasin…
ofloveandhate Jun 24, 2026
2b3f6a7
feat(nag): solver marks one representative per multiplicity cluster; …
ofloveandhate Jun 24, 2026
019998b
Merge remote-tracking branch 'origin/develop' into feature/solution_a…
ofloveandhate Jun 24, 2026
5888162
fix(nag): update #258 solver-detection fingerprint for the solutions(…
ofloveandhate Jun 24, 2026
dbd6a50
Merge pull request #30 from ofloveandhate/feature/solution_access
ofloveandhate Jun 24, 2026
59e84b7
refactor(python): to_dataframe keeps the whole solution in one column…
ofloveandhate Jun 24, 2026
3bee545
Merge pull request #32 from ofloveandhate/feature/solution_column
ofloveandhate Jun 24, 2026
b4f99e7
docs(adr): ADR-0031 — eigenpy Vec indexing returns an aliasing view; …
ofloveandhate Jun 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
183 changes: 147 additions & 36 deletions .github/workflows/build_and_test.yml

Large diffs are not rendered by default.

9 changes: 8 additions & 1 deletion .github/workflows/build_docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ jobs:
python -m pip install --upgrade pip
pip install \
sphinx sphinx-rtd-theme sphinxcontrib-bibtex gitpython \
scikit-build-core build numpy
scikit-build-core build numpy matplotlib pandas

- name: Download built wheel
uses: actions/download-artifact@v5
Expand All @@ -115,6 +115,13 @@ jobs:
- name: Install bertini from built wheel
run: pip install --no-index --find-links dist/ bertini2

- name: Run tutorial doctests (Sphinx)
# Execute the `.. testcode::` / `>>>` blocks in the docs against the installed wheel, so
# the tutorials are verified code, not just prose. Fails the build if any doctest fails.
working-directory: python/docs
run: |
sphinx-build -b doctest --keep-going source ../../build/docs/doctest

- name: Build Python docs (Sphinx)
working-directory: python/docs
env:
Expand Down
19 changes: 14 additions & 5 deletions .github/workflows/github-gitlab-sync.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
name: Sync to MPI GitLab
on:
name: Sync to GitLab mirror
on:
push

# Any repo (upstream or fork) that configures the three GITLAB_* secrets gets
# mirrored to its own GitLab target; repos without the secrets skip silently.
# This replaces the old hardcoded `if: github.repository == 'bertiniteam/b2'`,
# which prevented forks from syncing even when their secrets were set.
# Note: the `secrets` context is not available in job-level `if`, hence the
# env indirection.

jobs:
sync:
if: github.repository == 'bertiniteam/b2' #only on official
runs-on: ubuntu-latest
env:
GITLAB_CONFIGURED: ${{ secrets.GITLAB_URL != '' }}
steps:
- name: Sync to GitLab
if: env.GITLAB_CONFIGURED == 'true'
# You may pin to the exact commit or the version.
# uses: kujov/gitlab-sync@b19399d43e81ac88acb6eefd5588e6ebde3d7d88
uses: kujov/gitlab-sync@2.2.1
Expand All @@ -18,5 +28,4 @@ jobs:
# Your GitLab Personal Access Token with required permissions
gitlab_pat: ${{ secrets.GITLAB_PAT }}
# Whether to force push to GitLab. Defaults to false.

force_push: true # optional, default is false
force_push: true
28 changes: 28 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,31 @@ _skbuild/
build/
bld/
build_mine/

# Wheel / sdist output
dist/

# Local Claude Code config and personal working notes
.claude/
z_notes/
.mcp.json

# C++ test runner logs (ctest/Boost.Test output at repo root)
bertini2_tests_*.log

# Serialization test output files (Boost.Serialization archives)
/serialization_test_*

# Classic Bertini CLI output files (written by bertini2_exe when run from repo root)
/main_data
/raw_data
/raw_solutions
/real_finite_solutions
/midpath_data
/finite_solutions
/nonfinite_solutions
/start
/failed_paths

# Compiled benchmark binaries (keep the .cpp sources)
/tuning/arithmetic_cost
52 changes: 49 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,24 @@ ctest --test-dir build/core

### Python Tests

`pytest` is the single way to run the Python tests (the suites are plain pytest
functions + fixtures; the old `unittest` `TextTestRunner` aggregator scripts are gone):

```bash
pytest python/test/
```

The multiprecision default precision is **global mutable state**
(`bertini.default_precision(n)`). An **autouse fixture in `python/test/conftest.py`**
(`_reset_precision`) resets it to a known baseline (`DEFAULT_TEST_PRECISION = 30`) before
every test and restores it afterward, so no test can inherit a neighbor's precision — do
**not** re-introduce per-test `default_precision(...)` setup. To override the precision for
a specific test, use the `precision` fixture (parametrize it indirectly, e.g.
`@pytest.mark.parametrize("precision", [30, 50, 80], indirect=True)` with a
precision-derived tolerance). When adding or debugging precision-sensitive tests, run the
file on its own (`pytest python/test/classes/<file>.py`) to confirm it does not depend on
cross-test state.

## Architecture

The project has three layers, built in order:
Expand Down Expand Up @@ -101,11 +115,43 @@ The project has three layers, built in order:

## CI/CD

- `.github/workflows/build-and-publish-to-pypi.yml` -- Builds wheels on Ubuntu/macOS/Windows, publishes to TestPyPI on `develop` push, PyPI on version tags (`v*.*.*`).
- Pushes to `develop` trigger TestPyPI publish; tagged releases go to PyPI with Sigstore signing and GitHub Releases.
- `.github/workflows/build_and_test.yml` -- Builds wheels on Ubuntu/macOS/Windows and runs tests. Triggered by pull requests and pushes to `develop`/`main`.
- `.github/workflows/publish.yml` -- Publishes to TestPyPI on `develop` push, PyPI on version tags (`v*.*.*`) with Sigstore signing and GitHub Releases.

### Linux wheel test coverage

Linux wheels are built inside a `manylinux_2_34` container (AlmaLinux 9, MPFR 4.1; set via `CIBW_MANYLINUX_X86_64_IMAGE`). The **full pytest suite runs on all three platforms** — on Linux it runs *inside* that container via `CIBW_TEST_COMMAND_LINUX`, and on macOS/Windows via the host-runner test jobs.

This was not always so: for a while Linux ran an import smoke test only, because the suite was SIGABRT/SIGSEGV-crashing — a crash *misattributed* to the older `manylinux_2_28` container's MPFR 3.1.6. The real cause is a **version-independent** bug (uninitialized `mpfr`/`mpc` numpy slots), now fixed in the bindings. Do **not** try to fix Linux test crashes by bumping MPFR or the manylinux image (that was tried and does not work) or by building MPFR from source (specifically out of bounds). See `docs/adr/0006-eigenpy-uninitialized-numpy-slot-guards.md` for the fix and `docs/adr/0003-manylinux-no-full-pytest.md` for the (now reversed) smoke-test stopgap and its history.

## Python Bindings — Known Pitfalls

### eigenpy writable Ref + adjacent scalar (ADR-0001)

Never place a writable `Eigen::Ref<Vec<mpc_complex>>` argument **adjacent** to a `mpc_complex const&` scalar argument in a Boost.Python binding. eigenpy's from-Python converter for the writable Ref writes into a static rvalue-converter slot that overlaps with the storage for adjacent `const&` scalars, corrupting them. The corrupted `mpc_complex` then triggers `MPFR_ASSERTN` → SIGABRT.

**Rule:** If a binding takes a writable `Eigen::Ref<Vec<ComplexT>>` and also needs scalar `ComplexT` args, pass the scalars **by value**:

```cpp
// WRONG — start_time/end_time get corrupted
SuccessCode wrap(Eigen::Ref<Vec<ComplexT>> result,
ComplexT const& start_time, // ← adjacent const& scalar
ComplexT const& end_time);

// CORRECT — by-value copy is taken before the Ref converter runs
SuccessCode wrap(Eigen::Ref<Vec<ComplexT>> result,
ComplexT start_time, // ← by value
ComplexT end_time);
```

Single-argument bindings and read-only `Vec<T> const&` bindings are unaffected. See `docs/adr/0001-eigenpy-writable-ref-scalar-by-value.md`.

## Architecture Decision Records

`docs/adr/` contains ADRs for load-bearing design decisions — where the *why* would not be obvious from reading the code. Check there before undoing anything that looks strange.

## Conventions

- C++ standard: C++17. Headers use `.hpp` extension.
- License: GPL v3 with additional terms (see `licenses/`, `core/ADDITIONAL_GPL_TERMS`).
- Version is tracked in `python/bertini/_version.py` and `pyproject.toml`.
- Version is tracked in `pyproject.toml` (the `version = "..."` line), read at runtime via `importlib.metadata.version("bertini2")`.
12 changes: 10 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,16 @@ include("${JRL_CMAKE_MODULES}/base.cmake")
compute_project_args(PROJECT_ARGS LANGUAGES CXX)
project(${PROJECT_NAME} ${PROJECT_ARGS})

option(USE_CCACHE "Use ccache to speed up rebuilds if available" ON)
if(USE_CCACHE)
find_program(CCACHE_PROGRAM ccache)
if(CCACHE_PROGRAM)
set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PROGRAM}")
set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_PROGRAM}")
message(STATUS "ccache enabled: ${CCACHE_PROGRAM}")
endif()
endif()

include("${JRL_CMAKE_MODULES}/boost.cmake")

if(BUILD_PYTHON_BINDINGS)
Expand Down Expand Up @@ -200,8 +210,6 @@ endif(WIN32)

#target_link_boost_python(${PROJECT_NAME} PUBLIC)

#set_property(TARGET bertini2_exe PROPERTY OUTPUT_NAME bertini2)

add_subdirectory(core)


Expand Down
31 changes: 17 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@

# Quick links

- [Documentation](https://bertini2.org)
- [`bertini2` PyPI package](https://pypi.org/project/bertini2/)
- [Wiki](https://github.com/bertiniteam/b2/wiki)

---

# Overview

The solution of arbitrary polynomial systems is an area of active research, and has many applications in math, science and engineering. This software, Bertini 2, is a complete re-implementation of [Bertini 1](https://bertini.nd.edu) from C into C++/Python.
The solution of arbitrary polynomial systems is an area of active research, and has many applications in math, science and engineering. This software, Bertini 2, is a re-implementation of [Bertini 1](https://bertini.nd.edu) from C into C++/Python.

The theoretical basis for the solution of polynomials with Bertini is a theorem which bounds the number of solutions a system may have. It sits together with the numerical computational tool of "homotopy continuation". the act of "continuing" from one system into another through a "homotopy", as depicted in the below diagram:

Expand All @@ -18,29 +20,30 @@ The theoretical basis for the solution of polynomials with Bertini is a theorem

# Current capabilites

Bertini 2 currently has implemented the foundations of Numerical Algebraic Geometry. Development is ongoing, and here's what we have so far:
Bertini 2 has already implemented most of the foundations of Numerical Algebraic Geometry. Development is ongoing, and here's what we have so far:

- C++ functions and types, with Python bindings.
- Through Python, runtime scriptable construction of systems and interactivity with their zero-dimensional solutions.
- Construction of multivariate polynomial and non-polynomial systems.
- Evaluation of systems and their Jacobians in double and arbitrary multiple precision, using two different methods.
- A blackbox that implements tracktype 0 (zerodim solving) for the total degree and mhom start systems. User homotopy not yet exposed
- Through Python bindings, runtime scriptable construction of systems and interactivity with their zero-dimensional solutions.
- Python construction of multivariate polynomial and non-polynomial systems, including from linear algebra operations via numpy and Bertini 2's variables and extended numeric types.
- Evaluation of systems and their Jacobians in double and arbitrary multiple precision.
- Construction of the Total Degree and Multihomogeneous start systems.
- Construction of homotopies (they're just systems with path variables defined).
- Tracking of a start point x_0, corresponding to a particular time $t_0 \in \mathbb{C}^n$ in a homotopy $H$, from $t_0$ to $t_1$.
- Running of the Power Series and Cauchy endgames, in double, multiple, and adaptive precision.

Development is ongoing, and we want your help!
See the published docs for latest the officially released documentation (which will always lag behind the doc from the dev version).

---

# Missing functionality

* Parallel solving
✨ In-progress!!!

* Numerical irreducible decomposition
* Membership testing
* and other algorithms

Users wanting a more developed implementation are recommended to use [Bertini 1](https://bertini.nd.edu) or [homotopycontinuation.jl](https://www.juliahomotopycontinuation.org/), or one of the other packages implementing the theory.
Users wanting a more stable implementation are recommended to use [Bertini 1](https://bertini.nd.edu) or [homotopycontinuation.jl](https://www.juliahomotopycontinuation.org/), or one of the other packages implementing the theory.

---

Expand All @@ -55,12 +58,12 @@ The Python package `bertini2` provides pre-built wheels for Linux, macOS, and Wi
pip install bertini2
```

Once it's installed, you `import bertini`
Once it's installed, you `import bertini` (not `import bertini2`!)

* Linux: Python 3.9-3.14
* MacOS (Apple Silicon): Python 3.9-3.14
* MacOS (Intel): not supported
* Windows: Python 3.9-3.14
* Linux: Python 3.10-3.14
* MacOS (Apple Silicon): Python 3.10-3.14
* MacOS (Intel): not currently supported
* Windows: Python 3.10-3.14


## Building from source
Expand Down
69 changes: 69 additions & 0 deletions benchmark/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Bertini2 Parallel Benchmark

Scripts for measuring MPI + thread parallel speedup of the `bertini2` solver.

## Prerequisites

- `bertini2` built with MPI support (`cmake -DENABLE_MPI=ON ...`)
- `mpirun` on `PATH`
- Python 3.7+, no external packages needed

## Quick Start

```bash
# From the repo root
python benchmark/run_benchmark.py \
--bertini2 ./build/core/bertini2 \
--input benchmark/inputs/small.b2 \
--ranks 1 2 \
--threads 1 2
```

This runs the `small.b2` system (27 paths) with 4 combinations of ranks × threads,
prints a speedup table, and writes `benchmark_results.csv`.

## Sample Input Files

| File | Variables | Degree | Paths |
|------|-----------|--------|-------|
| `inputs/small.b2` | 3 | 3 | 27 |
| `inputs/medium.b2` | 5 | 3 | 243 |
| `inputs/large.b2` | 6 | 3 | 729 |
| `inputs/xlarge.b2` | 7 | 3 | 2187 |
| `inputs/huge.b2` | 9 | 3 | 19683 |

Each system is diagonal (`xi^3 - ci = 0`) with distinct prime constants, so solutions
are known analytically and correctness is easy to verify (solution count = number of
paths for these fully real systems).

## Options

```
--bertini2 PATH Path to bertini2 executable (default: ./build/core/bertini2)
--input FILE Bertini input file to solve (required)
--ranks N ... MPI rank counts to sweep (default: 1 2 4)
--threads N ... OMP thread counts per rank (default: 1)
--output FILE CSV output path (default: benchmark_results.csv)
--timeout SECS Per-run timeout (default: 600)
--repeats N Timed repeats per combo; records minimum (default: 1)
--mpirun CMD mpirun command (default: mpirun)
```

## Cluster Submission (SLURM)

Edit `submit.slurm.sh` (paths, module loads, rank/thread sweep) and submit:

```bash
sbatch benchmark/submit.slurm.sh
```

Results are written to `benchmark/results_<JOBID>.csv`.

## Notes

- `--bind-to none` is passed to `mpirun` automatically so that threaded workers
can use all cores on a node without affinity conflicts.
- Each (ranks, threads) combo runs in its own temp directory to avoid file conflicts.
- The serial baseline (ranks=1, threads=1) is always run first; speedup is computed
relative to that measurement.
- `OMP_NUM_THREADS` is set per-run by the script; do not set it externally when sweeping.
2 changes: 2 additions & 0 deletions benchmark/baseline_large.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ranks,threads,total_workers,wall_time_s,solutions_found,speedup_vs_serial
1,1,1,66.8036,7,1.0000
2 changes: 2 additions & 0 deletions benchmark/baseline_large_seeded.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ranks,threads,total_workers,wall_time_s,solutions_found,speedup_vs_serial
1,1,1,143.9177,7,1.0000
2 changes: 2 additions & 0 deletions benchmark/baseline_medium.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ranks,threads,total_workers,wall_time_s,solutions_found,speedup_vs_serial
1,1,1,42.7632,6,1.0000
2 changes: 2 additions & 0 deletions benchmark/baseline_medium_seeded.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ranks,threads,total_workers,wall_time_s,solutions_found,speedup_vs_serial
1,1,1,44.6928,6,1.0000
2 changes: 2 additions & 0 deletions benchmark/baseline_small.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ranks,threads,total_workers,wall_time_s,solutions_found,speedup_vs_serial
1,1,1,3.7077,4,1.0000
2 changes: 2 additions & 0 deletions benchmark/baseline_small_seeded.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ranks,threads,total_workers,wall_time_s,solutions_found,speedup_vs_serial
1,1,1,3.3135,4,1.0000
22 changes: 22 additions & 0 deletions benchmark/inputs/huge.b2
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
CONFIG

tracktype: 0;

END;

INPUT

variable_group x1, x2, x3, x4, x5, x6, x7, x8, x9;
function f1, f2, f3, f4, f5, f6, f7, f8, f9;

f1 = x1^3 - 2;
f2 = x2^3 - 3;
f3 = x3^3 - 5;
f4 = x4^3 - 7;
f5 = x5^3 - 11;
f6 = x6^3 - 13;
f7 = x7^3 - 17;
f8 = x8^3 - 19;
f9 = x9^3 - 23;

END;
24 changes: 24 additions & 0 deletions benchmark/inputs/huge_seeded.b2
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
CONFIG

tracktype: 0;

randomseed: 314159;

END;

INPUT

variable_group x1, x2, x3, x4, x5, x6, x7, x8, x9;
function f1, f2, f3, f4, f5, f6, f7, f8, f9;

f1 = x1^3 - 2;
f2 = x2^3 - 3;
f3 = x3^3 - 5;
f4 = x4^3 - 7;
f5 = x5^3 - 11;
f6 = x6^3 - 13;
f7 = x7^3 - 17;
f8 = x8^3 - 19;
f9 = x9^3 - 23;

END;
Loading
Loading