Skip to content

Commit 736969d

Browse files
prep(3.4.0): VERSION -> 3.4.0 (final); CHANGELOG [3.4.0] entry extended with the endgame-hardening sweep (#357)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent 3c033ed commit 736969d

2 files changed

Lines changed: 44 additions & 4 deletions

File tree

CHANGELOG.md

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,20 +67,60 @@ _______________________________________________________________________________
6767

6868
_______________________________________________________________________________
6969

70-
## [3.4.0] - 2026-07-14
70+
## [3.4.0] - 2026-07-16
7171

72-
A one-call way to build a linear slice that passes through a chosen point.
72+
A one-call way to build a linear slice that passes through a chosen point, an endgame-hardening
73+
sweep (power series and Cauchy both), and friendlier start-point handling in the Python layer.
7374

7475
### Added
7576

7677
- **`Slice.through_point(variables, point, dim=1, coefficients=None, real=False, orthogonal=True, homogeneous=False)`**
77-
— the single place to make a slice through a given point. With `coefficients=None` (the default) it
78+
— the single place to make a slice through a given point (#343). With `coefficients=None` (the default) it
7879
draws a random block of `dim` linear forms (complex, or real with `real=True`; orthonormalized when
7980
`orthogonal`) and sets the constant column so every form vanishes at `point`; pass `coefficients` (a
8081
bare, non-augmented block) to use exactly those directional coefficients. Backed by the new C++
8182
primitives `Slice::ThroughPoint` and a `through_point` option on `Slice::RandomReal` /
8283
`Slice::RandomComplex`. `homogeneous=True` builds a projective slice through the point (rows
8384
orthogonal to it); it is random-only.
85+
- **`HomotopySolver` accepts start points in any faithful numeric representation** (#350, fixing #347):
86+
multiprecision scalars, Python/numpy numbers, and *constant* symbolic nodes (an ndarray of
87+
`symbolics.Complex` previously crashed with a raw eigenpy converter error). Start points are
88+
transported values — the tracker refines them — so lossy doubles are welcome here; expressions still
89+
containing variables are refused as the math errors they are, with an error that names the variables.
90+
`complex_mp` now constructs explicitly from a Python `complex` (still no implicit conversion).
91+
92+
### Fixed
93+
94+
- **The power-series endgame's Hermite interpolation now evaluates the actual Hermite
95+
interpolant** (#353). The Horner walk over the doubled node list advanced at half speed, evaluating
96+
a different (lower-order) interpolant — the limit was still correct, but convergence order was
97+
degraded. This changes computed results at agreeing inputs: approximations land measurably closer
98+
to the truth (the old test oracle values were themselves off and have been re-pinned exactly).
99+
- **`max_cycle_number` is enforced as a ceiling, not a floor** (#353). The bound was applied with
100+
`max()`, and a near-unity sample ratio could push the estimate through an unsigned conversion of
101+
infinity (UB). Clamped before conversion; cycle-number candidates now default sanely on
102+
degenerate samples.
103+
- **NaN is a failure, never `Converged`** (#354). IEEE comparison semantics made every NaN
104+
comparison false, so a NaN correction step exited the convergence loop as success, and the
105+
security valve (`norm > max_norm`) was blind to NaN norms. Both endgames now fail fast on NaN
106+
approximations (new `bertini::ContainsNaN` in `eigen_extensions.hpp` — component-wise, because
107+
multiprecision complex NaN compares *equal* to itself) and the valve is NaN-aware.
108+
- **Slow divergers truncate honestly in the Cauchy endgame** (#355). Paths diverging to infinity
109+
slower than the shrinking time zones could grind precision escalation for minutes before dying.
110+
The security valve now also arms below B1's `cycle_cutoff_time` and watches the *loop floor* — the
111+
minimum dehomogenized norm over the Cauchy loop samples — which exceeds `max_norm` only when the
112+
entire loop is beyond it (single-sample spikes on legitimate paths cannot trip it).
113+
- **Singularity classification uses the endpoint's spectral-norm condition number** (#344, the B1
114+
`CondNumThreshold` spec), instead of a mixed-norm estimate that mislabeled borderline endpoints.
115+
- **`frequency_of_CN_estimation` was inert** (#345): the tracker's condition-number refresh counter
116+
was passed by value, so the estimate never refreshed at the configured cadence.
117+
- **`max_precision_used` is harvested from failed endgames too** (#349); previously a path that
118+
failed after escalating precision reported as if it had never left double.
119+
120+
### Changed
121+
122+
- **Binomial start points are computed at working precision** (#346) — about 3.2× faster on small
123+
total-degree solves, with start-point accuracy unchanged (start points are transported values).
84124

85125
_______________________________________________________________________________
86126

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3.4.0.dev1
1+
3.4.0

0 commit comments

Comments
 (0)