@@ -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
0 commit comments