Motivation
The pure-Python cellular decomposition work has established that decomposition reliability hinges on the accuracy of a small population of boundary-stage points (critical points above all): a crit point accurate to eps yields slices whose tangency geometry is perturbed by ~sqrt(eps), which materializes as duplicate-vertex mis-assembly downstream. The fix is Newton sharpening of these points at registration time — and the core already owns the right primitive, so the Python layer should not re-implement Newton.
What exists in core
trackers/base_tracker.hpp provides tracker-owned Newton refinement, in fixed and adaptive precision:
SuccessCode Refine(Vec<C>& new_space, Vec<C> const& start_point, C const& current_time); // implicit tolerance
SuccessCode Refine(Vec<C>& new_space, Vec<C> const& start_point, C const& current_time,
RealT const& tolerance, unsigned max_iterations); // explicit
The explicit-tolerance overload is exactly the sharpening primitive: refine this point, on this tracker's system, at this time, to this tolerance. Neither overload is currently exposed in python_bindings/src/tracker_export.cpp.
(nag_algorithms/sharpen.hpp is an empty scaffold — the algorithm-level Sharpen can come later; this issue is only about exposing the existing tracker primitive.)
Proposed binding shape
- Return the refined vector; do not bind the output-reference signature. The natural
Vec<C>& out-param sits adjacent to a C const& time scalar — the exact eigenpy writable-Ref/adjacent-scalar corruption pattern of ADR-0001. A small wrapper that allocates, calls Refine, and returns (SuccessCode, Vec) sidesteps the hazard entirely; scalar time passed by value per the ADR.
- Bind both overloads (implicit and explicit tolerance) on the fixed-precision and AMP tracker classes.
- Tolerance as
real (mp), max_iterations as unsigned; defaults mirroring NewtonConfig.
Acceptance
tracker.refine(point, time) and tracker.refine(point, time, tolerance=..., max_iterations=...) from Python on both tracker types, returning the refined point plus the SuccessCode.
- A Python test refining a loosely-tracked nonsingular solution to a tight tolerance and verifying the residual/step-size claim.
- No re-implementation of Newton in the pure-Python layer.
Context
Needed by the decomposition-reliability work: sharpening all boundary-stage points (crit/preimage/singular/sphere) at the vertex-registration boundary so identity decisions and projection-value authorities run on honest, tight error bars. Nonsingular points use this primitive directly on the already-squared (randomized) tracking systems; singular points will layer isosingular deflation on top of the same call.
Motivation
The pure-Python cellular decomposition work has established that decomposition reliability hinges on the accuracy of a small population of boundary-stage points (critical points above all): a crit point accurate to eps yields slices whose tangency geometry is perturbed by ~sqrt(eps), which materializes as duplicate-vertex mis-assembly downstream. The fix is Newton sharpening of these points at registration time — and the core already owns the right primitive, so the Python layer should not re-implement Newton.
What exists in core
trackers/base_tracker.hppprovides tracker-owned Newton refinement, in fixed and adaptive precision:The explicit-tolerance overload is exactly the sharpening primitive: refine this point, on this tracker's system, at this time, to this tolerance. Neither overload is currently exposed in
python_bindings/src/tracker_export.cpp.(
nag_algorithms/sharpen.hppis an empty scaffold — the algorithm-level Sharpen can come later; this issue is only about exposing the existing tracker primitive.)Proposed binding shape
Vec<C>&out-param sits adjacent to aC const&time scalar — the exact eigenpy writable-Ref/adjacent-scalar corruption pattern of ADR-0001. A small wrapper that allocates, callsRefine, and returns(SuccessCode, Vec)sidesteps the hazard entirely; scalar time passed by value per the ADR.real(mp), max_iterations as unsigned; defaults mirroringNewtonConfig.Acceptance
tracker.refine(point, time)andtracker.refine(point, time, tolerance=..., max_iterations=...)from Python on both tracker types, returning the refined point plus the SuccessCode.Context
Needed by the decomposition-reliability work: sharpening all boundary-stage points (crit/preimage/singular/sphere) at the vertex-registration boundary so identity decisions and projection-value authorities run on honest, tight error bars. Nonsingular points use this primitive directly on the already-squared (randomized) tracking systems; singular points will layer isosingular deflation on top of the same call.