class_docstr: Combines one or more `LinearOperators` in to a Block Diagonal matrix.
  
  This operator combines one or more linear operators `[op1,...,opJ]`,
  building a new `LinearOperator`, whose underlying matrix representation
  has each operator `opi` on the main diagonal, and zero's elsewhere.
  
  #### Shape compatibility
  
  If `opj` acts like a [batch] matrix `Aj`, then `op_combined` acts like
  the [batch] matrix formed by having each matrix `Aj` on the main
  diagonal.
  
  Each `opj` is required to represent a matrix, and hence will have
  shape `batch_shape_j + [M_j, N_j]`.
  
  If `opj` has shape `batch_shape_j + [M_j, N_j]`, then the combined operator
  has shape `broadcast_batch_shape + [sum M_j, sum N_j]`, where
  `broadcast_batch_shape` is the mutual broadcast of `batch_shape_j`,
  `j = 1,...,J`, assuming the intermediate batch shapes broadcast.
  
  Arguments to `matmul`, `matvec`, `solve`, and `solvevec` may either be single
  `Tensor`s or lists of `Tensor`s that are interpreted as blocks. The `j`th
  element of a blockwise list of `Tensor`s must have dimensions that match
  `opj` for the given method. If a list of blocks is input, then a list of
  blocks is returned as well.
  
  When the `opj` are not guaranteed to be square, this operator's methods might
  fail due to the combined operator not being square and/or lack of efficient
  methods.
  
  ```python
  # Create a 4 x 4 linear operator combined of two 2 x 2 operators.
  operator_1 = LinearOperatorFullMatrix([[1., 2.], [3., 4.]])
  operator_2 = LinearOperatorFullMatrix([[1., 0.], [0., 1.]])
  operator = LinearOperatorBlockDiag([operator_1, operator_2])
  
  operator.to_dense()
  ==> [[1., 2., 0., 0.],
       [3., 4., 0., 0.],
       [0., 0., 1., 0.],
       [0., 0., 0., 1.]]
  
  tensor_shape.TensorShape(operator.shape)
  ==> [4, 4]
  
  operator.log_abs_determinant()
  ==> scalar Tensor
  
  x1 = ... # Shape [2, 2] Tensor
  x2 = ... # Shape [2, 2] Tensor
  x = tf.concat([x1, x2], 0)  # Shape [2, 4] Tensor
  operator.matmul(x)
  ==> tf.concat([operator_1.matmul(x1), operator_2.matmul(x2)])
  
  # Create a 5 x 4 linear operator combining three blocks.
  operator_1 = LinearOperatorFullMatrix([[1.], [3.]])
  operator_2 = LinearOperatorFullMatrix([[1., 6.]])
  operator_3 = LinearOperatorFullMatrix([[2.], [7.]])
  operator = LinearOperatorBlockDiag([operator_1, operator_2, operator_3])
  
  operator.to_dense()
  ==> [[1., 0., 0., 0.],
       [3., 0., 0., 0.],
       [0., 1., 6., 0.],
       [0., 0., 0., 2.]]
       [0., 0., 0., 7.]]
  
  tensor_shape.TensorShape(operator.shape)
  ==> [5, 4]
  
  
  # Create a [2, 3] batch of 4 x 4 linear operators.
  matrix_44 = tf.random.normal(shape=[2, 3, 4, 4])
  operator_44 = LinearOperatorFullMatrix(matrix)
  
  # Create a [1, 3] batch of 5 x 5 linear operators.
  matrix_55 = tf.random.normal(shape=[1, 3, 5, 5])
  operator_55 = LinearOperatorFullMatrix(matrix_55)
  
  # Combine to create a [2, 3] batch of 9 x 9 operators.
  operator_99 = LinearOperatorBlockDiag([operator_44, operator_55])
  
  # Create a shape [2, 3, 9] vector.
  x = tf.random.normal(shape=[2, 3, 9])
  operator_99.matmul(x)
  ==> Shape [2, 3, 9] Tensor
  
  # Create a blockwise list of vectors.
  x = [tf.random.normal(shape=[2, 3, 4]), tf.random.normal(shape=[2, 3, 5])]
  operator_99.matmul(x)
  ==> [Shape [2, 3, 4] Tensor, Shape [2, 3, 5] Tensor]
  ```
  
  #### Performance
  
  The performance of `LinearOperatorBlockDiag` on any operation is equal to
  the sum of the individual operators' operations.
  
  
  #### Matrix property hints
  
  This `LinearOperator` is initialized with boolean flags of the form `is_X`,
  for `X = non_singular, self_adjoint, positive_definite, square`.
  These have the following meaning:
  
  * If `is_X == True`, callers should expect the operator to have the
    property `X`.  This is a promise that should be fulfilled, but is *not* a
    runtime assert.  For example, finite floating point precision may result
    in these promises being violated.
  * If `is_X == False`, callers should expect the operator to not have `X`.
  * If `is_X == None` (the default), callers should have no expectation either
    way.
class_docstr_tok: ["Combines","one","or","more","`","LinearOperators","`","in","to","a","Block","Diagonal","matrix",".","This","operator","combines","one","or","more","linear","operators","`","[","op1",",","...",",","opJ","]","`",",","building","a","new","`","LinearOperator","`",",","whose","underlying","matrix","representation","has","each","operator","`","opi","`","on","the","main","diagonal",",","and","zero","'s","elsewhere",".","#","#","#","#","Shape","compatibility","If","`","opj","`","acts","like","a","[","batch","]","matrix","`","Aj","`",",","then","`","op_combined","`","acts","like","the","[","batch","]","matrix","formed","by","having","each","matrix","`","Aj","`","on","the","main","diagonal",".","Each","`","opj","`","is","required","to","represent","a","matrix",",","and","hence","will","have","shape","`","batch_shape_j","+","[","M_j",",","N_j","]","`",".","If","`","opj","`","has","shape","`","batch_shape_j","+","[","M_j",",","N_j","]","`",",","then","the","combined","operator","has","shape","`","broadcast_batch_shape","+","[","sum","M_j",",","sum","N_j","]","`",",","where","`","broadcast_batch_shape","`","is","the","mutual","broadcast","of","`","batch_shape_j","`",",","`","j","=","1",",","...",",","J","`",",","assuming","the","intermediate","batch","shapes","broadcast",".","Arguments","to","`","matmul","`",",","`","matvec","`",",","`","solve","`",",","and","`","solvevec","`","may","either","be","single","`","Tensor","`","s","or","lists","of","`","Tensor","`","s","that","are","interpreted","as","blocks",".","The","`","j","`","th","element","of","a","blockwise","list","of","`","Tensor","`","s","must","have","dimensions","that","match","`","opj","`","for","the","given","method",".","If","a","list","of","blocks","is","input",",","then","a","list","of","blocks","is","returned","as","well",".","When","the","`","opj","`","are","not","guaranteed","to","be","square",",","this","operator","'s","methods","might","fail","due","to","the","combined","operator","not","being","square","and\/or","lack","of","efficient","methods",".","``","`","python","#","Create","a","4","x","4","linear","operator","combined","of","two","2","x","2","operators",".","operator_1","=","LinearOperatorFullMatrix","(","[","[","1.",",","2",".","]",",","[","3.",",","4",".","]","]",")","operator_2","=","LinearOperatorFullMatrix","(","[","[","1.",",","0",".","]",",","[","0.",",","1",".","]","]",")","operator","=","LinearOperatorBlockDiag","(","[","operator_1",",","operator_2","]",")","operator.to_dense","(",")","==",">","[","[","1.",",","2.",",","0.",",","0",".","]",",","[","3.",",","4.",",","0.",",","0",".","]",",","[","0.",",","0.",",","1.",",","0",".","]",",","[","0.",",","0.",",","0.",",","1",".","]","]","tensor_shape.TensorShape","(","operator.shape",")","==",">","[","4",",","4","]","operator.log_abs_determinant","(",")","==",">","scalar","Tensor","x1","=","...","#","Shape","[","2",",","2","]","Tensor","x2","=","...","#","Shape","[","2",",","2","]","Tensor","x","=","tf.concat","(","[","x1",",","x2","]",",","0",")","#","Shape","[","2",",","4","]","Tensor","operator.matmul","(","x",")","==",">","tf.concat","(","[","operator_1.matmul","(","x1",")",",","operator_2.matmul","(","x2",")","]",")","#","Create","a","5","x","4","linear","operator","combining","three","blocks",".","operator_1","=","LinearOperatorFullMatrix","(","[","[","1",".","]",",","[","3",".","]","]",")","operator_2","=","LinearOperatorFullMatrix","(","[","[","1.",",","6",".","]","]",")","operator_3","=","LinearOperatorFullMatrix","(","[","[","2",".","]",",","[","7",".","]","]",")","operator","=","LinearOperatorBlockDiag","(","[","operator_1",",","operator_2",",","operator_3","]",")","operator.to_dense","(",")","==",">","[","[","1.",",","0.",",","0.",",","0",".","]",",","[","3.",",","0.",",","0.",",","0",".","]",",","[","0.",",","1.",",","6.",",","0",".","]",",","[","0.",",","0.",",","0.",",","2",".","]","]","[","0.",",","0.",",","0.",",","7",".","]","]","tensor_shape.TensorShape","(","operator.shape",")","==",">","[","5",",","4","]","#","Create","a","[","2",",","3","]","batch","of","4","x","4","linear","operators",".","matrix_44","=","tf.random.normal","(","shape=","[","2",",","3",",","4",",","4","]",")","operator_44","=","LinearOperatorFullMatrix","(","matrix",")","#","Create","a","[","1",",","3","]","batch","of","5","x","5","linear","operators",".","matrix_55","=","tf.random.normal","(","shape=","[","1",",","3",",","5",",","5","]",")","operator_55","=","LinearOperatorFullMatrix","(","matrix_55",")","#","Combine","to","create","a","[","2",",","3","]","batch","of","9","x","9","operators",".","operator_99","=","LinearOperatorBlockDiag","(","[","operator_44",",","operator_55","]",")","#","Create","a","shape","[","2",",","3",",","9","]","vector",".","x","=","tf.random.normal","(","shape=","[","2",",","3",",","9","]",")","operator_99.matmul","(","x",")","==",">","Shape","[","2",",","3",",","9","]","Tensor","#","Create","a","blockwise","list","of","vectors",".","x","=","[","tf.random.normal","(","shape=","[","2",",","3",",","4","]",")",",","tf.random.normal","(","shape=","[","2",",","3",",","5","]",")","]","operator_99.matmul","(","x",")","==",">","[","Shape","[","2",",","3",",","4","]","Tensor",",","Shape","[","2",",","3",",","5","]","Tensor","]","``","`","#","#","#","#","Performance","The","performance","of","`","LinearOperatorBlockDiag","`","on","any","operation","is","equal","to","the","sum","of","the","individual","operators","'","operations",".","#","#","#","#","Matrix","property","hints","This","`","LinearOperator","`","is","initialized","with","boolean","flags","of","the","form","`","is_X","`",",","for","`","X","=","non_singular",",","self_adjoint",",","positive_definite",",","square","`",".","These","have","the","following","meaning",":","*","If","`","is_X","==","True","`",",","callers","should","expect","the","operator","to","have","the","property","`","X","`",".","This","is","a","promise","that","should","be","fulfilled",",","but","is","*","not","*","a","runtime","assert",".","For","example",",","finite","floating","point","precision","may","result","in","these","promises","being","violated",".","*","If","`","is_X","==","False","`",",","callers","should","expect","the","operator","to","not","have","`","X","`",".","*","If","`","is_X","==","None","`","(","the","default",")",",","callers","should","have","no","expectation","either","way","."]
code: def _shape(self):
      # Get final matrix shape.
      domain_dimension = sum(self._block_domain_dimensions())
      range_dimension = sum(self._block_range_dimensions())
      matrix_shape = tensor_shape.TensorShape(
          [range_dimension, domain_dimension]
      )
  
      # Get broadcast batch shape.
      # broadcast_shape checks for compatibility.
      batch_shape = self.operators[0].batch_shape
      for operator in self.operators[1:]:
          batch_shape = common_shapes.broadcast_shape(
              batch_shape, operator.batch_shape
          )
  
      return batch_shape.concatenate(matrix_shape)
  
imports: from tensorflow_probability.python.internal.backend.numpy import ops
  from tensorflow_probability.python.internal.backend.numpy import dtype
  from tensorflow_probability.python.internal.backend.numpy import ops
  from tensorflow_probability.python.internal.backend.numpy.gen import tensor_shape
  from tensorflow_probability.python.internal.backend.numpy import numpy_array
  from tensorflow_probability.python.internal.backend.numpy import numpy_array
  from tensorflow_probability.python.internal.backend.numpy import debugging
  from tensorflow_probability.python.internal.backend.numpy import control_flow
  from tensorflow_probability.python.internal.backend.numpy.gen import linear_operator
  from tensorflow_probability.python.internal.backend.numpy.gen import linear_operator_util
  from tensorflow_probability.python.internal.backend.numpy.gen import property_hint_util
  import numpy
  from tensorflow_probability.python.internal.backend.numpy import linalg_impl
  from tensorflow_probability.python.internal.backend.numpy import ops
  from tensorflow_probability.python.internal.backend.numpy.gen import tensor_shape
  from tensorflow_probability.python.internal.backend.numpy import private
label_desc: Use image node_id 7 for calling the LinearOperatorBlockDiag obj's underlying member method code with example usage: obj._shape() and returns: batch_shape