class_docstr: `LinearOperator` acting like a [batch] zero matrix.
  
  This operator acts like a [batch] zero matrix `A` with shape
  `[B1,...,Bb, N, M]` for some `b >= 0`.  The first `b` indices index a
  batch member.  For every batch index `(i1,...,ib)`, `A[i1,...,ib, : :]` is
  an `N x M` matrix.  This matrix `A` is not materialized, but for
  purposes of broadcasting this shape will be relevant.
  
  `LinearOperatorZeros` is initialized with `num_rows`, and optionally
  `num_columns, `batch_shape`, and `dtype` arguments.  If `num_columns` is
  `None`, then this operator will be initialized as a square matrix. If
  `batch_shape` is `None`, this operator efficiently passes through all
  arguments.  If `batch_shape` is provided, broadcasting may occur, which will
  require making copies.
  
  ```python
  # Create a 2 x 2 zero matrix.
  operator = LinearOperatorZero(num_rows=2, dtype=tf.float32)
  
  operator.to_dense()
  ==> [[0., 0.]
       [0., 0.]]
  
  tensor_shape.TensorShape(operator.shape)
  ==> [2, 2]
  
  operator.determinant()
  ==> 0.
  
  x = ... Shape [2, 4] Tensor
  operator.matmul(x)
  ==> Shape [2, 4] Tensor, same as x.
  
  # Create a 2-batch of 2x2 zero matrices
  operator = LinearOperatorZeros(num_rows=2, batch_shape=[2])
  operator.to_dense()
  ==> [[[0., 0.]
        [0., 0.]],
       [[0., 0.]
        [0., 0.]]]
  
  # Here, even though the operator has a batch shape, the input is the same as
  # the output, so x can be passed through without a copy.  The operator is able
  # to detect that no broadcast is necessary because both x and the operator
  # have statically defined shape.
  x = ... Shape [2, 2, 3]
  operator.matmul(x)
  ==> Shape [2, 2, 3] Tensor, same as tf.zeros_like(x)
  
  # Here the operator and x have different batch_shape, and are broadcast.
  # This requires a copy, since the output is different size than the input.
  x = ... Shape [1, 2, 3]
  operator.matmul(x)
  ==> Shape [2, 2, 3] Tensor, equal to tf.zeros_like([x, x])
  ```
  
  ### Shape compatibility
  
  This operator acts on [batch] matrix with compatible shape.
  `x` is a batch matrix with compatible shape for `matmul` and `solve` if
  
  ```
  tensor_shape.TensorShape(operator.shape) = [B1,...,Bb] + [N, M],  with b >= 0
  tensor_shape.TensorShape(x.shape) =   [C1,...,Cc] + [M, R],
  and [C1,...,Cc] broadcasts with [B1,...,Bb] to [D1,...,Dd]
  ```
  
  #### 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: ["`","LinearOperator","`","acting","like","a","[","batch","]","zero","matrix",".","This","operator","acts","like","a","[","batch","]","zero","matrix","`","A","`","with","shape","`","[","B1",",","...",",","Bb",",","N",",","M","]","`","for","some","`","b",">","=","0","`",".","The","first","`","b","`","indices","index","a","batch","member",".","For","every","batch","index","`","(","i1",",","...",",","ib",")","`",",","`","A","[","i1",",","...",",","ib",",",":",":","]","`","is","an","`","N","x","M","`","matrix",".","This","matrix","`","A","`","is","not","materialized",",","but","for","purposes","of","broadcasting","this","shape","will","be","relevant",".","`","LinearOperatorZeros","`","is","initialized","with","`","num_rows","`",",","and","optionally","`","num_columns",",","`","batch_shape","`",",","and","`","dtype","`","arguments",".","If","`","num_columns","`","is","`","None","`",",","then","this","operator","will","be","initialized","as","a","square","matrix",".","If","`","batch_shape","`","is","`","None","`",",","this","operator","efficiently","passes","through","all","arguments",".","If","`","batch_shape","`","is","provided",",","broadcasting","may","occur",",","which","will","require","making","copies",".","``","`","python","#","Create","a","2","x","2","zero","matrix",".","operator","=","LinearOperatorZero","(","num_rows=2",",","dtype=tf.float32",")","operator.to_dense","(",")","==",">","[","[","0.",",","0",".","]","[","0.",",","0",".","]","]","tensor_shape.TensorShape","(","operator.shape",")","==",">","[","2",",","2","]","operator.determinant","(",")","==",">","0.","x","=","...","Shape","[","2",",","4","]","Tensor","operator.matmul","(","x",")","==",">","Shape","[","2",",","4","]","Tensor",",","same","as","x",".","#","Create","a","2-batch","of","2x2","zero","matrices","operator","=","LinearOperatorZeros","(","num_rows=2",",","batch_shape=","[","2","]",")","operator.to_dense","(",")","==",">","[","[","[","0.",",","0",".","]","[","0.",",","0",".","]","]",",","[","[","0.",",","0",".","]","[","0.",",","0",".","]","]","]","#","Here",",","even","though","the","operator","has","a","batch","shape",",","the","input","is","the","same","as","#","the","output",",","so","x","can","be","passed","through","without","a","copy",".","The","operator","is","able","#","to","detect","that","no","broadcast","is","necessary","because","both","x","and","the","operator","#","have","statically","defined","shape",".","x","=","...","Shape","[","2",",","2",",","3","]","operator.matmul","(","x",")","==",">","Shape","[","2",",","2",",","3","]","Tensor",",","same","as","tf.zeros_like","(","x",")","#","Here","the","operator","and","x","have","different","batch_shape",",","and","are","broadcast",".","#","This","requires","a","copy",",","since","the","output","is","different","size","than","the","input",".","x","=","...","Shape","[","1",",","2",",","3","]","operator.matmul","(","x",")","==",">","Shape","[","2",",","2",",","3","]","Tensor",",","equal","to","tf.zeros_like","(","[","x",",","x","]",")","``","`","#","#","#","Shape","compatibility","This","operator","acts","on","[","batch","]","matrix","with","compatible","shape",".","`","x","`","is","a","batch","matrix","with","compatible","shape","for","`","matmul","`","and","`","solve","`","if","``","`","tensor_shape.TensorShape","(","operator.shape",")","=","[","B1",",","...",",","Bb","]","+","[","N",",","M","]",",","with","b",">","=","0","tensor_shape.TensorShape","(","x.shape",")","=","[","C1",",","...",",","Cc","]","+","[","M",",","R","]",",","and","[","C1",",","...",",","Cc","]","broadcasts","with","[","B1",",","...",",","Bb","]","to","[","D1",",","...",",","Dd","]","``","`","#","#","#","#","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 _matmul(self, x, adjoint=False, adjoint_arg=False):
      if self._assert_proper_shapes:
          x = linalg.adjoint(x) if adjoint_arg else x
          aps = (
              linear_operator_util.assert_compatible_matrix_dimensions(
                  self, x
              )
          )
          x = distribution_util.with_dependencies([aps], x)
      if self.is_square:
          # Note that adjoint has no effect since this matrix is self-adjoint.
          if adjoint_arg:
              output_shape = prefer_static.concat(
                  [
                      prefer_static.shape(x)[:-2],
                      [
                          prefer_static.shape(x)[-1],
                          prefer_static.shape(x)[-2],
                      ],
                  ],
                  axis=0,
              )
          else:
              output_shape = prefer_static.shape(x)
  
          return self._possibly_broadcast_batch_shape(
              array_ops.zeros(shape=output_shape, dtype=x.dtype)
          )
  
      x_shape = prefer_static.shape(x)
      n = self._num_columns if adjoint else self._num_rows
      m = x_shape[-2] if adjoint_arg else x_shape[-1]
  
      output_shape = prefer_static.concat(
          [x_shape[:-2], [n, m]], axis=0
      )
  
      zeros = array_ops.zeros(shape=output_shape, dtype=x.dtype)
      return self._possibly_broadcast_batch_shape(zeros)
  
imports: import numpy
  from tensorflow_probability.python.internal.backend.numpy import dtype
  from tensorflow_probability.python.internal.backend.numpy import errors
  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 ops
  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 import numpy_math
  from tensorflow_probability.python.internal.backend.numpy import linalg_impl
  from tensorflow_probability.python.internal.backend.numpy.gen import linear_operator
  from tensorflow_probability.python.internal.backend.numpy.gen import linear_operator_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 8 for calling the LinearOperatorZeros obj's underlying member method code with example usage: obj._matmul(x, adjoint, adjoint_arg) and returns: self, self