From 6139a4383c268c21216b76c2426e1923a24d4dd0 Mon Sep 17 00:00:00 2001 From: 40% Date: Tue, 19 Aug 2025 13:40:03 +0800 Subject: [PATCH 1/5] Add __matmul__ support to MatrixExpr Implements the __matmul__ method for MatrixExpr, enabling matrix multiplication using the @ operator and ensuring the result is returned as a MatrixExpr instance. --- src/pyscipopt/matrix.pxi | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pyscipopt/matrix.pxi b/src/pyscipopt/matrix.pxi index 0548fbd10..9eb0349f2 100644 --- a/src/pyscipopt/matrix.pxi +++ b/src/pyscipopt/matrix.pxi @@ -98,7 +98,10 @@ class MatrixExpr(np.ndarray): def __rsub__(self, other): return super().__rsub__(other).view(MatrixExpr) - + + def __matmul__(self, other): + return super().__matmul__(other).view(MatrixExpr) + class MatrixGenExpr(MatrixExpr): pass From b38481ac2bb720529ff0e6c084d64b3725b6ca52 Mon Sep 17 00:00:00 2001 From: 40% Date: Tue, 19 Aug 2025 13:45:56 +0800 Subject: [PATCH 2/5] Add tests for matrix matmul return types Adds tests to verify that matrix multiplication returns MatrixExpr instead of MatrixVariable for various input shapes. --- tests/test_matrix_variable.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/test_matrix_variable.py b/tests/test_matrix_variable.py index 0308bb694..e2ed2f383 100644 --- a/tests/test_matrix_variable.py +++ b/tests/test_matrix_variable.py @@ -392,3 +392,20 @@ def test_matrix_cons_indicator(): assert m.getVal(is_equal).sum() == 2 assert (m.getVal(x) == m.getVal(y)).all().all() assert (m.getVal(x) == np.array([[5, 5, 5], [5, 5, 5]])).all().all() + + +def test_matrix_matmul_return_type(): + # test #1058, require returning type is MatrixExpr not MatrixVariable + m = Model() + + # test 1D @ 1D → 0D + x = m.addMatrixVar(3) + assert isinstance(x @ x, MatrixExpr) + + # test 1D @ 1D → 2D + assert isinstance(x[:, None] @ x[None, :], MatrixExpr) + + # test 2D @ 2D → 2D + y = m.addMatrixVar((3, 4)) + z = m.addMatrixVar((2, 3)) + assert isinstance(y @ z, MatrixExpr) From ad513776614f3026c3e85b753b1d780a1310db4d Mon Sep 17 00:00:00 2001 From: 40% Date: Tue, 19 Aug 2025 13:50:02 +0800 Subject: [PATCH 3/5] Use type() checks instead of isinstance in matmul tests Replaces isinstance checks with type() comparisons for MatrixExpr in matrix matmul return type tests to ensure exact type matching. --- tests/test_matrix_variable.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_matrix_variable.py b/tests/test_matrix_variable.py index e2ed2f383..44da4c04c 100644 --- a/tests/test_matrix_variable.py +++ b/tests/test_matrix_variable.py @@ -400,12 +400,12 @@ def test_matrix_matmul_return_type(): # test 1D @ 1D → 0D x = m.addMatrixVar(3) - assert isinstance(x @ x, MatrixExpr) + assert type(x @ x) is MatrixExpr # test 1D @ 1D → 2D - assert isinstance(x[:, None] @ x[None, :], MatrixExpr) + assert type(x[:, None] @ x[None, :]) is MatrixExpr # test 2D @ 2D → 2D y = m.addMatrixVar((3, 4)) z = m.addMatrixVar((2, 3)) - assert isinstance(y @ z, MatrixExpr) + assert type(y @ z) is MatrixExpr From a9051835c8bb5c2b48ce2e4a697b1e0e6530c330 Mon Sep 17 00:00:00 2001 From: 40% Date: Tue, 19 Aug 2025 13:56:42 +0800 Subject: [PATCH 4/5] Fix matrix variable shapes in matmul test Corrects the shapes of matrix variables in test_matrix_matmul_return_type to ensure proper 2D matrix multiplication and type assertion. --- tests/test_matrix_variable.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_matrix_variable.py b/tests/test_matrix_variable.py index 44da4c04c..c7db949b3 100644 --- a/tests/test_matrix_variable.py +++ b/tests/test_matrix_variable.py @@ -406,6 +406,6 @@ def test_matrix_matmul_return_type(): assert type(x[:, None] @ x[None, :]) is MatrixExpr # test 2D @ 2D → 2D - y = m.addMatrixVar((3, 4)) - z = m.addMatrixVar((2, 3)) + y = m.addMatrixVar((2, 3)) + z = m.addMatrixVar((3, 4)) assert type(y @ z) is MatrixExpr From fe1773dd91248890d32736945786942ed745ff54 Mon Sep 17 00:00:00 2001 From: 40% Date: Tue, 19 Aug 2025 13:56:51 +0800 Subject: [PATCH 5/5] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index addf21992..868656025 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ ### Fixed - Raised an error when an expression is used when a variable is required - Fixed some compile warnings +- Fixed the type of @ matrix operation result from MatrixVariable to MatrixExpr. ### Changed - MatrixExpr.sum() now supports axis arguments and can return either a scalar or MatrixExpr, depending on the result dimensions. - AddMatrixCons() also accepts ExprCons.