Plot the mu-trajectory for any non-empty 2D quadric

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>
This commit is contained in:
loicvhandClaude Opus 5 committed 2026-09-15 21:45:51 +02:00
1 parent 5b118416be
commit bdcf0e0b02
3 files changed
+272 -130

No files matched your search

+10 -10
View File
@@ -1,13 +1,13 @@
# mu-trajectories
Visualize the KKT trajectory of the Euclidean projection of a point `x0` onto an ellipse
`x'Ax + b'x + c = 0`:
Visualize the KKT trajectory of the Euclidean projection of a point `x0` onto a 2D quadric
`x'Ax + b'x + c = 0` (ellipse, hyperbola, parabola, two lines, a line or a point):
x(mu) = (I + mu A)^{-1} (x0 - mu b / 2)
The figure shows the trajectory in the plane, `f(mu) = psi(x(mu))`, the distance
`||x0 - x(mu)||` and `f'(mu)`, together with the nearest/farthest KKT points `x(mu*)`,
`x(mu**)` and, when `x0` has a zero standardized coordinate, the degenerate point `x^d`.
The figure shows the trajectory in the plane, the secular function `f(mu)`, the distance
`||x0 - x(mu)||` and `f'(mu)`, together with the KKT points: `x(mu*)`, the other roots of `f`
and, when `x0` has a zero normalized coordinate, the degenerate points `x^d`.
## Usage
@@ -24,8 +24,8 @@ Text is typeset with LaTeX (`text.usetex`) when `latex` is on the `PATH`, with t
## Files
- `plot_mu_trajectories.py`: the figure. The quadric, `x(mu)`, `f`, `f'`, `mu*` and the degenerate
points come from [quadproj](https://loicvh.gitlab.io/quadproj); the script only adds `mu**`,
the asymptotes and the ellipse boundary.
- `test_plot_mu_trajectories.py`: checks these helpers against brute-force sampling of the ellipse
and against `quadproj.project`.
- `plot_mu_trajectories.py`: the figure. The quadric, `x(mu)`, `f`, `f'` and the degenerate
points come from [quadproj](https://loicvh.gitlab.io/quadproj); the script adds the roots of
`f`, the asymptotes and the plot limits.
- `test_plot_mu_trajectories.py`: checks, for each type of quadric, that the KKT points contain
the projection found by brute-force sampling, and that every type can be plotted.