class_docstr: Rotation in 3 dimensions.
  
  This class provides an interface to initialize from and represent rotations
  with:
  
      - Quaternions
      - Direction Cosine Matrices
      - Rotation Vectors
      - Euler angles
  
  The following operations on rotations are supported:
  
      - Application on vectors
      - Rotation Composition
      - Rotation Inversion
      - Rotation Indexing
  
  Indexing within a rotation is supported since multiple rotation transforms
  can be stored within a single `Rotation` instance.
  
  To create `Rotation` objects use `from_...` classmethods, `__init__` is not
  supposed to be used directly.
  
  Methods
  -------
  __len__
  from_quat
  from_dcm
  from_rotvec
  from_euler
  as_quat
  as_dcm
  as_rotvec
  as_euler
  apply
  __mul__
  inv
  __getitem__
  random
  
  Examples
  --------
  >>> from scipy.spatial.transform import Rotation as R
  
  A `Rotation` instance can be initialized in any of the above formats and
  converted to any of the others. The underlying object is independent of the
  representation used for initialization.
  
  Consider a counter-clockwise rotation of 90 degrees about the z-axis. This
  corresponds to the following quaternion (in scalar-last format):
  
  >>> r = R.from_quat([0, 0, np.sin(np.pi/4), np.cos(np.pi/4)])
  
  The rotation can be expressed in any of the other formats:
  
  >>> r.as_dcm()
  array([[ 2.22044605e-16, -1.00000000e+00,  0.00000000e+00],
  [ 1.00000000e+00,  2.22044605e-16,  0.00000000e+00],
  [ 0.00000000e+00,  0.00000000e+00,  1.00000000e+00]])
  >>> r.as_rotvec()
  array([0.        , 0.        , 1.57079633])
  >>> r.as_euler('zyx', degrees=True)
  array([90.,  0.,  0.])
  
  The same rotation can be initialized using a direction cosine matrix:
  
  >>> r = R.from_dcm(np.array([
  ... [0, -1, 0],
  ... [1, 0, 0],
  ... [0, 0, 1]]))
  
  Representation in other formats:
  
  >>> r.as_quat()
  array([0.        , 0.        , 0.70710678, 0.70710678])
  >>> r.as_rotvec()
  array([0.        , 0.        , 1.57079633])
  >>> r.as_euler('zyx', degrees=True)
  array([90.,  0.,  0.])
  
  The rotation vector corresponding to this rotation is given by:
  
  >>> r = R.from_rotvec(np.pi/2 * np.array([0, 0, 1]))
  
  Representation in other formats:
  
  >>> r.as_quat()
  array([0.        , 0.        , 0.70710678, 0.70710678])
  >>> r.as_dcm()
  array([[ 2.22044605e-16, -1.00000000e+00,  0.00000000e+00],
         [ 1.00000000e+00,  2.22044605e-16,  0.00000000e+00],
         [ 0.00000000e+00,  0.00000000e+00,  1.00000000e+00]])
  >>> r.as_euler('zyx', degrees=True)
  array([90.,  0.,  0.])
  
  The `from_euler` function is quite flexible in the range of input formats
  it supports. Here we initialize a single rotation about a single axis:
  
  >>> r = R.from_euler('z', 90, degrees=True)
  
  Again, the object is representation independent and can be converted to any
  other format:
  
  >>> r.as_quat()
  array([0.        , 0.        , 0.70710678, 0.70710678])
  >>> r.as_dcm()
  array([[ 2.22044605e-16, -1.00000000e+00,  0.00000000e+00],
         [ 1.00000000e+00,  2.22044605e-16,  0.00000000e+00],
         [ 0.00000000e+00,  0.00000000e+00,  1.00000000e+00]])
  >>> r.as_rotvec()
  array([0.        , 0.        , 1.57079633])
  
  It is also possible to initialize multiple rotations in a single instance
  using any of the `from_...` functions. Here we initialize a stack of 3
  rotations using the `from_euler` function:
  
  >>> r = R.from_euler('zyx', [
  ... [90, 0, 0],
  ... [0, 45, 0],
  ... [45, 60, 30]], degrees=True)
  
  The other representations also now return a stack of 3 rotations. For
  example:
  
  >>> r.as_quat()
  array([[0.        , 0.        , 0.70710678, 0.70710678],
         [0.        , 0.38268343, 0.        , 0.92387953],
         [0.39190384, 0.36042341, 0.43967974, 0.72331741]])
  
  Applying the above rotations onto a vector:
  
  >>> v = [1, 2, 3]
  >>> r.apply(v)
  array([[-2.        ,  1.        ,  3.        ],
         [ 2.82842712,  2.        ,  1.41421356],
         [ 2.24452282,  0.78093109,  2.89002836]])
  
  A `Rotation` instance can be indexed and sliced as if it were a single
  1D array or list:
  
  >>> r.as_quat()
  array([[0.        , 0.        , 0.70710678, 0.70710678],
         [0.        , 0.38268343, 0.        , 0.92387953],
         [0.39190384, 0.36042341, 0.43967974, 0.72331741]])
  >>> p = r[0]
  >>> p.as_dcm()
  array([[ 2.22044605e-16, -1.00000000e+00,  0.00000000e+00],
         [ 1.00000000e+00,  2.22044605e-16,  0.00000000e+00],
         [ 0.00000000e+00,  0.00000000e+00,  1.00000000e+00]])
  >>> q = r[1:3]
  >>> q.as_quat()
  array([[0.        , 0.38268343, 0.        , 0.92387953],
         [0.39190384, 0.36042341, 0.43967974, 0.72331741]])
  
  Multiple rotations can be composed using the `*` operator:
  
  >>> r1 = R.from_euler('z', 90, degrees=True)
  >>> r2 = R.from_rotvec([np.pi/4, 0, 0])
  >>> v = [1, 2, 3]
  >>> r2.apply(r1.apply(v))
  array([-2.        , -1.41421356,  2.82842712])
  >>> r3 = r2 * r1 # Note the order
  >>> r3.apply(v)
  array([-2.        , -1.41421356,  2.82842712])
  
  Finally, it is also possible to invert rotations:
  
  >>> r1 = R.from_euler('z', [90, 45], degrees=True)
  >>> r2 = r1.inv()
  >>> r2.as_euler('zyx', degrees=True)
  array([[-90.,   0.,   0.],
         [-45.,   0.,   0.]])
  
  These examples serve as an overview into the `Rotation` class and highlight
  major functionalities. For more thorough examples of the range of input and
  output formats supported, consult the individual method's examples.
class_docstr_tok: ["Rotation","in","3","dimensions",".","This","class","provides","an","interface","to","initialize","from","and","represent","rotations","with",":","-","Quaternions","-","Direction","Cosine","Matrices","-","Rotation","Vectors","-","Euler","angles","The","following","operations","on","rotations","are","supported",":","-","Application","on","vectors","-","Rotation","Composition","-","Rotation","Inversion","-","Rotation","Indexing","Indexing","within","a","rotation","is","supported","since","multiple","rotation","transforms","can","be","stored","within","a","single","`","Rotation","`","instance",".","To","create","`","Rotation","`","objects","use","`","from_","...","`","classmethods",",","`","__init__","`","is","not","supposed","to","be","used","directly",".","Methods","--","--","--","-","__len__","from_quat","from_dcm","from_rotvec","from_euler","as_quat","as_dcm","as_rotvec","as_euler","apply","__mul__","inv","__getitem__","random","Examples","--","--","--","--",">",">",">","from","scipy.spatial.transform","import","Rotation","as","R","A","`","Rotation","`","instance","can","be","initialized","in","any","of","the","above","formats","and","converted","to","any","of","the","others",".","The","underlying","object","is","independent","of","the","representation","used","for","initialization",".","Consider","a","counter-clockwise","rotation","of","90","degrees","about","the","z-axis",".","This","corresponds","to","the","following","quaternion","(","in","scalar-last","format",")",":",">",">",">","r","=","R.from_quat","(","[","0",",","0",",","np.sin","(","np.pi\/4",")",",","np.cos","(","np.pi\/4",")","]",")","The","rotation","can","be","expressed","in","any","of","the","other","formats",":",">",">",">","r.as_dcm","(",")","array","(","[","[","2.22044605e-16",",","-1.00000000e+00",",","0.00000000e+00","]",",","[","1.00000000e+00",",","2.22044605e-16",",","0.00000000e+00","]",",","[","0.00000000e+00",",","0.00000000e+00",",","1.00000000e+00","]","]",")",">",">",">","r.as_rotvec","(",")","array","(","[","0.",",","0.",",","1.57079633","]",")",">",">",">","r.as_euler","(","'zyx","'",",","degrees=True",")","array","(","[","90.",",","0.",",","0",".","]",")","The","same","rotation","can","be","initialized","using","a","direction","cosine","matrix",":",">",">",">","r","=","R.from_dcm","(","np.array","(","[","...","[","0",",","-1",",","0","]",",","...","[","1",",","0",",","0","]",",","...","[","0",",","0",",","1","]","]",")",")","Representation","in","other","formats",":",">",">",">","r.as_quat","(",")","array","(","[","0.",",","0.",",","0.70710678",",","0.70710678","]",")",">",">",">","r.as_rotvec","(",")","array","(","[","0.",",","0.",",","1.57079633","]",")",">",">",">","r.as_euler","(","'zyx","'",",","degrees=True",")","array","(","[","90.",",","0.",",","0",".","]",")","The","rotation","vector","corresponding","to","this","rotation","is","given","by",":",">",">",">","r","=","R.from_rotvec","(","np.pi\/2","*","np.array","(","[","0",",","0",",","1","]",")",")","Representation","in","other","formats",":",">",">",">","r.as_quat","(",")","array","(","[","0.",",","0.",",","0.70710678",",","0.70710678","]",")",">",">",">","r.as_dcm","(",")","array","(","[","[","2.22044605e-16",",","-1.00000000e+00",",","0.00000000e+00","]",",","[","1.00000000e+00",",","2.22044605e-16",",","0.00000000e+00","]",",","[","0.00000000e+00",",","0.00000000e+00",",","1.00000000e+00","]","]",")",">",">",">","r.as_euler","(","'zyx","'",",","degrees=True",")","array","(","[","90.",",","0.",",","0",".","]",")","The","`","from_euler","`","function","is","quite","flexible","in","the","range","of","input","formats","it","supports",".","Here","we","initialize","a","single","rotation","about","a","single","axis",":",">",">",">","r","=","R.from_euler","(","'","z","'",",","90",",","degrees=True",")","Again",",","the","object","is","representation","independent","and","can","be","converted","to","any","other","format",":",">",">",">","r.as_quat","(",")","array","(","[","0.",",","0.",",","0.70710678",",","0.70710678","]",")",">",">",">","r.as_dcm","(",")","array","(","[","[","2.22044605e-16",",","-1.00000000e+00",",","0.00000000e+00","]",",","[","1.00000000e+00",",","2.22044605e-16",",","0.00000000e+00","]",",","[","0.00000000e+00",",","0.00000000e+00",",","1.00000000e+00","]","]",")",">",">",">","r.as_rotvec","(",")","array","(","[","0.",",","0.",",","1.57079633","]",")","It","is","also","possible","to","initialize","multiple","rotations","in","a","single","instance","using","any","of","the","`","from_","...","`","functions",".","Here","we","initialize","a","stack","of","3","rotations","using","the","`","from_euler","`","function",":",">",">",">","r","=","R.from_euler","(","'zyx","'",",","[","...","[","90",",","0",",","0","]",",","...","[","0",",","45",",","0","]",",","...","[","45",",","60",",","30","]","]",",","degrees=True",")","The","other","representations","also","now","return","a","stack","of","3","rotations",".","For","example",":",">",">",">","r.as_quat","(",")","array","(","[","[","0.",",","0.",",","0.70710678",",","0.70710678","]",",","[","0.",",","0.38268343",",","0.",",","0.92387953","]",",","[","0.39190384",",","0.36042341",",","0.43967974",",","0.72331741","]","]",")","Applying","the","above","rotations","onto","a","vector",":",">",">",">","v","=","[","1",",","2",",","3","]",">",">",">","r.apply","(","v",")","array","(","[","[","-2.",",","1.",",","3",".","]",",","[","2.82842712",",","2.",",","1.41421356","]",",","[","2.24452282",",","0.78093109",",","2.89002836","]","]",")","A","`","Rotation","`","instance","can","be","indexed","and","sliced","as","if","it","were","a","single","1D","array","or","list",":",">",">",">","r.as_quat","(",")","array","(","[","[","0.",",","0.",",","0.70710678",",","0.70710678","]",",","[","0.",",","0.38268343",",","0.",",","0.92387953","]",",","[","0.39190384",",","0.36042341",",","0.43967974",",","0.72331741","]","]",")",">",">",">","p","=","r","[","0","]",">",">",">","p.as_dcm","(",")","array","(","[","[","2.22044605e-16",",","-1.00000000e+00",",","0.00000000e+00","]",",","[","1.00000000e+00",",","2.22044605e-16",",","0.00000000e+00","]",",","[","0.00000000e+00",",","0.00000000e+00",",","1.00000000e+00","]","]",")",">",">",">","q","=","r","[","1:3","]",">",">",">","q.as_quat","(",")","array","(","[","[","0.",",","0.38268343",",","0.",",","0.92387953","]",",","[","0.39190384",",","0.36042341",",","0.43967974",",","0.72331741","]","]",")","Multiple","rotations","can","be","composed","using","the","`","*","`","operator",":",">",">",">","r1","=","R.from_euler","(","'","z","'",",","90",",","degrees=True",")",">",">",">","r2","=","R.from_rotvec","(","[","np.pi\/4",",","0",",","0","]",")",">",">",">","v","=","[","1",",","2",",","3","]",">",">",">","r2.apply","(","r1.apply","(","v",")",")","array","(","[","-2.",",","-1.41421356",",","2.82842712","]",")",">",">",">","r3","=","r2","*","r1","#","Note","the","order",">",">",">","r3.apply","(","v",")","array","(","[","-2.",",","-1.41421356",",","2.82842712","]",")","Finally",",","it","is","also","possible","to","invert","rotations",":",">",">",">","r1","=","R.from_euler","(","'","z","'",",","[","90",",","45","]",",","degrees=True",")",">",">",">","r2","=","r1.inv","(",")",">",">",">","r2.as_euler","(","'zyx","'",",","degrees=True",")","array","(","[","[","-90.",",","0.",",","0",".","]",",","[","-45.",",","0.",",","0",".","]","]",")","These","examples","serve","as","an","overview","into","the","`","Rotation","`","class","and","highlight","major","functionalities",".","For","more","thorough","examples","of","the","range","of","input","and","output","formats","supported",",","consult","the","individual","method","'s","examples","."]
docstr: Estimate a rotation to match two sets of vectors.
  
  Find a rotation between frames A and B which best matches a set of unit
  vectors `a` and `b` observed in these frames. The following loss
  function is minimized to solve for the direction cosine matrix
  :math:`C`:
  
  .. math::
  
      L(C) = \frac{1}{2} \sum_{i = 1}^{n} w_i \lVert \mathbf{a}_i -
      C \mathbf{b}_i \rVert^2 ,
  
  where :math:`w_i`'s are the `weights` corresponding to each vector.
  
  The rotation is estimated using Markley's SVD method [1]_.
  
  Parameters
  ----------
  a : array_like, shape (N, 3)
      Vector components observed in initial frame A. Each row of `a`
      denotes a vector.
  b : array_like, shape (N, 3)
      Vector components observed in another frame B. Each row of `b`
      denotes a vector.
  weights : array_like shape (N,), optional
      Weights describing the relative importance of the vectors in
      `a`. If None (default), then all values in `weights` are assumed to
      be equal.
  normalized : boolean, optional
      If True, assume input vectors `a` and `b` to have unit norm. If
      False, normalize `a` and `b` before estimating rotation. Default
      is False.
  
  Returns
  -------
  estimated_rotation : `Rotation` instance
      Best estimate of the rotation that transforms `b` to `a`.
  sensitivity_matrix : `numpy.ndarray`, shape (3, 3)
      Scaled covariance of the attitude errors expressed as the small
      rotation vector of frame A. Multiply with harmonic mean [3]_ of
      variance in each observation to get true covariance matrix. The
      error model is detailed in [2]_.
  
  References
  ----------
  .. [1] F. Landis Markley,
          "Attitude determination using vector observations: a fast
          optimal matrix algorithm", Journal of Astronautical Sciences,
          Vol. 41, No.2, 1993, pp. 261-280.
  .. [2] F. Landis Markley,
          "Attitude determination using vector observations and the
          Singular Value Decomposition", Journal of Astronautical
          Sciences, Vol. 38, No.3, 1988, pp. 245-258.
  .. [3] `Harmonic Mean <https://en.wikipedia.org/wiki/Harmonic_mean>`_
docstr_tok: ["Estimate","a","rotation","to","match","two","sets","of","vectors",".","Find","a","rotation","between","frames","A","and","B","which","best","matches","a","set","of","unit","vectors","`","a","`","and","`","b","`","observed","in","these","frames",".","The","following","loss","function","is","minimized","to","solve","for","the","direction","cosine","matrix",":","math",":","`","C","`",":","..","math",":",":","L","(","C",")","=","\\frac","{","1","}","{","2","}","\\sum_","{","i","=","1","}","^","{","n","}","w_i","\\lVert","\\mathbf","{","a","}","_i","-","C","\\mathbf","{","b","}","_i","\\rVert^2",",","where",":","math",":","`","w_i","`","'s","are","the","`","weights","`","corresponding","to","each","vector",".","The","rotation","is","estimated","using","Markley","'s","SVD","method","[","1","]","_.","Parameters","--","--","--","--","--","a",":","array_like",",","shape","(","N",",","3",")","Vector","components","observed","in","initial","frame","A",".","Each","row","of","`","a","`","denotes","a","vector",".","b",":","array_like",",","shape","(","N",",","3",")","Vector","components","observed","in","another","frame","B",".","Each","row","of","`","b","`","denotes","a","vector",".","weights",":","array_like","shape","(","N",",",")",",","optional","Weights","describing","the","relative","importance","of","the","vectors","in","`","a","`",".","If","None","(","default",")",",","then","all","values","in","`","weights","`","are","assumed","to","be","equal",".","normalized",":","boolean",",","optional","If","True",",","assume","input","vectors","`","a","`","and","`","b","`","to","have","unit","norm",".","If","False",",","normalize","`","a","`","and","`","b","`","before","estimating","rotation",".","Default","is","False",".","Returns","--","--","--","-","estimated_rotation",":","`","Rotation","`","instance","Best","estimate","of","the","rotation","that","transforms","`","b","`","to","`","a","`",".","sensitivity_matrix",":","`","numpy.ndarray","`",",","shape","(","3",",","3",")","Scaled","covariance","of","the","attitude","errors","expressed","as","the","small","rotation","vector","of","frame","A",".","Multiply","with","harmonic","mean","[","3","]","_","of","variance","in","each","observation","to","get","true","covariance","matrix",".","The","error","model","is","detailed","in","[","2","]","_.","References","--","--","--","--","--","..","[","1","]","F.","Landis","Markley",",","``","Attitude","determination","using","vector","observations",":","a","fast","optimal","matrix","algorithm","''",",","Journal","of","Astronautical","Sciences",",","Vol",".","41",",","No.2",",","1993",",","pp",".","261-280",".","..","[","2","]","F.","Landis","Markley",",","``","Attitude","determination","using","vector","observations","and","the","Singular","Value","Decomposition","''",",","Journal","of","Astronautical","Sciences",",","Vol",".","38",",","No.3",",","1988",",","pp",".","245-258",".","..","[","3","]","`","Harmonic","Mean","<","https",":","\/\/en.wikipedia.org\/wiki\/Harmonic_mean",">","`","_"]
code: def match_vectors(cls, a, b, weights=None, normalized=False):
      """Estimate a rotation to match two sets of vectors.
  
      Find a rotation between frames A and B which best matches a set of unit
      vectors `a` and `b` observed in these frames. The following loss
      function is minimized to solve for the direction cosine matrix
      :math:`C`:
  
      .. math::
  
          L(C) = \\frac{1}{2} \\sum_{i = 1}^{n} w_i \\lVert \\mathbf{a}_i -
          C \\mathbf{b}_i \\rVert^2 ,
  
      where :math:`w_i`'s are the `weights` corresponding to each vector.
  
      The rotation is estimated using Markley's SVD method [1]_.
  
      Parameters
      ----------
      a : array_like, shape (N, 3)
          Vector components observed in initial frame A. Each row of `a`
          denotes a vector.
      b : array_like, shape (N, 3)
          Vector components observed in another frame B. Each row of `b`
          denotes a vector.
      weights : array_like shape (N,), optional
          Weights describing the relative importance of the vectors in
          `a`. If None (default), then all values in `weights` are assumed to
          be equal.
      normalized : boolean, optional
          If True, assume input vectors `a` and `b` to have unit norm. If
          False, normalize `a` and `b` before estimating rotation. Default
          is False.
  
      Returns
      -------
      estimated_rotation : `Rotation` instance
          Best estimate of the rotation that transforms `b` to `a`.
      sensitivity_matrix : `numpy.ndarray`, shape (3, 3)
          Scaled covariance of the attitude errors expressed as the small
          rotation vector of frame A. Multiply with harmonic mean [3]_ of
          variance in each observation to get true covariance matrix. The
          error model is detailed in [2]_.
  
      References
      ----------
      .. [1] F. Landis Markley,
              "Attitude determination using vector observations: a fast
              optimal matrix algorithm", Journal of Astronautical Sciences,
              Vol. 41, No.2, 1993, pp. 261-280.
      .. [2] F. Landis Markley,
              "Attitude determination using vector observations and the
              Singular Value Decomposition", Journal of Astronautical
              Sciences, Vol. 38, No.3, 1988, pp. 245-258.
      .. [3] `Harmonic Mean <https://en.wikipedia.org/wiki/Harmonic_mean>`_
  
      """
      a = np.asarray(a)
      if a.ndim != 2 or a.shape[-1] != 3:
          raise ValueError(
              "Expected input `a` to have shape (N, 3), "
              "got {}".format(a.shape)
          )
      b = np.asarray(b)
      if b.ndim != 2 or b.shape[-1] != 3:
          raise ValueError(
              "Expected input `b` to have shape (N, 3), "
              "got {}.".format(b.shape)
          )
  
      if a.shape != b.shape:
          raise ValueError(
              "Expected inputs `a` and `b` to have same shapes"
              ", got {} and {} respectively.".format(a.shape, b.shape)
          )
  
      if b.shape[0] == 1:
          raise ValueError(
              "Rotation cannot be estimated using a single " "vector."
          )
  
      if weights is None:
          weights = np.ones(b.shape[0])
      else:
          weights = np.asarray(weights)
          if weights.ndim != 1:
              raise ValueError(
                  "Expected `weights` to be 1 dimensional, got "
                  "shape {}.".format(weights.shape)
              )
          if weights.shape[0] != b.shape[0]:
              raise ValueError(
                  "Expected `weights` to have number of values "
                  "equal to number of input vectors, got "
                  "{} values and {} vectors.".format(
                      weights.shape[0], b.shape[0]
                  )
              )
      weights = weights / np.sum(weights)
  
      if not normalized:
          a = a / scipy.linalg.norm(a, axis=1)[:, None]
          b = b / scipy.linalg.norm(b, axis=1)[:, None]
  
      B = np.einsum("ji,jk->ik", weights[:, None] * a, b)
      u, s, vh = np.linalg.svd(B)
      C = np.dot(u, vh)
  
      zeta = (s[0] + s[1]) * (s[1] + s[2]) * (s[2] + s[0])
      if np.abs(zeta) <= 1e-16:
          raise ValueError(
              "Three component error vector has infinite "
              "covariance. It is impossible to determine the "
              "rotation uniquely."
          )
  
      kappa = s[0] * s[1] + s[1] * s[2] + s[2] * s[0]
      sensitivity = (kappa * np.eye(3) + np.dot(B, B.T)) / (
          zeta * a.shape[0]
      )
      return cls.from_dcm(C), sensitivity
  
imports: from __future__ import division, print_function, absolute_import
  import re
  import warnings
  import numpy
  import scipy.linalg
  from scipy._lib._util import check_random_state
label_desc: Use image node_id 16 for calling the Rotation obj's underlying member method code with example usage: obj.match_vectors(cls, a, b, weights, normalized) and returns: cls,  sensitivity