ó
    ˆ*£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     ÚV/home/mande/repo/quber/.venv/lib/python3.13/site-packages/sympy/algebras/quaternion.pyÚ	<genexpr>Ú_check_norm.<locals>.<genexpr>   s#   é € ÐLÂ8¸aŸ™×9¨¯	©	°TÐ(9Ô9Â8ùs   ‚-/é   c              3   ó*   #   • U  H	  oS -  v •  M     g7f)r'   N© r!   s     r$   r%   r&      s   é € Ð+Cº(°Q¨q®Dº(ùs   ‚zIncompatible value for norm.)r   Úis_positiveÚ
ValueErrorÚallr   Úsum)ÚelementsÚnormÚ	numericals      r$   Ú_check_normr1      st   € àÑ˜DŸNŸNØ×Ñ˜uÒ$ÜÐ;Ó<Ð<äÑLÁ8ÓLÓLˆ	Þœ˜t Q™w¬Ñ+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Ð   € äˆCƒy”CÓÜÐ7Ó8Ð8Ü
ˆ3ƒx�1ƒ}ÜÐ5×<Ñ<¸SÓAÓBÐBà—‘“€IØ—‘“€IÞžÜð 'ó (ð 	(ð �i‰i‹k�G€Aˆ!Ø	‹�A“FÜÐ=Ó>Ð>ä
ˆ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¸±,Ó?×?Ñ?ÜÐ?Ó@Ð@Ü‰g‰o˜c a¨AÓ.ˆØ$ŒØ�‰�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‹}ˆÜ�D—I‘I˜tÔ$Ø�
r2   c                 ó    • U R                   S   $ )Nr   ©r^   ©r`   s    r$   rU   ÚQuaternion.a�   ó   € à�y‰y˜‰|Ð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 Ø—‘˜$Ÿ&™&˜ 4§6¡6 '¨D¯F©F¨7Ð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 Ø—‘˜$Ÿ&™&˜ 4§6¡6 '¨D¯F©F¨7Ð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 Ü˜$Ÿ)™) A B˜-Ó(Ð(ä˜$Ÿ)™)Ó$Ð$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‹;˜6 Q›;Üð (ß(.©¨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	                  X�S   5      nU R	                  X‘S   5      nU R	                  X¡S   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˜“6‰a˜qÒ ©%ˆÐ0Ù*/Ó0ª% Q˜“6‰a˜qÒ ©%ˆÐ0Ù*/Ó0ª% Q˜“6‰a˜qÒ ©%ˆÐ0ð × Ñ  ¨A¡YÓ/ˆØ× Ñ  ¨A¡YÓ/ˆØ× Ñ  ¨A¡YÓ/ˆæÜ˜B™G b™LÓ)Ð)ä˜B™G b™LÓ)Ð)ùò 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  X†p†Xh: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  pÍpïU(       av  U	(       a6  U R                  5       S-  n[        XÌ-  XÝ-  -   Xî-  -
  Xÿ-  -
  U-  5      US'   O�S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  [        XÜ5      [        Xþ5      -   US'   [        XÜ5      [        Xþ5      -
  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[        XÜ5      -  USU-  '   O-S[        Xþ5      -  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ð �K‰K˜‹N˜QÑˆØ�K‰K˜‹N˜QÑˆØ�K‰K˜‹N˜QÑˆæØˆqð ‘Fˆ	ÞØ�A‘˜‘	ˆAð ‘˜!™%Ñ  A¡EÑ*¨aÑ/ˆð —F‘F˜DŸF™F D§F¡F¨D¯F©FÐ3ˆØ�Q‰KˆØ‰KˆØ‰KˆØ‰K˜$ÑˆæØ™ ¡ q¡u¨a©eÐ3‰JˆA�!æÞØ—Y‘Y“[ !‘^�Ü  !¡%¨!©%¡-°!±%Ñ"7¸!¹%Ñ"?À2Ñ!EÓF��q’	à˜Ÿ™› a™Ñ'�Ü  !¡%¨!©%¡-°!±%Ñ"7¸!¹%Ñ"?À2Ñ!EÓF��q’	àœE¤$ q¡u¨q©u¡}Ó"5´t¸A¹EÀAÁE¹MÓ7JÓKÑKˆF�1‰IÞØ�q“	œQŸT™T A™XÑ%“	ð ˆÜ�”A—F‘F×Ñ¤ a¬¯©× 0Ñ 0ØˆDÜ�”A—F‘F×Ñ¤ a¬¯©× 0Ñ 0ØˆDà�1‹9ÞÜ! !›K¬%°«+Ñ5��q‘	Ü! !›K¬%°«+Ñ5��q’	ä! !¡#¨©¡)¨Q©S°1±3©YÓ7��q‘	Ü! !¡#¨©¡)¨Q©S°1±3©YÓ7��q’	ô +,¯&©&ˆF�1˜IœÑ&Ñ'Ø�q‹yØ()¬E°!«K©��q˜9‘}Ò%à()¬E°!«K©��q˜9‘}Ñ%Ø�q˜9‘}Ó%¶	©"¸qÑAÓ%ö Ø�1‹I˜Ñ‹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 " X‰X«5      $ )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Ü�A�q‘D˜1˜a™4‘K ! Q¡$Ñ&Ó'ˆØ‘X˜q™x¨©ˆ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  € ð> �u‰u‹wœ  A›Ñ&ˆä�˜$™‘ ! D¡'Ñ)¨A¨d©GÑ3Ó4°qÑ8ˆÜ�˜$™‘ ! D¡'Ñ)¨A¨d©GÑ3Ó4°qÑ8ˆÜ�˜$™‘ ! D¡'Ñ)¨A¨d©GÑ3Ó4°qÑ8ˆÜ�˜$™‘ ! D¡'Ñ)¨A¨d©GÑ3Ó4°qÑ8ˆà”�Q�t‘W˜q ™wÑ&Ó'Ñ'ˆØ”�Q�t‘W˜q ™wÑ&Ó'Ñ'ˆØ”�Q�t‘W˜q ™wÑ&Ó'Ñ'ˆä˜! Ó%Ð%r2   c                 ó$   • U R                  U5      $ ro   ©Úadd©r`   Úothers     r$   Ú__add__ÚQuaternion.__add__›  ó   € Ø�x‰x˜‹Ð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   € Ø�x‰x˜˜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   € Ø�x‰x˜‹{Ð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+   € Ü˜4Ÿ6™6˜' D§F¡F 7¨T¯V©V¨G°d·f±f°WÓ=Ð=r2   c                 ó$   • U [        U5      S-  -  $ r¹   ©r   r°   s     r$   Ú__truediv__ÚQuaternion.__truediv__°  s   € Ø”g˜e“n bÑ(Ñ(Ð(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Ô+Ø�yŠyÀÇ	Â	ÓJÂ	¸!Ÿ6š6 7Ð5¨fÔ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£&¨2¯4©4¡-´°B³¸"¿$¹$±ÀÇÁÀbÇdÁdÓKÐKØ×"×"Ü! "§$¡$¨¡)¨R¯T©T°2·4±4¸¿¹Ó>Ð>ä Ð!_Ó`Ð`ä˜"Ÿ$™$ §¡™+ r§t¡t¨b¯d©d¡{°B·D±D¸2¿4¹4±KÀÇÁØŸD™Dñ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Ä×2LÑ2LØ‘7ˆNô ˜"œj×)Ñ)Ø�}�} §§Ü!¤" R£&¬"¨R«&°!°QÓ7¸"Ñ<Ð<Ø×"×"Ü! "§t¡t¡)¨R·$±$©Y¸¿T¹T¹	À2ÏÉÁ9ÓMÐMä Ð!dÓeÐeô ˜"œj×)Ñ)Ø�}�} §§ØœJ¤r¨"£v¬r°"«v°q¸!Ó<Ñ<Ð<Ø×"×"Ü! "§t¡t¡)¨R·$±$©Y¸¿T¹T¹	À2ÏÉÁ9ÓMÐMä Ð!dÓeÐeð �8‰8Ñ §¡Ñ 0Ø‰Dà—7‘7“9˜rŸw™w›yÑ(ˆDä˜2Ÿ4™4˜% §¡™* r§t¡t¨B¯D©D¡yÑ0°2·4±4¸¿¹±9Ñ<¸r¿t¹tÀBÇDÁD¹yÑHØŸ$™$˜rŸt™t™) b§d¡d¨2¯4©4¡iÑ/°"·$±$°r·t±t±)Ñ;¸b¿d¹dÀ2Ç4Á4¹iÑGØŸ4™4˜% §¡™* r§t¡t¨B¯D©D¡yÑ0°2·4±4¸¿¹±9Ñ<¸r¿t¹tÀBÇDÁD¹yÑHØŸ$™$˜rŸt™t™) b§d¡d¨2¯4©4¡iÑ/°"·$±$°r·t±t±)Ñ;¸b¿d¹dÀRÇTÁT¹kÑ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   € àˆÜ˜!Ÿ#™# §¡˜t a§c¡c T¨A¯C©C¨4°a·g±gÑ>Ð>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©&¡°1·3±3¸±6Ñ!9¸A¿C¹CÀ¹FÑ!BÓCÓDÐDà�z‰zÐ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   € àˆØ�A�a—f‘f“h‘JÑÐ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;   € àˆØ�v‰v�x‰xÜÐ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ð ˆq‹5Ø—9‘9“;  ˆqà�‹6ØˆHä˜˜A˜q !Ó$ˆØ�!‹eØ�1�uØ‘�Ø‰FˆAØ�!‰GˆAð	 �!�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Ç   € ð, ˆÜ˜1Ÿ3™3 ™6 A§C¡C¨¡F™?¨Q¯S©S°!©VÑ3Ó4ˆÜ�—‘‹H”s˜;Ó'Ñ'ˆÜ�—‘‹H”s˜;Ó'Ñ'¨!¯#©#Ñ-°Ñ;ˆÜ�—‘‹H”s˜;Ó'Ñ'¨!¯#©#Ñ-°Ñ;ˆÜ�—‘‹H”s˜;Ó'Ñ'¨!¯#©#Ñ-°Ñ;ˆä˜! Ó%Ð%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µ   € ð  ˆÜ˜1Ÿ3™3 ™6 A§C¡C¨¡F™?¨Q¯S©S°!©VÑ3Ó4ˆØ—‘“ˆÜˆv‹JˆØ�C‰C”$�q—s‘s˜V‘|Ó$Ñ$ {Ñ2ˆØ�C‰C”$�q—s‘s˜V‘|Ó$Ñ$ {Ñ2ˆØ�C‰C”$�q—s‘s˜V‘|Ó$Ñ$ {Ñ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   € Ø+/¯9ª9Ó5ª9 a—F’F˜D“M©9ˆÐ5Ø�z‰zˆØÑØ—9’9˜dÐ#ˆ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º)°3ŸI™I¨˜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>   € ð< ˆØ—_‘_Ó&‰
ˆÜ×'Ñ'¨¨u©9Ó5ˆØ—V‘V“X˜q‘[Ñ!Ð!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   € ô: œ) D§F¡FÐ2¨TÒ2´I¸d¿f¹fÐ4LÀtÒ4LÜ# D§F¡FÐ2¨TÒ2´I¸d¿f¹fÐ4LÀtÒ4Ló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œ×Ñä×*Ñ*¨1¨Q©4°°1±Ó6‰Að —‘“ˆAØ”:˜a  Q¡¨¨Q©°°Q±Ó8Ñ8¼9ÀQ»<Ñ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¥   € ð* ˆØ�3‰3�?�?Ø�B‘ˆAà�K‰K‹MˆÜ˜œT !§#¡#›Y™Ó'ˆô ��Q—S‘S˜Ÿ™‘W‘Óˆä�Q—S‘S˜1‘WÓˆÜ�Q—S‘S˜1‘WÓˆÜ�Q—S‘S˜1‘WÓˆà�1ˆIˆØˆ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	/X¦U/XÍU//5      $ Uu  pïnXîU-  -
  Xø-  -
  UU	-  -
  nXþU
-  -
  Xö-  -
  UU-  -
  nUXì-  -
  Xý-  -
  UU-  -
  nS=n=nnSn[        XXU	U/X¦UU/XÍU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 ˆØ�F‰F‹H�b‰Lˆö Ø—S‘S˜!‘V˜aŸc™c 1™f‘_ q§s¡s¨A¡vÑ-°·±°Q±Ñ6Ñ7ˆCØ—S‘S˜!‘V˜aŸc™c 1™f‘_ q§s¡s¨A¡vÑ-°·±°Q±Ñ6Ñ7ˆCØ—S‘S˜!‘V˜aŸc™c 1™f‘_ q§s¡s¨A¡vÑ-°·±°Q±Ñ6Ñ7‰Cà�a˜‘c˜1Ÿ3™3 ™6 A§C¡C¨¡F™?Ñ+Ñ+ˆCØ�a˜‘c˜1Ÿ3™3 ™6 A§C¡C¨¡F™?Ñ+Ñ+ˆCØ�a˜‘c˜1Ÿ3™3 ™6 A§C¡C¨¡F™?Ñ+Ñ+ˆCà�‰c�1—3‘3�q—s‘s‘7˜QŸS™S §¡™WÑ$Ñ%ˆØ�‰c�1—3‘3�q—s‘s‘7˜QŸS™S §¡™WÑ$Ñ%ˆà�‰c�1—3‘3�q—s‘s‘7˜QŸS™S §¡™WÑ$Ñ%ˆØ�‰c�1—3‘3�q—s‘s‘7˜QŸS™S §¡™WÑ$Ñ%ˆà�‰c�1—3‘3�q—s‘s‘7˜QŸS™S §¡™WÑ$Ñ%ˆØ�‰c�1—3‘3�q—s‘s‘7˜QŸS™S §¡™WÑ$Ñ%ˆæÜ˜C c˜?¨S°s¨O¸cÈ¸_ÐMÓNÐNð ‰IˆQ�1à˜‘e‘)˜a™eÑ# a¨¡eÑ+ˆCØ˜‘e‘)˜a™eÑ# a¨¡eÑ+ˆCØ�a‘e‘)˜a™eÑ# a¨¡eÑ+ˆCØÐˆCÐ�#˜ØˆCä˜C c¨3Ð/°#¸CÀÐ1EØ S¨#Ð.°°c¸3ÀÐ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   € ð$ �v‰vˆ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!   € ô. ˜!˜TŸV™V T§V¡V¨T¯V©VÓ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 ×ÑÓ!×+Ñ+Ó-ˆä˜!˜TŸV™V T§V¡V¨T¯V©VÓ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 �v‰v�~‰~Ð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   € ð< �y‰y‹{×"Ñ"Ð"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Ó2°D×4DÑ4DÓ4FÓ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ÓJÈTÏYÉYË[Ð[`×[eÑ[eÓ[gÑMg×L{Ñ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 �R—Z‘Z“\×"Ñ"¤i°·
±
³×&=Ñ&=ÄÈ2Ï:É:Ë<×AXÑAXÜÐAÓBÐBä�R—T‘T˜2Ÿ4™4 §¡Ð&¨¯©¨r¯t©t°R·T±TÐ(:¸R¿T¹TÀ2Ç4Á4ÈÏÉÐ<NÐOÓP×TÑTÓVˆØ�y‰yÐ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à‘
˜U™ZÑ'×;Ñ;Ó=Ð=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à‘
˜U™ZÑ'×;Ñ;Ó=Ð=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   € ð> �y‰y‹{˜TŸY™Y›[Ñ(Ð(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ó ð/4ðb ñ44ó ð44ôl/%ðb ñ()ó ð()ðT ñ=*ó ð=*ô~L!ð\ ñ(ó ð(ðT ñ)&ó ð)&òVòò"ò8ò8òò>ò)ò)ò%òLò4"òl'8ðR ñI%ó ðI%òV?ò
ò ò
.ò+òZ&ò>&ò40òFò2!"òFNð@ ñ*(ó ð*(òX&ôPJGòXò(5ò2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   