Skip to content

Conversation

@bstellato
Copy link
Member

Summary

Fix two bugs in solve_internal() when using Clarabel with PSD cones.

Problem

When using diffcp.solve_and_derivative(..., solve_method='CLARABEL') with problems containing multiple PSD cones, the solution was incorrect. For example, a problem with optimal objective ~0.088 would return ~1.3e-10.

Root Cause

Two bugs in the Clarabel code path:

Bug 1: Wrong start_row increment (line 542)

# Before (incorrect)
start_row += v

# After (correct)
start_row += v * (v + 1) // 2  # triangular number for vectorized PSD cone

For a PSD cone of dimension n (an n×n matrix), the vectorized representation has n*(n+1)/2 elements, not n. This caused incorrect row permutations when problems have multiple PSD cones.

Bug 2: Missing inverse permutation for y and s

After solving with Clarabel, the returned y and s vectors are in Clarabel's upper-triangular convention but were not permuted back to SCS's lower-triangular convention.

Added inverse_permute_psd_solution() function to handle this conversion.

Testing

Added comprehensive test file tests/test_clarabel_psd.py with 6 tests:

  • test_multiple_psd_cones_objective_match - verifies fix for the reported issue
  • test_single_psd_cone - single PSD cone works correctly
  • test_mixed_cones - problems with zero, nonneg, and PSD cones
  • test_constraint_satisfaction - verifies Ax + s = b
  • test_derivative_lsqr_mode - derivatives work in lsqr mode
  • test_psd_permutation_logic - permutation logic is correct

Verification

Before fix:

CVXPy objective: 0.088146
diffcp + Clarabel objective: 1.3e-10  # WRONG

After fix:

CVXPy objective: 0.088146
diffcp + SCS objective: 0.088158
diffcp + Clarabel objective: 0.088146  # CORRECT

Two bugs fixed in solve_internal() for Clarabel:

1. Wrong start_row increment: Changed from `start_row += v` to
   `start_row += v * (v + 1) // 2` because for a PSD cone of
   dimension n, the vectorized representation has n*(n+1)/2 elements.

2. Missing inverse permutation: Added inverse_permute_psd_solution()
   to convert y and s from Clarabel's upper-triangular convention
   back to SCS's lower-triangular convention after solving.

The first bug caused incorrect row permutations when problems have
multiple PSD cones - the second cone's permutation was applied to
the wrong rows, scrambling the problem.

Includes comprehensive tests verifying solution and constraint
satisfaction match between SCS and Clarabel solvers.
@SteveDiamond SteveDiamond merged commit bb5b91d into cvxgrp:master Jan 21, 2026
5 of 6 checks passed
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