code: def test_mi_gradient(rng):
      # Test the gradient of mutual information
      h = 1e-5
      # Make sure dictionary entries are processed in the same order regardless
      # of the platform. Otherwise any random numbers drawn within the loop would
      # make the test non-deterministic even if we fix the seed before the loop:
      # in this case the samples are drawn with `np.random.randn` below
  
      for ttype in sorted(factors):
          transform = regtransforms[ttype]
          dim = ttype[1]
          if dim == 2:
              nslices = 1
          else:
              nslices = 45
          factor = factors[ttype][0]
          sampling_proportion = factors[ttype][1]
          theta = factors[ttype][2]
          # Start from a small rotation
          start = regtransforms[("ROTATION", dim)]
          nrot = start.get_number_of_parameters()
          starting_affine = start.param_to_matrix(
              0.25 * rng.standard_normal(nrot)
          )
          # Get data (pair of images related to each other by an known transform)
          (
              static,
              moving,
              static_g2w,
              moving_g2w,
              smask,
              mmask,
              M,
          ) = setup_random_transform(
              transform, factor, nslices, 2.0, rng=rng
          )
  
          # Prepare a MutualInformationMetric instance
          mi_metric = imaffine.MutualInformationMetric(
              32, sampling_proportion
          )
          mi_metric.setup(
              transform, static, moving, starting_affine=starting_affine
          )
          # Compute the gradient with the implementation under test
          actual = mi_metric.gradient(theta)
  
          # Compute the gradient using finite-differences
          n = transform.get_number_of_parameters()
          expected = np.empty(n, dtype=np.float64)
  
          val0 = mi_metric.distance(theta)
          for i in range(n):
              dtheta = theta.copy()
              dtheta[i] += h
              val1 = mi_metric.distance(dtheta)
              expected[i] = (val1 - val0) / h
  
          dp = expected.dot(actual)
          enorm = npl.norm(expected)
          anorm = npl.norm(actual)
          nprod = dp / (enorm * anorm)
          assert nprod >= 0.99
  
file_path: dipy/dipy/align/tests/test_imaffine.py
imports: import numpy
  import numpy.linalg
  from numpy.testing import assert_array_equal, assert_array_almost_equal, assert_equal, assert_raises, assert_warns
  from dipy.core import geometry
  from dipy.align import vector_fields
  from dipy.align import imaffine
  from dipy.align.imaffine import AffineInversionError, AffineInvalidValuesError, AffineMap, _number_dim_affine_matrix
  from dipy.align.transforms import regtransforms
  from dipy.align.tests.test_parzenhist import setup_random_transform
  from dipy.testing.decorators import set_random_number_generator
label_desc: Use image node_id 6 for calling a global function with example usage: test_mi_gradient(rng) without return types