+
    i{                        ^ RI Ht ^ RIHt ^ RIHt ^ RIHtHtH	t	H
t
 ^ RIHtHt ^ RIHt ^ RIHtHtHt ^ RIHtHt ^ R	IHt ^ R
IHt ^ RIHt ^ RIHtH t  ^ RI!H"t" ^ RI#H$t$H%t% ^ RI&H't' ^ RI(H)t) R t*R t+ ! R R]"4      t,R# )    )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                P   Ve   VP                   '       d   VP                  RJ d   \        R4      h\        ;QJ d    R V  4       F  '       d   K   RM	  RM! R V  4       4      pV'       d5   \	        V^,          \        R V  4       4      4      RJ d   \        R4      hR# R# R# R# )z$validate if input norm is consistentNFzInput norm must be positive.c              3   d   "   T F&  qP                   ;'       d    VP                  R J x  K(  	  R# 5i)TN)	is_numberis_real.0is   & y/Users/tonyclaw/.openclaw/workspace/skills/math-calculator/venv/lib/python3.14/site-packages/sympy/algebras/quaternion.py	<genexpr>_check_norm.<locals>.<genexpr>   s&     L8a99		T(998s   00Tc              3   2   "   T F  q^,          x  K  	  R# 5i)   N r!   s   & r$   r%   r&      s     +C(QqDD(s   zIncompatible value for norm.)r   is_positive
ValueErrorallr   sum)elementsnorm	numericals   && r$   _check_normr1      s    DNNNu$;<<CL8LCCCL8LL	tQw+C(+C(CDM;<< N9 +    c                   \        V 4      \        8w  d   \        R4      h\        V 4      ^8w  d   \        RP	                  V 4      4      hV P                  4       pV P                  4       pV'       g   V'       g   \        R4      hV P                  4       w  r4pW48X  g   WE8X  d   \        R4      h\        V 4      \        R4      ,
          pV'       d*   \        RP	                  RP                  V4      4      4      hV# )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_extrinsicrE      s    CyC788
3x1}5<<SABBII ' ( 	( iikGA!	AF=>>
c(S]
"C
 ""(&"68 	8 r2   c                     a a ] tR t^:t oRtRtRtR<V 3R lltR t]	R 4       t
]	R 4       t]	R 4       t]	R	 4       t]	R
 4       t]	R 4       t]	R 4       tR=R lt]R 4       t]R 4       tR>R lt]R 4       t]R 4       tR tR tR tR tR tR tR tR tR t R t!R t"R t#R t$]%R  4       t&R! t'R" t(R# t)R$ t*R% t+R& t,R' t-R( t.R) t/R* t0R+ t1]%R, 4       t2R- t3R?R. lt4R/ t5R0 t6R1 t7R2 t8R3 t9R4 t:R5 t;]R6 4       t<R7 t=R8 t>R9 t?R: t@R;tAVtBV ;tC# )@
Quaternionaf  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                  < \        \        WW434      w  rr4\        ;QJ d    R  WW43 4       F  '       g   K   RM	  RM! R  WW43 4       4      '       d   \        R4      h\        SV `  WW#V4      pWWn        VP                  V4       V# )c              3   <   "   T F  qP                   R J x  K  	  R# 5i)FN)is_commutativer!   s   & r$   r%   %Quaternion.__new__.<locals>.<genexpr>r   s     ?,Q5(,s   TFz arguments have to be commutative)mapr   anyr+   super__new___real_fieldset_norm)	clsabcd
real_fieldr/   obj	__class__s	   &&&&&&& r$   rO   Quaternion.__new__o   st    1,/
a3?1,?333?1,????@@gocaA.$T
r2   c                T    \        V4      p\        V P                  V4       Wn        R# )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$   rQ   Quaternion.set_normy   s!    @ t}DIIt$
r2   c                (    V P                   ^ ,          # )r   r\   r^   s   &r$   rS   Quaternion.a       yy|r2   c                (    V P                   ^,          # )   ra   rb   s   &r$   rT   Quaternion.b   rd   r2   c                (    V P                   ^,          # )r(   ra   rb   s   &r$   rU   Quaternion.c   rd   r2   c                (    V P                   ^,          # )   ra   rb   s   &r$   rV   Quaternion.d   rd   r2   c                    V P                   # N)rP   rb   s   &r$   rW   Quaternion.real_field   s    r2   c           	        \        V P                  V P                  ) V P                  ) V P                  ) .V P                  V P                  V P                  ) V P                  .V P                  V P                  V P                  V P                  ) .V P                  V P                  ) V P                  V P                  ..4      # )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]])
MatrixrS   rT   rU   rV   rb   s   &r$   product_matrix_leftQuaternion.product_matrix_left   s    X $&&466'DFF73$&&$&&1$&&1$&&$&&$&&1	3 4 	4r2   c           	        \        V P                  V P                  ) V P                  ) V P                  ) .V P                  V P                  V P                  V P                  ) .V P                  V P                  ) V P                  V P                  .V P                  V P                  V P                  ) V P                  ..4      # )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]])
rq   rb   s   &r$   product_matrix_rightQuaternion.product_matrix_right   s    b $&&466'DFF73$&&1$&&$&&$&&1$&&$&&1	3 4 	4r2   c                t    V'       d   \        V P                  R,          4      # \        V P                  4      # )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]])

:rf   NN)rr   r\   )r^   vector_onlys   &&r$   	to_MatrixQuaternion.to_Matrix  s*    X $))B-(($))$$r2   c                    \        V4      pV^8w  d"   V^8w  d   \        RP                  V4      4      hV^8X  d   \        ^ .VO5!  # \        V!  # )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

z7Input elements must have length 3 or 4, got {} elements)r8   r+   r9   rG   )rR   r.   lengths   && r$   from_MatrixQuaternion.from_MatrixK  sZ    B XQ;6Q; ((.v8 8 Q;a+(++x((r2   c                (   \        V4      ^8w  d   \        R4      h\        V4      pVP                  4       w  rEpR Uu. uF  qwV8X  d   ^M^ NK  	  ppR Uu. uF  qwV8X  d   ^M^ NK  	  p	pR Uu. uF  qwV8X  d   ^M^ NK  	  p
pV P	                  W^ ,          4      pV P	                  W^,          4      pV P	                  W^,          4      pV'       d   \        W,          V,          4      # \        W,          V,          4      # u upi u upi u upi )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

z3 angles must be given.xyz)r8   r+   rE   r<   from_axis_angler   )rR   anglesr?   rA   r#   rB   rC   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   DD
0Dc           	     X	   V P                  4       '       d   \        R4      h. ROp\        V4      pVP                  4       w  rgpRP	                  V4      ^,           pRP	                  V4      ^,           pRP	                  V4      ^,           pV'       g   YrWh8H  p	V	'       d   ^V,
          V,
          pWg,
          Wx,
          ,          W,
          ,          ^,          p
V P
                  V P                  V P                  V P                  .pV^ ,          pW,          pW,          pW,          V
,          pV	'       g"   W,
          W,           W,           W,
          3w  rrV'       d   V	'       d[   V P                  4       ^,          p\        W,          W,          ,           W,          ,
          W,          ,
          V,          4      V^&   M^V P                  4       ^,          ,          p\        W,          W,          ,           W,          ,
          W,          ,
          V,          4      V^&   M^\        \        W,          W,          ,           4      \        W,          W,          ,           4      4      ,          V^&   V	'       g+   V^;;,          \        P                  ^,          ,          uu&   ^ p\!        V\        P"                  4      '       d#   \!        V\        P"                  4      '       d   ^p\!        V\        P"                  4      '       d#   \!        V\        P"                  4      '       d   ^pV^ 8X  d   V'       d>   \        W4      \        W4      ,           V^ &   \        W4      \        W4      ,
          V^&   M\        W,          W,          ,           W,          W,          ,
          4      V^ &   \        W,          W,          ,
          W,          W,          ,           4      V^&   M\        P"                  V^V'       * ,          &   V^8X  d   ^\        W4      ,          V^V,          &   MB^\        W4      ,          V^V,          &   T^V,          ;;,          V'       d   RM^,          uu&   V	'       g   V^ ;;,          V
,          uu&   V'       d   \%        VRRR1,          4      # \%        V4      # )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   N)r   r   r   )is_zero_quaternionr+   rE   r<   indexrS   rT   rU   rV   r/   r   r   r   r   r   Pir   Zerotuple)r^   r?   angle_additionavoid_square_rootr   rA   r#   rB   rC   	symmetricr	   r.   rS   rT   rU   rV   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                X   Vw  r4p\        V^,          V^,          ,           V^,          ,           4      pW6,          WF,          WV,          rTp\        V\        P                  ,          4      p\	        V\        P                  ,          4      pW7,          p	WG,          p
WW,          pV ! WW4      # )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   Halfr   )rR   vectoranglexyzr/   srS   rT   rU   rV   s   &&&         r$   r   Quaternion.from_axis_angleD  s    8 	qAqD1a4K!Q$&'XqxqEEE 1r2   c                   VP                  4       \        ^^4      ,          p\        W!R,          ,           VR,          ,           VR,          ,           4      ^,          p\        W!R,          ,           VR,          ,
          VR,          ,
          4      ^,          p\        W!R,          ,
          VR,          ,           VR,          ,
          4      ^,          p\        W!R,          ,
          VR,          ,
          VR,          ,           4      ^,          pV\        VR,          VR,          ,
          4      ,          pV\        VR,          VR,          ,
          4      ,          pV\        VR,          VR	,          ,
          4      ,          p\	        W4WV4      # )
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

)r   r   )rf   rf   )r(   r(   )r(   rf   )rf   r(   )r   r(   )r(   r   )rf   r   )r   rf   )detr   r   r	   rG   )rR   MabsQrS   rT   rU   rV   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                $    V P                  V4      # rn   addr^   others   &&r$   __add__Quaternion.__add__      xxr2   c                $    V P                  V4      # rn   r   r   s   &&r$   __radd__Quaternion.__radd__  r   r2   c                2    V P                  VR,          4      # rf   r   r   r   s   &&r$   __sub__Quaternion.__sub__  s    xxb!!r2   c                8    V P                  V \        V4      4      # rn   _generic_mulr   r   s   &&r$   __mul__Quaternion.__mul__  s      x77r2   c                8    V P                  \        V4      V 4      # rn   r   r   s   &&r$   __rmul__Quaternion.__rmul__  s      %$77r2   c                $    V P                  V4      # rn   )pow)r^   ps   &&r$   __pow__Quaternion.__pow__  s    xx{r2   c                v    \        V P                  ) V P                  ) V P                  ) V P                  ) 4      # rn   )rG   rS   rT   rU   rV   rb   s   &r$   __neg__Quaternion.__neg__  s+    466'DFF7TVVGdffW==r2   c                4    V \        V4      R,          ,          # r   r   r   s   &&r$   __truediv__Quaternion.__truediv__  s    genb(((r2   c                4    \        V4      V R,          ,          # r   r   r   s   &&r$   __rtruediv__Quaternion.__rtruediv__  s    u~b((r2   c                "    V P                   ! V!  # rn   r   r^   r\   s   &*r$   _eval_IntegralQuaternion._eval_Integral  s    ~~t$$r2   c           
         VP                  R R4       V P                  ! V P                   Uu. uF  q3P                  ! V/ VB NK  	  up!  # u upi )evaluateT)
setdefaultfuncr\   diff)r^   symbolskwargsrS   s   &*, r$   r   Quaternion.diff  sC    *d+yy		J	!6675f5	JKKJs   Ac                   T p\        V4      p\        V\        4      '       g   VP                  '       di   VP                  '       dW   \        \        V4      VP                  ,           \        V4      VP                  ,           VP                  VP                  4      # VP                  '       d>   \        VP                  V,           VP                  VP                  VP                  4      # \        R4      h\        VP                  VP                  ,           VP                  VP                  ,           VP                  VP                  ,           VP                  VP                  ,           4      # )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   
isinstancerG   rW   
is_complexr   rS   r   rT   rU   rV   rJ   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    V P                  V \        V4      4      # )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                N   \        V \        4      '       g   \        V\        4      '       g	   W,          # \        V \        4      '       g   VP                  '       d:   V P                  '       d(   \        \	        V 4      \        V 4      ^ ^ 4      V,          # V P                  '       dO   \        WP                  ,          WP                  ,          WP                  ,          WP                  ,          4      # \        R4      h\        V\        4      '       g   V P                  '       d:   VP                  '       d(   V \        \	        V4      \        V4      ^ ^ 4      ,          # VP                  '       dO   \        WP                  ,          WP                  ,          WP                  ,          WP                  ,          4      # \        R4      hV P                  f   VP                  f   RpM%V P                  4       VP                  4       ,          p\        V P                  ) VP                  ,          V P                  VP                  ,          ,
          V P                  VP                  ,          ,
          V P                  VP                  ,          ,           V P                  VP                  ,          V P                  VP                  ,          ,           V P                  VP                  ,          ,
          V P                  VP                  ,          ,           V P                  ) VP                  ,          V P                  VP                  ,          ,           V P                  VP                  ,          ,           V P                  VP                  ,          ,           V P                  VP                  ,          V P                  VP                  ,          ,
          V P                  VP                  ,          ,           V P                  VP                  ,          ,           VR7      # )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

zAOnly commutative expressions can be multiplied with a Quaternion.Nr/   )r   rG   rW   r   r   r   rJ   rS   rT   rU   rV   r+   r]   r/   )r   r   r/   s   && r$   r   Quaternion._generic_mul  sn   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                    T p\        VP                  VP                  ) VP                  ) VP                  ) VP
                  R7      # )z(Returns the conjugate of the quaternion.r   )rG   rS   rT   rU   rV   r]   r^   qs   & r$   _eval_conjugateQuaternion._eval_conjugateh  s4    !##taccTACC4agg>>r2   c                   V P                   fp   T p\        \        VP                  ^,          VP                  ^,          ,           VP
                  ^,          ,           VP                  ^,          ,           4      4      # V P                   # )z#Returns the norm of the quaternion.)r]   r   r   rS   rT   rU   rV   r   s   & r$   r/   Quaternion.normm  s[    ::A a!##q&1336!9ACCF!BCDDzzr2   c                B    T pV^VP                  4       ,          ,          # )z.Returns the normalized form of the quaternion.r   r   s   & r$   	normalizeQuaternion.normalizew  s    AaffhJr2   c                    T pVP                  4       '       g   \        R4      h\        V4      ^VP                  4       ^,          ,          ,          # )z&Returns the inverse of the quaternion.z6Cannot compute inverse for a quaternion with zero norm)r/   r+   r   r   s   & r$   inverseQuaternion.inverse|  s;    vvxxUVV|q1}--r2   c                    T \        V4      rT^ 8  d   TP                  4       T) rT^8X  d   T# \	        ^^ ^ ^ 4      pT^ 8  d+   T^,          '       d	   Y2,          pY",          pT^,          pK1  T#   \         d
    \        u # i ; i)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   r+   NotImplementedr   rG   )r^   r   r   ress   &&  r$   r   Quaternion.pow  s    2	"q q599;q6HAq!$!e1uuFA!GA
!  	"!!	"s   A1 1BBc                n   T p\        VP                  ^,          VP                  ^,          ,           VP                  ^,          ,           4      p\	        VP
                  4      \        V4      ,          p\	        VP
                  4      \        V4      ,          VP                  ,          V,          p\	        VP
                  4      \        V4      ,          VP                  ,          V,          p\	        VP
                  4      \        V4      ,          VP                  ,          V,          p\        W4WV4      # )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   rT   rU   rV   r
   rS   r   r   rG   )r^   r   vector_normrS   rT   rU   rV   s   &      r$   r
   Quaternion.exp  s    , 1336ACCF?QSS!V34Hs;''Hs;''!##-;Hs;''!##-;Hs;''!##-;!%%r2   c                $   T p\        VP                  ^,          VP                  ^,          ,           VP                  ^,          ,           4      pVP	                  4       p\        V4      pVP                  \        VP                  V,          4      ,          V,          pVP                  \        VP                  V,          4      ,          V,          pVP                  \        VP                  V,          4      ,          V,          p\        WEWg4      # )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   rT   rU   rV   r/   lnr   rS   rG   )r^   r   r   q_normrS   rT   rU   rV   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                    V P                    Uu. uF  q"P                  ! V!  NK  	  ppV P                  pVe   VP                  ! V!  p\        W44       \	        VRV/ # u upi )Nr/   )r\   subsr]   r1   rG   )r^   r\   r#   r.   r/   s   &*   r$   
_eval_subsQuaternion._eval_subs  sZ    +/9959aFFDM95zz99d#DH#8/$// 6s   Ac           	         \        V4      p\        V P                   Uu. uF  q3P                  VR7      NK  	  up!  # u upi )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   rG   r\   evalf)r^   precnprecargs   &&  r$   _eval_evalfQuaternion._eval_evalf  s8    , D!$))D)3III.)DEEDs   >c                    T pVP                  4       w  r4\        P                  W1V,          4      pWRP                  4       V,          ,          # )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_anglerG   r   r/   )r^   r   r   vr   r   s   &&    r$   pow_cos_sinQuaternion.pow_cos_sin
  s>    < __&
''u95VVXq[!!r2   c           	         \        \        V P                  .VO5!  \        V P                  .VO5!  \        V P                  .VO5!  \        V P
                  .VO5!  4      # )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

)rG   r   rS   rT   rU   rV   r   s   &*r$   r   Quaternion.integrate-  sT    : )DFF2T2Idff4Lt4L#DFF2T2Idff4Lt4LN 	Nr2   c                R   \        V\        4      '       d&   \        P                  V^ ,          V^,          4      pMVP	                  4       pV\        ^ V ^ ,          V ^,          V ^,          4      ,          \        V4      ,          pVP                  VP                  VP                  3# )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   r   rG   r   r   r   rT   rU   rV   )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                   T pVP                   P                  '       d
   VR,          pVP                  4       p\        ^\	        VP                   4      ,          4      p\        ^VP                   VP                   ,          ,
          4      p\        VP                  V,          4      p\        VP                  V,          4      p\        VP                  V,          4      pWEV3pWr3pV# )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   )	rS   is_negativer   r   r   r   rT   rU   rV   )	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           	     0	   T pVP                  4       R,          pV'       Ed%   WCP                  ^,          VP                  ^,          ,           VP                  ^,          ,
          VP                  ^,          ,
          ,          pWCP                  ^,          VP                  ^,          ,
          VP                  ^,          ,           VP                  ^,          ,
          ,          pWCP                  ^,          VP                  ^,          ,
          VP                  ^,          ,
          VP                  ^,          ,           ,          pM^^V,          VP                  ^,          VP                  ^,          ,           ,          ,
          p^^V,          VP                  ^,          VP                  ^,          ,           ,          ,
          p^^V,          VP                  ^,          VP                  ^,          ,           ,          ,
          p^V,          VP                  VP                  ,          VP                  VP                  ,          ,
          ,          p^V,          VP                  VP                  ,          VP                  VP                  ,          ,           ,          p	^V,          VP                  VP                  ,          VP                  VP                  ,          ,           ,          p
^V,          VP                  VP                  ,          VP                  VP                  ,          ,
          ,          p^V,          VP                  VP                  ,          VP                  VP                  ,          ,
          ,          p^V,          VP                  VP                  ,          VP                  VP                  ,          ,           ,          pV'       g   \        WXV	.WV.WV..4      # Vw  rpWV,          ,
          W,          ,
          VV	,          ,
          pWV
,          ,
          W,          ,
          VV,          ,
          pVW,          ,
          W,          ,
          VV,          ,
          p^ ;p;pp^p\        WXV	V.WVV.WVV.VVVV..4      # )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/   rS   rT   rU   rV   rr   )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                    V P                   # )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

)rS   rb   s   &r$   scalar_partQuaternion.scalar_part  s    $ vvr2   c                Z    \        ^ V P                  V P                  V P                  4      # )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

)rG   rT   rU   rV   rb   s   &r$   vector_partQuaternion.vector_part  s!    . !TVVTVVTVV44r2   c                    V P                  4       P                  4       p\        ^ VP                  VP                  VP
                  4      # )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

)r5  r   rG   rT   rU   rV   )r^   axiss   & r$   r8  Quaternion.axis  s8    2 !++-!TVVTVVTVV44r2   c                .    V P                   P                  # )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

)rS   is_zerorb   s   &r$   is_pureQuaternion.is_pure8  s    2 vv~~r2   c                6    V P                  4       P                  # )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;  rb   s   &r$   r   Quaternion.is_zero_quaternionS  s    < yy{"""r2   c                |    ^\        V P                  4       P                  4       V P                  4       4      ,          # )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   r5  r/   r2  rb   s   &r$   r   Quaternion.angles  s1    . 5))+002D4D4D4FGGGr2   c                N   V P                  4       '       g   VP                  4       '       d   \        R4      h\        V P                  4       VP                  4       ,
          P                  4       V P                  4       VP                  4       ,           P                  4       .4      # )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   r8  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                   \        VP                  4       4      '       g?   \        VP                  4       4      '       g    \        VP                  4       4      '       d   \        R4      h\        VP                  VP
                  VP                  .VP                  VP
                  VP                  .VP                  VP
                  VP                  ..4      P                  4       pVP                  # )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+   rr   rT   rU   rV   r   r;  )rR   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                    \        V P                  4       4      '       g    \        VP                  4       4      '       d   \        R4      hW,          W,          ,
          P                  4       # )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                    \        V P                  4       4      '       g    \        VP                  4       4      '       d   \        R4      hW,          W,          ,           P                  4       # )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

rF  rK  r   s   &&r$   
orthogonalQuaternion.orthogonal"  sJ    J T\\^$$	%--/(B(BABB
UZ';;==r2   c                L    V P                  4       V P                  4       ,          # )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/   r8  rb   s   &r$   index_vectorQuaternion.index_vectorL  s    > yy{TYY[((r2   c                4    \        V P                  4       4      # )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/   rb   s   &r$   mensorQuaternion.mensorm  s    * $))+r2   )r]   )r   r   r   r   TN)F)TF)NT)D__name__
__module____qualname____firstlineno____doc___op_priorityrJ   rO   rQ   propertyrS   rT   rU   rV   rW   rs   rv   rz   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  r/  r2  r5  r8  r<  r   r   rC  rH  rL  rO  rR  rU  __static_attributes____classdictcell____classcell__)rY   __classdict__s   @@r$   rG   rG   :   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   rG   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   rr   sympy.core.sympifyr   r   sympy.core.exprr   sympy.core.logicr   r   sympy.utilities.miscr   mpmath.libmp.libmpfr   r1   rE   rG   r)   r2   r$   <module>rs     sS    ' " ' J J C 9 H H ? , / = 0   0 ' +=6H Hr2   