code: def testBijector(self, bijector_name, data):
      tfp_hps.guitar_skip_if_matches(
          "Tanh", bijector_name, "b/144163991"
      )
  
      bijector, event_dim = self._draw_bijector(bijector_name, data)
  
      # Forward mapping: Check differentiation through forward mapping with
      # respect to the input and parameter variables.  Also check that any
      # variables are not referenced overmuch.
      xs = self._draw_domain_tensor(bijector, data, event_dim)
      wrt_vars = [xs] + [
          v for v in bijector.trainable_variables if v.dtype.is_floating
      ]
      with tf.GradientTape() as tape:
          with tfp_hps.assert_no_excessive_var_usage(
              "method `forward` of {}".format(bijector)
          ):
              tape.watch(wrt_vars)
              # TODO(b/73073515): Fix graph mode gradients with bijector caching.
              ys = bijector.forward(xs + 0)
      grads = tape.gradient(ys, wrt_vars)
      assert_no_none_grad(bijector, "forward", wrt_vars, grads)
  
      # For scalar bijectors, verify correctness of the _is_increasing method.
      # TODO(b/148459057): Except, don't verify Softfloor on Guitar because
      # of numerical problem.
      def exception(bijector):
          if not tfp_hps.running_under_guitar():
              return False
          if isinstance(bijector, tfb.Softfloor):
              return True
          if is_invert(bijector):
              return exception(bijector.bijector)
          return False
  
      if (
          bijector.forward_min_event_ndims == 0
          and bijector.inverse_min_event_ndims == 0
          and not exception(bijector)
      ):
          dydx = grads[0]
          hp.note("dydx: {}".format(dydx))
          isfinite = tf.math.is_finite(dydx)
          incr_or_slope_eq0 = (
              bijector._internal_is_increasing() | tf.equal(dydx, 0)
          )  # pylint: disable=protected-access
          self.assertAllEqual(
              isfinite & incr_or_slope_eq0,
              isfinite & (dydx >= 0) | tf.zeros_like(incr_or_slope_eq0),
          )
  
      # FLDJ: Check differentiation through forward log det jacobian with
      # respect to the input and parameter variables.  Also check that any
      # variables are not referenced overmuch.
      event_ndims = data.draw(
          hps.integers(
              min_value=bijector.forward_min_event_ndims,
              max_value=xs.shape.ndims,
          )
      )
      with tf.GradientTape() as tape:
          max_permitted = _ldj_tensor_conversions_allowed(
              bijector, is_forward=True
          )
          with tfp_hps.assert_no_excessive_var_usage(
              "method `forward_log_det_jacobian` of {}".format(
                  bijector
              ),
              max_permissible=max_permitted,
          ):
              tape.watch(wrt_vars)
              # TODO(b/73073515): Fix graph mode gradients with bijector caching.
              ldj = bijector.forward_log_det_jacobian(
                  xs + 0, event_ndims=event_ndims
              )
      grads = tape.gradient(ldj, wrt_vars)
      assert_no_none_grad(
          bijector, "forward_log_det_jacobian", wrt_vars, grads
      )
  
      # Inverse mapping: Check differentiation through inverse mapping with
      # respect to the codomain "input" and parameter variables.  Also check that
      # any variables are not referenced overmuch.
      ys = self._draw_codomain_tensor(bijector, data, event_dim)
      wrt_vars = [ys] + [
          v for v in bijector.trainable_variables if v.dtype.is_floating
      ]
      with tf.GradientTape() as tape:
          with tfp_hps.assert_no_excessive_var_usage(
              "method `inverse` of {}".format(bijector)
          ):
              tape.watch(wrt_vars)
              # TODO(b/73073515): Fix graph mode gradients with bijector caching.
              xs = bijector.inverse(ys + 0)
      grads = tape.gradient(xs, wrt_vars)
      assert_no_none_grad(bijector, "inverse", wrt_vars, grads)
  
      # ILDJ: Check differentiation through inverse log det jacobian with respect
      # to the codomain "input" and parameter variables.  Also check that any
      # variables are not referenced overmuch.
      event_ndims = data.draw(
          hps.integers(
              min_value=bijector.inverse_min_event_ndims,
              max_value=ys.shape.ndims,
          )
      )
      with tf.GradientTape() as tape:
          max_permitted = _ldj_tensor_conversions_allowed(
              bijector, is_forward=False
          )
          with tfp_hps.assert_no_excessive_var_usage(
              "method `inverse_log_det_jacobian` of {}".format(
                  bijector
              ),
              max_permissible=max_permitted,
          ):
              tape.watch(wrt_vars)
              # TODO(b/73073515): Fix graph mode gradients with bijector caching.
              ldj = bijector.inverse_log_det_jacobian(
                  ys + 0, event_ndims=event_ndims
              )
      grads = tape.gradient(ldj, wrt_vars)
      assert_no_none_grad(
          bijector, "inverse_log_det_jacobian", wrt_vars, grads
      )
  
      # Verify that `_is_permutation` implies constant zero Jacobian.
      if bijector._is_permutation:
          self.assertTrue(bijector._is_constant_jacobian)
          self.assertAllEqual(ldj, 0.0)
  
      # Verify correctness of batch shape.
      xs_batch_shapes = tf.nest.map_structure(
          lambda x, nd: ps.shape(x)[: ps.rank(x) - nd],
          xs,
          bijector.inverse_event_ndims(event_ndims),
      )
      empirical_batch_shape = functools.reduce(
          ps.broadcast_shape,
          nest.flatten_up_to(
              bijector.forward_min_event_ndims, xs_batch_shapes
          ),
      )
      batch_shape = bijector.experimental_batch_shape(
          y_event_ndims=event_ndims
      )
      if tensorshape_util.is_fully_defined(batch_shape):
          self.assertAllEqual(empirical_batch_shape, batch_shape)
      self.assertAllEqual(
          empirical_batch_shape,
          bijector.experimental_batch_shape_tensor(
              y_event_ndims=event_ndims
          ),
      )
  
      # Check that the outputs of forward_dtype and inverse_dtype match the dtypes
      # of the outputs of forward and inverse.
      self.assertAllEqualNested(
          ys.dtype, bijector.forward_dtype(xs.dtype)
      )
      self.assertAllEqualNested(
          xs.dtype, bijector.inverse_dtype(ys.dtype)
      )
  
imports: import collections
  import functools
  from absl.testing import parameterized
  import hypothesis
  from hypothesis import strategies
  import numpy
  import tensorflow.compat.v2
  from tensorflow_probability.python import bijectors
  from tensorflow_probability.python import util
  from tensorflow_probability.python.bijectors import hypothesis_testlib
  from tensorflow_probability.python.bijectors import invert
  from tensorflow_probability.python.internal import auto_composite_tensor
  from tensorflow_probability.python.internal import hypothesis_testlib
  from tensorflow_probability.python.internal import prefer_static
  from tensorflow_probability.python.internal import samplers
  from tensorflow_probability.python.internal import tensor_util
  from tensorflow_probability.python.internal import tensorshape_util
  from tensorflow_probability.python.internal import test_util
  from tensorflow.python.util import nest
label_desc: Use image node_id 4 for calling the BijectorPropertiesTest obj's underlying member method code with example usage: obj.testBijector(bijector_name, data) and returns: False, False, True, exception