docs(api): a dual is the rate at which the optimal objective rises with its row's right side, on every sink - #1774
Merged
FBumann merged 5 commits intoSep 29, 2026
Conversation
…th its row's right side, on every sink Result.dual now states the sign: of lhs <= rhs, the rate in d of lhs <= rhs + d, for every comparator and under either sense. A test pins it against a finite difference for six ways of writing one row, under minimize and maximize, on every installed sink. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CvcU9JRnsinc9e9syvVcHS
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CvcU9JRnsinc9e9syvVcHS
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CvcU9JRnsinc9e9syvVcHS
This was referenced Sep 27, 2026
Documentation build overview
4 files changed± about/architecture/index.html± about/changelog/index.html± reference/api/index.html± reference/data/index.html |
Merging this PR will not alter performance
Comparing Footnotes
|
…sign Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CvcU9JRnsinc9e9syvVcHS
…sis-features-zy7x4n-dual-sign # Conflicts: # CHANGELOG.md
FBumann
pushed a commit
that referenced
this pull request
Sep 29, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q7hhaASVuhgSVvaXkmUpEh
Merged
FBumann
deleted the
claude/mathspec-analysis-features-zy7x4n-dual-sign
branch
September 29, 2026 10:00
FBumann
added a commit
that referenced
this pull request
Sep 29, 2026
> **Prompt:** "Merged. Lets prepare a release" … "We want 1774 in there too!" > [!NOTE] > The following content was generated by AI. Merging this releases 0.2.1. It is a patch: three fixes for wrong answers that raised no error (#1784, #1779, #1776), the sign of a dual stated on `Result.dual` (#1774), and no break of a file, archive or import. The diff is `CHANGELOG.md` alone. <details><summary>What the section says, and what was checked</summary> - `## Upcoming version` became `## 0.2.1 (2026-09-29)`, with a paragraph on who is affected by each fix, a paragraph on the dual's sign, and then the four pull requests, each listed once. A new, empty `## Upcoming version` sits above it. - **Why a patch.** No construct was renamed or refused, no import moved, and nothing a result, sweep or archive writes to disk changed: `relational/parquet.py` is unchanged since `v0.2.0`, so `LAYOUT` is too. `pyproject.toml` changed only tool pins in the `dev` and `docs` groups. The fixes change values that were wrong, and #1774 changes no value. - `python -m tools.changelog check` prints `releases 0.2.1 on merge`. `python -m tools.changelog notes 0.2.1` prints the section as the release notes. `tests/test_changelog.py` passes. - Left out, as their types owe no line: #1781 (`test`), #1737 (`test`), #1761 (`chore`) and #1760 (`ci`). - On merge, `release.yaml` tags `v0.2.1`, opens the GitHub release, builds, and waits for a reviewer to approve the `pypi` environment before it uploads. </details> 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01Q7hhaASVuhgSVvaXkmUpEh --------- Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
The following content was generated by AI.
Result.dualstates its sign: the rate at which the optimal objective rises with the row's right side, for every comparator and sense. That is the definition energy-models/mathspec#751 givesdual(c). A test pins it on every sink against finite differences.Method, mutation, gates, departures
What was ambiguous
Result.dualsaid "shadow prices" and nothing about sign. mathspec's page said a dual is the rate at which the objective improves as the row is relaxed. That makes a<=dual underminimizenon-negative, where every sink here returns it non-positive, and it leaves an==row without a sign. No code changes here: all three sinks already return the rate in the right side, as written in the YAML. energy-models/mathspec#751 moves mathspec's definition to match.The test
test_a_dual_is_the_rate_of_the_optimum_in_its_rows_right_side, intests/test_duals.py. One row, "p is at least 2 + b", is written six ways:p >= 2 + b,2 + b <= p,-p <= -2 - b,p - b >= 2,p == 2 + band2 + b == p. Each runs underminimizeandmaximize, on every sinksolver_nameyields. The dual has to equal the finite difference of the objective inb(step1e-3; the row binds, so the difference is exact), times howbmovesrhs - lhs.Result: 36 passed, highs, gurobi and xpress. Gurobi and Xpress ran on the size-limited licences their PyPI wheels carry.
Mutation
row_dualnegated inhighs.pyGates
pixi installcould not run in the session: it fetches the conda-to-PyPI mapping from a host the session's network refuses. The gates ran fromuv sync --group dev --extra gurobi --extra xpresson Python 3.12, with the tool versions thedevgroup pins.ruff check .: clean.ruff format --check .: clean.pyrefly check, both configs: 0 errors.pytest -q -n auto: 4078 passed, 320 skipped, 1 xfailed.docs-buildwas not run.Not done
examples/benders/run.pyalready reads the slope with this sign, so it is unchanged.dual_rayhas its own convention, stated intest_dual_ray.py, and is untouched.🤖 Generated with Claude Code
https://claude.ai/code/session_01CvcU9JRnsinc9e9syvVcHS
Generated by Claude Code