class_docstr: A set of domain and range CoordinateSystems and a function between them.
  
  For example, the function may represent the mapping of a voxel (the
  domain of the function) to real space (the range).  The function may
  be an affine or non-affine transformation.
  
  Attributes
  ----------
  function_domain : :class:`CoordinateSystem` instance
     The input coordinate system.
  function_range : :class:`CoordinateSystem` instance
     The output coordinate system.
  function : callable
     A callable that maps the function_domain to the function_range.
  inverse_function : None or callable
     A callable that maps the function_range to the function_domain.
     Not all functions have an inverse, in which case inverse_function
     is None.
  
  Examples
  --------
  >>> function_domain = CoordinateSystem('ijk', 'voxels')
  >>> function_range = CoordinateSystem('xyz', 'world')
  >>> mni_orig = np.array([-90.0, -126.0, -72.0])
  >>> function = lambda x: x + mni_orig
  >>> inv_function = lambda x: x - mni_orig
  >>> cm = CoordinateMap(function_domain, function_range, function, inv_function)
  
  Map the first 3 voxel coordinates, along the x-axis, to mni space:
  
  >>> x = np.array([[0,0,0], [1,0,0], [2,0,0]])
  >>> cm.function(x)
  array([[ -90., -126.,  -72.],
         [ -89., -126.,  -72.],
         [ -88., -126.,  -72.]])
  
  >>> x = CoordinateSystem('x')
  >>> y = CoordinateSystem('y')
  >>> m = CoordinateMap(x, y, np.exp, np.log)
  >>> m
  CoordinateMap(
     function_domain=CoordinateSystem(coord_names=('x',), name='', coord_dtype=float64),
     function_range=CoordinateSystem(coord_names=('y',), name='', coord_dtype=float64),
     function=<ufunc 'exp'>,
     inverse_function=<ufunc 'log'>
    )
  >>> m.inverse()
  CoordinateMap(
     function_domain=CoordinateSystem(coord_names=('y',), name='', coord_dtype=float64),
     function_range=CoordinateSystem(coord_names=('x',), name='', coord_dtype=float64),
     function=<ufunc 'log'>,
     inverse_function=<ufunc 'exp'>
    )
class_docstr_tok: ["A","set","of","domain","and","range","CoordinateSystems","and","a","function","between","them",".","For","example",",","the","function","may","represent","the","mapping","of","a","voxel","(","the","domain","of","the","function",")","to","real","space","(","the","range",")",".","The","function","may","be","an","affine","or","non-affine","transformation",".","Attributes","--","--","--","--","--","function_domain",":",":","class",":","`","CoordinateSystem","`","instance","The","input","coordinate","system",".","function_range",":",":","class",":","`","CoordinateSystem","`","instance","The","output","coordinate","system",".","function",":","callable","A","callable","that","maps","the","function_domain","to","the","function_range",".","inverse_function",":","None","or","callable","A","callable","that","maps","the","function_range","to","the","function_domain",".","Not","all","functions","have","an","inverse",",","in","which","case","inverse_function","is","None",".","Examples","--","--","--","--",">",">",">","function_domain","=","CoordinateSystem","(","'ijk","'",",","'voxels","'",")",">",">",">","function_range","=","CoordinateSystem","(","'xyz","'",",","'world","'",")",">",">",">","mni_orig","=","np.array","(","[","-90.0",",","-126.0",",","-72.0","]",")",">",">",">","function","=","lambda","x",":","x","+","mni_orig",">",">",">","inv_function","=","lambda","x",":","x","-","mni_orig",">",">",">","cm","=","CoordinateMap","(","function_domain",",","function_range",",","function",",","inv_function",")","Map","the","first","3","voxel","coordinates",",","along","the","x-axis",",","to","mni","space",":",">",">",">","x","=","np.array","(","[","[","0,0,0","]",",","[","1,0,0","]",",","[","2,0,0","]","]",")",">",">",">","cm.function","(","x",")","array","(","[","[","-90.",",","-126.",",","-72",".","]",",","[","-89.",",","-126.",",","-72",".","]",",","[","-88.",",","-126.",",","-72",".","]","]",")",">",">",">","x","=","CoordinateSystem","(","'","x","'",")",">",">",">","y","=","CoordinateSystem","(","'","y","'",")",">",">",">","m","=","CoordinateMap","(","x",",","y",",","np.exp",",","np.log",")",">",">",">","m","CoordinateMap","(","function_domain=CoordinateSystem","(","coord_names=","(","'","x","'",",",")",",","name=","''",",","coord_dtype=float64",")",",","function_range=CoordinateSystem","(","coord_names=","(","'","y","'",",",")",",","name=","''",",","coord_dtype=float64",")",",","function=","<","ufunc","'exp","'",">",",","inverse_function=","<","ufunc","'log","'",">",")",">",">",">","m.inverse","(",")","CoordinateMap","(","function_domain=CoordinateSystem","(","coord_names=","(","'","y","'",",",")",",","name=","''",",","coord_dtype=float64",")",",","function_range=CoordinateSystem","(","coord_names=","(","'","x","'",",",")",",","name=","''",",","coord_dtype=float64",")",",","function=","<","ufunc","'log","'",">",",","inverse_function=","<","ufunc","'exp","'",">",")"]
docstr: Create a CoordinateMap given function, domain and range.
  
  Parameters
  ----------
  function_domain : :class:`CoordinateSystem`
     The input coordinate system.
  function_range : :class:`CoordinateSystem`
     The output coordinate system
  function : callable
     The function between function_domain and function_range.  It
     should be a callable that accepts arrays of shape (N,
     function_domain.ndim) and returns arrays of shape (N,
     function_range.ndim), where N is the number of points for
     transformation.
  inverse_function : None or callable, optional
     The optional inverse of function, with the intention being
     ``x = inverse_function(function(x))``.  If the function is
     affine and invertible, then this is true for all x.  The
     default is None
  
  Returns
  -------
  coordmap : CoordinateMap
docstr_tok: ["Create","a","CoordinateMap","given","function",",","domain","and","range",".","Parameters","--","--","--","--","--","function_domain",":",":","class",":","`","CoordinateSystem","`","The","input","coordinate","system",".","function_range",":",":","class",":","`","CoordinateSystem","`","The","output","coordinate","system","function",":","callable","The","function","between","function_domain","and","function_range",".","It","should","be","a","callable","that","accepts","arrays","of","shape","(","N",",","function_domain.ndim",")","and","returns","arrays","of","shape","(","N",",","function_range.ndim",")",",","where","N","is","the","number","of","points","for","transformation",".","inverse_function",":","None","or","callable",",","optional","The","optional","inverse","of","function",",","with","the","intention","being","``","x","=","inverse_function","(","function","(","x",")",")","``",".","If","the","function","is","affine","and","invertible",",","then","this","is","true","for","all","x",".","The","default","is","None","Returns","--","--","--","-","coordmap",":","CoordinateMap"]
code: def __init__(
      self,
      function_domain,
      function_range,
      function,
      inverse_function=None,
  ):
      """Create a CoordinateMap given function, domain and range.
  
      Parameters
      ----------
      function_domain : :class:`CoordinateSystem`
         The input coordinate system.
      function_range : :class:`CoordinateSystem`
         The output coordinate system
      function : callable
         The function between function_domain and function_range.  It
         should be a callable that accepts arrays of shape (N,
         function_domain.ndim) and returns arrays of shape (N,
         function_range.ndim), where N is the number of points for
         transformation.
      inverse_function : None or callable, optional
         The optional inverse of function, with the intention being
         ``x = inverse_function(function(x))``.  If the function is
         affine and invertible, then this is true for all x.  The
         default is None
  
      Returns
      -------
      coordmap : CoordinateMap
      """
      # These attrs define the structure of the coordmap.
      if not is_coordsys(function_domain):
          function_domain = CoordinateSystem(function_domain)
      self.function_domain = function_domain
      if not is_coordsys(function_range):
          function_range = CoordinateSystem(function_range)
      self.function_range = function_range
      self.function = function
      self.inverse_function = inverse_function
      self.ndims = (function_domain.ndim, function_range.ndim)
      if not callable(function):
          raise ValueError("The function must be callable.")
      if inverse_function is not None:
          if not callable(inverse_function):
              raise ValueError("The inverse_function must be callable.")
      self._checkfunction()
  
imports: import warnings
  import numpy
  import numpy.linalg
  from nibabel import io_orientation
  from nibabel.affines import from_matvec, to_matvec
  from .coordinate_system import CoordinateSystem, is_coordsys, safe_dtype
  from .coordinate_system import product
label_desc: Use image node_id 1 to create a new CoordinateMap object  with example: obj = CoordinateMap(function_domain, function_range, function, inverse_function)