code: def lu_reconstruct(lower_upper, perm, validate_args=False, name=None):
      """The inverse LU decomposition, `X == lu_reconstruct(*tf.linalg.lu(X))`.
  
      Args:
        lower_upper: `lu` as returned by `tf.linalg.lu`, i.e., if
          `matmul(P, matmul(L, U)) = X` then `lower_upper = L + U - eye`.
        perm: `p` as returned by `tf.linag.lu`, i.e., if
          `matmul(P, matmul(L, U)) = X` then `perm = argmax(P)`.
        validate_args: Python `bool` indicating whether arguments should be checked
          for correctness.
          Default value: `False` (i.e., don't validate arguments).
        name: Python `str` name given to ops managed by this object.
          Default value: `None` (i.e., 'lu_reconstruct').
  
      Returns:
        x: The original input to `tf.linalg.lu`, i.e., `x` as in,
          `lu_reconstruct(*tf.linalg.lu(x))`.
  
      #### Examples
  
      ```python
      import numpy as np
      import tensorflow as tf
      import tensorflow_probability as tfp
  
      x = [[[3., 4], [1, 2]],
           [[7., 8], [3, 4]]]
      x_reconstructed = tfp.math.lu_reconstruct(*tf.linalg.lu(x))
      tf.assert_near(x, x_reconstructed)
      # ==> True
      ```
  
      """
      with tf.name_scope(name or "lu_reconstruct"):
          lower_upper = tf.convert_to_tensor(
              lower_upper, dtype_hint=tf.float32, name="lower_upper"
          )
          perm = tf.convert_to_tensor(
              perm, dtype_hint=tf.int32, name="perm"
          )
  
          assertions = lu_reconstruct_assertions(
              lower_upper, perm, validate_args
          )
          if assertions:
              with tf.control_dependencies(assertions):
                  lower_upper = tf.identity(lower_upper)
                  perm = tf.identity(perm)
  
          shape = tf.shape(lower_upper)
  
          lower = tf.linalg.set_diag(
              tf.linalg.band_part(
                  lower_upper, num_lower=-1, num_upper=0
              ),
              tf.ones(shape[:-1], dtype=lower_upper.dtype),
          )
          upper = tf.linalg.band_part(
              lower_upper, num_lower=0, num_upper=-1
          )
          x = tf.matmul(lower, upper)
  
          if (
              tensorshape_util.rank(lower_upper.shape) is None
              or tensorshape_util.rank(lower_upper.shape) != 2
          ):
              # We either don't know the batch rank or there are >0 batch dims.
              batch_size = tf.reduce_prod(shape[:-2])
              d = shape[-1]
              x = tf.reshape(x, [batch_size, d, d])
              perm = tf.reshape(perm, [batch_size, d])
              perm = tf.map_fn(tf.math.invert_permutation, perm)
              batch_indices = tf.broadcast_to(
                  tf.range(batch_size)[:, tf.newaxis], [batch_size, d]
              )
              x = tf.gather_nd(
                  x, tf.stack([batch_indices, perm], axis=-1)
              )
              x = tf.reshape(x, shape)
          else:
              x = tf.gather(x, tf.math.invert_permutation(perm))
  
          tensorshape_util.set_shape(x, lower_upper.shape)
          return x
  
imports: import numpy
  import tensorflow.compat.v1
  import tensorflow.compat.v2
  from tensorflow_probability.python.internal import assert_util
  from tensorflow_probability.python.internal import custom_gradient
  from tensorflow_probability.python.internal import distribution_util
  from tensorflow_probability.python.internal import dtype_util
  from tensorflow_probability.python.internal import prefer_static
  from tensorflow_probability.python.internal import tensorshape_util
  from tensorflow_probability.python.math import generic
label_desc: Use image node_id 9 for calling a global function with example usage: lu_reconstruct(lower_upper, perm, validate_args, name) and returns: x