
    \h{                     
   S SK Jr  S SKJr  S SKJr  S SKJrJrJ	r	J
r
  S SKJrJr  S SKJr  S SKJrJrJr  S SKJrJr  S S	KJr  S S
KJr  S SKJr  S SKJrJ r   S SK!J"r"  S SK#J$r$J%r%  S SK&J'r'  S SK(J)r)  S r*S r+ " S S\"5      r,g)    )Rational)S)is_eq)	conjugateimresign)explog)sqrt)acosasinatan2)cossin)trigsimp	integrate)MutableDenseMatrix)sympify_sympify)Expr)	fuzzy_notfuzzy_or)as_int)prec_to_dpsc                     Ubt  UR                   (       ab  UR                  SL a  [        S5      e[        S U  5       5      nU(       a.  [	        US-  [        S U  5       5      5      SL a  [        S5      egggg)z$validate if input norm is consistentNFzInput norm must be positive.c              3   b   #    U  H%  oR                   =(       a    UR                  S L v   M'     g7f)TN)	is_numberis_real.0is     Q/var/www/auris/envauris/lib/python3.13/site-packages/sympy/algebras/quaternion.py	<genexpr>_check_norm.<locals>.<genexpr>   s#     L8a9		T(998s   -/   c              3   *   #    U  H	  oS -  v   M     g7f)r'   N r!   s     r$   r%   r&      s     +C(QqD(s   zIncompatible value for norm.)r   is_positive
ValueErrorallr   sum)elementsnorm	numericals      r$   _check_normr1      st    DNNu$;<<L8LL	tQw+C(+C(CDM;<< N9 +    c                    [        U 5      [        :w  a  [        S5      e[        U 5      S:w  a  [        SR	                  U 5      5      eU R                  5       nU R                  5       nU(       d  U(       d  [        S5      eU R                  5       u  p4nX4:X  d  XE:X  a  [        S5      e[        U 5      [        S5      -
  nU(       a)  [        SR	                  SR                  U5      5      5      eU$ )	zGvalidate seq and return True if seq is lowercase and False if uppercasezExpected seq to be a string.   zExpected 3 axes, got `{}`.zkseq must either be fully uppercase (for extrinsic rotations), or fully lowercase, for intrinsic rotations).z"Consecutive axes must be differentxyzXYZzNExpected axes from `seq` to be from ['x', 'y', 'z'] or ['X', 'Y', 'Z'], got {} )
typestrr+   lenformatisupperislowerlowersetjoin)seq	intrinsic	extrinsicr#   jkbads          r$   _is_extrinsicrF      s    CyC788
3x1}5<<SABBII ' ( 	( iikGA!	AF=>>
c(S]
"C
 ""(&"68 	8 r2   c                     ^  \ rS rSrSrSrSrS=U 4S jjrS r\	S 5       r
\	S 5       r\	S	 5       r\	S
 5       r\	S 5       r\	S 5       r\	S 5       rS>S jr\S 5       r\S 5       rS?S jr\S 5       r\S 5       rS rS rS rS rS rS rS rS rS r S r!S r"S r#S  r$\%S! 5       r&S" r'S# r(S$ r)S% r*S& r+S' r,S( r-S) r.S* r/S+ r0S, r1\%S- 5       r2S. r3S@S/ jr4S0 r5S1 r6S2 r7S3 r8S4 r9S5 r:S6 r;\S7 5       r<S8 r=S9 r>S: r?S; r@S<rAU =rB$ )A
Quaternion:   af  Provides basic quaternion operations.
Quaternion objects can be instantiated as ``Quaternion(a, b, c, d)``
as in $q = a + bi + cj + dk$.

Parameters
==========

norm : None or number
    Pre-defined quaternion norm. If a value is given, Quaternion.norm
    returns this pre-defined value instead of calculating the norm

Examples
========

>>> from sympy import Quaternion
>>> q = Quaternion(1, 2, 3, 4)
>>> q
1 + 2*i + 3*j + 4*k

Quaternions over complex fields can be defined as:

>>> from sympy import Quaternion
>>> from sympy import symbols, I
>>> x = symbols('x')
>>> q1 = Quaternion(x, x**3, x, x**2, real_field = False)
>>> q2 = Quaternion(3 + 4*I, 2 + 5*I, 0, 7 + 8*I, real_field = False)
>>> q1
x + x**3*i + x*j + x**2*k
>>> q2
(3 + 4*I) + (2 + 5*I)*i + 0*j + (7 + 8*I)*k

Defining symbolic unit quaternions:

>>> from sympy import Quaternion
>>> from sympy.abc import w, x, y, z
>>> q = Quaternion(w, x, y, z, norm=1)
>>> q
w + x*i + y*j + z*k
>>> q.norm()
1

References
==========

.. [1] https://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/
.. [2] https://en.wikipedia.org/wiki/Quaternion

g      &@Fc                    > [        [        XX445      u  pp4[        S XX44 5       5      (       a  [        S5      e[        TU ]  XX#U5      nXWl        UR                  U5        U$ )Nc              3   <   #    U  H  oR                   S L v   M     g7f)FN)is_commutativer!   s     r$   r%   %Quaternion.__new__.<locals>.<genexpr>r   s     ?,Q5(,s   z arguments have to be commutative)mapr   anyr+   super__new___real_fieldset_norm)	clsabcd
real_fieldr/   obj	__class__s	           r$   rQ   Quaternion.__new__o   s`    1,/
a?1,????@@gocaA.$T
r2   c                 R    [        U5      n[        U R                  U5        Xl        g)a  Sets norm of an already instantiated quaternion.

Parameters
==========

norm : None or number
    Pre-defined quaternion norm. If a value is given, Quaternion.norm
    returns this pre-defined value instead of calculating the norm

Examples
========

>>> from sympy import Quaternion
>>> from sympy.abc import a, b, c, d
>>> q = Quaternion(a, b, c, d)
>>> q.norm()
sqrt(a**2 + b**2 + c**2 + d**2)

Setting the norm:

>>> q.set_norm(1)
>>> q.norm()
1

Removing set norm:

>>> q.set_norm(None)
>>> q.norm()
sqrt(a**2 + b**2 + c**2 + d**2)

N)r   r1   args_norm)selfr/   s     r$   rS   Quaternion.set_normy   s!    @ t}DIIt$
r2   c                      U R                   S   $ )Nr   r^   r`   s    r$   rU   Quaternion.a       yy|r2   c                      U R                   S   $ )N   rc   rd   s    r$   rV   Quaternion.b   rf   r2   c                      U R                   S   $ )Nr'   rc   rd   s    r$   rW   Quaternion.c   rf   r2   c                      U R                   S   $ )Nr4   rc   rd   s    r$   rX   Quaternion.d   rf   r2   c                     U R                   $ N)rR   rd   s    r$   rY   Quaternion.real_field   s    r2   c           	         [        U R                  U R                  * U R                  * U R                  * /U R                  U R                  U R                  * U R                  /U R                  U R                  U R                  U R                  * /U R                  U R                  * U R                  U R                  //5      $ )a  Returns 4 x 4 Matrix equivalent to a Hamilton product from the
left. This can be useful when treating quaternion elements as column
vectors. Given a quaternion $q = a + bi + cj + dk$ where a, b, c and d
are real numbers, the product matrix from the left is:

.. math::

    M  =  \begin{bmatrix} a  &-b  &-c  &-d \\
                          b  & a  &-d  & c \\
                          c  & d  & a  &-b \\
                          d  &-c  & b  & a \end{bmatrix}

Examples
========

>>> from sympy import Quaternion
>>> from sympy.abc import a, b, c, d
>>> q1 = Quaternion(1, 0, 0, 1)
>>> q2 = Quaternion(a, b, c, d)
>>> q1.product_matrix_left
Matrix([
[1, 0,  0, -1],
[0, 1, -1,  0],
[0, 1,  1,  0],
[1, 0,  0,  1]])

>>> q1.product_matrix_left * q2.to_Matrix()
Matrix([
[a - d],
[b - c],
[b + c],
[a + d]])

This is equivalent to:

>>> (q1 * q2).to_Matrix()
Matrix([
[a - d],
[b - c],
[b + c],
[a + d]])
MatrixrU   rV   rW   rX   rd   s    r$   product_matrix_leftQuaternion.product_matrix_left   s    X $&&466'DFF73$&&$&&1$&&1$&&$&&$&&1	3 4 	4r2   c           	         [        U R                  U R                  * U R                  * U R                  * /U R                  U R                  U R                  U R                  * /U R                  U R                  * U R                  U R                  /U R                  U R                  U R                  * U R                  //5      $ )a%  Returns 4 x 4 Matrix equivalent to a Hamilton product from the
right. This can be useful when treating quaternion elements as column
vectors. Given a quaternion $q = a + bi + cj + dk$ where a, b, c and d
are real numbers, the product matrix from the left is:

.. math::

    M  =  \begin{bmatrix} a  &-b  &-c  &-d \\
                          b  & a  & d  &-c \\
                          c  &-d  & a  & b \\
                          d  & c  &-b  & a \end{bmatrix}


Examples
========

>>> from sympy import Quaternion
>>> from sympy.abc import a, b, c, d
>>> q1 = Quaternion(a, b, c, d)
>>> q2 = Quaternion(1, 0, 0, 1)
>>> q2.product_matrix_right
Matrix([
[1, 0, 0, -1],
[0, 1, 1, 0],
[0, -1, 1, 0],
[1, 0, 0, 1]])

Note the switched arguments: the matrix represents the quaternion on
the right, but is still considered as a matrix multiplication from the
left.

>>> q2.product_matrix_right * q1.to_Matrix()
Matrix([
[ a - d],
[ b + c],
[-b + c],
[ a + d]])

This is equivalent to:

>>> (q1 * q2).to_Matrix()
Matrix([
[ a - d],
[ b + c],
[-b + c],
[ a + d]])
rr   rd   s    r$   product_matrix_rightQuaternion.product_matrix_right   s    b $&&466'DFF73$&&1$&&$&&$&&1$&&$&&1	3 4 	4r2   c                 j    U(       a  [        U R                  SS 5      $ [        U R                  5      $ )a  Returns elements of quaternion as a column vector.
By default, a ``Matrix`` of length 4 is returned, with the real part as the
first element.
If ``vector_only`` is ``True``, returns only imaginary part as a Matrix of
length 3.

Parameters
==========

vector_only : bool
    If True, only imaginary part is returned.
    Default value: False

Returns
=======

Matrix
    A column vector constructed by the elements of the quaternion.

Examples
========

>>> from sympy import Quaternion
>>> from sympy.abc import a, b, c, d
>>> q = Quaternion(a, b, c, d)
>>> q
a + b*i + c*j + d*k

>>> q.to_Matrix()
Matrix([
[a],
[b],
[c],
[d]])


>>> q.to_Matrix(vector_only=True)
Matrix([
[b],
[c],
[d]])

rh   N)rs   r^   )r`   vector_onlys     r$   	to_MatrixQuaternion.to_Matrix  s,    X $))AB-(($))$$r2   c                     [        U5      nUS:w  a   US:w  a  [        SR                  U5      5      eUS:X  a  [        S/UQ76 $ [        U6 $ )aK  Returns quaternion from elements of a column vector`.
If vector_only is True, returns only imaginary part as a Matrix of
length 3.

Parameters
==========

elements : Matrix, list or tuple of length 3 or 4. If length is 3,
    assume real part is zero.
    Default value: False

Returns
=======

Quaternion
    A quaternion created from the input elements.

Examples
========

>>> from sympy import Quaternion
>>> from sympy.abc import a, b, c, d
>>> q = Quaternion.from_Matrix([a, b, c, d])
>>> q
a + b*i + c*j + d*k

>>> q = Quaternion.from_Matrix([b, c, d])
>>> q
0 + b*i + c*j + d*k

r4      z7Input elements must have length 3 or 4, got {} elementsr   )r9   r+   r:   rH   )rT   r.   lengths      r$   from_MatrixQuaternion.from_MatrixK  sZ    B XQ;6Q; ((.v8 8 Q;a+(++x((r2   c                    [        U5      S:w  a  [        S5      e[        U5      nUR                  5       u  pEnS Vs/ s H  owU:X  a  SOSPM     nnS Vs/ s H  owU:X  a  SOSPM     n	nS Vs/ s H  owU:X  a  SOSPM     n
nU R	                  XS   5      nU R	                  XS   5      nU R	                  XS   5      nU(       a  [        X-  U-  5      $ [        X-  U-  5      $ s  snf s  snf s  snf )a  Returns quaternion equivalent to rotation represented by the Euler
angles, in the sequence defined by ``seq``.

Parameters
==========

angles : list, tuple or Matrix of 3 numbers
    The Euler angles (in radians).
seq : string of length 3
    Represents the sequence of rotations.
    For extrinsic rotations, seq must be all lowercase and its elements
    must be from the set ``{'x', 'y', 'z'}``
    For intrinsic rotations, seq must be all uppercase and its elements
    must be from the set ``{'X', 'Y', 'Z'}``

Returns
=======

Quaternion
    The normalized rotation quaternion calculated from the Euler angles
    in the given sequence.

Examples
========

>>> from sympy import Quaternion
>>> from sympy import pi
>>> q = Quaternion.from_euler([pi/2, 0, 0], 'xyz')
>>> q
sqrt(2)/2 + sqrt(2)/2*i + 0*j + 0*k

>>> q = Quaternion.from_euler([0, pi/2, pi] , 'zyz')
>>> q
0 + (-sqrt(2)/2)*i + 0*j + sqrt(2)/2*k

>>> q = Quaternion.from_euler([0, pi/2, pi] , 'ZYZ')
>>> q
0 + sqrt(2)/2*i + 0*j + sqrt(2)/2*k

r4   z3 angles must be given.xyzrh   r   r'   )r9   r+   rF   r=   from_axis_angler   )rT   anglesr@   rB   r#   rC   rD   neiejekqiqjqks                 r$   
from_eulerQuaternion.from_eulerv  s    V v;!677!#&	))+a +00%Q6aq %0*/0%Q6aq %0*/0%Q6aq %0   AY/  AY/  AY/BGbL))BGbL)) 100s   C'C,/C1c           	         U R                  5       (       a  [        S5      e/ SQn[        U5      nUR                  5       u  pgnSR	                  U5      S-   nSR	                  U5      S-   nSR	                  U5      S-   nU(       d  XpXh:H  n	U	(       a  SU-
  U-
  nXg-
  Xx-
  -  X-
  -  S-  n
U R
                  U R                  U R                  U R                  /nUS   nX   nX   nX   U
-  nU	(       d  X-
  X-   X-   X-
  4u  ppU(       av  U	(       a6  U R                  5       S-  n[        X-  X-  -   X-  -
  X-  -
  U-  5      US'   OSU R                  5       S-  -  n[        X-  X-  -   X-  -
  X-  -
  U-  5      US'   OWS[        [        X-  X-  -   5      [        X-  X-  -   5      5      -  US'   U	(       d  US==   [        R                  S-  -  ss'   Sn[!        U[        R"                  5      (       a!  [!        U[        R"                  5      (       a  Sn[!        U[        R"                  5      (       a!  [!        U[        R"                  5      (       a  SnUS:X  aw  U(       a5  [        X5      [        X5      -   US'   [        X5      [        X5      -
  US'   O[        X-  X-  -   X-  X-  -
  5      US'   [        X-  X-  -
  X-  X-  -   5      US'   Oc[        R"                  USU(       + -  '   US:X  a  S[        X5      -  USU-  '   O-S[        X5      -  USU-  '   USU-  ==   U(       a  SOS-  ss'   U	(       d  US==   U
-  ss'   U(       a  [%        US	S	S2   5      $ [%        U5      $ )
a  Returns Euler angles representing same rotation as the quaternion,
in the sequence given by ``seq``. This implements the method described
in [1]_.

For degenerate cases (gymbal lock cases), the third angle is
set to zero.

Parameters
==========

seq : string of length 3
    Represents the sequence of rotations.
    For extrinsic rotations, seq must be all lowercase and its elements
    must be from the set ``{'x', 'y', 'z'}``
    For intrinsic rotations, seq must be all uppercase and its elements
    must be from the set ``{'X', 'Y', 'Z'}``

angle_addition : bool
    When True, first and third angles are given as an addition and
    subtraction of two simpler ``atan2`` expressions. When False, the
    first and third angles are each given by a single more complicated
    ``atan2`` expression. This equivalent expression is given by:

    .. math::

        \operatorname{atan_2} (b,a) \pm \operatorname{atan_2} (d,c) =
        \operatorname{atan_2} (bc\pm ad, ac\mp bd)

    Default value: True

avoid_square_root : bool
    When True, the second angle is calculated with an expression based
    on ``acos``, which is slightly more complicated but avoids a square
    root. When False, second angle is calculated with ``atan2``, which
    is simpler and can be better for numerical reasons (some
    numerical implementations of ``acos`` have problems near zero).
    Default value: False


Returns
=======

Tuple
    The Euler angles calculated from the quaternion

Examples
========

>>> from sympy import Quaternion
>>> from sympy.abc import a, b, c, d
>>> euler = Quaternion(a, b, c, d).to_euler('zyz')
>>> euler
(-atan2(-b, c) + atan2(d, a),
 2*atan2(sqrt(b**2 + c**2), sqrt(a**2 + d**2)),
 atan2(-b, c) + atan2(d, a))


References
==========

.. [1] https://doi.org/10.1371/journal.pone.0276302

z(Cannot convert a quaternion with norm 0.)r   r   r   r   rh      r'   r   N)is_zero_quaternionr+   rF   r=   indexrU   rV   rW   rX   r/   r   r   r   r   r   Pir   Zerotuple)r`   r@   angle_additionavoid_square_rootr   rB   r#   rC   rD   	symmetricr	   r.   rU   rV   rW   rX   n2cases                     r$   to_eulerQuaternion.to_euler  s4   @ ""$$GHH!#&	))+a KKNQKKNQKKNQq F	A	A !% AE*a/ FFDFFDFFDFF3QKKKK$quae3JA!YY[!^ !%!%-!%"7!%"?2!EFq	a' !%!%-!%"7!%"?2!EFq	E$ququ}"5tAEAEM7JKKF1Iq	QTTAX%	 AFFa 0 0DAFFa 0 0D19!!K%+5q	!!K%+5q	!!#)QS13Y7q	!!#)QS13Y7q	 +,&&F1I&'qy()E!Kq9}%()E!Kq9}%q9}%	"qA% 1II"&&= r2   c                     Uu  p4n[        US-  US-  -   US-  -   5      nX6-  XF-  XV-  pTn[        U[        R                  -  5      n[	        U[        R                  -  5      nX7-  n	XG-  n
XW-  nU " XX5      $ )a8  Returns a rotation quaternion given the axis and the angle of rotation.

Parameters
==========

vector : tuple of three numbers
    The vector representation of the given axis.
angle : number
    The angle by which axis is rotated (in radians).

Returns
=======

Quaternion
    The normalized rotation quaternion calculated from the given axis and the angle of rotation.

Examples
========

>>> from sympy import Quaternion
>>> from sympy import pi, sqrt
>>> q = Quaternion.from_axis_angle((sqrt(3)/3, sqrt(3)/3, sqrt(3)/3), 2*pi/3)
>>> q
1/2 + 1/2*i + 1/2*j + 1/2*k

r'   )r   r   r   Halfr   )rT   vectoranglexyzr/   srU   rV   rW   rX   s               r$   r   Quaternion.from_axis_angleD  s    8 	qAqD1a4K!Q$&'XqxqEEE 1r2   c                    UR                  5       [        SS5      -  n[        X!S   -   US   -   US   -   5      S-  n[        X!S   -   US   -
  US   -
  5      S-  n[        X!S   -
  US   -   US   -
  5      S-  n[        X!S   -
  US   -
  US   -   5      S-  nU[        US   US   -
  5      -  nU[        US	   US
   -
  5      -  nU[        US   US   -
  5      -  n[	        X4XV5      $ )a  Returns the equivalent quaternion of a matrix. The quaternion will be normalized
only if the matrix is special orthogonal (orthogonal and det(M) = 1).

Parameters
==========

M : Matrix
    Input matrix to be converted to equivalent quaternion. M must be special
    orthogonal (orthogonal and det(M) = 1) for the quaternion to be normalized.

Returns
=======

Quaternion
    The quaternion equivalent to given matrix.

Examples
========

>>> from sympy import Quaternion
>>> from sympy import Matrix, symbols, cos, sin, trigsimp
>>> x = symbols('x')
>>> M = Matrix([[cos(x), -sin(x), 0], [sin(x), cos(x), 0], [0, 0, 1]])
>>> q = trigsimp(Quaternion.from_rotation_matrix(M))
>>> q
sqrt(2)*sqrt(cos(x) + 1)/2 + 0*i + 0*j + sqrt(2 - 2*cos(x))*sign(sin(x))/2*k

rh   r4   )r   r   )rh   rh   )r'   r'   r'   )r'   rh   )rh   r'   )r   r'   )r'   r   )rh   r   )r   rh   )detr   r   r	   rH   )rT   MabsQrU   rV   rW   rX   s          r$   from_rotation_matrixQuaternion.from_rotation_matrixo  s   > uuwA&$!D')AdG34q8$!D')AdG34q8$!D')AdG34q8$!D')AdG34q8QtWqw&''QtWqw&''QtWqw&''!%%r2   c                 $    U R                  U5      $ ro   addr`   others     r$   __add__Quaternion.__add__      xxr2   c                 $    U R                  U5      $ ro   r   r   s     r$   __radd__Quaternion.__radd__  r   r2   c                 *    U R                  US-  5      $ Nr   r   r   s     r$   __sub__Quaternion.__sub__  s    xxb!!r2   c                 8    U R                  U [        U5      5      $ ro   _generic_mulr   r   s     r$   __mul__Quaternion.__mul__  s      x77r2   c                 8    U R                  [        U5      U 5      $ ro   r   r   s     r$   __rmul__Quaternion.__rmul__  s      %$77r2   c                 $    U R                  U5      $ ro   )pow)r`   ps     r$   __pow__Quaternion.__pow__  s    xx{r2   c                 v    [        U R                  * U R                  * U R                  * U R                  * 5      $ ro   )rH   rU   rV   rW   rX   rd   s    r$   __neg__Quaternion.__neg__  s+    466'DFF7TVVGdffW==r2   c                 $    U [        U5      S-  -  $ r   r   r   s     r$   __truediv__Quaternion.__truediv__  s    genb(((r2   c                 $    [        U5      U S-  -  $ r   r   r   s     r$   __rtruediv__Quaternion.__rtruediv__  s    u~b((r2   c                      U R                   " U6 $ ro   r   r`   r^   s     r$   _eval_IntegralQuaternion._eval_Integral  s    ~~t$$r2   c           
          UR                  SS5        U R                  " U R                   Vs/ s H  o3R                  " U0 UD6PM     sn6 $ s  snf )NevaluateT)
setdefaultfuncr^   diff)r`   symbolskwargsrU   s       r$   r   Quaternion.diff  sC    *d+yy		J	!6675f5	JKKJs   Ac                    U n[        U5      n[        U[        5      (       d  UR                  (       a_  UR                  (       aN  [        [        U5      UR                  -   [        U5      UR                  -   UR                  UR                  5      $ UR                  (       a9  [        UR                  U-   UR                  UR                  UR                  5      $ [        S5      e[        UR                  UR                  -   UR                  UR                  -   UR                  UR                  -   UR                  UR                  -   5      $ )a  Adds quaternions.

Parameters
==========

other : Quaternion
    The quaternion to add to current (self) quaternion.

Returns
=======

Quaternion
    The resultant quaternion after adding self to other

Examples
========

>>> from sympy import Quaternion
>>> from sympy import symbols
>>> q1 = Quaternion(1, 2, 3, 4)
>>> q2 = Quaternion(5, 6, 7, 8)
>>> q1.add(q2)
6 + 8*i + 10*j + 12*k
>>> q1 + 5
6 + 2*i + 3*j + 4*k
>>> x = symbols('x', real = True)
>>> q1.add(x)
(x + 1) + 2*i + 3*j + 4*k

Quaternions over complex fields :

>>> from sympy import Quaternion
>>> from sympy import I
>>> q3 = Quaternion(3 + 4*I, 2 + 5*I, 0, 7 + 8*I, real_field = False)
>>> q3.add(2 + 3*I)
(5 + 7*I) + (2 + 5*I)*i + 0*j + (7 + 8*I)*k

z<Only commutative expressions can be added with a Quaternion.)r   
isinstancerH   rY   
is_complexr   rU   r   rV   rW   rX   rL   r+   )r`   r   q1q2s       r$   r   Quaternion.add  s    N U^ "j))}}!"R&244-B"$$bddKK""!"$$)RTT244>> !_``"$$+rttbdd{BDD244KDDB! " 	"r2   c                 8    U R                  U [        U5      5      $ )a  Multiplies quaternions.

Parameters
==========

other : Quaternion or symbol
    The quaternion to multiply to current (self) quaternion.

Returns
=======

Quaternion
    The resultant quaternion after multiplying self with other

Examples
========

>>> from sympy import Quaternion
>>> from sympy import symbols
>>> q1 = Quaternion(1, 2, 3, 4)
>>> q2 = Quaternion(5, 6, 7, 8)
>>> q1.mul(q2)
(-60) + 12*i + 30*j + 24*k
>>> q1.mul(2)
2 + 4*i + 6*j + 8*k
>>> x = symbols('x', real = True)
>>> q1.mul(x)
x + 2*x*i + 3*x*j + 4*x*k

Quaternions over complex fields :

>>> from sympy import Quaternion
>>> from sympy import I
>>> q3 = Quaternion(3 + 4*I, 2 + 5*I, 0, 7 + 8*I, real_field = False)
>>> q3.mul(2 + 3*I)
(2 + 3*I)*(3 + 4*I) + (2 + 3*I)*(2 + 5*I)*i + 0*j + (2 + 3*I)*(7 + 8*I)*k

r   r   s     r$   mulQuaternion.mul  s    N   x77r2   c                    [        U [        5      (       d  [        U[        5      (       d  X-  $ [        U [        5      (       d  UR                  (       a4  U R                  (       a#  [        [	        U 5      [        U 5      SS5      U-  $ U R                  (       a>  [        XR                  -  XR                  -  XR                  -  XR                  -  5      $ [        S5      e[        U[        5      (       d  U R                  (       a4  UR                  (       a#  U [        [	        U5      [        U5      SS5      -  $ UR                  (       a>  [        XR                  -  XR                  -  XR                  -  XR                  -  5      $ [        S5      eU R                  c  UR                  c  SnO!U R                  5       UR                  5       -  n[        U R                  * UR                  -  U R                  UR                  -  -
  U R                  UR                  -  -
  U R                  UR                  -  -   U R                  UR                  -  U R                  UR                  -  -   U R                  UR                  -  -
  U R                  UR                  -  -   U R                  * UR                  -  U R                  UR                  -  -   U R                  UR                  -  -   U R                  UR                  -  -   U R                  UR                  -  U R                  UR                  -  -
  U R                  UR                  -  -   U R                  UR                  -  -   US9$ )a  Generic multiplication.

Parameters
==========

q1 : Quaternion or symbol
q2 : Quaternion or symbol

It is important to note that if neither q1 nor q2 is a Quaternion,
this function simply returns q1 * q2.

Returns
=======

Quaternion
    The resultant quaternion after multiplying q1 and q2

Examples
========

>>> from sympy import Quaternion
>>> from sympy import Symbol, S
>>> q1 = Quaternion(1, 2, 3, 4)
>>> q2 = Quaternion(5, 6, 7, 8)
>>> Quaternion._generic_mul(q1, q2)
(-60) + 12*i + 30*j + 24*k
>>> Quaternion._generic_mul(q1, S(2))
2 + 4*i + 6*j + 8*k
>>> x = Symbol('x', real = True)
>>> Quaternion._generic_mul(q1, x)
x + 2*x*i + 3*x*j + 4*x*k

Quaternions over complex fields :

>>> from sympy import I
>>> q3 = Quaternion(3 + 4*I, 2 + 5*I, 0, 7 + 8*I, real_field = False)
>>> Quaternion._generic_mul(q3, 2 + 3*I)
(2 + 3*I)*(3 + 4*I) + (2 + 3*I)*(2 + 5*I)*i + 0*j + (2 + 3*I)*(7 + 8*I)*k

r   zAOnly commutative expressions can be multiplied with a Quaternion.Nr/   )r   rH   rY   r   r   r   rL   rU   rV   rW   rX   r+   r_   r/   )r   r   r/   s      r$   r   Quaternion._generic_mul  s`   V "j))*R2L2L7N "j))}}!"R&"R&!Q7"<<""!"tt)R$$YTT	29MM !dee "j))}}Jr"vr"vq!<<<""!"tt)R$$YTT	29MM !dee 88 0D779rwwy(D244%*rttBDDy02449<rttBDDyH$$rtt)bdd244i/"$$rtt);bdd244iG44%*rttBDDy02449<rttBDDyH$$rtt)bdd244i/"$$rtt);bddRTTkI#	% 	%r2   c                     U n[        UR                  UR                  * UR                  * UR                  * UR
                  S9$ )z(Returns the conjugate of the quaternion.r   )rH   rU   rV   rW   rX   r_   r`   qs     r$   _eval_conjugateQuaternion._eval_conjugateh  s4    !##taccTACC4agg>>r2   c                     U R                   cS  U n[        [        UR                  S-  UR                  S-  -   UR
                  S-  -   UR                  S-  -   5      5      $ U R                   $ )z#Returns the norm of the quaternion.r'   )r_   r   r   rU   rV   rW   rX   r   s     r$   r/   Quaternion.normm  s[    ::A a!##q&1336!9ACCF!BCDDzzr2   c                 2    U nUSUR                  5       -  -  $ )z.Returns the normalized form of the quaternion.rh   r   r   s     r$   	normalizeQuaternion.normalizew  s    AaffhJr2   c                     U nUR                  5       (       d  [        S5      e[        U5      SUR                  5       S-  -  -  $ )z&Returns the inverse of the quaternion.z6Cannot compute inverse for a quaternion with zero normrh   r'   )r/   r+   r   r   s     r$   inverseQuaternion.inverse|  s;    vvxxUVV|q1}--r2   c                      U [        U5      pUS:  a  UR                  5       U* pUS:X  a  U$ [	        SSSS5      nUS:  a  US-  (       a  X2-  nX"-  nUS-  nUS:  a  M  U$ ! [         a	    [        s $ f = f)ak  Finds the pth power of the quaternion.

Parameters
==========

p : int
    Power to be applied on quaternion.

Returns
=======

Quaternion
    Returns the p-th power of the current quaternion.
    Returns the inverse if p = -1.

Examples
========

>>> from sympy import Quaternion
>>> q = Quaternion(1, 2, 3, 4)
>>> q.pow(4)
668 + (-224)*i + (-336)*j + (-448)*k

r   rh   )r   r+   NotImplementedr   rH   )r`   r   r   ress       r$   r   Quaternion.pow  s    2	"q q599;q6HAq!$!e1uFA!GA	 !e 
!  	"!!	"s   A# #A65A6c                    U n[        UR                  S-  UR                  S-  -   UR                  S-  -   5      n[	        UR
                  5      [        U5      -  n[	        UR
                  5      [        U5      -  UR                  -  U-  n[	        UR
                  5      [        U5      -  UR                  -  U-  n[	        UR
                  5      [        U5      -  UR                  -  U-  n[        X4XV5      $ )aK  Returns the exponential of $q$, given by $e^q$.

Returns
=======

Quaternion
    The exponential of the quaternion.

Examples
========

>>> from sympy import Quaternion
>>> q = Quaternion(1, 2, 3, 4)
>>> q.exp()
E*cos(sqrt(29))
+ 2*sqrt(29)*E*sin(sqrt(29))/29*i
+ 3*sqrt(29)*E*sin(sqrt(29))/29*j
+ 4*sqrt(29)*E*sin(sqrt(29))/29*k

r'   )	r   rV   rW   rX   r
   rU   r   r   rH   )r`   r   vector_normrU   rV   rW   rX   s          r$   r
   Quaternion.exp  s    , 1336ACCF?QSS!V34Hs;''Hs;''!##-;Hs;''!##-;Hs;''!##-;!%%r2   c                    U n[        UR                  S-  UR                  S-  -   UR                  S-  -   5      nUR	                  5       n[        U5      nUR                  [        UR                  U-  5      -  U-  nUR                  [        UR                  U-  5      -  U-  nUR                  [        UR                  U-  5      -  U-  n[        XEXg5      $ )a  Returns the logarithm of the quaternion, given by $\log q$.

Examples
========

>>> from sympy import Quaternion
>>> q = Quaternion(1, 2, 3, 4)
>>> q.log()
log(sqrt(30))
+ 2*sqrt(29)*acos(sqrt(30)/30)/29*i
+ 3*sqrt(29)*acos(sqrt(30)/30)/29*j
+ 4*sqrt(29)*acos(sqrt(30)/30)/29*k

r'   )	r   rV   rW   rX   r/   lnr   rU   rH   )r`   r   r   q_normrU   rV   rW   rX   s           r$   r   Quaternion.log  s      1336ACCF?QSS!V34vJCC$qssV|$${2CC$qssV|$${2CC$qssV|$${2!%%r2   c                     U R                    Vs/ s H  o"R                  " U6 PM     nnU R                  nUb  UR                  " U6 n[        X45        [	        USU06$ s  snf )Nr/   )r^   subsr_   r1   rH   )r`   r^   r#   r.   r/   s        r$   
_eval_subsQuaternion._eval_subs  sZ    +/9959aFFDM95zz99d#DH#8/$// 6s   Ac           	          [        U5      n[        U R                   Vs/ s H  o3R                  US9PM     sn6 $ s  snf )a  Returns the floating point approximations (decimal numbers) of the quaternion.

Returns
=======

Quaternion
    Floating point approximations of quaternion(self)

Examples
========

>>> from sympy import Quaternion
>>> from sympy import sqrt
>>> q = Quaternion(1/sqrt(1), 1/sqrt(2), 1/sqrt(3), 1/sqrt(4))
>>> q.evalf()
1.00000000000000
+ 0.707106781186547*i
+ 0.577350269189626*j
+ 0.500000000000000*k

)r   )r   rH   r^   evalf)r`   precnprecargs       r$   _eval_evalfQuaternion._eval_evalf  s8    , D!$))D)3III.)DEEDs   ;c                     U nUR                  5       u  p4[        R                  X1U-  5      nXRR                  5       U-  -  $ )a  Computes the pth power in the cos-sin form.

Parameters
==========

p : int
    Power to be applied on quaternion.

Returns
=======

Quaternion
    The p-th power in the cos-sin form.

Examples
========

>>> from sympy import Quaternion
>>> q = Quaternion(1, 2, 3, 4)
>>> q.pow_cos_sin(4)
900*cos(4*acos(sqrt(30)/30))
+ 1800*sqrt(29)*sin(4*acos(sqrt(30)/30))/29*i
+ 2700*sqrt(29)*sin(4*acos(sqrt(30)/30))/29*j
+ 3600*sqrt(29)*sin(4*acos(sqrt(30)/30))/29*k

)to_axis_anglerH   r   r/   )r`   r   r   vr   r   s         r$   pow_cos_sinQuaternion.pow_cos_sin
  s>    < __&
''u95VVXq[!!r2   c           	          [        [        U R                  /UQ76 [        U R                  /UQ76 [        U R                  /UQ76 [        U R
                  /UQ76 5      $ )a  Computes integration of quaternion.

Returns
=======

Quaternion
    Integration of the quaternion(self) with the given variable.

Examples
========

Indefinite Integral of quaternion :

>>> from sympy import Quaternion
>>> from sympy.abc import x
>>> q = Quaternion(1, 2, 3, 4)
>>> q.integrate(x)
x + 2*x*i + 3*x*j + 4*x*k

Definite integral of quaternion :

>>> from sympy import Quaternion
>>> from sympy.abc import x
>>> q = Quaternion(1, 2, 3, 4)
>>> q.integrate((x, 1, 5))
4 + 8*i + 12*j + 16*k

)rH   r   rU   rV   rW   rX   r   s     r$   r   Quaternion.integrate-  sT    : )DFF2T2Idff4Lt4L#DFF2T2Idff4Lt4LN 	Nr2   c                    [        U[        5      (       a  [        R                  US   US   5      nOUR	                  5       nU[        SU S   U S   U S   5      -  [        U5      -  nUR                  UR                  UR                  4$ )a>  Returns the coordinates of the point pin (a 3 tuple) after rotation.

Parameters
==========

pin : tuple
    A 3-element tuple of coordinates of a point which needs to be
    rotated.
r : Quaternion or tuple
    Axis and angle of rotation.

    It's important to note that when r is a tuple, it must be of the form
    (axis, angle)

Returns
=======

tuple
    The coordinates of the point after rotation.

Examples
========

>>> from sympy import Quaternion
>>> from sympy import symbols, trigsimp, cos, sin
>>> x = symbols('x')
>>> q = Quaternion(cos(x/2), 0, 0, sin(x/2))
>>> trigsimp(Quaternion.rotate_point((1, 1, 1), q))
(sqrt(2)*cos(x + pi/4), sqrt(2)*sin(x + pi/4), 1)
>>> (axis, angle) = q.to_axis_angle()
>>> trigsimp(Quaternion.rotate_point((1, 1, 1), (axis, angle)))
(sqrt(2)*cos(x + pi/4), sqrt(2)*sin(x + pi/4), 1)

r   rh   r'   )	r   r   rH   r   r   r   rV   rW   rX   )pinrr   pouts       r$   rotate_pointQuaternion.rotate_pointM  s|    H a**1Q416A A:aQQQ889Q<G''r2   c                    U nUR                   R                  (       a  US-  nUR                  5       n[        S[	        UR                   5      -  5      n[        SUR                   UR                   -  -
  5      n[        UR                  U-  5      n[        UR                  U-  5      n[        UR                  U-  5      nXEU4nXr4nU$ )a"  Returns the axis and angle of rotation of a quaternion.

Returns
=======

tuple
    Tuple of (axis, angle)

Examples
========

>>> from sympy import Quaternion
>>> q = Quaternion(1, 1, 1, 1)
>>> (axis, angle) = q.to_axis_angle()
>>> axis
(sqrt(3)/3, sqrt(3)/3, sqrt(3)/3)
>>> angle
2*pi/3

r   r'   rh   )	rU   is_negativer   r   r   r   rV   rW   rX   )	r`   r   r   r   r   r   r   r  ts	            r$   r  Quaternion.to_axis_anglez  s    * 33??BAKKMT!##Y' QSSWQSS1WQSS1WQSS1W1IJr2   c           	      R   U nUR                  5       S-  nU(       a  XCR                  S-  UR                  S-  -   UR                  S-  -
  UR                  S-  -
  -  nXCR                  S-  UR                  S-  -
  UR                  S-  -   UR                  S-  -
  -  nXCR                  S-  UR                  S-  -
  UR                  S-  -
  UR                  S-  -   -  nOxSSU-  UR                  S-  UR                  S-  -   -  -
  nSSU-  UR                  S-  UR                  S-  -   -  -
  nSSU-  UR                  S-  UR                  S-  -   -  -
  nSU-  UR                  UR                  -  UR                  UR                  -  -
  -  nSU-  UR                  UR                  -  UR                  UR                  -  -   -  n	SU-  UR                  UR                  -  UR                  UR                  -  -   -  n
SU-  UR                  UR                  -  UR                  UR                  -  -
  -  nSU-  UR                  UR                  -  UR                  UR                  -  -
  -  nSU-  UR                  UR                  -  UR                  UR                  -  -   -  nU(       d  [        XXU	/XU/XU//5      $ Uu  pnXU-  -
  X-  -
  UU	-  -
  nXU
-  -
  X-  -
  UU-  -
  nUX-  -
  X-  -
  UU-  -
  nS=n=nnSn[        XXU	U/XUU/XUU/UUUU//5      $ )a  Returns the equivalent rotation transformation matrix of the quaternion
which represents rotation about the origin if ``v`` is not passed.

Parameters
==========

v : tuple or None
    Default value: None
homogeneous : bool
    When True, gives an expression that may be more efficient for
    symbolic calculations but less so for direct evaluation. Both
    formulas are mathematically equivalent.
    Default value: True

Returns
=======

tuple
    Returns the equivalent rotation transformation matrix of the quaternion
    which represents rotation about the origin if v is not passed.

Examples
========

>>> from sympy import Quaternion
>>> from sympy import symbols, trigsimp, cos, sin
>>> x = symbols('x')
>>> q = Quaternion(cos(x/2), 0, 0, sin(x/2))
>>> trigsimp(q.to_rotation_matrix())
Matrix([
[cos(x), -sin(x), 0],
[sin(x),  cos(x), 0],
[     0,       0, 1]])

Generates a 4x4 transformation matrix (used for rotation about a point
other than the origin) if the point(v) is passed as an argument.
r'   rh   r   )r/   rU   rV   rW   rX   rs   )r`   r  homogeneousr   r   m00m11m22m01m02m10m12m20m21r   r   r   m03m13m23m30m31m32m33s                           r$   to_rotation_matrixQuaternion.to_rotation_matrix  s   N FFHbL SS!Vacc1f_qssAv-Q67CSS!Vacc1f_qssAv-Q67CSS!Vacc1f_qssAv-Q67Cac1336ACCF?++Cac1336ACCF?++Cac1336ACCF?++Cc133qss7QSSW$%c133qss7QSSW$%c133qss7QSSW$%c133qss7QSSW$%c133qss7QSSW$%c133qss7QSSW$%Cc?SsOc_MNN IQ1e)ae#ae+Ce)ae#ae+Cae)ae#ae+CC#CCc3/#C1ES#.c30DF G Gr2   c                     U R                   $ )a  Returns scalar part($\mathbf{S}(q)$) of the quaternion q.

Explanation
===========

Given a quaternion $q = a + bi + cj + dk$, returns $\mathbf{S}(q) = a$.

Examples
========

>>> from sympy.algebras.quaternion import Quaternion
>>> q = Quaternion(4, 8, 13, 12)
>>> q.scalar_part()
4

)rU   rd   s    r$   scalar_partQuaternion.scalar_part  s    $ vvr2   c                 Z    [        SU R                  U R                  U R                  5      $ )a  
Returns $\mathbf{V}(q)$, the vector part of the quaternion $q$.

Explanation
===========

Given a quaternion $q = a + bi + cj + dk$, returns $\mathbf{V}(q) = bi + cj + dk$.

Examples
========

>>> from sympy.algebras.quaternion import Quaternion
>>> q = Quaternion(1, 1, 1, 1)
>>> q.vector_part()
0 + 1*i + 1*j + 1*k

>>> q = Quaternion(4, 8, 13, 12)
>>> q.vector_part()
0 + 8*i + 13*j + 12*k

r   )rH   rV   rW   rX   rd   s    r$   vector_partQuaternion.vector_part  s!    . !TVVTVVTVV44r2   c                     U R                  5       R                  5       n[        SUR                  UR                  UR
                  5      $ )a  
Returns $\mathbf{Ax}(q)$, the axis of the quaternion $q$.

Explanation
===========

Given a quaternion $q = a + bi + cj + dk$, returns $\mathbf{Ax}(q)$  i.e., the versor of the vector part of that quaternion
equal to $\mathbf{U}[\mathbf{V}(q)]$.
The axis is always an imaginary unit with square equal to $-1 + 0i + 0j + 0k$.

Examples
========

>>> from sympy.algebras.quaternion import Quaternion
>>> q = Quaternion(1, 1, 1, 1)
>>> q.axis()
0 + sqrt(3)/3*i + sqrt(3)/3*j + sqrt(3)/3*k

See Also
========

vector_part

r   )r8  r   rH   rV   rW   rX   )r`   axiss     r$   r;  Quaternion.axis  s8    2 !++-!TVVTVVTVV44r2   c                 .    U R                   R                  $ )a  
Returns true if the quaternion is pure, false if the quaternion is not pure
or returns none if it is unknown.

Explanation
===========

A pure quaternion (also a vector quaternion) is a quaternion with scalar
part equal to 0.

Examples
========

>>> from sympy.algebras.quaternion import Quaternion
>>> q = Quaternion(0, 8, 13, 12)
>>> q.is_pure()
True

See Also
========
scalar_part

)rU   is_zerord   s    r$   is_pureQuaternion.is_pure8  s    2 vv~~r2   c                 6    U R                  5       R                  $ )a  
Returns true if the quaternion is a zero quaternion or false if it is not a zero quaternion
and None if the value is unknown.

Explanation
===========

A zero quaternion is a quaternion with both scalar part and
vector part equal to 0.

Examples
========

>>> from sympy.algebras.quaternion import Quaternion
>>> q = Quaternion(1, 0, 0, 0)
>>> q.is_zero_quaternion()
False

>>> q = Quaternion(0, 0, 0, 0)
>>> q.is_zero_quaternion()
True

See Also
========
scalar_part
vector_part

)r/   r>  rd   s    r$   r   Quaternion.is_zero_quaternionS  s    < yy{"""r2   c                 t    S[        U R                  5       R                  5       U R                  5       5      -  $ )a  
Returns the angle of the quaternion measured in the real-axis plane.

Explanation
===========

Given a quaternion $q = a + bi + cj + dk$ where $a$, $b$, $c$ and $d$
are real numbers, returns the angle of the quaternion given by

.. math::
    \theta := 2 \operatorname{atan_2}\left(\sqrt{b^2 + c^2 + d^2}, {a}\right)

Examples
========

>>> from sympy.algebras.quaternion import Quaternion
>>> q = Quaternion(1, 4, 4, 4)
>>> q.angle()
2*atan(4*sqrt(3))

r'   )r   r8  r/   r5  rd   s    r$   r   Quaternion.angles  s1    . 5))+002D4D4D4FGGGr2   c                 :   U R                  5       (       d  UR                  5       (       a  [        S5      e[        U R                  5       UR                  5       -
  R                  5       U R                  5       UR                  5       -   R                  5       /5      $ )as  
Returns True if the transformation arcs represented by the input quaternions happen in the same plane.

Explanation
===========

Two quaternions are said to be coplanar (in this arc sense) when their axes are parallel.
The plane of a quaternion is the one normal to its axis.

Parameters
==========

other : a Quaternion

Returns
=======

True : if the planes of the two quaternions are the same, apart from its orientation/sign.
False : if the planes of the two quaternions are not the same, apart from its orientation/sign.
None : if plane of either of the quaternion is unknown.

Examples
========

>>> from sympy.algebras.quaternion import Quaternion
>>> q1 = Quaternion(1, 4, 4, 4)
>>> q2 = Quaternion(3, 8, 8, 8)
>>> Quaternion.arc_coplanar(q1, q2)
True

>>> q1 = Quaternion(2, 8, 13, 12)
>>> Quaternion.arc_coplanar(q1, q2)
False

See Also
========

vector_coplanar
is_pure

z)Neither of the given quaternions can be 0)r   r+   r   r;  r   s     r$   arc_coplanarQuaternion.arc_coplanar  sv    T ##%%5+C+C+E+EHII$))+

4HHJTYY[[`[e[e[gMgL{L{L}~r2   c                    [        UR                  5       5      (       d<  [        UR                  5       5      (       d  [        UR                  5       5      (       a  [        S5      e[        UR                  UR
                  UR                  /UR                  UR
                  UR                  /UR                  UR
                  UR                  //5      R                  5       nUR                  $ )a  
Returns True if the axis of the pure quaternions seen as 3D vectors
``q1``, ``q2``, and ``q3`` are coplanar.

Explanation
===========

Three pure quaternions are vector coplanar if the quaternions seen as 3D vectors are coplanar.

Parameters
==========

q1
    A pure Quaternion.
q2
    A pure Quaternion.
q3
    A pure Quaternion.

Returns
=======

True : if the axis of the pure quaternions seen as 3D vectors
q1, q2, and q3 are coplanar.
False : if the axis of the pure quaternions seen as 3D vectors
q1, q2, and q3 are not coplanar.
None : if the axis of the pure quaternions seen as 3D vectors
q1, q2, and q3 are coplanar is unknown.

Examples
========

>>> from sympy.algebras.quaternion import Quaternion
>>> q1 = Quaternion(0, 4, 4, 4)
>>> q2 = Quaternion(0, 8, 8, 8)
>>> q3 = Quaternion(0, 24, 24, 24)
>>> Quaternion.vector_coplanar(q1, q2, q3)
True

>>> q1 = Quaternion(0, 8, 16, 8)
>>> q2 = Quaternion(0, 8, 3, 12)
>>> Quaternion.vector_coplanar(q1, q2, q3)
False

See Also
========

axis
is_pure

"The given quaternions must be pure)	r   r?  r+   rs   rV   rW   rX   r   r>  )rT   r   r   q3r   s        r$   vector_coplanarQuaternion.vector_coplanar  s    l RZZ\""i

&=&=2::<AXAXABBRTT244&rttRTT(:RTT244<NOPTTVyyr2   c                     [        U R                  5       5      (       d  [        UR                  5       5      (       a  [        S5      eX-  X-  -
  R                  5       $ )a  
Returns True if the two pure quaternions seen as 3D vectors are parallel.

Explanation
===========

Two pure quaternions are called parallel when their vector product is commutative which
implies that the quaternions seen as 3D vectors have same direction.

Parameters
==========

other : a Quaternion

Returns
=======

True : if the two pure quaternions seen as 3D vectors are parallel.
False : if the two pure quaternions seen as 3D vectors are not parallel.
None : if the two pure quaternions seen as 3D vectors are parallel is unknown.

Examples
========

>>> from sympy.algebras.quaternion import Quaternion
>>> q = Quaternion(0, 4, 4, 4)
>>> q1 = Quaternion(0, 8, 8, 8)
>>> q.parallel(q1)
True

>>> q1 = Quaternion(0, 8, 13, 12)
>>> q.parallel(q1)
False

z%The provided quaternions must be purer   r?  r+   r   r   s     r$   parallelQuaternion.parallel  sJ    J T\\^$$	%--/(B(BDEE
UZ';;==r2   c                     [        U R                  5       5      (       d  [        UR                  5       5      (       a  [        S5      eX-  X-  -   R                  5       $ )a  
Returns the orthogonality of two quaternions.

Explanation
===========

Two pure quaternions are called orthogonal when their product is anti-commutative.

Parameters
==========

other : a Quaternion

Returns
=======

True : if the two pure quaternions seen as 3D vectors are orthogonal.
False : if the two pure quaternions seen as 3D vectors are not orthogonal.
None : if the two pure quaternions seen as 3D vectors are orthogonal is unknown.

Examples
========

>>> from sympy.algebras.quaternion import Quaternion
>>> q = Quaternion(0, 4, 4, 4)
>>> q1 = Quaternion(0, 8, 8, 8)
>>> q.orthogonal(q1)
False

>>> q1 = Quaternion(0, 2, 2, 0)
>>> q = Quaternion(0, 2, -2, 0)
>>> q.orthogonal(q1)
True

rI  rN  r   s     r$   
orthogonalQuaternion.orthogonal"  sJ    J T\\^$$	%--/(B(BABB
UZ';;==r2   c                 D    U R                  5       U R                  5       -  $ )a  
Returns the index vector of the quaternion.

Explanation
===========

The index vector is given by $\mathbf{T}(q)$, the norm (or magnitude) of
the quaternion $q$, multiplied by $\mathbf{Ax}(q)$, the axis of $q$.

Returns
=======

Quaternion: representing index vector of the provided quaternion.

Examples
========

>>> from sympy.algebras.quaternion import Quaternion
>>> q = Quaternion(2, 4, 2, 4)
>>> q.index_vector()
0 + 4*sqrt(10)/3*i + 2*sqrt(10)/3*j + 4*sqrt(10)/3*k

See Also
========

axis
norm

)r/   r;  rd   s    r$   index_vectorQuaternion.index_vectorL  s    > yy{TYY[((r2   c                 4    [        U R                  5       5      $ )a  
Returns the natural logarithm of the norm(magnitude) of the quaternion.

Examples
========

>>> from sympy.algebras.quaternion import Quaternion
>>> q = Quaternion(2, 4, 2, 4)
>>> q.mensor()
log(2*sqrt(10))
>>> q.norm()
2*sqrt(10)

See Also
========

norm

)r   r/   rd   s    r$   mensorQuaternion.mensorm  s    * $))+r2   )r_   )r   r   r   r   TN)F)TF)NT)C__name__
__module____qualname____firstlineno____doc___op_priorityrL   rQ   rS   propertyrU   rV   rW   rX   rY   rt   rw   r{   classmethodr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   staticmethodr   r   r/   r   r   r   r
   r   r  r  r  r   r  r  r2  r5  r8  r;  r?  r   r   rF  rK  rO  rR  rU  rX  __static_attributes____classcell__)r[   s   @r$   rH   rH   :   s!   /` LN"H             /4 /4b 44 44l/%b () ()T =* =*~L!\ ( (T )& )&V"88>))%L4"l'8R I% I%V?
 
.+Z&>&40F2!"FN@ *( *(X&PJGX(525:6#@H4-@^ 9 9v(>T(>T)B r2   rH   N)-sympy.core.numbersr   sympy.core.singletonr   sympy.core.relationalr   $sympy.functions.elementary.complexesr   r   r   r	   &sympy.functions.elementary.exponentialr
   r   r   (sympy.functions.elementary.miscellaneousr   (sympy.functions.elementary.trigonometricr   r   r   r   r   sympy.simplify.trigsimpr   sympy.integrals.integralsr   sympy.matrices.denser   rs   sympy.core.sympifyr   r   sympy.core.exprr   sympy.core.logicr   r   sympy.utilities.miscr   mpmath.libmp.libmpfr   r1   rF   rH   r)   r2   r$   <module>rt     sS    ' " ' J J C 9 H H ? , / = 0   0 ' +=6H Hr2   