fistinz

Finished
99from sympy.utilities.misc import filldedent
1010
1111from sympy.matrices.expressions.matexpr import MatrixExpr, ZeroMatrix, Identity
12from sympy.core.numbers import Zero
1213from sympy.matrices.expressions.matmul import MatMul
1314from sympy.matrices.expressions.matadd import MatAdd
1415from sympy.matrices.expressions.matpow import MatPow
7980 def __new__(cls, *args, **kwargs):
8081 from sympy.matrices.immutable import ImmutableDenseMatrix
8182 from sympy.utilities.iterables import is_sequence
82 isMat = lambda i: getattr(i, 'is_Matrix', False)
83 isMat = lambda i: getattr(i, 'is_Matrix', False) or isinstance(i, Zero)
8384 if len(args) != 1 or \
8485 not is_sequence(args[0]) or \
8586 len(set([isMat(r) for r in args[0]])) != 1:
124125 block matrix. If this matrix is known to consist of
125126 blocks fully filling a 2-D space then see
126127 Matrix.irregular.'''))
128 # Convert any Zero objects to ZeroMatrix objects with appropriate dimensions
129 def convert_zero_to_zero_matrix(matrix):
130 if not matrix:
131 return matrix
132
133 # If this is already a matrix (like ImmutableDenseMatrix), work with its elements
134 if hasattr(matrix, 'shape') and hasattr(matrix, '__getitem__'):
135 from sympy.matrices.immutable import ImmutableDenseMatrix
136
137 # First, determine the dimensions for each row and column
138 row_dims = [None] * matrix.shape[0]
139 col_dims = [None] * matrix.shape[1]
140
141 # Find dimensions from non-Zero blocks
142 for i in range(matrix.shape[0]):
143 for j in range(matrix.shape[1]):
144 block = matrix[i, j]
145 if not isinstance(block, Zero) and hasattr(block, 'rows') and hasattr(block, 'cols'):
146 if row_dims[i] is None:
147 row_dims[i] = block.rows
148 if col_dims[j] is None:
149 col_dims[j] = block.cols
150
151 # For any remaining None dimensions, use reasonable defaults or infer from other dimensions
152 # In a proper block matrix, all blocks in a row should have the same row count
153 # and all blocks in a column should have the same column count
154 for i in range(matrix.shape[0]):
155 if row_dims[i] is None:
156 # Try to find row dimension from any column in this row
157 for j in range(matrix.shape[1]):
158 block = matrix[i, j]
159 if isinstance(block, ZeroMatrix) and hasattr(block, 'rows'):
160 row_dims[i] = block.rows
161 break
162 if row_dims[i] is None:
163 row_dims[i] = 1 # fallback
164
165 for j in range(matrix.shape[1]):
166 if col_dims[j] is None:
167 # Try to find column dimension from any row in this column
168 for i in range(matrix.shape[0]):
169 block = matrix[i, j]
170 if isinstance(block, ZeroMatrix) and hasattr(block, 'cols'):
171 col_dims[j] = block.cols
172 break
173 if col_dims[j] is None:
174 col_dims[j] = 1 # fallback
175
176 # Create a new matrix with converted elements
177 new_data = []
178 for i in range(matrix.shape[0]):
179 row = []
180 for j in range(matrix.shape[1]):
181 block = matrix[i, j]
182 if isinstance(block, Zero):
183 row.append(ZeroMatrix(row_dims[i], col_dims[j]))
184 else:
185 row.append(block)
186 new_data.append(row)
187 return ImmutableDenseMatrix(new_data, evaluate=False)
188
189 # Handle the case where rows is a list of lists
190 new_rows = []
191 for r in rows:
192 new_row = []
193 for block in r:
194 if isinstance(block, Zero):
195 # For list format, we need to determine dimensions differently
196 # This is a fallback - should primarily use matrix format
197 new_row.append(ZeroMatrix(1, 1))
198 else:
199 new_row.append(block)
200 new_rows.append(new_row)
201 return new_rows
202
203 rows = convert_zero_to_zero_matrix(rows)
127204 mat = ImmutableDenseMatrix(rows, evaluate=False)
128205 obj = Basic.__new__(cls, mat)
129206 return obj
164241 def _blockmul(self, other):
165242 if (isinstance(other, BlockMatrix) and
166243 self.colblocksizes == other.rowblocksizes):
167 return BlockMatrix(self.blocks*other.blocks)
244 # Multiply the blocks
245 result_blocks = self.blocks * other.blocks
246
247 # Convert any Zero objects to ZeroMatrix with appropriate dimensions
248 # The result should have the same row structure as self and column structure as other
249 from sympy.matrices.immutable import ImmutableDenseMatrix
250 new_data = []
251 for i in range(result_blocks.shape[0]):
252 row = []
253 for j in range(result_blocks.shape[1]):
254 block = result_blocks[i, j]
255 if isinstance(block, Zero):
256 # Use the row dimension from self and column dimension from other
257 row_dim = self.rowblocksizes[i]
258 col_dim = other.colblocksizes[j]
259 row.append(ZeroMatrix(row_dim, col_dim))
260 else:
261 row.append(block)
262 new_data.append(row)
263
264 return BlockMatrix(ImmutableDenseMatrix(new_data, evaluate=False))
168265
169266 return self * other
170267
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.