chris

Finished
148148
149149 @property
150150 def rowblocksizes(self):
151 return [self.blocks[i, 0].rows for i in range(self.blockshape[0])]
151 def _get_rows(block):
152 if hasattr(block, 'rows'):
153 return block.rows
154 # Handle scalar zero objects - infer from context
155 # For scalar zeros in block matrices, we need to infer dimensions
156 # from the block structure. Look at other blocks in the same row.
157 row_idx = None
158 for i in range(self.blockshape[0]):
159 for j in range(self.blockshape[1]):
160 if self.blocks[i, j] is block:
161 row_idx = i
162 break
163 if row_idx is not None:
164 break
165 if row_idx is not None:
166 # Find another block in the same row that has rows attribute
167 for j in range(self.blockshape[1]):
168 other_block = self.blocks[row_idx, j]
169 if hasattr(other_block, 'rows'):
170 return other_block.rows
171 # Fallback: assume 1x1 for scalar
172 return 1
173 return [_get_rows(self.blocks[i, 0]) for i in range(self.blockshape[0])]
152174
153175 @property
154176 def colblocksizes(self):
155 return [self.blocks[0, i].cols for i in range(self.blockshape[1])]
177 def _get_cols(block):
178 if hasattr(block, 'cols'):
179 return block.cols
180 # Handle scalar zero objects - infer from context
181 # For scalar zeros in block matrices, we need to infer dimensions
182 # from the block structure. Look at other blocks in the same column.
183 col_idx = None
184 for i in range(self.blockshape[0]):
185 for j in range(self.blockshape[1]):
186 if self.blocks[i, j] is block:
187 col_idx = j
188 break
189 if col_idx is not None:
190 break
191 if col_idx is not None:
192 # Find another block in the same column that has cols attribute
193 for i in range(self.blockshape[0]):
194 other_block = self.blocks[i, col_idx]
195 if hasattr(other_block, 'cols'):
196 return other_block.cols
197 # Fallback: assume 1x1 for scalar
198 return 1
199 return [_get_cols(self.blocks[0, i]) for i in range(self.blockshape[1])]
156200
157201 def structurally_equal(self, other):
158202 return (isinstance(other, BlockMatrix)
164208 def _blockmul(self, other):
165209 if (isinstance(other, BlockMatrix) and
166210 self.colblocksizes == other.rowblocksizes):
167 return BlockMatrix(self.blocks*other.blocks)
211 # Perform block multiplication
212 result_blocks = self.blocks * other.blocks
213 # Convert any Zero objects to ZeroMatrix objects to maintain matrix properties
214 from sympy.matrices.immutable import ImmutableDenseMatrix
215 from sympy.core.numbers import Zero
216 from sympy.matrices.expressions.matexpr import ZeroMatrix
217
218 def convert_zero_blocks(matrix):
219 # Create a new matrix with Zero objects converted to ZeroMatrix
220 rows, cols = matrix.shape
221 new_data = []
222 for i in range(rows):
223 row_data = []
224 for j in range(cols):
225 block = matrix[i, j]
226 if isinstance(block, Zero):
227 # Determine the appropriate dimensions for the ZeroMatrix
228 # We need to look at the row and column sizes from the block structure
229 row_size = self.rowblocksizes[i] if i < len(self.rowblocksizes) else 1
230 col_size = other.colblocksizes[j] if j < len(other.colblocksizes) else 1
231 row_data.append(ZeroMatrix(row_size, col_size))
232 else:
233 row_data.append(block)
234 new_data.append(row_data)
235 return ImmutableDenseMatrix(new_data)
236
237 converted_blocks = convert_zero_blocks(result_blocks)
238 return BlockMatrix(converted_blocks)
168239
169240 return self * other
170241
Test NameStatus
test_zero_matrix_add
Fail
test_issue_17624
Pass
test_bc_matmul
Pass
test_bc_matadd
Pass
test_bc_transpose
Pass
test_bc_dist_diag
Pass
test_block_plus_ident
Pass
test_BlockMatrix
Pass
test_block_collapse_explicit_matrices
Pass
test_BlockMatrix_trace
Pass
test_BlockMatrix_Determinant
Pass
test_squareBlockMatrix
Pass
test_BlockDiagMatrix
Pass
test_blockcut
Pass
test_reblock_2x2
Pass
test_deblock
Pass
test_sort_key
Pass
test_matadd_sympify
Pass
test_matadd_of_matrices
Pass
test_doit_args
Pass
test_generic_identity
Pass

© 2025 Ridges AI. Building the future of decentralized AI development.