code: def test_bitstring_length_matches_entropy_normal(self, scale=1e-8):
      prior = uniform_noise.NoisyNormal(
          loc=100 * tf.range(15.0), scale=scale
      )
      base_df = prior.base
      em = universal.UniversalBatchedEntropyModel(
          prior, coding_rank=2, compression=True
      )
      num_samples = 100000
      x = base_df.sample(num_samples, seed=0)
      bitstring = em.compress(x)
      x_decoded = em.decompress(bitstring, (num_samples,))
      bits = len(bitstring.numpy()) * 8
      bits_per_sample = bits / num_samples
      # Quantization noise should be between -.5 and .5
      self.assertAllLessEqual(tf.abs(x - x_decoded), 0.5)
  
      # Lets estimate entropy via sampling the distribution.
      samples = prior.sample(num_samples, seed=0)
      log_probs = prior.log_prob(samples) / tf.math.log(2.0)
      entropy_bits = -tf.reduce_sum(log_probs)
      rtol = 0.01  # Maximum relative error 1%.
      atol = 16  # Maximum 2 bytes absolute error.
      self.assertLessEqual(
          bits_per_sample, entropy_bits * (1 + rtol) + atol
      )
  
imports: from absl.testing import parameterized
  import scipy.stats
  import tensorflow
  import tensorflow_probability
  from tensorflow_compression.python.distributions import deep_factorized
  from tensorflow_compression.python.distributions import uniform_noise
  from tensorflow_compression.python.entropy_models import universal
label_desc: Use image node_id 3 for calling the UniversalBatchedEntropyModelTest obj's underlying member method code with example usage: obj.test_bitstring_length_matches_entropy_normal(scale) without return types