Skip to content

Add addMatrixConsDisjunction for matrix constraints#1210

Open
Joao-Dionisio wants to merge 2 commits intomasterfrom
addMatrixConsDisjunction
Open

Add addMatrixConsDisjunction for matrix constraints#1210
Joao-Dionisio wants to merge 2 commits intomasterfrom
addMatrixConsDisjunction

Conversation

@Joao-Dionisio
Copy link
Copy Markdown
Member

@Joao-Dionisio Joao-Dionisio commented Apr 22, 2026

Fixes #1084.

@Zeroto521 you're our matrix guy, would you mind taking a look? :)

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 dedicated Model.addMatrixConsDisjunction() API to support elementwise disjunctions when working with matrix constraint expressions (MatrixExprCons), addressing a gap in matrix-constraint composition.

Changes:

  • Implement Model.addMatrixConsDisjunction() in scip.pxi, creating one disjunction constraint per matrix index (with scalar fallback).
  • Add regression tests covering shape mismatch/type validation and optimization behavior for matrix + scalar fallback.
  • Expose the method in type stubs and document it in the changelog.

Reviewed changes

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

File Description
src/pyscipopt/scip.pxi Implements addMatrixConsDisjunction() including broadcasting and scalar fallback logic.
tests/test_matrix_variable.py Adds test coverage for matrix disjunction behavior and error paths.
src/pyscipopt/scip.pyi Adds stub entry for the new Model method.
CHANGELOG.md Documents the new API addition.

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

Comment thread src/pyscipopt/scip.pxi
Comment on lines +6649 to +6664
dynamic: Union[bool, np.ndarray] = False):
"""
Add an elementwise disjunction of matrix constraints.

Given an iterable of ``MatrixExprCons`` with a common shape, creates one
disjunction per index: for each position ``idx``, the resulting
disjunction enforces that at least one of ``conss[k][idx]`` holds.
``ExprCons`` entries are broadcast to every position. If every entry in
``conss`` is a plain ``ExprCons``, the call is forwarded to
:meth:`addConsDisjunction` and returns a single ``Constraint``.

Parameters
----------
conss : iterable of MatrixExprCons or ExprCons
Constraints to combine elementwise into disjunctions. All
``MatrixExprCons`` entries must share the same shape.
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

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

The new API is named/worded as if it works with already-added MatrixConstraint objects (like those returned by addMatrixCons), but the implementation only accepts MatrixExprCons/ExprCons. This means the #1084 reproduction (building c1 = addMatrixCons(...) then passing c1 into a disjunction) still won’t work unless users change how they call the API. Consider either (a) extending this method to also accept MatrixConstraint/Constraint inputs (elementwise) or (b) explicitly documenting here that callers must pass constraint expressions (e.g., A @ x == b) rather than constraints returned by addMatrixCons.

Copilot uses AI. Check for mistakes.
Comment thread CHANGELOG.md
- `Expr` and `GenExpr` support NumPy unary functions (`np.sin`, `np.cos`, `np.sqrt`, `np.exp`, `np.log`, `np.absolute`)
- Added `getBase()` and `setBase()` methods to `LP` class for getting/setting basis status
- Added `getMemUsed()`, `getMemTotal()`, and `getMemExternEstim()` methods
- Added `addMatrixConsDisjunction()` for elementwise disjunctions over matrix constraints (#1084)
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

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

Changelog entry says “disjunctions over matrix constraints”, which can be read as supporting MatrixConstraint objects (returned by addMatrixCons). Since the new function currently takes MatrixExprCons/ExprCons, consider adjusting the wording to “matrix constraint expressions”/“MatrixExprCons” (or similar) so users don’t expect addConsDisjunction([c1, c2]) with c1/c2 being MatrixConstraint to work.

Suggested change
- Added `addMatrixConsDisjunction()` for elementwise disjunctions over matrix constraints (#1084)
- Added `addMatrixConsDisjunction()` for elementwise disjunctions over matrix constraint expressions (`MatrixExprCons`/`ExprCons`) (#1084)

Copilot uses AI. Check for mistakes.
Comment thread src/pyscipopt/scip.pxi
Comment on lines +6699 to +6704
if all(isinstance(cons, ExprCons) for cons in conss):
return self.addConsDisjunction(
conss, name=name, initial=initial, relaxcons=relaxcons,
enforce=enforce, check=check, local=local,
modifiable=modifiable, dynamic=dynamic,
)
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

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

In the all(ExprCons) fallback, this forwards name/initial/enforce/... directly to addConsDisjunction. If a caller passes NumPy arrays for these (allowed by this method’s signature), the scalar call will receive an np.ndarray where it expects a str/bool, leading to a runtime error. Consider validating that all matrix-style parameters are scalars in the scalar-fallback path (or reducing them to a scalar explicitly) and raising a clear TypeError/ValueError otherwise.

Copilot uses AI. Check for mistakes.
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.

Cannot create disjunction of matrix constraints

2 participants