code: def test_perturb_and_apply_noise(self):
      x = tf.random.normal([10000], seed=0)
      y, x_plus_u0 = math_ops.perturb_and_apply(
          tf.identity, x, expected_grads=True
      )
      u0 = x_plus_u0 - x
      u1 = y - x
      # Check if residuals are as expected
      self.assertAllClose(u0, u1)
      # Check if noise has expected uniform distribution
      _, p = scipy.stats.kstest(u0, "uniform", (-0.5, 1.0))
      self.assertAllLessEqual(tf.abs(u0), 0.5)
      self.assertGreater(p, 1e-6)
  
file_path: compression/tensorflow_compression/python/ops/math_ops_test.py
imports: from absl.testing import parameterized
  import scipy.stats
  import tensorflow
  from tensorflow_compression.python.ops import math_ops
  from tensorflow_compression.python.ops import round_ops
label_desc: Use image node_id 1 for calling the PerturbAndApplyTest obj's underlying member method code with example usage: obj.test_perturb_and_apply_noise() without return types