116 lines
5.3 KiB
Diff
116 lines
5.3 KiB
Diff
# sympy__sympy-17630
|
|
# Loki Mode Multi-Agent Patch
|
|
# Attempts: 1
|
|
|
|
The sympy repository is not available locally. Based on the issue description and the architect's analysis, I can generate the patch for the upstream SymPy repository. The bug is well-documented: when `ZeroMatrix * ZeroMatrix` or similar operations occur in `_blockmul`, the result is a scalar `Zero` instead of `ZeroMatrix`, causing subsequent operations to fail.
|
|
|
|
```
|
|
--- a/sympy/matrices/expressions/blockmatrix.py
|
|
+++ b/sympy/matrices/expressions/blockmatrix.py
|
|
@@ -1,5 +1,6 @@
|
|
from __future__ import print_function, division
|
|
|
|
+from sympy import S
|
|
from sympy.assumptions.ask import ask, Q
|
|
from sympy.core import Basic, Add
|
|
from sympy.strategies import typed, exhaust, condition, do_one, unpack
|
|
@@ -88,6 +89,23 @@ class BlockMatrix(MatrixExpr):
|
|
def colblocksizes(self):
|
|
return [self.blocks[0, i].cols for i in range(self.blockshape[1])]
|
|
|
|
+ def _ensure_zero_matrix(self, block, rows, cols):
|
|
+ """Convert scalar Zero to ZeroMatrix with proper dimensions."""
|
|
+ from sympy.matrices.expressions.matexpr import ZeroMatrix
|
|
+ if block == S.Zero:
|
|
+ return ZeroMatrix(rows, cols)
|
|
+ return block
|
|
+
|
|
+ def _get_block_sizes(self, blocks, rowblocksizes, colblocksizes):
|
|
+ """Get row and column sizes for each block position."""
|
|
+ result = []
|
|
+ for i in range(len(rowblocksizes)):
|
|
+ row = []
|
|
+ for j in range(len(colblocksizes)):
|
|
+ row.append((rowblocksizes[i], colblocksizes[j]))
|
|
+ result.append(row)
|
|
+ return result
|
|
+
|
|
def _blockmul(self, other):
|
|
if (isinstance(other, BlockMatrix) and
|
|
self.colblocksizes == other.rowblocksizes):
|
|
@@ -95,8 +113,14 @@ class BlockMatrix(MatrixExpr):
|
|
for i in range(self.blockshape[0])
|
|
for j in range(other.blockshape[1])]
|
|
|
|
- return BlockMatrix(Matrix(self.blockshape[0], other.blockshape[1], block_mul))
|
|
- return self * other
|
|
+ result = BlockMatrix(Matrix(self.blockshape[0], other.blockshape[1], block_mul))
|
|
+ # Convert any scalar Zero entries back to ZeroMatrix with proper dimensions
|
|
+ rowsizes = self.rowblocksizes
|
|
+ colsizes = other.colblocksizes
|
|
+ new_blocks = [[self._ensure_zero_matrix(result.blocks[i, j], rowsizes[i], colsizes[j])
|
|
+ for j in range(result.blockshape[1])]
|
|
+ for i in range(result.blockshape[0])]
|
|
+ return BlockMatrix(Matrix(new_blocks))
|
|
+ return self * other
|
|
|
|
def _blockadd(self, other):
|
|
if (isinstance(other, BlockMatrix)
|
|
```
|
|
|
|
Wait, I need to reconsider this approach. The issue is that when we compute `MatMul(A, ZeroMatrix)` or `MatMul(ZeroMatrix, ZeroMatrix)`, it gets simplified to scalar `Zero` rather than `ZeroMatrix`. The fix should handle this in the `_blockmul` method where the matrix multiplication results are computed.
|
|
|
|
Let me provide a cleaner patch:
|
|
|
|
```
|
|
--- a/sympy/matrices/expressions/blockmatrix.py
|
|
+++ b/sympy/matrices/expressions/blockmatrix.py
|
|
@@ -163,6 +163,8 @@ def bc_matmul(expr):
|
|
def bc_block_plus_ident(expr):
|
|
pass
|
|
|
|
+from sympy.matrices.expressions.matexpr import ZeroMatrix
|
|
+
|
|
def _block_mul(A, B):
|
|
"""Multiply two block matrices.
|
|
Assumes that both matrices have conforming block structures.
|
|
@@ -176,6 +178,10 @@ def _block_mul(A, B):
|
|
block = Add(*[A.blocks[i, k] * B.blocks[k, j]
|
|
for k in range(A.blockshape[1])])
|
|
blocks[i*n + j] = block
|
|
+ # Convert scalar Zero back to ZeroMatrix with proper dimensions
|
|
+ from sympy import S
|
|
+ if blocks[i*n + j] == S.Zero:
|
|
+ blocks[i*n + j] = ZeroMatrix(A.rowblocksizes[i], B.colblocksizes[j])
|
|
return BlockMatrix(Matrix(m, n, blocks))
|
|
```
|
|
|
|
Actually, let me reconsider. Looking at the traceback more carefully, the issue is in the `_blockmul` method itself. The patch should be applied there. Let me provide a complete, clean patch:
|
|
|
|
--- a/sympy/matrices/expressions/blockmatrix.py
|
|
+++ b/sympy/matrices/expressions/blockmatrix.py
|
|
@@ -89,13 +89,20 @@ class BlockMatrix(MatrixExpr):
|
|
return [self.blocks[0, i].cols for i in range(self.blockshape[1])]
|
|
|
|
def _blockmul(self, other):
|
|
+ from sympy.matrices.expressions.matexpr import ZeroMatrix
|
|
+ from sympy import S
|
|
if (isinstance(other, BlockMatrix) and
|
|
self.colblocksizes == other.rowblocksizes):
|
|
- block_mul = lambda i, j: Add(*[self.blocks[i, k]*other.blocks[k, j]
|
|
- for k in range(self.blockshape[1])])
|
|
-
|
|
- return BlockMatrix(Matrix(self.blockshape[0], other.blockshape[1], block_mul))
|
|
- return self * other
|
|
+ def block_mul(i, j):
|
|
+ result = Add(*[self.blocks[i, k]*other.blocks[k, j]
|
|
+ for k in range(self.blockshape[1])])
|
|
+ # Convert scalar Zero to ZeroMatrix with proper dimensions
|
|
+ if result == S.Zero:
|
|
+ return ZeroMatrix(self.rowblocksizes[i], other.colblocksizes[j])
|
|
+ return result
|
|
+ return BlockMatrix(Matrix(self.blockshape[0], other.blockshape[1], block_mul))
|
|
+ return self * other
|
|
|
|
def _blockadd(self, other):
|
|
if (isinstance(other, BlockMatrix)
|