code: def test_affine_map(rng):
      dom_shape = np.array([64, 64, 64], dtype=np.int32)
      cod_shape = np.array([80, 80, 80], dtype=np.int32)
      # Radius of the circle/sphere (testing image)
      radius = 16
      # Rotation axis (used for 3D transforms only)
      rot_axis = np.array([0.5, 2.0, 1.5])
      # Arbitrary transform parameters
      t = 0.15
      rotations = [-1 * np.pi / 10.0, 0.0, np.pi / 10.0]
      scales = [0.9, 1.0, 1.1]
      for dim1 in [2, 3]:
          # Setup current dimension
          if dim1 == 2:
              # Create image of a circle
              img = vf.create_circle(cod_shape[0], cod_shape[1], radius)
              oracle_linear = vf.transform_2d_affine
              oracle_nn = vf.transform_2d_affine_nn
          else:
              # Create image of a sphere
              img = vf.create_sphere(
                  cod_shape[0], cod_shape[1], cod_shape[2], radius
              )
              oracle_linear = vf.transform_3d_affine
              oracle_nn = vf.transform_3d_affine_nn
          img = np.array(img)
          # Translation is the only parameter differing for 2D and 3D
          translations = [t * dom_shape[:dim1]]
          # Generate affine transforms
          gt_affines = create_affine_transforms(
              dim1, translations, rotations, scales, rot_axis
          )
          # Include the None case
          gt_affines.append(None)
  
          # testing str/format/repr
          for affine_mat in gt_affines:
              aff_map = AffineMap(affine_mat)
              assert_equal(str(aff_map), aff_map.__str__())
              assert_equal(repr(aff_map), aff_map.__repr__())
              for spec in ["f", "r", "t", ""]:
                  assert_equal(
                      format(aff_map, spec), aff_map.__format__(spec)
                  )
  
          for affine in gt_affines:
              # make both domain point to the same physical region
              # It's ok to use the same transform, we just want to test
              # that this information is actually being considered
              domain_grid2world = affine
              codomain_grid2world = affine
              grid2grid_transform = affine
  
              # Evaluate the transform with vector_fields module (already tested)
              expected_linear = oracle_linear(
                  img, dom_shape[:dim1], grid2grid_transform
              )
              expected_nn = oracle_nn(
                  img, dom_shape[:dim1], grid2grid_transform
              )
  
              # Evaluate the transform with the implementation under test
              affine_map = imaffine.AffineMap(
                  affine,
                  dom_shape[:dim1],
                  domain_grid2world,
                  cod_shape[:dim1],
                  codomain_grid2world,
              )
              actual_linear = affine_map.transform(
                  img, interpolation="linear"
              )
              actual_nn = affine_map.transform(
                  img, interpolation="nearest"
              )
              assert_array_almost_equal(actual_linear, expected_linear)
              assert_array_almost_equal(actual_nn, expected_nn)
  
              # Test set_affine with valid matrix
              affine_map.set_affine(affine)
              if affine is None:
                  assert affine_map.affine is None
                  assert affine_map.affine_inv is None
              else:
                  # compatibility with previous versions
                  assert_array_equal(affine, affine_map.affine)
                  # new getter
                  new_copy_affine = affine_map.affine
                  # value must be the same
                  assert_array_equal(affine, new_copy_affine)
                  # but not its reference
                  assert id(affine) != id(new_copy_affine)
                  actual = affine_map.affine.dot(affine_map.affine_inv)
                  assert_array_almost_equal(actual, np.eye(dim1 + 1))
  
              # Evaluate via the inverse transform
  
              # AffineMap will use the inverse of the input matrix when we call
              # `transform_inverse`. Since the inverse of the inverse of a matrix
              # is not exactly equal to the original matrix (numerical
              #  limitations) we need to invert the matrix twice to make sure
              # the oracle and the implementation under test apply the same
              # transform
              aff_inv = None if affine is None else npl.inv(affine)
              aff_inv_inv = (
                  None if aff_inv is None else npl.inv(aff_inv)
              )
              expected_linear = oracle_linear(
                  img, dom_shape[:dim1], aff_inv_inv
              )
              expected_nn = oracle_nn(
                  img, dom_shape[:dim1], aff_inv_inv
              )
  
              affine_map = imaffine.AffineMap(
                  aff_inv,
                  cod_shape[:dim1],
                  codomain_grid2world,
                  dom_shape[:dim1],
                  domain_grid2world,
              )
              actual_linear = affine_map.transform_inverse(
                  img, interpolation="linear"
              )
              actual_nn = affine_map.transform_inverse(
                  img, interpolation="nearest"
              )
              assert_array_almost_equal(actual_linear, expected_linear)
              assert_array_almost_equal(actual_nn, expected_nn)
  
          # Verify AffineMap can not be created with non-square matrix
          non_square_shapes = [
              np.zeros((dim1, dim1 + 1), dtype=np.float64),
              np.zeros((dim1 + 1, dim1), dtype=np.float64),
          ]
          for nsq in non_square_shapes:
              assert_raises(AffineInversionError, AffineMap, nsq)
  
          # Verify incorrect augmentations are caught
          for affine_mat in gt_affines:
              aff_map = AffineMap(affine_mat)
              if affine_mat is None:
                  continue
              bad_aug = aff_map.affine
              # no zeros in the first n-1 columns on last row
              bad_aug[-1, :] = 1
              assert_raises(
                  AffineInvalidValuesError, AffineMap, bad_aug
              )
  
              bad_aug = aff_map.affine
              bad_aug[-1, -1] = 0  # lower right not 1
              assert_raises(
                  AffineInvalidValuesError, AffineMap, bad_aug
              )
  
          # Verify AffineMap cannot be created with a non-invertible matrix
          invalid_nan = np.zeros((dim1 + 1, dim1 + 1), dtype=np.float64)
          invalid_nan[1, 1] = np.nan
          invalid_zeros = np.zeros(
              (dim1 + 1, dim1 + 1), dtype=np.float64
          )
          assert_raises(
              imaffine.AffineInvalidValuesError,
              imaffine.AffineMap,
              invalid_nan,
          )
          assert_raises(
              AffineInvalidValuesError,
              imaffine.AffineMap,
              invalid_zeros,
          )
  
          # Test exception is raised when the affine transform matrix is not
          # valid
          invalid_shape = np.eye(dim1)
          affmap_invalid_shape = imaffine.AffineMap(
              invalid_shape,
              dom_shape[:dim1],
              None,
              cod_shape[:dim1],
              None,
          )
          assert_raises(ValueError, affmap_invalid_shape.transform, img)
          assert_raises(
              ValueError, affmap_invalid_shape.transform_inverse, img
          )
  
          # Verify exception is raised when sampling info is not provided
          valid = np.eye(3)
          affmap_invalid_shape = imaffine.AffineMap(valid)
          assert_raises(ValueError, affmap_invalid_shape.transform, img)
          assert_raises(
              ValueError, affmap_invalid_shape.transform_inverse, img
          )
  
          # Verify exception is raised when requesting an invalid interpolation
          assert_raises(
              ValueError, affine_map.transform, img, "invalid"
          )
          assert_raises(
              ValueError, affine_map.transform_inverse, img, "invalid"
          )
  
          # Verify exception is raised when attempting to warp an image of
          # invalid dimension
          for dim2 in [2, 3]:
              affine_map = imaffine.AffineMap(
                  np.eye(dim2),
                  cod_shape[:dim2],
                  None,
                  dom_shape[:dim2],
                  None,
              )
              for sh in [(2,), (2, 2, 2, 2)]:
                  img = np.zeros(sh)
                  assert_raises(ValueError, affine_map.transform, img)
                  assert_raises(
                      ValueError, affine_map.transform_inverse, img
                  )
              aff_sing = np.zeros((dim2 + 1, dim2 + 1))
              aff_nan = np.zeros((dim2 + 1, dim2 + 1))
              aff_nan[...] = np.nan
              aff_inf = np.zeros((dim2 + 1, dim2 + 1))
              aff_inf[...] = np.inf
  
              assert_raises(
                  AffineInvalidValuesError,
                  affine_map.set_affine,
                  aff_sing,
              )
              assert_raises(
                  AffineInvalidValuesError,
                  affine_map.set_affine,
                  aff_nan,
              )
              assert_raises(
                  AffineInvalidValuesError,
                  affine_map.set_affine,
                  aff_inf,
              )
  
      # Verify AffineMap can not be created with non-2D matrices : len(shape) != 2
      for dim_not_2 in range(10):
          if dim_not_2 != _number_dim_affine_matrix:
              mat_large_dim = rng.random([2] * dim_not_2)
              assert_raises(
                  AffineInversionError, AffineMap, mat_large_dim
              )
  
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 8 for calling a global function with example usage: test_affine_map(rng) without return types