Skip to content

Balance-system sleeve panel in the min-var experiment#31

Merged
tschm merged 1 commit into
mainfrom
balance-sleeve-experiment
Jul 4, 2026
Merged

Balance-system sleeve panel in the min-var experiment#31
tschm merged 1 commit into
mainfrom
balance-sleeve-experiment

Conversation

@tschm

@tschm tschm commented Jul 3, 2026

Copy link
Copy Markdown
Member

Adds a balance-system panel to the S&P 500 min-var experiment: the p ∈ {1, 4, 8} sleeve systems (B, c) run through the same matrix-free CG and dense-KKT solvers as the budget benchmark, writing sp500_sleeves_def.tex (\dataSpSleeves) with timings directly comparable to the budget rows. Also drops the proximal-gradient and FISTA rows from the paper tables (first-order methods are covered in the nncg companion) and regenerates ftse_defs.tex / sp500_defs.tex.

⚠️ Known caveats (WIP)

Flagging these openly — this is opened at the author's request while the supporting pieces land:

  • Unreleased dependency. Depends on (B, c) balance support in fast-minimum-variance that is not yet released; the inline pyproject source is pinned to a local checkout (../../fast_minimum_variance). CI make figures / a clean checkout will not resolve this until the package ships.
  • Orphan table. sp500_sleeves_def.tex / \dataSpSleeves is generated but not yet \input by any paper.
  • Dangling reference. A code comment cites experiment_balance.py, which is not in this repo.

🤖 Generated with Claude Code

Run the p in {1,4,8} sleeve balance systems (B, c) through the same
matrix-free CG and dense-KKT solvers as the budget benchmark and write
sp500_sleeves_def.tex (\dataSpSleeves), with timings comparable to the
budget rows. Drop the proximal-gradient and FISTA rows from the paper
tables (first-order methods are treated in the nncg companion), and
regenerate ftse_defs.tex and sp500_defs.tex.

Depends on unreleased (B, c) support in fast-minimum-variance; the inline
pyproject source is pinned to a local checkout until the next release.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 3, 2026 19:41

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new “balance-system sleeves” benchmark panel to the S&P 500 min-var experiment so sleeve-based balance constraints (p \in {1,4,8}) run through the same CG and dense-KKT solvers as the budget case, and regenerates the paper-facing timing macro definitions while removing first-order rows from those tables.

Changes:

  • Generate a new LaTeX macro file sp500_sleeves_def.tex for sleeve-system solver timings (CG/KKT; (p=1,4,8)).
  • Remove proximal-gradient/FISTA rows from the experiment.py table method lists and regenerate sp500_defs.tex / ftse_defs.tex.
  • Extend experiment.py to benchmark balance-system sleeve constraints under LW (\alpha=0.5).

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
experiment/experiment.py Adds sleeves benchmark panel; removes first-order methods from table generation and updates runner imports.
experiment/tables/sp500_sleeves_def.tex New generated macro \\dataSpSleeves containing sleeves timing rows.
experiment/tables/sp500_defs.tex Regenerated S&P 500 benchmark macro definitions without first-order rows.
experiment/tables/ftse_defs.tex Regenerated FTSE benchmark macro definitions without first-order rows.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread experiment/experiment.py
Comment on lines +187 to +191
# Balance-system panel: the production package now accepts (B, c), so the
# p in {1, 4, 8} sleeve systems of Section (balance) run through the same
# matrix-free CG / dense-KKT solvers as the budget benchmark above, with
# timings directly comparable to the budget rows. Sleeve construction
# matches experiment_balance.py (seed 0, proportional shares).
Comment thread experiment/experiment.py
Comment on lines +195 to +207
sleeve_rng = np.random.default_rng(0)

def _sleeve(p, n=N, rng=sleeve_rng):
"""Partition the universe into p sleeves each holding its budget share."""
if p == 1:
return np.ones((1, n)), np.array([1.0])
groups = np.array_split(rng.permutation(n), p)
b_eq = np.zeros((p, n))
c_eq = np.zeros(p)
for g, idx in enumerate(groups):
b_eq[g, idx] = 1.0
c_eq[g] = len(idx) / n
return b_eq, c_eq
Comment thread experiment/experiment.py
Comment on lines +209 to +227
sleeve_lines = []
for solver_label, solver_fn, is_kkt in (
("CG (SPD)", lambda pr: pr.solve_cg(), False),
("KKT (Cholesky)", lambda pr: pr.solve_kkt(), True),
):
for p in (1, 4, 8):
b_eq, c_eq = _sleeve(p)
prob = MinVarProblem(R, alpha=alpha_hard, target=target, B=b_eq, c=c_eq)
(_ref, _), t_ref = run_timed(lambda pr=prob: pr.solve_cvxpy(project=False))
entry = _make_entry(prob, solver_fn, is_kkt)
iters = entry["inner"] if entry["inner"] is not None else entry["outer"]
speedup = t_ref / entry["time_s"]
tag = "(budget)" if p == 1 else "(sleeves)"
label = f"{solver_label}, $p = {p}$ {tag}"
sleeve_lines.append(
f"{label:<32} & {_fmt_time(entry['time_s']):>8} & {iters:>6} & {speedup:>6.1f}x \\\\\n"
)
print(f"{solver_label:<16} {p:>3} {entry['time_s']:>9.4f} {iters:>7} {speedup:>8.1f}x")

@tschm tschm merged commit 9760a87 into main Jul 4, 2026
1 check passed
@tschm tschm deleted the balance-sleeve-experiment branch July 4, 2026 03:44
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