Skip to content

Release v0.3.2: algorithm-verification fixes - #15

Merged
mmogib merged 2 commits into
mainfrom
feature-dev
May 25, 2026
Merged

mmogib merged 2 commits into
mainfrom
feature-dev

Conversation

@mmogib

@mmogib mmogib commented May 25, 2026

Copy link
Copy Markdown
Owner

Release v0.3.2 — algorithm-verification fixes

Summary

Two additive correctness-relevant fixes surfaced during a paper-fidelity
cross-check of DFProjection.step! against the canonical literature
(Solodov–Svaiter 1999, La Cruz 2006, Ibrahim 2023 STTDFPM/ISTTDFPM,
Yin 2021, Sabi'u 2023, Halpern 1967; aggregated in
notes/task_1_algorithm_verification.md):

  • SpectralThreeTerm gains alpha_min / alpha_max keyword
    arguments — the spectral coefficient ϑ_k^I is now clamped to
    [alpha_min, alpha_max], restoring the strict-descent bound
    F(w_k)' d_k ≤ -\alpha_{\min}\|F(w_k)\|^2 that's central to the
    convergence theory. The previous implementation fell back to 0 in
    the degenerate y_{k-1} = 0 case, which violated the bound silently.
  • SolodovSvaiterProjection gains a γ keyword argument (γ ∈ (0, 2), default 1.0) — the well-known relaxation factor for the
    hyperplane-projection family. Default γ = 1 preserves v0.3.1
    behavior byte-for-byte. The Dykstra tolerance ε_k is scaled by
    γ² so the inner solver works to a constant fractional accuracy of
    the projection step across all γ values.

Companion documentation polish (extension contracts, docstring
lineage, extending.md section renumber).

No source-API removals. Default behavior unchanged except the
degenerate-y fallback in SpectralThreeTerm (which previously gave zero
descent and now gives strict descent). PATCH-classified release;
262/262 tests pass.

What's new

Source

  • SpectralThreeTerm clamping (src/search_directions.jl):
    • New fields alpha_min::Float64 = 1e-10 and alpha_max::Float64 = 1e30.
    • direction! computes ϑ_I = clamp(yy_sq > 0 ? sy/yy_sq : alpha_min, alpha_min, alpha_max).
    • Underwrites both the sufficient-descent bound -F(w_k)' d_k ≥ α_min ‖F(w_k)‖² and the trust-region bound ‖d_k‖ ≤ (α_max + 2/ᾱ_1)‖F(w_k)‖.
  • SolodovSvaiterProjection.γ (src/iterate_updates.jl):
    • Now Base.@kwdef with γ::Float64 = 1.0.
    • Projection target becomes w − γ·λ·F(z); Dykstra tolerance scaled to ε_k = (ζ²/2) γ² λ² ‖F(z)‖².
    • Docstring expanded to document the convergence-bound coefficient γ(2 − γ), the recommended over-relaxation range (1.6–1.8), and the caveat that γ ≤ 1 cancels in RealSpace (the halfspace projection pulls the target back to the boundary).

Tests

  • test/runtests.jl: 20 new tests.
    • 5 in Search direction (SpectralThreeTerm): constructor defaults + overrides for alpha_min/alpha_max, lower-bound clamp activation, upper-bound clamp activation, degenerate y = 0 fallback to alpha_min, default-knob bit-equivalence regression.
    • 5 in v0.2 iterate update (Section A): γ constructor default + overrides, γ = 1 byte-equivalence regression against the existing SolodovSvaiterProjection() default, γ = 1.8 over-relaxation converges on the simple f(u) = u problem, γ = 0.5 RealSpace cancellation regression (proves γ = 0.5 produces the same iterate sequence as γ = 1.0), γ = 1.6 with BoxSet smoke test.
  • Test count: 242 (v0.3.1) → 262 (this release), all passing.

Documentation

  • docs/src/extending.md:
    • § 2 (Search direction) gains a new ### Convergence contract subsection at the top, stating the sufficient-descent + bounded-growth conditions for custom directions and showing how SpectralThreeTerm's [α_min, α_max] clamp + v_k denominator satisfy them.
    • § 3 (Iterate update) gains an ### Implicit contract for SolodovSvaiterProjection subsection documenting the λ_k > 0 requirement and how all three built-in line searches enforce it via the Armijo separation.
    • Renumber: § 0 (Contract surface) → Preliminaries: contract surface (un-numbered). The remaining § 1 – § 7 now correspond 1-to-1 to the seven extension slots; § 8 (Convergence caveats) stays numbered as an appendix.
  • src/iterate_updates.jl SolodovSvaiterProjection docstring: paragraph added noting the 1999 scheme assumes exact projection, and DFMethods realizes it via the inexact-projection refinement standard in the broader Solodov–Svaiter inexact-projection lineage.
  • CHANGELOG.md [Unreleased]: ### Added and ### Changed entries for both source changes.
  • DFMethods.jl/CLAUDE.md: new naming-convention rule under § Coding style (single-character Greek/math letters → Unicode; multi-character or compound → ASCII spelled-out; decorated symbols with single Greek head → Unicode head + ASCII suffix).

Test plan

  • Local Pkg.test() — 262/262 passing.
  • Local julia --project=docs docs/make.jl — Documenter renders cleanly with the extending.md updates.
  • CI: GitHub Actions (CI.yml) — same matrix as v0.3.1; expected identical.

Notes for AutoMerge

  • PATCH bump (0.3.1 → 0.3.2) — not a BREAKING release per Julia
    semver. release.sh correctly classifies this and does not require
    --breaking/--notes-file.
  • No new direct deps in Project.toml. Existing compat bounds
    (CommonSolve = "0.2", LineSearch = "0.1", SciMLBase = "2.53",
    julia = "1.10") unchanged.
  • No public-API removals — both source changes are additive (new
    keyword arguments with conservative defaults).
  • Default behavior change (worth surfacing): the previous
    SpectralThreeTerm.direction! returned ϑ_I = 0 in the degenerate
    y_{k-1} = 0 case, which gives zero descent (F(w_k)' d_k = 0).
    This release returns ϑ_I = alpha_min, restoring strict descent.
    Users hitting the degenerate path will see a tiny iterate change.
    Other code paths are byte-identical.

mmogib and others added 2 commits May 25, 2026 07:56
…polish

Two additive correctness-relevant changes surfaced during a paper-fidelity
cross-check of DFProjection.step! against the canonical literature
(Solodov-Svaiter 1999, La Cruz 2006, Ibrahim 2024 STTDFPM, Yin 2021,
Sabi'u 2023, Halpern 1967).

SpectralThreeTerm now clamps the spectral coefficient ϑ_I to
[alpha_min, alpha_max] (defaults [1e-10, 1e30]). The clamp underwrites
the strict-descent bound F(w_k)' d_k ≤ -α_min ‖F(w_k)‖² and the trust-
region bound on ‖d_k‖. In the degenerate case y_{k-1} = 0 the rule now
falls back to alpha_min rather than zero, restoring strict descent.

SolodovSvaiterProjection gains a γ::Float64 = 1.0 keyword argument for
the standard relaxation factor γ ∈ (0, 2). The projection target becomes
w − γ·λ·F(z), and the Dykstra tolerance scales by γ² so the inner solver
stops at constant fractional accuracy of the projection step across γ
values. Default γ = 1 preserves v0.3.1 behavior byte-for-byte;
over-relaxation (γ > 1) matches the published convergence theory's
γ(2−γ) descent coefficient.

Documentation:
- extending.md § 2 gains a "Convergence contract" subsection stating the
  descent + boundedness requirements for custom search directions, with
  SpectralThreeTerm's clamp/v_k as the worked example.
- extending.md § 3 gains an "Implicit contract for SolodovSvaiterProjection"
  subsection documenting the λ_k > 0 requirement.
- SolodovSvaiterProjection docstring notes that the 1999 exact-projection
  scheme is realized here as the standard inexact-projection refinement
  (Dykstra terminated at ε_k).
- extending.md § 0 renamed to "Preliminaries: contract surface"
  (un-numbered); § 1 – § 7 now correspond 1-to-1 to the seven extension
  slots.

Tests: 242 → 262 passing (10 new for each source change; default-
equivalence regressions confirm v0.3.1 byte-for-byte behavior outside
the formerly-degenerate code paths).

Findings tracked in notes/task_1_algorithm_verification.md
(P1.1, P1.2, P2.1, P2.2, P3.1; P3.3 dropped after discussion).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@mmogib
mmogib merged commit 7de1e8e into main May 25, 2026
@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.81%. Comparing base (c2cf75a) to head (99c6eaf).
⚠️ Report is 3 commits behind head on main.
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #15      +/-   ##
==========================================
+ Coverage   90.74%   90.81%   +0.06%     
==========================================
  Files          12       12              
  Lines         670      675       +5     
==========================================
+ Hits          608      613       +5     
  Misses         62       62              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants