Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
630 commits
Select commit Hold shift + click to select a range
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
e14fed5
fix(system): reject equations in the wrong block of a moving homotopy…
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
80edc0c
Merge pull request #33 from ofloveandhate/fix/258-moving-homotopy-blo…
ofloveandhate Jun 24, 2026
d06b569
refactor(core): retire LinearSlice; Slice is a thin wrapper over Line…
ofloveandhate Jun 24, 2026
416f43b
feat(python): expose Slice and the WitnessSet getters/setters
ofloveandhate Jun 24, 2026
5d509de
feat(serialization): make Slice, WitnessSet, and NID result serializa…
ofloveandhate Jun 24, 2026
c4ed510
feat(slice): composition surface -- concatenate (+), as_system, and a…
ofloveandhate Jun 24, 2026
7d475ca
docs(adr): ADR-0032 — Slice is a thin wrapper over LinearFormsBlock; …
ofloveandhate Jun 24, 2026
66f258a
feat(slice): validate variable count when adding a slice to a System
ofloveandhate Jun 24, 2026
e32c1f9
feat(nid): Bertini 1 / classic emission for slices and witness sets
ofloveandhate Jun 24, 2026
00658f7
fix(system): Concatenate appends structured blocks, not just polynomi…
ofloveandhate Jun 24, 2026
bb769e2
feat(slice): homogenization-aware add_to; patch-correct witness_system
ofloveandhate Jun 24, 2026
926bc5d
docs(adr): ADR-0032 — record slice homogenization semantics and add_t…
ofloveandhate Jun 24, 2026
2e1f003
feat(nid): readable repr/str for WitnessSet
ofloveandhate Jun 24, 2026
3fb8ec0
feat(slice): own the shape contract — coefficients() 2-D, slice[i] a …
ofloveandhate Jun 24, 2026
f79a4a1
docs(tutorial): "Intro to slices" — witness sets, the slice shape sem…
ofloveandhate Jun 24, 2026
1783bc8
docs(claude): correct stale architecture/dependency notes
ofloveandhate Jun 24, 2026
31df08e
Merge pull request #34 from ofloveandhate/feature/witness-set-slice-e…
ofloveandhate Jun 24, 2026
0771b01
chore: bump version to 3.0.0.dev4
ofloveandhate Jun 24, 2026
6079e1e
fix(core): clear AppleClang warnings in core library
ofloveandhate Jun 25, 2026
ac84800
fix(core): clear remaining AppleClang warnings (tests + template-only…
ofloveandhate Jun 26, 2026
e4c882d
fix(bindings): remove -Wno-conversion, fix first-party warnings, mark…
ofloveandhate Jun 26, 2026
fcb96d1
Merge pull request #35 from ofloveandhate/feature/macos_compiler_warn…
ofloveandhate Jun 26, 2026
8273db1
feat(threading): MPI-less shared-memory threaded ZeroDim solve
ofloveandhate Jun 27, 2026
973cb46
feat(threading): carry executing tracker on path events (event.tracke…
ofloveandhate Jun 27, 2026
0a6c094
feat(benchmark): MPI-less thread sweep, speedup gate, portable mpirun…
ofloveandhate Jun 27, 2026
0bcb3a0
feat(python): parallel-by-default threaded solve, GIL-released, obser…
ofloveandhate Jun 27, 2026
32b931a
Merge remote-tracking branch 'origin/develop' into feature/mpi-less-t…
ofloveandhate Jun 27, 2026
6dc1c05
fix(python): hold the GIL while extracting the MPI communicator in so…
ofloveandhate Jun 27, 2026
2265745
docs(observers): upgrade meta-observer to event.tracker(); threading …
ofloveandhate Jun 27, 2026
c2ae2a2
feat(nag): parameter_sweep — one ab-initio solve, track to many param…
ofloveandhate Jun 27, 2026
cf57757
fix(python): solve() is local unless given a communicator; MPI-aware …
ofloveandhate Jun 27, 2026
86e6801
docs(tutorial): parallel parameter homotopy — Schlögl bistability map
ofloveandhate Jun 27, 2026
bdab2ef
ci: MPI smoke test (CLI under mpirun) on Linux and macOS
ofloveandhate Jun 27, 2026
7bfd6c9
Merge pull request #36 from ofloveandhate/feature/mpi-less-threading
ofloveandhate Jun 27, 2026
296cd73
refactor!: rename function-tree node Float -> Complex
ofloveandhate Jun 27, 2026
68407ac
Merge pull request #37 from ofloveandhate/feature/float-to-complex-node
ofloveandhate Jun 27, 2026
6b76e2c
refactor!: standardize scalar numeric type names (real/complex x dbl/mp)
ofloveandhate Jun 27, 2026
1401121
feat(blackbox): emit Bertini 1.7-compatible solution files + external…
ofloveandhate Jun 27, 2026
7dabb65
fix(amp): start ZeroDim paths in double precision, like Bertini 1
ofloveandhate Jun 27, 2026
e8290bb
Merge pull request #39 from ofloveandhate/feature/bertini1-output-compat
ofloveandhate Jun 27, 2026
649d6c5
Merge remote-tracking branch 'origin/develop' into feature/amp-start-…
ofloveandhate Jun 27, 2026
5455e80
perf(amp): memoize NumTraits<mpfr>::epsilon/dummy_precision per preci…
ofloveandhate Jun 27, 2026
3ed486a
TEMP(blackbox): env-gated GMP allocation counter for perf measurement
ofloveandhate Jun 27, 2026
ae6d28e
Merge pull request #38 from ofloveandhate/feature/scalar-type-naming
ofloveandhate Jun 27, 2026
297a0dd
docs(adr): ADR-0034 — tiered numeric arithmetic in the SLP
ofloveandhate Jun 27, 2026
6834e5f
feat(slp): NumType foundation for tiered arithmetic (real/complex banks)
ofloveandhate Jun 27, 2026
13e3ca8
feat(slp): real-tier inference + NumType-aware eval dispatch (ADR-003…
ofloveandhate Jun 27, 2026
26653ea
test(slp): A/B tier-speedup benchmark + tiers_enabled_ toggle (ADR-00…
ofloveandhate Jun 27, 2026
f592205
test(slp): benchmark double precision too (the tracker's hot path)
ofloveandhate Jun 27, 2026
0255f0c
test(slp): raw-op probe + size-scalable benchmark system
ofloveandhate Jun 27, 2026
eb29c1e
docs(adr): ADR-0034 — record Stage 1 implemented + measured outcome
ofloveandhate Jun 27, 2026
1c43b5f
fix(slp): work around Boost real/complex division precision-tag bug (…
ofloveandhate Jun 27, 2026
507c501
perf(slp): narrow the Boost-div re-tag to exactly the affected branch
ofloveandhate Jun 27, 2026
4b699aa
perf(slp): fold operand/result bank selection into the opcode at comp…
ofloveandhate Jun 27, 2026
1167dc2
perf(slp): lower integer powers to multiplies + fix differentiation e…
ofloveandhate Jun 27, 2026
c95e576
test(slp): mpfr allocation-churn probes (counting GMP allocator)
ofloveandhate Jun 27, 2026
f42a933
test(slp): power-method crossover probe (repeated-mul vs pow)
ofloveandhate Jun 27, 2026
354e16d
perf(slp): exp-by-squaring power lowering + alloc-free Assign/Negate …
ofloveandhate Jun 27, 2026
bdf80d8
docs(adr): ADR-0035 — the SLP eval loop is allocation-free
ofloveandhate Jun 27, 2026
9261f8d
Merge pull request #40 from ofloveandhate/feature/tiered-slp-arithmetic
ofloveandhate Jun 27, 2026
c74c5dc
Merge remote-tracking branch 'origin/develop' into feature/amp-start-…
ofloveandhate Jun 27, 2026
14f6c70
docs(adr): renumber bertini1-output ADR 0034 -> 0036 (collision with …
ofloveandhate Jun 27, 2026
6467c3d
perf(linalg): squared-magnitude IsSmallValue/IsLargeChange (drop abs/…
ofloveandhate Jun 27, 2026
99ed9cb
perf(trackers): remove per-step mpc temporaries in predict/correct
ofloveandhate Jun 27, 2026
55d922d
perf(alloc): route GMP/MPFR/MPC limb allocation through mimalloc (CLI…
ofloveandhate Jun 28, 2026
5e4bf90
Merge branch 'feature/amp-start-paths-at-double' into feature/mimallo…
ofloveandhate Jun 28, 2026
0f843cf
Revert "TEMP(blackbox): env-gated GMP allocation counter for perf mea…
ofloveandhate Jun 28, 2026
a0a903a
fix(alloc): build mimalloc with local-dynamic TLS for the dlopen-ed _…
ofloveandhate Jun 28, 2026
4e70450
Merge pull request #41 from ofloveandhate/feature/mimalloc-gmp-allocator
ofloveandhate Jun 28, 2026
1b66501
refactor(trackers): remove dead predict/correct headers
ofloveandhate Jun 28, 2026
18c76ab
refactor(trackers): collapse predict/correct overloads into StepMetad…
ofloveandhate Jun 28, 2026
dc0f8b1
refactor(trackers): share one per-path condition probe (predictor + c…
ofloveandhate Jun 28, 2026
b6b856c
perf(trackers): noalias the predictor final axpy; temp-audit clean
ofloveandhate Jun 28, 2026
673ac78
fix(endgame): Cauchy SecurityLevel guard was inverted (truncate diver…
ofloveandhate Jun 28, 2026
841e3a5
Merge pull request #42 from ofloveandhate/feature/cauchy-securitylevel
ofloveandhate Jun 28, 2026
13eca81
Merge pull request #43 from ofloveandhate/feature/predict-correct-rew…
ofloveandhate Jun 28, 2026
9a9f497
fix(amp): Criterion B cost model uses Newton residual, not size_propo…
ofloveandhate Jun 28, 2026
681293f
docs(tutorial): recreate the continuation cartoon from real data + se…
ofloveandhate Jun 28, 2026
6a0272c
fix(bindings): keep the System alive for the ZeroDim solver's lifetime
ofloveandhate Jun 28, 2026
6d65ccd
docs(tutorial): the classic continuation cartoon, recreated from real…
ofloveandhate Jun 28, 2026
1e45f68
feat(wheel): ship the bertini2 blackbox CLI in the PyPI wheel
ofloveandhate Jun 28, 2026
8d9b928
docs(tutorial): time Bertini 1 vs Bertini 2, with a provenance-stampe…
ofloveandhate Jun 28, 2026
59c2005
fix(wheel): strip x86-64-v2 ISA note from bundled CLI for auditwheel
ofloveandhate Jun 28, 2026
e0b1d66
Merge pull request #44 from ofloveandhate/feature/double-precision-perf
ofloveandhate Jun 29, 2026
23e8ca6
Merge remote-tracking branch 'origin/develop' into feature/pip_instal…
ofloveandhate Jun 29, 2026
7cc8d04
fix(nag): count SecurityMaxNormReached as diverged, not failed
ofloveandhate Jun 29, 2026
c240dac
test(zero_dim): make observer temp-system test pandas-optional
ofloveandhate Jun 29, 2026
1bc06d3
fix(ci): add pandas to test deps; document numpy-reduction gotcha for…
ofloveandhate Jun 29, 2026
379a924
Merge pull request #46 from ofloveandhate/feature/pip_install_CLI
ofloveandhate Jun 29, 2026
64ad540
Merge remote-tracking branch 'origin/develop' into fix/ci-pandas-and-…
ofloveandhate Jun 29, 2026
0504b4d
Merge pull request #47 from ofloveandhate/fix/ci-pandas-and-numpy-red…
ofloveandhate Jun 29, 2026
621e248
feat(nag): de-template ZeroDim on the start system; add linear-produc…
ofloveandhate Jun 29, 2026
266eadf
Merge pull request #48 from ofloveandhate/feature/start-system-detemp…
ofloveandhate Jun 29, 2026
0437f44
refactor(nag): rename public surface to ZeroDimSolver + HomotopySolver
ofloveandhate Jun 29, 2026
76d395a
refactor(nag): collapse aliases into concrete HomotopySolver + ZeroDi…
ofloveandhate Jun 29, 2026
2937f4e
refactor(nag): delete common/policies.hpp; rehome StartSystemFactory;…
ofloveandhate Jun 29, 2026
ed43a2e
feat(nag): ZeroDimSolver auto-squares over-determined systems + rank …
ofloveandhate Jun 29, 2026
c3c99be
docs(tutorial): add ZeroDimSolver tutorial; robustify the extraneous-…
ofloveandhate Jun 29, 2026
1034c24
docs(adr): ADR-0040 split ZeroDimSolver/HomotopySolver; index + 0039 …
ofloveandhate Jun 29, 2026
092e612
docs(tutorial): promote user_homotopy -> HomotopySolver in tutorials
ofloveandhate Jun 29, 2026
ed026a7
build(cli): sync the CLI into python/bertini/_bin for editable/dev in…
ofloveandhate Jun 29, 2026
fb35f01
build(cli): add a `cli` install component for a CLI-only install
ofloveandhate Jun 29, 2026
0bd35c7
docs(readme): add a CLI install note covering every build path
ofloveandhate Jun 29, 2026
7ca5f93
feat(nag): is_nonsolution flag + solutions() filtered getter
ofloveandhate Jun 29, 2026
442a2b8
test(nag): make the nonsolution-count assertions seed-robust; rename …
ofloveandhate Jun 29, 2026
9e8506b
fix(endgames): deterministic, reused c/k probe vector in the Cauchy o…
ofloveandhate Jun 29, 2026
f7a5ecc
test(start-systems): cross-cutting sanity tests for TotalDegree/MHom …
ofloveandhate Jun 29, 2026
b27b595
tools: add run_with_watchdog.sh (hard timeout + process-group kill fo…
ofloveandhate Jun 29, 2026
58834bb
feat(zero-dim): per-path wall-clock timing in solution metadata (path…
ofloveandhate Jun 29, 2026
4a91d48
fix(system): System +=/*= handle structured-block systems instead of …
ofloveandhate Jun 29, 2026
2c2c6a7
docs(precision_models): update solver class-name doctest to the de-te…
ofloveandhate Jun 29, 2026
0fa7f4c
fix(system): make function() work on structured systems; add slices()…
ofloveandhate Jun 29, 2026
de1d057
docs(adr): update ADR-0040 for is_nonsolution + solutions() getter
ofloveandhate Jun 29, 2026
99e2174
feat(describe): show low-precision coefficients in system describe (#…
ofloveandhate Jun 29, 2026
d5d2df8
Merge pull request #49 from ofloveandhate/feature/split_zerodimsolver…
ofloveandhate Jun 29, 2026
e7e20e5
Merge branch 'develop' into feature/cauchy-probe-sanity-timing
ofloveandhate Jun 29, 2026
bcaf8d4
Merge remote-tracking branch 'origin/develop' into feature/amp-endgam…
ofloveandhate Jun 29, 2026
31367da
Merge pull request #50 from ofloveandhate/feature/cauchy-probe-sanity…
ofloveandhate Jun 29, 2026
1beac99
Merge pull request #51 from ofloveandhate/fix/263-function-on-slice-s…
ofloveandhate Jun 29, 2026
676a8f4
Merge remote-tracking branch 'origin/develop' into feature/amp-endgam…
ofloveandhate Jun 29, 2026
6b833d1
Merge pull request #52 from ofloveandhate/fix/264-describe-coefficients
ofloveandhate Jun 29, 2026
02c0e6b
Merge remote-tracking branch 'origin/develop' into feature/amp-endgam…
ofloveandhate Jun 29, 2026
1882d33
bump version to 3.0.0.dev5
ofloveandhate Jun 29, 2026
6e3e36f
fix(docs): moving_slice eval_time_derivative doctest precision mismatch
ofloveandhate Jun 29, 2026
df34030
Merge pull request #53 from ofloveandhate/fix/moving-slice-doctest-pr…
ofloveandhate Jun 29, 2026
6a7c7a6
docs(cpp): add Doxygen doc-lint gate + clean up doc config
ofloveandhate Jun 29, 2026
a2172f8
docs(cpp): correct rotted Doxygen comments across the core
ofloveandhate Jun 29, 2026
7379098
ci: gate the build matrix on the doc lint (fail before any compile)
ofloveandhate Jun 29, 2026
c2b9198
chore: add .git-blame-ignore-revs for future formatting passes
ofloveandhate Jun 29, 2026
24e8c4d
docs(cpp): document the blackbox public API (Phase C)
ofloveandhate Jun 29, 2026
acfdbb5
docs(cpp): document nag_algorithms event/midpath/trace helpers (Phase C)
ofloveandhate Jun 29, 2026
1cf3c07
docs(cpp): document the NID algorithm + datatype scaffolding (Phase C)
ofloveandhate Jun 29, 2026
c3997b0
docs(cpp): document the classic-output formatters (Phase C)
ofloveandhate Jun 29, 2026
ad64132
docs(cpp): document the zero-dim solver (Phase C)
ofloveandhate Jun 29, 2026
8b1fae9
docs(cpp): document the nag algorithm config structs + base (Phase C)
ofloveandhate Jun 29, 2026
ad040f2
feat(endgames): adaptive numeric type for the AMP Cauchy endgame (dou…
ofloveandhate Jun 29, 2026
00188a3
feat(endgames): PowerSeries double-first AMP driver; factor migration…
ofloveandhate Jun 29, 2026
92b451f
test(endgames): prove the PowerSeries double->mpfr migration path
ofloveandhate Jun 29, 2026
0e7c9d1
feat(nag): honest per-solution precision + accuracy in metadata (digi…
ofloveandhate Jun 29, 2026
0a16fb6
docs(tutorial): refresh b1-vs-b2 timing honestly after the adaptive-n…
ofloveandhate Jun 29, 2026
3253391
docs(cpp): document the function_tree expression-tree core (Phase C)
ofloveandhate Jun 29, 2026
0cc1569
fix(start): bound start-system coefficient modulus (replace heavy-tai…
ofloveandhate Jun 30, 2026
22eeda8
docs(cpp): document the endgames subsystem (Phase C)
ofloveandhate Jun 30, 2026
2d9866b
fix(start): bound RootsOfUnity (binomial) constant modulus too
ofloveandhate Jun 30, 2026
2ec6f3c
docs(cpp): document the trackers subsystem (Phase C)
ofloveandhate Jun 30, 2026
e67f074
refactor(start): rename start systems to TotalDegreeBinomial / TotalD…
ofloveandhate Jun 30, 2026
df14838
refactor(metadata): rename endgame_success -> endgame_success_code (a…
ofloveandhate Jun 30, 2026
22d6571
docs(cpp): document the system subsystem (Phase C)
ofloveandhate Jun 30, 2026
615105b
docs(cpp): document the detail subsystem (Phase C)
ofloveandhate Jun 30, 2026
b15002c
docs(cpp): document the io subsystem (Phase C)
ofloveandhate Jun 30, 2026
b3dbc0f
docs(cpp): document parallel, pool, and nag_datatypes (Phase C)
ofloveandhate Jun 30, 2026
b2fd42b
fix(patch): draw patch coefficients with bounded modulus (away from 0…
ofloveandhate Jun 30, 2026
410b09b
docs(cpp): document the top-level headers; ratchet reaches 0 (Phase C)
ofloveandhate Jun 30, 2026
a5e08eb
Merge pull request #54 from ofloveandhate/feature/cpp-doc-lint
ofloveandhate Jun 30, 2026
efef3d9
Merge remote-tracking branch 'origin/develop' into feature/amp-endgam…
ofloveandhate Jun 30, 2026
344dea0
docs(cpp)+rename: document 55's new entities for the doc-lint; final_…
ofloveandhate Jun 30, 2026
e7da229
fix(slice): draw slice coefficients with bounded modulus (away from 0…
ofloveandhate Jun 30, 2026
714df41
docs(adr): ADR-0041 — bounded-modulus random coefficients (start syst…
ofloveandhate Jun 30, 2026
93a81f8
feat(random): conjugate-orthonormal random matrices (RandomConjugateO…
ofloveandhate Jun 30, 2026
2f198ec
test(docs): un-gate the crossed_paths doc example -- the fast endgame…
ofloveandhate Jun 30, 2026
2b0a8b6
Merge pull request #55 from ofloveandhate/feature/amp-endgame-numeric…
ofloveandhate Jun 30, 2026
3e699a3
bump version to 3.0.0.dev6
ofloveandhate Jun 30, 2026
febfd62
fix(mhom): serialize all MHomogeneous members so MPI workers get a va…
ofloveandhate Jun 30, 2026
f3d0134
docs(scaling): refresh solving_at_scale timing tables on a 16-core M3…
ofloveandhate Jun 30, 2026
853ee9b
fix(parse): strip % comments when reading a classic input FILE (Berti…
ofloveandhate Jun 30, 2026
861e3ca
test(printing): magnitude-independent terse coefficient bound (fix fl…
ofloveandhate Jun 30, 2026
ab65ed7
feat(system): symbolic Jacobian (matrix of expression nodes) + natura…
ofloveandhate Jun 30, 2026
3dd5fa3
feat(python): bind the symbolic Jacobian -> bertini.jacobian + System…
ofloveandhate Jun 30, 2026
fb434c8
test(jacobian): cover every block type (linear-forms, slice, products…
ofloveandhate Jun 30, 2026
c5ade48
feat(random): bertini.random_matrix (orthonormal / bounded-modulus / …
ofloveandhate Jun 30, 2026
2212c80
feat(criticality): nullvector critical-points recipe -- test, tutoria…
ofloveandhate Jun 30, 2026
342cffa
fix(system): snapshot pre-homogenization functions BEFORE resizing ho…
ofloveandhate Jun 30, 2026
eeb866e
docs(criticality): explain critical points as branch points (where th…
ofloveandhate Jun 30, 2026
cfa7c32
docs(criticality): fix the projection-direction arrow (project ALONG …
ofloveandhate Jul 1, 2026
4e8ed6e
docs(criticality): fix two section-underline lengths (sphinx warnings)
ofloveandhate Jul 1, 2026
24440cc
fix(slp): stop over-reading the instruction tape by one word in Eval
ofloveandhate Jul 1, 2026
d45a5b4
prototype(slp-cse): power-fold x*x -> x^2 at operator*= (binary/adjac…
ofloveandhate Jul 1, 2026
e19c888
feat(slp-cse): flatten + sort + power-fold products in CanonicalizeNa…
ofloveandhate Jul 1, 2026
7bf9ad2
feat(slp-cse): instruction-level value-numbering in the SLP compiler
ofloveandhate Jul 1, 2026
9f876e1
fix(slp-cse): don't splice divisor sub-products when flattening (avoi…
ofloveandhate Jul 1, 2026
641ec02
fix(function_tree): correct group-degree of an integer power of a sum
ofloveandhate Jul 1, 2026
a25436a
Merge pull request #56 from ofloveandhate/fix/parallel_serialization
ofloveandhate Jul 1, 2026
2bdd4b9
Merge pull request #58 from ofloveandhate/fix/slp-eval-tape-overread
ofloveandhate Jul 1, 2026
9ec829e
Merge remote-tracking branch 'origin/develop' into feature/symbolic-j…
ofloveandhate Jul 1, 2026
6d073b1
docs(cpp): document NodeMatrix rows/cols members + note the doc-lint …
ofloveandhate Jul 1, 2026
ad99d58
test(slp-cse): env-var A/B toggles + isolated SLP benchmark
ofloveandhate Jul 1, 2026
1759501
docs(criticality): make the tutorial honest -- full reducible curve, …
ofloveandhate Jul 1, 2026
a0a187e
Merge remote-tracking branch 'origin/develop' into feature/slp-cse-fo…
ofloveandhate Jul 1, 2026
2e7a762
Merge pull request #59 from ofloveandhate/feature/symbolic-jacobian
ofloveandhate Jul 1, 2026
1c71696
Merge pull request #60 from ofloveandhate/feature/slp-cse-fold-and-va…
ofloveandhate Jul 1, 2026
8e99d6b
docs(tutorials): one folder per tutorial (index.rst) with owned assets
ofloveandhate Jul 1, 2026
3ea5832
chore(examples): delete dead/redundant example scripts
ofloveandhate Jul 1, 2026
7655702
docs(tutorials): complete runnable script at the bottom of 5 tutorials
ofloveandhate Jul 1, 2026
f1feec7
docs(tutorials): complete runnable script at the bottom of 5 more tut…
ofloveandhate Jul 1, 2026
06afbcf
docs(tutorials): complete runnable script at the bottom of 6 more tut…
ofloveandhate Jul 1, 2026
ba635f8
docs(tutorials): complete runnable script at the bottom of the 3 plot…
ofloveandhate Jul 1, 2026
cd3aaa9
tools: refresh_doc_artifacts.py -- one entry point, timings/plots split
ofloveandhate Jul 1, 2026
0f2d9ea
docs(solving_at_scale): numbers as data, not prose
ofloveandhate Jul 1, 2026
35c5438
build(version): single-source VERSION file + full version in C++/CLI
ofloveandhate Jul 1, 2026
f79e5b7
updated year
ofloveandhate Jul 1, 2026
d2be4fb
docs(detailed): auto-generate the API reference with autosummary :rec…
ofloveandhate Jul 1, 2026
b716285
Merge pull request #61 from ofloveandhate/feature/version-single-sour…
ofloveandhate Jul 1, 2026
476b4f5
feat(parsing,system): Unicode identifiers + collision-safe path varia…
ofloveandhate Jul 1, 2026
8b35e5f
fix(python): stop leaking os/sys/info into the bertini.* namespace
ofloveandhate Jul 1, 2026
5c49a71
feat(function_tree): validate variable names are well-formed identifiers
ofloveandhate Jul 1, 2026
9d1f04d
feat(naming): allow emoji in variable names, including multi-code-poi…
ofloveandhate Jul 1, 2026
9881bb2
docs(refresh): timing-freshness release gate + critical_points plot r…
ofloveandhate Jul 1, 2026
7c70cf7
Merge pull request #63 from ofloveandhate/feature/docs_structure
ofloveandhate Jul 1, 2026
22aa5c1
Merge pull request #62 from ofloveandhate/feature/unicode-identifiers…
ofloveandhate Jul 1, 2026
2917e81
Bump version to 3.0.0.dev7
ofloveandhate Jul 1, 2026
9e6672d
feat(python): flatten public API — hoists, root enums, constants, ope…
ofloveandhate Jul 2, 2026
5dc3f68
feat(python): introduce flat bertini.symbolics (renames function_tree)
ofloveandhate Jul 2, 2026
c392f0b
feat(python): dissolve linalg into System methods + top-level coeffic…
ofloveandhate Jul 2, 2026
a94dcfd
feat(python): hide NID/WitnessSet/Differential and make_* from the pu…
ofloveandhate Jul 2, 2026
dfdc586
feat(python): rename numeric types (_mp), spell out endgames, Variabl…
ofloveandhate Jul 2, 2026
36b6c2d
docs: add namespace-flattening migration guide (skeleton)
ofloveandhate Jul 2, 2026
b19213b
docs(adr): ADR-0042 System content identity — canonical encoding, sta…
ofloveandhate Jul 2, 2026
bf445b6
refactor: sweep tutorials, examples, and tests to the flat API
ofloveandhate Jul 2, 2026
901a05e
feat(detail): self-contained SHA-256 (FIPS 180-4) + Digest256, pinned…
ofloveandhate Jul 2, 2026
ba7a84c
refactor: remove deprecated aliases (function_tree, linalg, CapWords …
ofloveandhate Jul 2, 2026
2702e56
feat(slp): hash-cons SLPPrograms — ContentHash/SameContent + weak int…
ofloveandhate Jul 2, 2026
37dfb19
feat(function_tree): canonical exact node encoding — the persistent-i…
ofloveandhate Jul 2, 2026
0ec80a9
feat(system): ContentDigest/Hash/IsSame — persistent System content i…
ofloveandhate Jul 2, 2026
ee7e6ee
feat(system): Seal()/IsSealed() — hashcons-on-freeze; structural muta…
ofloveandhate Jul 2, 2026
cfd4804
feat(system): InternSystem — digest-keyed weak intern table for Syste…
ofloveandhate Jul 2, 2026
840b0bc
feat(function_tree): node::Reintern — re-intern deserialized DAGs ont…
ofloveandhate Jul 2, 2026
5520a87
feat(system): re-intern-on-load — System::ReinternNodes + LoadSystemU…
ofloveandhate Jul 2, 2026
4fc2848
feat(python): System content-identity surface — content_digest/is_sam…
ofloveandhate Jul 2, 2026
66992ad
docs: curated "everyday API" reference tier
ofloveandhate Jul 2, 2026
55a49c0
fix(system): ContentDigest never writes shared state — Seal() is the …
ofloveandhate Jul 2, 2026
158536e
docs: finalize the namespace migration guide
ofloveandhate Jul 2, 2026
8d68250
refactor: remove multiprec.Vector (eigenpy gives numpy interop directly)
ofloveandhate Jul 2, 2026
2be31e3
refactor(endgames): rename EndgameConfig.max_num_newton_iterations ->…
ofloveandhate Jul 2, 2026
92abc95
fix(zerodim): make Tolerances.final_tolerance the endgame's tolerance…
ofloveandhate Jul 2, 2026
8b9b754
Merge pull request #65 from ofloveandhate/feature/namespace_flattening
ofloveandhate Jul 2, 2026
98d2057
Merge pull request #66 from ofloveandhate/feature/config_model_cleanup
ofloveandhate Jul 2, 2026
5cbeb6d
Merge pull request #64 from ofloveandhate/feature/hashconsing_systems
ofloveandhate Jul 2, 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
  •  
  •  
  •  
13 changes: 13 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Commits listed here are skipped by `git blame` so that large, purely mechanical
# changes (whitespace, indentation, reformatting) do not obscure the real authorship
# of each line. GitHub honours this file automatically. Locally, run once:
#
# git config blame.ignoreRevsFile .git-blame-ignore-revs
#
# RULES:
# * Only add commits that are PURELY formatting -- no behavioural or semantic
# change, no documentation-content change. Keep such passes in their own
# isolated commit so the whole commit can be safely ignored.
# * Add the full 40-character commit SHA, with a comment naming what it did.
#
# (No revisions yet -- add the whitespace/indentation pass SHA here when it lands.)
257 changes: 217 additions & 40 deletions .github/workflows/build_and_test.yml

Large diffs are not rendered by default.

14 changes: 12 additions & 2 deletions .github/workflows/build_docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,10 @@ jobs:
- name: Install system dependencies (Doxygen)
run: |
sudo apt-get update
sudo apt-get install -y doxygen graphviz
# texlive-binaries provides bibtex, which Doxygen needs to number and
# render the \cite references (CITE_BIB_FILES in the Doxyfile) into a
# bibliography in the published C++ docs.
sudo apt-get install -y doxygen graphviz texlive-binaries

- name: Fetch doxygen-awesome-css
run: |
Expand All @@ -104,7 +107,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 +118,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
63 changes: 63 additions & 0 deletions .github/workflows/doc_lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
name: Documentation lint 📑

# Cheap, fast doc-correctness gate -- runs Doxygen only (no compilation, no wheel,
# no graphviz) so it can run on every PR in well under a minute. This is the first
# foothold of a broader linting initiative; future linters (clang-format,
# clang-tidy, include-what-you-use, ...) can be added as additional jobs here.
#
# It does NOT belong in build_and_test.yml: that workflow is the expensive
# build/test matrix, and it already `paths-ignore`s Doxyfile/doc_resources/docs, so
# doc-only changes skip it and hit only this lint -- exactly the fast feedback we want.

# Header (core/include) changes reach this lint through build_and_test.yml, which
# calls it as a prerequisite gate (see workflow_call below). The standalone
# triggers here cover only the doc-config/tooling paths that build_and_test
# deliberately `paths-ignore`s, so the lint still runs for doc-only changes without
# double-running on a typical code PR.
on:
push:
branches:
- develop
- main
paths:
- 'Doxyfile'
- 'doc_resources/**'
- 'tools/doclint.sh'
- 'tools/doc_undocumented_baseline.txt'
- '.github/workflows/doc_lint.yml'
pull_request:
paths:
- 'Doxyfile'
- 'doc_resources/**'
- 'tools/doclint.sh'
- 'tools/doc_undocumented_baseline.txt'
- '.github/workflows/doc_lint.yml'
workflow_dispatch:
# Called by build_and_test.yml as a prerequisite gate, so no C++ compilation
# starts until the docs lint is green.
workflow_call:

# The undocumented-entity ratchet count in tools/doc_undocumented_baseline.txt is
# specific to this Doxygen version; CI must use the same one that seeded the
# baseline, not whatever the runner's apt happens to ship. Bump both together.
env:
DOXYGEN_VERSION: "1.13.2"

jobs:
doc_lint:
name: Doxygen doc lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5

- name: Install pinned Doxygen
run: |
url="https://github.com/doxygen/doxygen/releases/download/Release_${DOXYGEN_VERSION//./_}/doxygen-${DOXYGEN_VERSION}.linux.bin.tar.gz"
curl -sSL "$url" | tar -xz
echo "$PWD/doxygen-${DOXYGEN_VERSION}/bin" >> "$GITHUB_PATH"

- name: Show Doxygen version
run: doxygen --version

- name: Lint C++ documentation
run: bash tools/doclint.sh
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
26 changes: 20 additions & 6 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ concurrency:

jobs:
check_version:
name: Check pyproject.toml version matches tag
name: Check VERSION file matches tag
runs-on: ubuntu-latest
outputs:
is_prerelease: ${{ steps.check.outputs.is_prerelease }}
Expand All @@ -31,17 +31,31 @@ jobs:
exit 1
fi
TAG_VERSION="${TAG#v}"
PYPROJECT_VERSION=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")
if [ "$TAG_VERSION" != "$PYPROJECT_VERSION" ]; then
echo "Error: tag '$TAG' does not match pyproject.toml version '$PYPROJECT_VERSION'"
# The version is dynamic in pyproject.toml; its single source of truth
# is the top-level VERSION file (read by scikit-build-core and CMake).
FILE_VERSION=$(tr -d '[:space:]' < VERSION)
if [ "$TAG_VERSION" != "$FILE_VERSION" ]; then
echo "Error: tag '$TAG' does not match VERSION file '$FILE_VERSION'"
exit 1
fi
echo "OK: tag '$TAG' matches pyproject.toml version '$PYPROJECT_VERSION'"
echo "OK: tag '$TAG' matches VERSION file '$FILE_VERSION'"
echo "$TAG" | grep -Eq '\.(dev|a|b|rc)[0-9]+$' && echo "is_prerelease=true" >> $GITHUB_OUTPUT || echo "is_prerelease=false" >> $GITHUB_OUTPUT

check_timing_freshness:
name: Check tutorial timings are fresh
# Only gate real releases -- prereleases (.dev/a/b/rc) are exactly when a timing refresh may not
# have happened yet. A skipped job counts as satisfied for downstream `needs`.
if: needs.check_version.outputs.is_prerelease == 'false'
needs: check_version
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Verify the scaling-tutorial timings are not stale
run: python tools/check_timing_freshness.py

build_and_test:
name: Build and test
needs: check_version
needs: [check_version, check_timing_freshness]
uses: ./.github/workflows/build_and_test.yml

publish-to-testpypi:
Expand Down
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
75 changes: 64 additions & 11 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,14 @@ Bertini 2 (b2) is a C++17 numerical algebraic geometry library with Python bindi
# Configure (from repo root)
cmake -DENABLE_UNIT_TESTING=ON -G Ninja -B build -S .

# Build
# Build everything (core library, bindings, exe, tests)
cmake --build build --target all --config Release

# For iterative C++ work, build just the core library first -- it's much faster, and
# the heavy Boost.Python/eigenpy bindings (`_pybertini`) only need rebuilding when the
# bindings themselves change:
cmake --build build --target bertini2 --config Release

# Run all C++ tests
ctest --test-dir build/core
```
Expand Down Expand Up @@ -57,28 +62,43 @@ ctest --test-dir build/core
./build/core/test_generating
./build/core/test_nag_algorithms
./build/core/test_nag_datatypes
./build/core/test_pool
./build/core/test_tracking_basics
./build/core/test_settings
```

### 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:

1. **`core/`** -- C++ shared library (`libbertini2`). Header-only-heavy design under `core/include/bertini2/`. Key subsystems:
- `function_tree/` -- Expression tree (nodes, operators, symbols) for representing polynomial systems
- `system/` -- Polynomial system construction, start systems (`start/total_degree.hpp`, `start/mhom.hpp`), patches, slices
- `function_tree/` -- Expression tree (nodes, operators, symbols) for *building and representing* polynomial systems. Nodes no longer evaluate: node-level recursive evaluation was removed -- the **SLP (`straight_line_program`) is the sole evaluator** (compile a system once, evaluate the compiled program). `Function`/`Handle` are gone; `NamedExpression` is the sole root node. See ADR-0027 (SLP: immutable Program + per-thread Memory) and ADR-0028 (named-node taxonomy).
- `system/` -- Polynomial system construction, start systems (`start/total_degree_linear_product.hpp`, `start/mhom.hpp`), patches, slices
- `trackers/` -- Path tracking (fixed-precision and adaptive-precision trackers, predictors, Newton correctors)
- `endgames/` -- Power series and Cauchy endgames for singular endpoint handling
- `nag_algorithms/` -- Higher-level algorithms (zero-dim solve, numerical irreducible decomposition)
- `nag_algorithms/` -- Higher-level algorithms (zero-dim solve; numerical irreducible decomposition is *framework scaffolding* -- not yet implemented, its `Solve()` throws)
- `io/parsing/` -- Boost.Spirit Qi parsers for classic Bertini input format
- `blackbox/` -- CLI executable entry point (`bertini2_exe`)
- `blackbox/` -- CLI executable entry point (CMake target `bertini2_exe`, binary named `bertini2`)

2. **`python_bindings/`** -- Boost.Python + eigenpy bindings producing `_pybertini` native module. Each `*_export.cpp` wraps the corresponding C++ subsystem. Depends on `eigenpy` for NumPy/Eigen interop.

Expand All @@ -87,9 +107,9 @@ The project has three layers, built in order:
## Key Dependencies

- **GMP/MPFR/MPC** -- Arbitrary-precision arithmetic (found via custom CMake modules in `cmake/`)
- **Eigen 3.3** -- Linear algebra (pinned to v3.3)
- **Boost** (serialization, filesystem, log, graph, regex, timer, chrono, thread, unit_test_framework, python) -- Boost >= 1.82 required; `boost_system` is conditionally linked for Boost < 1.89
- **eigenpy** -- Eigen/NumPy bridge for Python bindings
- **Eigen 3** -- Linear algebra. **Not** pinned in cmake (`find_package(Eigen3)`, no version floor). In practice the version is coupled to the eigenpy build: the wheel CI builds **eigen 3.4.0** and then builds eigenpy against it (a dev env may use newer, e.g. `eigen=5.0.1`). Newer Eigen is welcome -- we *want* upstream improvements -- but it must be matched by an eigenpy built against the same Eigen (they share Eigen types across the binding ABI).
- **Boost** (serialization, filesystem, log, graph, regex, timer, chrono, thread, unit_test_framework, python) -- no minimum version pinned in cmake; `boost_system` is conditionally linked for Boost < 1.89 (header-only from 1.89). Boost.Python is ABI-locked to one CPython version, so CI rebuilds it per target Python.
- **eigenpy** -- Eigen/NumPy bridge for Python bindings. Built **from source** in CI at a single pinned version (`EIGENPY_VERSION` in `build_and_test.yml`, currently `3.13.0`) against the chosen Eigen -- eigenpy and bertini must use the *same* Eigen. eigenpy >= 3.13 sets the Python floor (>= 3.10).
- **jrl-cmakemodules** -- CMake helper macros (auto-fetched via FetchContent if not found)

## Build System Notes
Expand All @@ -101,11 +121,44 @@ 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/doc_lint.yml` -- A cheap Doxygen doc-correctness gate that **the build matrix depends on** (it runs first; if it fails, nothing compiles). **Run `bash tools/doclint.sh` locally before pushing any C++ change**, or CI will bounce the whole build. It needs `doxygen` on PATH (`brew install doxygen`). Two passes: (1) *correctness* — `@param` names must match signatures, no doc blocks on removed signatures, no unresolved `\ref`/`\cite` (zero tolerance); (2) *undocumented ratchet* — the count of undocumented public entities in `tools/doc_undocumented_baseline.txt` may only **decrease** (currently `0`, so **every new public C++ entity — including each struct data member — needs a Doxygen comment**, e.g. `///< ...`). If you legitimately reduce the count, run `bash tools/doclint.sh --update-baseline` to lock it in.
- `.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")`.
Loading
Loading