Entropyk/_bmad-output/implementation-artifacts/4-8-jacobian-freezing-optimization.md

5.0 KiB

Story 4.8: Jacobian-Freezing Optimization

Status: done

Story

As a performance-critical user, I want to freeze Jacobian updates when approaching the solution, so that CPU time is reduced significantly without losing convergence stability.

Acceptance Criteria

  1. Enable Jacobian Freezing in Configuration

    • Given a NewtonConfig
    • When configured with with_jacobian_freezing(max_frozen_iters) (and optionally threshold)
    • Then the solver uses the frozen Jacobian optimization when conditions permit
  2. Reuse Jacobian Matrix

    • Given a system solving with Newton-Raphson
    • When the freezing condition is met
    • Then the solver skips calling traverse_for_jacobian and reuses the previous JacobianMatrix
    • And speed per iteration improves significantly (up to ~80% target)
  3. Auto-disable on Residual Increase

    • Given the solver is using a frozen Jacobian
    • When the current iteration's residual is GREATER than the previous iteration's residual
    • Then freezing is automatically disabled, and the Jacobian is recomputed for the next step
  4. Backward Compatibility

    • Given an existing NewtonConfig
    • When no freezing configuration is provided
    • Then the solver behaves exactly as before (recomputing Jacobian every step)

Tasks / Subtasks

  • Add JacobianFreezingConfig to NewtonConfig
    • Add jacobian_freezing: Option<JacobianFreezingConfig> field
    • Add builder method with_jacobian_freezing()
  • Implement Modified Newton logic in crates/solver/src/solver.rs
    • Track frozen iterations counter
    • Skip Jacobian update when conditions permit (residual decreasing, counter < max)
    • Force Jacobian update if residual increases
  • Fix broken test struct literals
    • Update crates/solver/tests/*.rs with ..Default::default() for NewtonConfig where new fields are added (if not using builders)
  • Add unit/integration tests
    • Test frozen Jacobian converges correctly
    • Test auto-recompute on divergence trend

Dev Notes

  • Relevant architecture patterns and constraints:
    • Zero Allocation: Do not dynamically allocate new matrices in the hot path. The JacobianMatrix should be reused.
    • Safety: No panics allowed.
  • Source tree components to touch:
    • crates/solver/src/solver.rs (update Newton solver loop)
    • crates/solver/tests/newton_raphson.rs (add integration tests for freezing)
  • Testing standards summary:
    • Use approx::assert_relative_eq! for floating point assertions.
    • Run cargo clippy -- -D warnings to ensure style compliance.

Project Structure Notes

  • Alignment with unified project structure: all changes are safely confined to the solver crate. No bindings code required.

References

  • [Source: epics.md FR19] "Solver can freeze Jacobian calculation to accelerate"
  • [Source: epics.md Story 4.8] "Jacobian-Freezing Optimization"
  • [Source: architecture.md NFR4] "No dynamic allocation in solver loop (pre-calculated allocation only)"

Dev Agent Record

Agent Model Used

Antigravity

Debug Log References

Completion Notes List

  • Ultimate context engine analysis completed - comprehensive developer guide created
  • Implemented JacobianFreezingConfig struct with max_frozen_iters and threshold fields
  • Added jacobian_freezing: Option<JacobianFreezingConfig> to NewtonConfig with None default for backward compatibility
  • Added with_jacobian_freezing() builder method on NewtonConfig
  • Modified Newton-Raphson solve loop: decision logic skips Jacobian assembly when frozen, stores and reuses JacobianMatrix via .clone()
  • Implemented auto-disable: sets force_recompute = true when residual ratio exceeds (1.0 - threshold), resets frozen counter
  • Fixed inline struct literal in existing test (test_with_timeout_preserves_other_fields)
  • Exported JacobianFreezingConfig from lib.rs
  • Created 12 new integration tests in jacobian_freezing.rs covering all ACs
  • All 151 tests pass (130 unit + 21 integration) + 17 doc-tests; zero regressions
  • [AI Code Review Fixes]: Fixed critical Zero-Allocation architecture violation by pre-allocating JacobianMatrix outside the loop and adding in-place update_from_builder logic to avoid clone().
  • [AI Code Review Fixes]: Added missing Rustdoc documentation to JacobianFreezingConfig public fields.
  • [AI Code Review Fixes]: Fixed integration test file jacobian_freezing.rs not being tracked in git natively.

File List

  • crates/solver/src/solver.rs (modified — added struct, field, builder, loop logic)
  • crates/solver/src/lib.rs (modified — exported JacobianFreezingConfig)
  • crates/solver/tests/jacobian_freezing.rs (new — 12 integration tests)
  • _bmad-output/implementation-artifacts/4-8-jacobian-freezing-optimization.md (modified — status + checkboxes + dev notes)

Change Log

  • 2026-02-19: Implemented Jacobian-Freezing Optimization (Story 4.8) — all ACs satisfied, 12 tests added, zero regressions