-
Notifications
You must be signed in to change notification settings - Fork 271
Open
Description
Describe the bug
MatrixVariable
can't broadcast between two matrices with different shapes.
To Reproduce
import numpy as np
a = np.arange(6).reshape(2, 3) # shape is (2, 3)
# array([[0, 1, 2],
# [3, 4, 5]])
b = np.array([[1], [4]]) # shape is (2, 1)
# array([[1],
# [4]])
a <= b # pass
# array([[ True, True, False],
# [ True, True, False]])
from pyscipopt import Model
model = Model()
x = model.addMatrixVar((2, 3))
y = model.addMatrixVar(2)
# convert y shape to (2, 1)
x <= y[:, None] # Error!
# Traceback (most recent call last):
# line 22, in <module>
# x <= y[:, None] # Error!
# ^^^^^^^^^^^^^^^
# File "src/pyscipopt/matrix.pxi", line 36, in pyscipopt.scip.MatrixExpr.__le__
# IndexError: index 1 is out of bounds for axis 1 with size 1
Expected behavior
Did like numpy and supported broadcast.
Solution
It may be simplified like this. And use numpy to do broadcasting.
Since pyscipopt has already done the comparison core work between two expressions or variables.
def __le__(self, other):
if isinstance(other, ...): # type checking
raise TypeError(f"Unsupported type {type(other)}")
return super().__le__(other).view(MatrixExprCons)
PySCIPOpt/src/pyscipopt/matrix.pxi
Lines 27 to 40 in c681f94
def __le__(self, other: Union[float, int, Variable, np.ndarray, 'MatrixExpr']) -> np.ndarray: | |
expr_cons_matrix = np.empty(self.shape, dtype=object) | |
if _is_number(other) or isinstance(other, Variable): | |
for idx in np.ndindex(self.shape): | |
expr_cons_matrix[idx] = self[idx] <= other | |
elif isinstance(other, np.ndarray): | |
for idx in np.ndindex(self.shape): | |
expr_cons_matrix[idx] = self[idx] <= other[idx] | |
else: | |
raise TypeError(f"Unsupported type {type(other)}") | |
return expr_cons_matrix.view(MatrixExprCons) |
Screenshots

System
- OS: Windows 11
- Version: 24H2 (26100.4061)
- SCIP version: 9.2.3
- How did you install pyscipopt?: build from c681f94, base on 5.5.0
Metadata
Metadata
Assignees
Labels
No labels