The poles, branches and mu range now follow the eigenvalues (one or two
poles of either sign), so hyperbolas, parabolas, line pairs, single
lines and points are supported, not only ellipses.
- Find every root of f from sign changes, including across inactive
poles where quadproj's f is 0/0; mu* is the root between the active
poles surrounding 0 and the other roots get their own marker.
- Mark the apex of conical quadrics as a degenerate KKT point.
- Draw the quadric as the contour psi = 0 and frame the trajectory
panel on x0, the KKT points and the vertices.
- Use the correct asymptote direction for repeated eigenvalues.
- Test every quadric type against brute-force sampling.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The quadric, x(mu), f, f', mu* and the degenerate points now come from
quadproj; the script keeps small helpers for what quadproj does not
provide: mu**, the asymptotes and the ellipse boundary. The tests check
these helpers against brute-force sampling and quadproj.project.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Replace the single A/B/C constants and --x0 option with a CASES table;
each case writes <name>.png and <name>.pdf. Add the A = diag(2, 0.75),
x0 = (0, -0.6) case.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Cleaned-up extraction of test_mu_ellipse from proj_ellipsoid:
- quadric.py: minimal Ellipsoid class (standardization, KKT trajectory,
extreme roots by exact bracketing, degenerate points, asymptotes).
- plot_mu_trajectories.py: the 4-panel figure, typeset with LaTeX.
- test_quadric.py: checks against brute-force sampling of the ellipse.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>