
    \h{                        S SK JrJr  S SKJrJrJrJr  S SKJ	r	  S SK
JrJr  S SKJrJrJrJrJr  S SKJr  S SKJrJr  S SKJr  S S	KJrJr  S S
KJr  S SKJ r J!r!  S SK"J#r#  S SK$J%r%  S SK&J'r'J(r(  S SK)J*r*  S SK+J,r,  S SK-J.r.  S SK/J0r0J1r1  S SK2J3r3  S SK4J5r5J6r6   " S S\'5      r7 " S S\75      r8S r9S r:S r;S r<S r=S r>S r?S  r@S! rAS" rBS# rCS$ rDS% rES& rFS' rGg())    )Qask)BasicAddMulS)_sympify)reim)typedexhaust	conditiondo_oneunpack)	bottom_up)is_sequencesift)
filldedent)Matrix
ShapeError)NonInvertibleMatrixError)detDeterminant)Inverse)MatAdd)
MatrixExprMatrixElement)MatMul)MatPow)MatrixSlice)
ZeroMatrixIdentity)trace)	Transpose	transposec                      ^  \ rS rSrSrS r\S 5       r\S 5       r\S 5       r	\S 5       r
\S 5       rS	 rS
 rS rS rS rS rS rS rS rS rSS jrS rS rS rS r\S 5       r\S 5       rU 4S jrSrU =r$ )BlockMatrix   a  A BlockMatrix is a Matrix comprised of other matrices.

The submatrices are stored in a SymPy Matrix object but accessed as part of
a Matrix Expression

>>> from sympy import (MatrixSymbol, BlockMatrix, symbols,
...     Identity, ZeroMatrix, block_collapse)
>>> n,m,l = symbols('n m l')
>>> X = MatrixSymbol('X', n, n)
>>> Y = MatrixSymbol('Y', m, m)
>>> Z = MatrixSymbol('Z', n, m)
>>> B = BlockMatrix([[X, Z], [ZeroMatrix(m,n), Y]])
>>> print(B)
Matrix([
[X, Z],
[0, Y]])

>>> C = BlockMatrix([[Identity(n), Z]])
>>> print(C)
Matrix([[I, Z]])

>>> print(block_collapse(C*B))
Matrix([[X, Z + Z*Y]])

Some matrices might be comprised of rows of blocks with
the matrices in each row having the same height and the
rows all having the same total number of columns but
not having the same number of columns for each matrix
in each row. In this case, the matrix is not a block
matrix and should be instantiated by Matrix.

>>> from sympy import ones, Matrix
>>> dat = [
... [ones(3,2), ones(3,3)*2],
... [ones(2,3)*3, ones(2,2)*4]]
...
>>> BlockMatrix(dat)
Traceback (most recent call last):
...
ValueError:
Although this matrix is comprised of blocks, the blocks do not fill
the matrix in a size-symmetric fashion. To create a full matrix from
these arguments, pass them directly to Matrix.
>>> Matrix(dat)
Matrix([
[1, 1, 2, 2, 2],
[1, 1, 2, 2, 2],
[1, 1, 2, 2, 2],
[3, 3, 3, 4, 4],
[3, 3, 3, 4, 4]])

See Also
========
sympy.matrices.matrixbase.MatrixBase.irregular
c           	      8   SSK Jn  S n[        U5      S:w  d;  [        US   5      (       a(  [        US    Vs1 s H
  oT" U5      iM     sn5      S:w  a  [	        [        S5      5      eU(       a  US   O/ nU" U5      (       Gd`  U(       a  U" US   5      (       a  U/n[        U Vs1 s H  n[        U5      iM     sn5      S:H  =pxU(       a  U H4  n[        U V	s1 s H  oR                  iM     sn	5      S:H  nU(       a  M4    O   UnU(       ag  [        [        US   5      5       HL  n
[        [        [        U5      5       V	s1 s H  n	Xi   U
   R                  iM     sn	5      S:H  nU(       a  ML    O   U(       de  [        U Vs1 s H  n[        S U 5       5      iM     sn5      S:H  nU(       a  U(       a  [	        [        S5      5      e[	        [        S5      5      eU" US	S
9n[        R                  " X5      nU$ s  snf s  snf s  sn	f s  sn	f s  snf )Nr   ImmutableDenseMatrixc                     [        U SS5      $ )N	is_MatrixF)getattr)is    ^/var/www/auris/envauris/lib/python3.13/site-packages/sympy/matrices/expressions/blockmatrix.py<lambda>%BlockMatrix.__new__.<locals>.<lambda>R   s    '![%8       z\
                expecting a sequence of 1 or more rows
                containing Matrices.c              3   8   #    U  H  oR                   v   M     g 7fNcols).0r/   s     r0   	<genexpr>&BlockMatrix.__new__.<locals>.<genexpr>q   s     *1   a0  
                        Although this matrix is comprised of blocks,
                        the blocks do not fill the matrix in a
                        size-symmetric fashion. To create a full matrix
                        from these arguments, pass them directly to
                        Matrix.a}  
                    When there are not the same number of rows in each
                    row's matrices or there are not the same number of
                    total columns in each row, the matrix is not a
                    block matrix. If this matrix is known to consist of
                    blocks fully filling a 2-D space then see
                    Matrix.irregular.Fevaluate)sympy.matrices.immutabler+   lenr   
ValueErrorr   rowsranger8   sumr   __new__)clsargskwargsr+   isMatrrB   blockyokr/   cmatobjs                r0   rE   BlockMatrix.__new__P   s   A8t9>Q((tAw/w!U1Xw/0A5Z )( ) * * tAwBT{{d1gv t4t!s1vt45::FAa0affa01Q6B2  "3tAw<0 %*3t9%5"7%5 #''!*//%5"7 8;<=!r!	 1
 48:48qC***D: ;>?@b$Z 1# &$ % % ! -) "* + + #4%8mmC%
[ 0 5 1"7:s   H'HH
H
Hc                     S=pU R                   n[        UR                  S   5       H  nXUS4   R                  S   -  nM     [        UR                  S   5       H  nX#SU4   R                  S   -  nM     X4$ Nr   r4   )blocksrC   shape)selfnumrowsnumcolsMr/   s        r0   rT   BlockMatrix.shape   s|    KKqwwqz"AAw}}Q''G #qwwqz"AAw}}Q''G #!!r3   c                 .    U R                   R                  $ r6   rS   rT   rU   s    r0   
blockshapeBlockMatrix.blockshape   s    {{   r3   c                      U R                   S   $ Nr   rG   r\   s    r0   rS   BlockMatrix.blocks   s    yy|r3   c                     [        U R                  S   5       Vs/ s H  oR                  US4   R                  PM     sn$ s  snf r`   )rC   r]   rS   rB   rU   r/   s     r0   rowblocksizesBlockMatrix.rowblocksizes   ;    05dooa6H0IJ0I1AqD!&&0IJJJ   $Ac                     [        U R                  S   5       Vs/ s H  oR                  SU4   R                  PM     sn$ s  snf )Nr4   r   )rC   r]   rS   r8   rd   s     r0   colblocksizesBlockMatrix.colblocksizes   rg   rh   c                 "   [        U[        5      =(       ay    U R                  UR                  :H  =(       aY    U R                  UR                  :H  =(       a9    U R                  UR                  :H  =(       a    U R
                  UR
                  :H  $ r6   )
isinstancer'   rT   r]   re   rj   rU   others     r0   structurally_equalBlockMatrix.structurally_equal   ss    5+. :

ekk):5#3#33: ""e&9&99: ""e&9&99		;r3   c                     [        U[        5      (       a<  U R                  UR                  :X  a"  [        U R                  UR                  -  5      $ X-  $ r6   )rm   r'   rj   re   rS   rn   s     r0   	_blockmulBlockMatrix._blockmul   sC    uk**""e&9&99t{{5<<788|r3   c                     [        U[        5      (       a8  U R                  U5      (       a"  [        U R                  UR                  -   5      $ X-   $ r6   )rm   r'   rp   rS   rn   s     r0   	_blockaddBlockMatrix._blockadd   s@    uk**++E22t{{U\\9::|r3   c                     U R                    Vs/ s H  n[        U5      PM     nn[        U R                  S   U R                  S   U5      nUR                  5       n[	        U5      $ s  snf rR   )rS   r%   r   r]   r'   )rU   matrixmatricesrX   s       r0   _eval_transposeBlockMatrix._eval_transpose   sZ    48KK@K&If%K@4??1%tq'98DKKM1~ As   A(c                     [        [        U R                  S   U R                  S   U R                  5      R	                  5       5      $ rR   )r'   r   r]   rS   adjointr\   s    r0   _eval_adjointBlockMatrix._eval_adjoint   s:    4??1%tq'94;;GOOQ
 	
r3   c                     U R                   U R                  :X  aW  [        U R                  S   5       Vs/ s H  oR                  X4   PM     nn[        U Vs/ s H  n[        U5      PM     sn6 $ g s  snf s  snf r`   )re   rj   rC   r]   rS   r   r#   )rU   r/   rS   blocks       r0   _eval_traceBlockMatrix._eval_trace   sl    !3!3316tq7I1JK1JAkk!$'1JFK6:6%u6:;; 4K:s   A3A8c                    U R                   S:X  a  [        U R                  S   5      $ U R                   S:X  a  U R                  R                  5       u  u  pu  p4[	        [
        R                  " U5      5      (       a)  [        U5      [        XCUR                  -  U-  -
  5      -  $ [	        [
        R                  " U5      5      (       a)  [        U5      [        XUR                  -  U-  -
  5      -  $ [        U 5      $ )Nr4   r4   r   r      r   )	r]   r   rS   tolistr   r   
invertibleIr   )rU   ABCDs        r0   _eval_determinantBlockMatrix._eval_determinant   s    ??f$t{{4())??f${{))+Vaa1<<?##1vc!eAg+...Q\\!_%%1vc!eAg+...4  r3   c                 r   U R                    Vs/ s H  n[        U5      PM     nn[        U R                  S   U R                  S   U5      nU R                    Vs/ s H  n[	        U5      PM     nn[        U R                  S   U R                  S   U5      n[        U5      [        U5      4$ s  snf s  snf rR   )rS   r
   r   r]   r   r'   )rU   ry   real_matricesim_matricess       r0   _eval_as_real_imagBlockMatrix._eval_as_real_imag   s    26++>+F+>tq14??13E}U04<fr&z<T__Q/1C[QM*K,DEE ? =s   B/B4c                 J    [        U R                  R                  U5      5      $ r6   )r'   rS   diff)rU   xs     r0   _eval_derivativeBlockMatrix._eval_derivative   s    4;;++A.//r3   c                 "    U R                  5       $ )a~  Return transpose of matrix.

Examples
========

>>> from sympy import MatrixSymbol, BlockMatrix, ZeroMatrix
>>> from sympy.abc import m, n
>>> X = MatrixSymbol('X', n, n)
>>> Y = MatrixSymbol('Y', m, m)
>>> Z = MatrixSymbol('Z', n, m)
>>> B = BlockMatrix([[X, Z], [ZeroMatrix(m,n), Y]])
>>> B.transpose()
Matrix([
[X.T,  0],
[Z.T, Y.T]])
>>> _.transpose()
Matrix([
[X, Z],
[0, Y]])
)r{   r\   s    r0   r%   BlockMatrix.transpose   s    * ##%%r3   c                    U R                   S:X  a  U R                  R                  5       u  u  p4u  pVX4XVS.n U(       a0  Xq   R                  Xq   -  R	                  5       Xq   R                  -  OXq   R	                  5       nUS:X  a
  XeU-  U-  -
  $ US:X  a
  XVU-  U-  -
  $ US:X  a
  XCU-  U-  -
  $ US:X  a
  X4U-  U-  -
  $ U $ [        S5      e! [
         a    [        S5      ef = f)	a  Return the Schur Complement of the 2x2 BlockMatrix

Parameters
==========

mat : String, optional
    The matrix with respect to which the
    Schur Complement is calculated. 'A' is
    used by default

generalized : bool, optional
    If True, returns the generalized Schur
    Component which uses Moore-Penrose Inverse

Examples
========

>>> from sympy import symbols, MatrixSymbol, BlockMatrix
>>> m, n = symbols('m n')
>>> A = MatrixSymbol('A', n, n)
>>> B = MatrixSymbol('B', n, m)
>>> C = MatrixSymbol('C', m, n)
>>> D = MatrixSymbol('D', m, m)
>>> X = BlockMatrix([[A, B], [C, D]])

The default Schur Complement is evaluated with "A"

>>> X.schur()
-C*A**(-1)*B + D
>>> X.schur('D')
A - B*D**(-1)*C

Schur complement with non-invertible matrices is not
defined. Instead, the generalized Schur complement can
be calculated which uses the Moore-Penrose Inverse. To
achieve this, `generalized` must be set to `True`

>>> X.schur('B', generalized=True)
C - D*(B.T*B)**(-1)*B.T*A
>>> X.schur('C', generalized=True)
-A*(C.T*C)**(-1)*C.T*D + B

Returns
=======

M : Matrix
    The Schur Complement Matrix

Raises
======

ShapeError
    If the block matrix is not a 2x2 matrix

NonInvertibleMatrixError
    If given matrix is non-invertible

References
==========

.. [1] Wikipedia Article on Schur Component : https://en.wikipedia.org/wiki/Schur_complement

See Also
========

sympy.matrices.matrixbase.MatrixBase.pinv
r   )r   r   r   r   r   r   r   r   zThe given matrix is not invertible. Please set generalized=True             to compute the generalized Schur Complement which uses Moore-Penrose Inversez>Schur Complement can only be calculated for 2x2 block matrices)r]   rS   r   Tinvr   r   )	rU   rN   generalizedr   r   r   r   dr   s	            r0   schurBlockMatrix.schur   s   J ??f${{))+Vaaq2A[:Eqvxx++-afhh616::<#:3w{?*CZ3w{?*CZ3w{?*CZ3w{?*
 ]^^	 , [. 0Z [ [[s$   AC C !C 1C C C$c                    U R                   S:X  a  U R                  R                  5       u  u  pu  p4 UR                  n[        UR                  S   5      n[        UR                  S   5      n[        UR                  6 n[        Xh/X5-  U//5      n	[        XR                  5       5      n[        XeU-  /UR                  U//5      n
XU
4$ [        S5      e! [         a    [	        S5      ef = f)aL  Returns the Block LDU decomposition of
a 2x2 Block Matrix

Returns
=======

(L, D, U) : Matrices
    L : Lower Diagonal Matrix
    D : Diagonal Matrix
    U : Upper Diagonal Matrix

Examples
========

>>> from sympy import symbols, MatrixSymbol, BlockMatrix, block_collapse
>>> m, n = symbols('m n')
>>> A = MatrixSymbol('A', n, n)
>>> B = MatrixSymbol('B', n, m)
>>> C = MatrixSymbol('C', m, n)
>>> D = MatrixSymbol('D', m, m)
>>> X = BlockMatrix([[A, B], [C, D]])
>>> L, D, U = X.LDUdecomposition()
>>> block_collapse(L*D*U)
Matrix([
[A, B],
[C, D]])

Raises
======

ShapeError
    If the block matrix is not a 2x2 matrix

NonInvertibleMatrixError
    If the matrix "A" is non-invertible

See Also
========
sympy.matrices.expressions.blockmatrix.BlockMatrix.UDLdecomposition
sympy.matrices.expressions.blockmatrix.BlockMatrix.LUdecomposition
r   zTBlock LDU decomposition cannot be calculated when                    "A" is singularr   r4   z@Block LDU decomposition is supported only for 2x2 block matrices)r]   rS   r   r   r   r"   rT   r!   r'   BlockDiagMatrixr   r   r   )rU   r   r   r   r   AIIpIqZLUs              r0   LDUdecompositionBlockMatrix.LDUdecompositionP  s    T ??e#{{))+Vaa&SS !''!*%B!''!*%BAGG$AbWqtRj12A::<0AbQ$Zb	23A7N_`` , &. 0% & &&s   C C.c                    U R                   S:X  a  U R                  R                  5       u  u  pu  p4 UR                  n[        UR                  S   5      n[        UR                  S   5      n[        UR                  6 n[        XbU-  /UR                  U//5      n	[        U R                  S5      U5      n[        Xh/XS-  U//5      n
XU
4$ [        S5      e! [         a    [	        S5      ef = f)aL  Returns the Block UDL decomposition of
a 2x2 Block Matrix

Returns
=======

(U, D, L) : Matrices
    U : Upper Diagonal Matrix
    D : Diagonal Matrix
    L : Lower Diagonal Matrix

Examples
========

>>> from sympy import symbols, MatrixSymbol, BlockMatrix, block_collapse
>>> m, n = symbols('m n')
>>> A = MatrixSymbol('A', n, n)
>>> B = MatrixSymbol('B', n, m)
>>> C = MatrixSymbol('C', m, n)
>>> D = MatrixSymbol('D', m, m)
>>> X = BlockMatrix([[A, B], [C, D]])
>>> U, D, L = X.UDLdecomposition()
>>> block_collapse(U*D*L)
Matrix([
[A, B],
[C, D]])

Raises
======

ShapeError
    If the block matrix is not a 2x2 matrix

NonInvertibleMatrixError
    If the matrix "D" is non-invertible

See Also
========
sympy.matrices.expressions.blockmatrix.BlockMatrix.LDUdecomposition
sympy.matrices.expressions.blockmatrix.BlockMatrix.LUdecomposition
r   zTBlock UDL decomposition cannot be calculated when                    "D" is singularr   r4   r   z@Block UDL decomposition is supported only for 2x2 block matrices)r]   rS   r   r   r   r"   rT   r!   r'   r   r   r   r   )rU   r   r   r   r   DIr   r   r   r   r   s              r0   UDLdecompositionBlockMatrix.UDLdecomposition  s    T ??e#{{))+Vaa&SS !''!*%B!''!*%BAGG$AbB$Z!##r34A

33AbWbdBZ01A7N_`` , &. 0% & &&s   C C0c                    U R                   S:X  a  U R                  R                  5       u  u  pu  p4 U[        R                  -  nUR
                  n[        UR                  6 nU R                  5       [        R                  -  n[        X/X5-  U//5      n[        XU-  /UR                  U//5      n	X4$ [        S5      e! [         a    [        S5      ef = f)a+  Returns the Block LU decomposition of
a 2x2 Block Matrix

Returns
=======

(L, U) : Matrices
    L : Lower Diagonal Matrix
    U : Upper Diagonal Matrix

Examples
========

>>> from sympy import symbols, MatrixSymbol, BlockMatrix, block_collapse
>>> m, n = symbols('m n')
>>> A = MatrixSymbol('A', n, n)
>>> B = MatrixSymbol('B', n, m)
>>> C = MatrixSymbol('C', m, n)
>>> D = MatrixSymbol('D', m, m)
>>> X = BlockMatrix([[A, B], [C, D]])
>>> L, U = X.LUdecomposition()
>>> block_collapse(L*U)
Matrix([
[A, B],
[C, D]])

Raises
======

ShapeError
    If the block matrix is not a 2x2 matrix

NonInvertibleMatrixError
    If the matrix "A" is non-invertible

See Also
========
sympy.matrices.expressions.blockmatrix.BlockMatrix.UDLdecomposition
sympy.matrices.expressions.blockmatrix.BlockMatrix.LDUdecomposition
r   zSBlock LU decomposition cannot be calculated when                    "A" is singularz?Block LU decomposition is supported only for 2x2 block matrices)r]   rS   r   r   Halfr   r   r!   rT   r   r'   r   r   )
rU   r   r   r   r   r   r   r   r   r   s
             r0   LUdecompositionBlockMatrix.LUdecomposition  s    R ??e#{{))+Vaa&qvvISS AGG$A

aff$AaVadAY/0AaAYQx01A4K^__ , &. 0% & &&s   C Cc                    XpT[        U R                  5       H@  u  pgX:  nUS:X  a    O3US:X  a  X-  nM  X`R                  S   S-
  :  d  M4  [        XU5      s  $    [        U R                  5       H@  u  pX*:  nUS:X  a    O3US:X  a  X*-  nM  XR                  S   S-
  :  d  M4  [        XU5      s  $    U R
                  WW	4   X4   $ )NTFr   r4   )	enumeratere   r]   r   rj   rS   )rU   r/   jrH   orig_iorig_j	row_blockrV   cmp	col_blockrW   s              r0   _entryBlockMatrix._entry  s    "+D,>,>"?I+Cd{__Q/!33$T6:: #@ #,D,>,>"?I+Cd{__Q/!33$T6:: #@ {{9i/066r3   c                 b   U R                   S   U R                   S   :w  a  g[        U R                   S   5       Hr  n[        U R                   S   5       HS  nX:X  a"  U R                  X4   R                  (       d      gX:w  d  M1  U R                  X4   R                  (       a  MR      g   Mt     g)Nr   r4   FT)r]   rC   rS   is_Identityis_ZeroMatrix)rU   r/   r   s      r0   r   BlockMatrix.is_Identity  s    ??1!33tq)*A4??1-.4AD 1 = = 4AD 1 ? ? ? 	 / + r3   c                 4    U R                   U R                  :H  $ r6   )re   rj   r\   s    r0   is_structurally_symmetric%BlockMatrix.is_structurally_symmetric$  s    !!T%7%777r3   c                    > X:X  a  g[        U[        5      (       a  U R                  UR                  :X  a  g[        TU ]  U5      $ )NT)rm   r'   rS   superequals)rU   ro   	__class__s     r0   r   BlockMatrix.equals(  s9    =uk**t{{ell/Jw~e$$r3    )r   F) __name__
__module____qualname____firstlineno____doc__rE   propertyrT   r]   rS   re   rj   rp   rs   rv   r{   r   r   r   r   r   r%   r   r   r   r   r   r   r   r   __static_attributes____classcell__)r   s   @r0   r'   r'      s    6n2h " " ! !   K K K K;

<

!F0&.Y_v:ax:ax8`t7, 	 	 8 8% %r3   r'   c                       \ rS rSrSrS r\S 5       r\S 5       r\S 5       r	\S 5       r
\S 5       r\S	 5       rS
 rS rSS jrS rS rS rS rSrg)r   i0  a  A sparse matrix with block matrices along its diagonals

Examples
========

>>> from sympy import MatrixSymbol, BlockDiagMatrix, symbols
>>> n, m, l = symbols('n m l')
>>> X = MatrixSymbol('X', n, n)
>>> Y = MatrixSymbol('Y', m, m)
>>> BlockDiagMatrix(X, Y)
Matrix([
[X, 0],
[0, Y]])

Notes
=====

If you want to get the individual diagonal blocks, use
:meth:`get_diag_blocks`.

See Also
========

sympy.matrices.dense.diag
c           	      v    [         R                  " [        /U Vs/ s H  n[        U5      PM     snQ76 $ s  snf r6   )r   rE   r   r	   )rF   matsms      r0   rE   BlockDiagMatrix.__new__J  s,    }}_KT/JTT/JKK/Js   6
c                     U R                   $ r6   ra   r\   s    r0   diagBlockDiagMatrix.diagM  s    yyr3   c                 2   SSK Jn  U R                  n[        [	        U5      5       VVs/ s HS  n[        [	        U5      5       Vs/ s H0  nX4:X  a  X#   O#[        X#   R                  X$   R                  5      PM2     snPMU     nnnU" USS9$ s  snf s  snnf )Nr   r*   Fr=   )r?   r+   rG   rC   r@   r!   rB   r8   )rU   r+   r   r/   r   datas         r0   rS   BlockDiagMatrix.blocksQ  s    Ayy "'s4y!13!1A "'s4y!13!1A F
47<<(NN!13!1 	 3 $D5993 3s   B7B=BBc                 r    [        S U R                   5       5      [        S U R                   5       5      4$ )Nc              3   8   #    U  H  oR                   v   M     g 7fr6   )rB   r9   r   s     r0   r:   (BlockDiagMatrix.shape.<locals>.<genexpr>\       6I5JJIr<   c              3   8   #    U  H  oR                   v   M     g 7fr6   r7   r   s     r0   r:   r   ]  r   r<   )rD   rG   r\   s    r0   rT   BlockDiagMatrix.shapeZ  s0    6DII666DII668 	8r3   c                 2    [        U R                  5      nX4$ r6   )r@   rG   )rU   ns     r0   r]   BlockDiagMatrix.blockshape_  s    		Nvr3   c                 X    U R                    Vs/ s H  oR                  PM     sn$ s  snf r6   )rG   rB   rU   r   s     r0   re   BlockDiagMatrix.rowblocksizesd       (,		2	u

	222   'c                 X    U R                    Vs/ s H  oR                  PM     sn$ s  snf r6   )rG   r8   r   s     r0   rj   BlockDiagMatrix.colblocksizesh  r   r   c                 :    [        S U R                   5       5      $ )z%Returns true if all blocks are squarec              3   8   #    U  H  oR                   v   M     g 7fr6   )	is_square)r9   rN   s     r0   r:   5BlockDiagMatrix._all_square_blocks.<locals>.<genexpr>n  s     6IS==Ir<   )allrG   r\   s    r0   _all_square_blocks"BlockDiagMatrix._all_square_blocksl  s    6DII666r3   c                     U R                  5       (       a,  [        U R                   Vs/ s H  n[        U5      PM     sn6 $ [        R
                  $ s  snf r6   )r   r   rG   r   r   ZerorU   rN   s     r0   r   !BlockDiagMatrix._eval_determinantp  sC    ""$$TYY7YcSY788 vv 8s   Ac                     U R                  5       (       a0  [        U R                   Vs/ s H  o"R                  5       PM     sn6 $ [	        S5      es  snf )Nz Matrix det == 0; not invertible.)r   r   rG   inverser   )rU   expandrN   s      r0   _eval_inverseBlockDiagMatrix._eval_inversew  sE    ""$$"dii$His[[]i$HII&'IJJ %Is   Ac                 l    [        U R                   Vs/ s H  oR                  5       PM     sn6 $ s  snf r6   )r   rG   r%   r   s     r0   r{   BlockDiagMatrix._eval_transpose}  s'    DII FISI FGG Fs   1c                    [        U[        5      (       aW  U R                  UR                  :X  a=  [        [	        U R
                  UR
                  5       VVs/ s H	  u  p#X#-  PM     snn6 $ [        R                  X5      $ s  snnf r6   )rm   r   rj   re   ziprG   r'   rs   rU   ro   abs       r0   rs   BlockDiagMatrix._blockmul  si    uo..""e&9&99"SEJJ5O$P5OTQQS5O$PQQ((55 %Qs   B
c                 x   [        U[        5      (       a  U R                  UR                  :X  aq  U R                  UR                  :X  aW  U R                  UR                  :X  a=  [        [        U R                  UR                  5       VVs/ s H	  u  p#X#-   PM     snn6 $ [        R                  X5      $ s  snnf r6   )	rm   r   r]   re   rj   r  rG   r'   rv   r  s       r0   rv   BlockDiagMatrix._blockadd  s    uo..5#3#33""e&9&99""e&9&99"s499ejj7Q$R7QtqQU7Q$RSS((55 %Ss   B6
c                     U R                   $ )a  Return the list of diagonal blocks of the matrix.

Examples
========

>>> from sympy import BlockDiagMatrix, Matrix

>>> A = Matrix([[1, 2], [3, 4]])
>>> B = Matrix([[5, 6], [7, 8]])
>>> M = BlockDiagMatrix(A, B)

How to get diagonal blocks from the block diagonal matrix:

>>> diag_blocks = M.get_diag_blocks()
>>> diag_blocks[0]
Matrix([
[1, 2],
[3, 4]])
>>> diag_blocks[1]
Matrix([
[5, 6],
[7, 8]])
ra   r\   s    r0   get_diag_blocksBlockDiagMatrix.get_diag_blocks  s    0 yyr3   r   N)ignored)r   r   r   r   r   rE   r   r   rS   rT   r]   re   rj   r   r   r  r{   rs   rv   r  r   r   r3   r0   r   r   0  s    2L   : : 8 8   3 3 3 37KH66r3   r   c                    SSK Jn  S n[        U[        [        [        [        [        5      [        [        [        [        5      [        [        [        [        [        [        [         [        ["        [$        5      05      5      n['        [)        ['        U5      US95      nU" U 5      n[+        USS5      nUb  U" 5       $ U$ )a  Evaluates a block matrix expression

>>> from sympy import MatrixSymbol, BlockMatrix, symbols, Identity, ZeroMatrix, block_collapse
>>> n,m,l = symbols('n m l')
>>> X = MatrixSymbol('X', n, n)
>>> Y = MatrixSymbol('Y', m, m)
>>> Z = MatrixSymbol('Z', n, m)
>>> B = BlockMatrix([[X, Z], [ZeroMatrix(m, n), Y]])
>>> print(B)
Matrix([
[X, Z],
[0, Y]])

>>> C = BlockMatrix([[Identity(n), Z]])
>>> print(C)
Matrix([[I, Z]])

>>> print(block_collapse(C*B))
Matrix([[X, Z + Z*Y]])
r   )expr_fnsc                 Z    [        U [        5      =(       a    U R                  [        5      $ r6   )rm   r   hasr'   exprs    r0   r1    block_collapse.<locals>.<lambda>  s    D*5O$((;:OOr3   )fnsdoitN)sympy.strategies.utilr  r   r   r   r   	bc_mataddbc_block_plus_identr   	bc_matmulbc_distr   r$   bc_transposer   
bc_inverser'   	bc_unpackdeblockr   r   r.   )r  r  hasbmconditioned_rlruleresultr  s          r0   block_collapser'    s    * /OEVI':;VIw/Yj&G46	

N N#	
D $ZF664(Dvr3   c                 D    U R                   S:X  a  U R                  S   $ U $ )Nr   r   )r]   rS   r  s    r0   r!  r!    s"    & {{4  Kr3   c                     [        U R                  S 5      nUS   nU(       d  U $ US   nUS   nUSS   H  nUR                  U5      nM     U(       a  [        U6 U-   $ U$ )Nc                 "    [        U [        5      $ r6   rm   r'   )rX   s    r0   r1   bc_matadd.<locals>.<lambda>  s    Z;%?r3   TFr   r4   )r   rG   rv   r   )r  rG   rS   	nonblocksr   r	  s         r0   r  r    sl    		?@D$ZFUI1IEABZ" y!E))r3   c                   ^ U R                    Vs/ s H  oR                  (       d  M  UPM     nnU(       d  U $ U R                    Vs/ s H  n[        U[        5      (       d  M  UPM     snmT(       a  [	        U4S jT 5       5      (       a  TS   R
                  (       a  [        TS   R                   Vs/ s H  n[        U5      PM     sn6 nU R                    Vs/ s H.  oR                  (       a  M  [        U[        5      (       a  M,  UPM0     nn[        U[        U5      -  /TQUQ76 R                  5       $ U $ s  snf s  snf s  snf s  snf )Nc              3   J   >#    U  H  oR                  TS    5      v   M     g7f)r   N)rp   )r9   r	  rS   s     r0   r:   &bc_block_plus_ident.<locals>.<genexpr>  s!     G1++F1I66s    #r   )rG   r   rm   r'   r   r   r   re   r"   r   r@   r  )r  argidentskblock_idrestrS   s         @r0   r  r    s   !YY:Yc//cYF:!YYGYc*S+*FcYGF3GGGG!966"171H1H%J1HA &.a[1H%J K#yyey
SVXcHdyehV,=v==BBDDK ; H%Jes.   E E E$E8E
E7EEc                    U R                  5       u  pUS:X  a  U $ [        U5      n[        U[        5      (       a(  UR                  nU Vs/ s H  o!U-  PM	     nn[        U6 $ [        U[
        5      (       ah  UR                  n[        UR                  5       VVs/ s H/  n[        UR                  5       Vs/ s H  oqXFU4   -  PM     snPM1     nnn[        U5      $ U $ s  snf s  snf s  snnf )zTurn  a*[X, Y] into [a*X, a*Y] r4   )
as_coeff_mmulr   rm   r   r   r'   rS   rC   rB   r8   )r  factorrN   unpackedr   new_Br/   r   s           r0   r  r    s    $$&KF{c{H(O,,MM)*+##+&&	Hk	*	*OO?DQVV}N?L!uQVV}5}!a1g}5} 	 N5!!K ,
 6Ns   C"C,9C'C,'C,c                 b   [        U [        5      (       aU  U R                  S   R                  (       a5  U R                  S   S:  a"  SU R                  S   /U R                  S   -  p!OU $ U R	                  5       u  pSnUS-   [        U5      :  Ga  X#US-    u  pE[        U[        5      (       a=  [        U[        5      (       a(  UR                  U5      X#'   UR                  US-   5        O[        U[        5      (       a3  UR                  [        U//5      5      X#'   UR                  US-   5        OM[        U[        5      (       a3  [        U//5      R                  U5      X#'   UR                  US-   5        OUS-  nUS-   [        U5      :  a  GM  [        U/UQ76 R                  5       $ )Nr4   r   r   )rm   r   rG   
is_Integeras_coeff_matricesr@   r'   rs   popr   r  )r  r8  rz   r/   r   r   s         r0   r  r    sc   $99Q<""tyy|a'7 499Q<.1"=HK113	AQ3X!A#a%%*Q*D*D++a.HKLL1;''++kA3%&89HKLL1;''%se,66q9HKLL1qDA Q3X &$8$))++r3   c                 L    [        U R                  5      nUR                  5       $ r6   )r'  r1  r{   )r  collapses     r0   r  r  .  s    dhh'H##%%r3   c                     [        U R                  [        5      (       a  U R                  5       $ [	        U 5      nX:w  a  U$ [        [        [        U R                  5      5      5      $ r6   )rm   r1  r   r   blockinverse_1x1blockinverse_2x2r   reblock_2x2)r  expr2s     r0   r   r   3  sL    $((O,,||~T"E}GK$9:;;r3   c                     [        U R                  [        5      (       aW  U R                  R                  S:X  a=  [	        U R                  R
                  S   R                  5       //5      n[        U5      $ U $ )Nr   r   )rm   r1  r'   r]   r   rS   r   )r  rN   s     r0   rB  rB  <  sZ    $((K((TXX-@-@F-Jtxxq)1134563Kr3   c                 6   [        U R                  [        5      (       Gax  U R                  R                  S:X  Ga]  U R                  R                  R                  5       u  u  pu  p4[        XX45      nUS :w  a%  U R                  R                  U5      R                  nUS:X  a9  UR                  n[        XwU-  W-  U-  U-  -   U* U-  U-  /U* U-  U-  U//5      $ US:X  a9  UR                  n[        W* U-  U-  U/XU-  U-  U-  U-  -   U* U-  U-  //5      $ US:X  a8  UR                  n	[        U	* U-  W-  XU-  U-  U-  U	-  -   /Xf* U-  U	-  //5      $ US:X  a9  UR                  n
[        WU* U-  U
-  /U
* U-  U-  XU-  U-  U-  U
-  -   //5      $ U $ )Nr   r   r   r   r   )	rm   r1  r'   r]   rS   r   _choose_2x2_inversion_formular   r   )r  r   r   r   r   formulaMIr   BICIr   s              r0   rC  rC  C  s   $((K((TXX-@-@F-J 88??))+	!	!/a;d?(**Bc>B1frkAo&:!:RC!GbL IRCRSGVXLZ\K]^__c>B"q2r 2Rq&2+/B:N5NQSPSVWPWZ\P\4]^__c>B"q2rFRK!Ob4H/H IBPSVWPWZ\P\K]^__c>BbS1Wr\ 2bS1Wr\2QQSVWZ\H\C\4]^__Kr3   c                 l   [        [        R                  " U 5      5      nUS:X  a  g[        [        R                  " U5      5      nUS:X  a  g[        [        R                  " U5      5      nUS:X  a  g[        [        R                  " U5      5      nUS:X  a  gUS:w  a  gUS:w  a  gUS:w  a  gUS:w  a  gg)a@  
Assuming [[A, B], [C, D]] would form a valid square block matrix, find
which of the classical 2x2 block matrix inversion formulas would be
best suited.

Returns 'A', 'B', 'C', 'D' to represent the algorithm involving inversion
of the given argument or None if the matrix cannot be inverted using
any of those formulas.
Tr   r   r   r   FN)r   r   r   )r   r   r   r   A_invB_invC_invD_invs           r0   rH  rH  \  s     Q E}Q E}Q E}Q E}~~~~r3   c           
      r  ^ [        U [        5      (       a$  U R                  R                  [        5      (       d  U $ S nU R                  R	                  U5      m [        S[        U4S j[        TR                  S   5       5       5      / 5      n[        STR                  S   5       Hm  n[        TUS4   R                  5      n[        STR                  S   5       H"  nUR                  TX54   R                  5      nM$     UR                  U5      nMo     [        U5      $ ! [         a    U s $ f = f)z'Flatten a BlockMatrix of BlockMatrices c                 J    [        U [        5      (       a  U $ [        U //5      $ r6   r+  )r   s    r0   r1   deblock.<locals>.<lambda>  s!    *Q44QL+se:LLr3   r   c              3   `   >#    U  H#  nTS U4   R                   R                  S   v   M%     g7f)r   r4   Nr[   )r9   r/   bbs     r0   r:   deblock.<locals>.<genexpr>  s*     P=O2ad8??003=Os   +.r4   )rm   r'   rS   r  	applyfuncr   rD   rC   rT   row_joincol_joinr   )r   wrapMMrowrX   colrV  s         @r0   r"  r"    s    a%%QXX\\+-F-FLD	
		D	!B
AsPU288A;=OPPRTUBHHQK(Cr#q&z(()AQ,JJr#(|223 -QB	 ) 2 s   C
D' 'D65D6c           
         [        U [        5      (       a!  [        S U R                   5       5      (       d  U $ [        nU R                  u  p#U R                  n[        SU5       H  n[        SU5       H  n[        U" USU2SU24   5      5      n[        U" USU2US24   5      5      n[        U" XES2SU24   5      5      n	[        U" XES2US24   5      5      n
[        XxX5      nUc  Mz  [        Xx/X//5      s  s  $    M     U" US   U" USSS24   5      /U" USS2S4   5      U" USS2SS24   5      //5      $ )z
Reblock a BlockMatrix so that it has 2x2 blocks of block matrices.  If
possible in such a way that the matrix continues to be invertible using the
classical 2x2 block inversion formulas.
c              3   *   #    U  H	  oS :  v   M     g7f)r   Nr   )r9   r   s     r0   r:   reblock_2x2.<locals>.<genexpr>  s     3S?aE?s   r4   Nr   r   )rm   r'   r   r]   rS   rC   r!  rH  )r  BM	rowblocks	colblocksrS   r/   r   r   r   r   r   rI  s               r0   rD  rD    sR    dK((3S4??3S0S0S	B??I[[F1i q)$A"VBQBF^,-A"VBQBF^,-A"VBF^,-A"VBF^,-A3A!?G""QFQF#344 % ! tb12/06!"a%=!2fQRVn#568 9 9r3   c                 R    Sn/ nU  H  nUR                  XU-   45        X-  nM     U$ )zConvert sequence of numbers into pairs of low-high pairs

>>> from sympy.matrices.expressions.blockmatrix import bounds
>>> bounds((1, 10, 50))
[(0, 1), (1, 11), (11, 61)]
r   )append)sizeslowrvsizes       r0   boundsrk    s9     C	B
		3d
#$  Ir3   c                     [        U5      n[        U5      n[        U VVs/ s H   nU Vs/ s H  n[        XU5      PM     snPM"     snn5      $ s  snf s  snnf )zCut a matrix expression into Blocks

>>> from sympy import ImmutableMatrix, blockcut
>>> M = ImmutableMatrix(4, 4, range(16))
>>> B = blockcut(M, (1, 3), (1, 3))
>>> type(B).__name__
'BlockMatrix'
>>> ImmutableMatrix(B.blocks[0, 1])
Matrix([[1, 2, 3]])
)rk  r'   r    )r  rowsizescolsizes	rowbounds	colboundsrowboundcolbounds          r0   blockcutrs    si     x Ix I)24)2X *34)2X %TX>)24)24 5 5 4 4s   
A
AA
A
N)Hsympy.assumptions.askr   r   
sympy.corer   r   r   r   sympy.core.sympifyr	   $sympy.functions.elementary.complexesr
   r   sympy.strategiesr   r   r   r   r   sympy.strategies.traverser   sympy.utilities.iterablesr   r   sympy.utilities.miscr   sympy.matricesr   r   sympy.matrices.exceptionsr   &sympy.matrices.expressions.determinantr   r   "sympy.matrices.expressions.inverser   !sympy.matrices.expressions.mataddr   "sympy.matrices.expressions.matexprr   r   !sympy.matrices.expressions.matmulr   !sympy.matrices.expressions.matpowr    sympy.matrices.expressions.slicer    "sympy.matrices.expressions.specialr!   r"    sympy.matrices.expressions.tracer#   $sympy.matrices.expressions.transposer$   r%   r'   r   r'  r!  r  r  r  r  r  r   rB  rC  rH  r"  rD  rk  rs  r   r3   r0   <module>r     s    * ) ) ' 7 F F / 7 + - > C 6 4 H 4 4 8 C 2 EU%* U%pxk xv1f
(,2&
<2!H(9:5r3   