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","."]
docstr: Solve single equation with best effort: `A X = rhs`.
  
  The returned `Tensor` will be close to an exact solution if `A` is well
  conditioned. Otherwise closeness will vary. See class docstring for details.
  
  Examples:
  
  ```python
  # Make an operator acting like batch matrix A.  Assume tensor_shape.TensorShape(A.shape) = [..., M, N]
  operator = LinearOperator(...)
  tensor_shape.TensorShape(operator.shape) = [..., M, N]
  
  # Solve one linear system for every member of the batch.
  RHS = ... # shape [..., M]
  
  X = operator.solvevec(RHS)
  # X is the solution to the linear system
  # sum_j A[..., :, j] X[..., j] = RHS[..., :]
  
  operator.matvec(X)
  ==> RHS
  ```
  
  Args:
    rhs: `Tensor` with same `dtype` as this operator, or list of `Tensor`s
      (for blockwise operators). `Tensor`s are treated as [batch] vectors,
      meaning for every set of leading dimensions, the last dimension defines
      a vector.  See class docstring for definition of compatibility regarding
      batch dimensions.
    adjoint: Python `bool`.  If `True`, solve the system involving the adjoint
      of this `LinearOperator`:  `A^H X = rhs`.
    name:  A name scope to use for ops added by this method.
  
  Returns:
    `Tensor` with shape `[...,N]` and same `dtype` as `rhs`.
  
  Raises:
    NotImplementedError:  If `self.is_non_singular` or `is_square` is False.
docstr_tok: ["Solve","single","equation","with","best","effort",":","`","A","X","=","rhs","`",".","The","returned","`","Tensor","`","will","be","close","to","an","exact","solution","if","`","A","`","is","well","conditioned",".","Otherwise","closeness","will","vary",".","See","class","docstring","for","details",".","Examples",":","``","`","python","#","Make","an","operator","acting","like","batch","matrix","A",".","Assume","tensor_shape.TensorShape","(","A.shape",")","=","[","...",",","M",",","N","]","operator","=","LinearOperator","(","...",")","tensor_shape.TensorShape","(","operator.shape",")","=","[","...",",","M",",","N","]","#","Solve","one","linear","system","for","every","member","of","the","batch",".","RHS","=","...","#","shape","[","...",",","M","]","X","=","operator.solvevec","(","RHS",")","#","X","is","the","solution","to","the","linear","system","#","sum_j","A","[","...",",",":",",","j","]","X","[","...",",","j","]","=","RHS","[","...",",",":","]","operator.matvec","(","X",")","==",">","RHS","``","`","Args",":","rhs",":","`","Tensor","`","with","same","`","dtype","`","as","this","operator",",","or","list","of","`","Tensor","`","s","(","for","blockwise","operators",")",".","`","Tensor","`","s","are","treated","as","[","batch","]","vectors",",","meaning","for","every","set","of","leading","dimensions",",","the","last","dimension","defines","a","vector",".","See","class","docstring","for","definition","of","compatibility","regarding","batch","dimensions",".","adjoint",":","Python","`","bool","`",".","If","`","True","`",",","solve","the","system","involving","the","adjoint","of","this","`","LinearOperator","`",":","`","A^H","X","=","rhs","`",".","name",":","A","name","scope","to","use","for","ops","added","by","this","method",".","Returns",":","`","Tensor","`","with","shape","`","[","...",",","N","]","`","and","same","`","dtype","`","as","`","rhs","`",".","Raises",":","NotImplementedError",":","If","`","self.is_non_singular","`","or","`","is_square","`","is","False","."]
code: def solvevec(self, rhs, adjoint=False, name="solve"):
      """Solve single equation with best effort: `A X = rhs`.
  
      The returned `Tensor` will be close to an exact solution if `A` is well
      conditioned. Otherwise closeness will vary. See class docstring for details.
  
      Examples:
  
      ```python
      # Make an operator acting like batch matrix A.  Assume tensor_shape.TensorShape(A.shape) = [..., M, N]
      operator = LinearOperator(...)
      tensor_shape.TensorShape(operator.shape) = [..., M, N]
  
      # Solve one linear system for every member of the batch.
      RHS = ... # shape [..., M]
  
      X = operator.solvevec(RHS)
      # X is the solution to the linear system
      # sum_j A[..., :, j] X[..., j] = RHS[..., :]
  
      operator.matvec(X)
      ==> RHS
      ```
  
      Args:
        rhs: `Tensor` with same `dtype` as this operator, or list of `Tensor`s
          (for blockwise operators). `Tensor`s are treated as [batch] vectors,
          meaning for every set of leading dimensions, the last dimension defines
          a vector.  See class docstring for definition of compatibility regarding
          batch dimensions.
        adjoint: Python `bool`.  If `True`, solve the system involving the adjoint
          of this `LinearOperator`:  `A^H X = rhs`.
        name:  A name scope to use for ops added by this method.
  
      Returns:
        `Tensor` with shape `[...,N]` and same `dtype` as `rhs`.
  
      Raises:
        NotImplementedError:  If `self.is_non_singular` or `is_square` is False.
      """
      with self._name_scope(name):  # pylint: disable=not-callable
          block_dimensions = (
              self._block_domain_dimensions()
              if adjoint
              else self._block_range_dimensions()
          )
          if linear_operator_util.arg_is_blockwise(
              block_dimensions, rhs, -1
          ):
              for i, block in enumerate(rhs):
                  if not isinstance(
                      block, linear_operator.LinearOperator
                  ):
                      block = ops.convert_to_tensor(block)
                      # self._check_input_dtype(block)
                      block_dimensions[i].assert_is_compatible_with(
                          tensor_shape.TensorShape(block.shape)[-1]
                      )
                      rhs[i] = block
              rhs_mat = [
                  array_ops.expand_dims(block, axis=-1) for block in rhs
              ]
              solution_mat = self.solve(rhs_mat, adjoint=adjoint)
              return [
                  array_ops.squeeze(x, axis=-1) for x in solution_mat
              ]
  
          rhs = ops.convert_to_tensor(rhs, name="rhs")
          # self._check_input_dtype(rhs)
          op_dimension = (
              self.domain_dimension if adjoint else self.range_dimension
          )
          op_dimension.assert_is_compatible_with(
              tensor_shape.TensorShape(rhs.shape)[-1]
          )
          rhs_mat = array_ops.expand_dims(rhs, axis=-1)
          solution_mat = self.solve(rhs_mat, adjoint=adjoint)
          return array_ops.squeeze(solution_mat, axis=-1)
  
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 20 for calling the LinearOperatorBlockDiag obj's underlying member method code with example usage: obj.solvevec(rhs, adjoint, name) and returns: array_ops, unknown