U
    	-ek                     @   s   d dl mZmZmZmZmZmZmZmZ	m
Z
 d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ dgZG dd deeZG d	d
 d
eZdd ZdS )    )	SsympifyexpandsqrtAddzerosacosImmutableMatrix_simplify_matrix)trigsimp)	Printable)
filldedent)
EvalfMixin)prec_to_dpsVectorc                   @   sf  e Zd ZdZdZdZdd Zedd Zdd Z	d	d
 Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd ZdMd d!Zd"d# Zd$d% Ze
ZeZeZd&d' Zd(d) Zeje_d*d+ Zeje_d,d- Zeje_dNd.d/ZdOd0d1Z d2d3 Z!d4d5 Z"d6d7 Z#d8d9 Z$d:d; Z%d<d= Z&d>d? Z'd@dA Z(dBdC Z)dDdE Z*dFdG Z+dHdI Z,dJdK Z-dLS )Pr   a  The class used to define vectors.

    It along with ReferenceFrame are the building blocks of describing a
    classical mechanics system in PyDy and sympy.physics.vector.

    Attributes
    ==========

    simp : Boolean
        Let certain methods use trigsimp on their outputs

    Fc                 C   s   g | _ |dkrg }t|tr"|}nDi }|D ]:}|d |krT||d   |d 7  < q*|d ||d < q*| D ]*\}}|tdddgkrn| j ||f qndS )a  This is the constructor for the Vector class.  You should not be
        calling this, it should only be used by other functions. You should be
        treating Vectors like you would with if you were doing the math by
        hand, and getting the first 3 from the standard basis vectors from a
        ReferenceFrame.

        The only exception is to create a zero vector:
        zv = Vector(0)

        r      N)args
isinstancedictitemsMatrixappend)selfinlistdZinpkv r   \/var/www/html/Darija-Ai-Train/env/lib/python3.8/site-packages/sympy/physics/vector/vector.py__init__   s    
zVector.__init__c                 C   s   t S )zReturns the class Vector. )r   r   r   r   r   func<   s    zVector.funcc                 C   s   t t| jS N)hashtupler   r    r   r   r   __hash__A   s    zVector.__hash__c                 C   s$   |dkr| S t |}t| j|j S )zThe add operator for Vector. r   )_check_vectorr   r   r   otherr   r   r   __add__D   s    zVector.__add__c                 C   s   ddl m} t||rtS t|}tj}t| jD ]H\}}t|jD ]4\}}||d j	|d 
|d  |d  d 7 }qDq2tjrt|ddS |S dS )aG  Dot product of two vectors.

        Returns a scalar, the dot product of the two Vectors

        Parameters
        ==========

        other : Vector
            The Vector which we are dotting with

        Examples
        ========

        >>> from sympy.physics.vector import ReferenceFrame, dot
        >>> from sympy import symbols
        >>> q1 = symbols('q1')
        >>> N = ReferenceFrame('N')
        >>> dot(N.x, N.x)
        1
        >>> dot(N.x, N.y)
        0
        >>> A = N.orientnew('A', 'Axis', [q1, N.x])
        >>> dot(N.y, A.y)
        cos(q1)

        r   Dyadicr   T)	recursiveN)sympy.physics.vector.dyadicr+   r   NotImplementedr&   r   ZZero	enumerater   Tdcmr   simpr   )r   r(   r+   outiZv1jv2r   r   r   __and__K   s"    


zVector.__and__c                 C   s   |  tj| S )z6This uses mul and inputs self and 1 divided by other. )__mul__r   ZOner'   r   r   r   __truediv__v   s    zVector.__truediv__c                 C   s   |dkrt d}zt|}W n tk
r2   Y dS X | jg krL|jg krLdS | jg ks`|jg krddS | jd d }|D ]}t| | |@ dkrv dS qvdS )at  Tests for equality.

        It is very import to note that this is only as good as the SymPy
        equality test; False does not always mean they are not equivalent
        Vectors.
        If other is 0, and self is empty, returns True.
        If other is 0 and self is not empty, returns False.
        If none of the above, only accepts other as a Vector.

        r   FTr   )r   r&   	TypeErrorr   r   )r   r(   framer   r   r   r   __eq__z   s    zVector.__eq__c                 C   sL   t | j}t|}t|D ](\}}||| d  || d f||< qt|S )a  Multiplies the Vector by a sympifyable expression.

        Parameters
        ==========

        other : Sympifyable
            The scalar to multiply this Vector with

        Examples
        ========

        >>> from sympy.physics.vector import ReferenceFrame
        >>> from sympy import Symbol
        >>> N = ReferenceFrame('N')
        >>> b = Symbol('b')
        >>> V = 10 * b * N.x
        >>> print(V)
        10*b*N.x

        r   r   )listr   r   r/   r   )r   r(   Znewlistr4   r   r   r   r   r8      s
    
"zVector.__mul__c                 C   s   | d S Nr   r    r   r   r   __neg__   s    zVector.__neg__c                 C   s   ddl m} t|}|d}t| jD ]\}}t|jD ]\}}|||d d |d d  |d j|d jfg7 }|||d d |d d  |d j|d jfg7 }|||d d |d d  |d j|d jfg7 }|||d d |d d  |d j|d jfg7 }|||d d |d d  |d j|d jfg7 }|||d d |d d  |d j|d jfg7 }|||d d |d d  |d j|d jfg7 }|||d d |d d  |d j|d jfg7 }|||d d |d d  |d j|d jfg7 }q:q&|S a  Outer product between two Vectors.

        A rank increasing operation, which returns a Dyadic from two Vectors

        Parameters
        ==========

        other : Vector
            The Vector to take the outer product with

        Examples
        ========

        >>> from sympy.physics.vector import ReferenceFrame, outer
        >>> N = ReferenceFrame('N')
        >>> outer(N.x, N.x)
        (N.x|N.x)

        r   r*   r      r-   r+   r&   r/   r   xyzr   r(   r+   olr4   r   i2r6   r   r   r   __or__   s    444444448zVector.__or__c           
      C   sl  | j }t|dkrtdS g }t|D ]\}}dD ]}|| d | dkrj|d|| d j|   q4|| d | dkr|d|| d j|   q4|| d | dkr4||| d | }t|| d | trd| }|d dkr|dd	 }d}nd}||| || d j|   q4q&d
	|}	|	
drP|	dd	 }	n|	
drh|	dd	 }	|	S )zLatex Printing method. r   r   r   rB   r    + r?    - (%s)-N     )r   lenstrr/   r   Z
latex_vecs_printr   r   join
startswith)
r   printerarrH   r4   r   r5   arg_str	str_startoutstrr   r   r   _latex   s2    $
zVector._latexc                    s,   ddl m |  G  fddd}| S )zPretty Printing method. r   )
prettyFormc                       s   e Zd Z fddZdS )zVector._pretty.<locals>.Fakec                    s   j }t|dkrtdS g }t|D ]\}}dD ]
}|| d | dkrh|| d j| }n|| d | dkr|| d j| }|d }j}	|d|	i}n~|| d | dkr4|| d | }t|| d | t	r|
 }
|
d |
d }|d|| d j|  }nq4|| q4q&j| }|d|d< |d	|d	< |j||}d
d |dD }d|S )Nr   rK   r   r?   rM   ZbindingrR   Z	wrap_lineZnum_columnsc                 S   s   g | ]}|  qS r   )rstrip).0liner   r   r   
<listcomp>*  s     z7Vector._pretty.<locals>.Fake.render.<locals>.<listcomp>
)r   rS   rT   r/   rU   Zpretty_vecsleftZNEGr   r   parensrightr   r)   getrendersplitrV   )r   r   kwargsrY   Zpformsr4   r   r5   ZpformbintmpZout_strZmlineser^   rX   r   r   rh     s<    
 
z#Vector._pretty.<locals>.Fake.renderN)__name__
__module____qualname__rh   r   rm   r   r   Fake  s   rr   )Z sympy.printing.pretty.stringpictr^   )r   rX   rr   r   rm   r   _pretty   s    (zVector._prettyc                 C   s   ddl m} t|}|d}t|jD ]\}}t| jD ]\}}|||d d |d d  |d j|d jfg7 }|||d d |d d  |d j|d jfg7 }|||d d |d d  |d j|d jfg7 }|||d d |d d  |d j|d jfg7 }|||d d |d d  |d j|d jfg7 }|||d d |d d  |d j|d jfg7 }|||d d |d d  |d j|d jfg7 }|||d d |d d  |d j|d jfg7 }|||d d |d d  |d j|d jfg7 }q:q&|S rA   rC   rG   r   r   r   __ror__/  s    444444448zVector.__ror__c                 C   s   d|  | S r>   r   r'   r   r   r   __rsub__W  s    zVector.__rsub__Tc                 C   s  |rt | jdkrt| j}n\t | jdkr6|dS dd | jD }t| dd d}g }|D ]}||| |f qbg }t|D ]\}}	dD ]}
|| d |
 dkr|d	|| d j|
   q|| d |
 d
kr|d|| d j|
   q|| d |
 dkr||| d |
 }t	|| d |
 t
rFd| }|d dkrf|dd }d}nd	}||| d || d j|
   qqd|}|d	r|dd }n|dr|dd }|S )zPrinting method. r   r   c                 S   s   i | ]}|d  |d qS )r   r   r   )r`   r   r   r   r   
<dictcomp>a  s      z$Vector._sympystr.<locals>.<dictcomp>c                 S   s   | j S r"   )indexrD   r   r   r   <lambda>b      z"Vector._sympystr.<locals>.<lambda>)keyrK   rL   r?   rM   rN   rO   N*rP   rQ   rR   )rS   r   r=   rU   sortedkeysr   r/   Zstr_vecsr   r   rV   rW   )r   rX   orderrY   r   r~   r{   rH   r4   r   r5   rZ   r[   r\   r   r   r   	_sympystrZ  s>    
(
zVector._sympystrc                 C   s   |  |d S )zThe subtraction operator. r?   )r)   r'   r   r   r   __sub__  s    zVector.__sub__c                 C   s   ddl m} t||rtS t|}|jg kr4tdS dd }g }|j}t|D ]\}}|d j}|d j	}	|d j
}
||	|
g| |@ | |	@ | |
@ gt|| g|@ t|| g|	@ t|| g|
@ gg}|||j7 }qNt|S )a  The cross product operator for two Vectors.

        Returns a Vector, expressed in the same ReferenceFrames as self.

        Parameters
        ==========

        other : Vector
            The Vector which we are crossing with

        Examples
        ========

        >>> from sympy import symbols
        >>> from sympy.physics.vector import ReferenceFrame, cross
        >>> q1 = symbols('q1')
        >>> N = ReferenceFrame('N')
        >>> cross(N.x, N.y)
        N.z
        >>> A = ReferenceFrame('A')
        >>> A.orient_axis(N, q1, N.x)
        >>> cross(A.x, N.y)
        N.z
        >>> cross(N.y, A.x)
        - sin(q1)*A.y - cos(q1)*A.z

        r   r*   c                 S   s   | d d | d d | d d  | d d | d d    | d d | d d | d d  | d d | d d     | d d | d d | d d  | d d | d d     S )a  This is needed as a little method for to find the determinant
            of a list in python; needs to work for a 3x3 list.
            SymPy's Matrix will not take in Vector, so need a custom function.
            You should not be calling this.

            r   r   rB   r   )matr   r   r   _det  s    :*
 zVector.__xor__.<locals>._detr   )r-   r+   r   r.   r&   r   r   r/   rD   rE   rF   )r   r(   r+   r   ZoutlistrY   r4   r   ZtempxZtempyZtempzZtempmr   r   r   __xor__  s*    




 zVector.__xor__c                 C   s&   i }| j D ]}t|g||d < q
|S )a  
        The constituents of this vector in different reference frames,
        as per its definition.

        Returns a dict mapping each ReferenceFrame to the corresponding
        constituent Vector.

        Examples
        ========

        >>> from sympy.physics.vector import ReferenceFrame
        >>> R1 = ReferenceFrame('R1')
        >>> R2 = ReferenceFrame('R2')
        >>> v = R1.x + R2.x
        >>> v.separate() == {R1: R1.x, R2: R2.x}
        True

        r   )r   r   )r   
componentsrD   r   r   r   separate  s    
zVector.separatec                 C   s   | |@ S r"   r   r'   r   r   r   dot  s    z
Vector.dotc                 C   s   | |A S r"   r   r'   r   r   r   cross  s    zVector.crossc                 C   s   | |B S r"   r   r'   r   r   r   outer  s    zVector.outerc                 C   s   ddl m} || t|}g }| jD ]}|d }|d }||krX||||fg7 }q&|rv|||tddkr||||fg7 }q&t|g|}	|	jd d |}
|t|
|fgj7 }q&t|S )a2  Returns the partial derivative of the vector with respect to a
        variable in the provided reference frame.

        Parameters
        ==========
        var : Symbol
            What the partial derivative is taken with respect to.
        frame : ReferenceFrame
            The reference frame that the partial derivative is taken in.
        var_in_dcm : boolean
            If true, the differentiation algorithm assumes that the variable
            may be present in any of the direction cosine matrices that relate
            the frame to the frames of any component of the vector. But if it
            is known that the variable is not present in the direction cosine
            matrices, false can be set to skip full reexpression in the desired
            frame.

        Examples
        ========

        >>> from sympy import Symbol
        >>> from sympy.physics.vector import dynamicsymbols, ReferenceFrame
        >>> from sympy.physics.vector import Vector
        >>> from sympy.physics.vector import init_vprinting
        >>> init_vprinting(pretty_print=False)
        >>> Vector.simp = True
        >>> t = Symbol('t')
        >>> q1 = dynamicsymbols('q1')
        >>> N = ReferenceFrame('N')
        >>> A = N.orientnew('A', 'Axis', [q1, N.y])
        >>> A.x.diff(t, N)
        - sin(q1)*q1'*N.x - cos(q1)*q1'*N.z
        >>> A.x.diff(t, N).express(A)
        - q1'*A.z
        >>> B = ReferenceFrame('B')
        >>> u1, u2 = dynamicsymbols('u1, u2')
        >>> v = u1 * A.x + u2 * B.y
        >>> v.diff(u2, N, var_in_dcm=False)
        B.y

        r   )_check_framer   rQ   )	Zsympy.physics.vector.framer   r   r   diffr1   r   r   express)r   varr;   Z
var_in_dcmr   r   Zvector_componentZmeasure_numberZcomponent_frameZreexp_vec_compZderivr   r   r   r     s"    +
zVector.diffc                 C   s   ddl m} || ||dS )a,  
        Returns a Vector equivalent to this one, expressed in otherframe.
        Uses the global express method.

        Parameters
        ==========

        otherframe : ReferenceFrame
            The frame for this Vector to be described in

        variables : boolean
            If True, the coordinate symbols(if present) in this Vector
            are re-expressed in terms otherframe

        Examples
        ========

        >>> from sympy.physics.vector import ReferenceFrame, dynamicsymbols
        >>> from sympy.physics.vector import init_vprinting
        >>> init_vprinting(pretty_print=False)
        >>> q1 = dynamicsymbols('q1')
        >>> N = ReferenceFrame('N')
        >>> A = N.orientnew('A', 'Axis', [q1, N.y])
        >>> A.x.express(N)
        cos(q1)*N.x - sin(q1)*N.z

        r   )r   )	variables)sympy.physics.vectorr   )r   
otherframer   r   r   r   r   r   1  s    zVector.expressc                    s   t  fdd|D ddS )a  Returns the matrix form of the vector with respect to the given
        frame.

        Parameters
        ----------
        reference_frame : ReferenceFrame
            The reference frame that the rows of the matrix correspond to.

        Returns
        -------
        matrix : ImmutableMatrix, shape(3,1)
            The matrix that gives the 1D vector.

        Examples
        ========

        >>> from sympy import symbols
        >>> from sympy.physics.vector import ReferenceFrame
        >>> a, b, c = symbols('a, b, c')
        >>> N = ReferenceFrame('N')
        >>> vector = a * N.x + b * N.y + c * N.z
        >>> vector.to_matrix(N)
        Matrix([
        [a],
        [b],
        [c]])
        >>> beta = symbols('beta')
        >>> A = N.orientnew('A', 'Axis', (beta, N.x))
        >>> vector.to_matrix(A)
        Matrix([
        [                         a],
        [ b*cos(beta) + c*sin(beta)],
        [-b*sin(beta) + c*cos(beta)]])

        c                    s   g | ]}  |qS r   )r   )r`   Zunit_vecr    r   r   rb   u  s     z$Vector.to_matrix.<locals>.<listcomp>rQ   r   )r   Zreshaper   reference_framer   r    r   	to_matrixP  s    % zVector.to_matrixc                    s6   i }| j D ]"}|d  fdd||d < q
t|S )z(Calls .doit() on each term in the Vectorr   c                    s   | j f  S r"   )doitrx   hintsr   r   ry   |  rz   zVector.doit.<locals>.<lambda>r   )r   	applyfuncr   )r   r   r   r   r   r   r   r   x  s    
 zVector.doitc                 C   s   ddl m} || |S )a.  
        Returns a Vector which is the time derivative of
        the self Vector, taken in frame otherframe.

        Calls the global time_derivative method

        Parameters
        ==========

        otherframe : ReferenceFrame
            The frame to calculate the time derivative in

        r   )time_derivative)r   r   )r   r   r   r   r   r   dt  s    z	Vector.dtc                 C   s,   i }| j D ]}t|d ||d < q
t|S )zReturns a simplified Vector.r   r   )r   r
   r   )r   r   r   r   r   r   simplify  s    
zVector.simplifyc                 O   s0   i }| j D ]}|d j||||d < q
t|S )a+  Substitution on the Vector.

        Examples
        ========

        >>> from sympy.physics.vector import ReferenceFrame
        >>> from sympy import Symbol
        >>> N = ReferenceFrame('N')
        >>> s = Symbol('s')
        >>> a = N.x * s
        >>> a.subs({s: 2})
        2*N.x

        r   r   )r   subsr   )r   r   rj   r   r   r   r   r   r     s    
zVector.subsc                 C   s   t | | @ S )a,  Returns the magnitude (Euclidean norm) of self.

        Warnings
        ========

        Python ignores the leading negative sign so that might
        give wrong results.
        ``-A.x.magnitude()`` would be treated as ``-(A.x.magnitude())``,
        instead of ``(-A.x).magnitude()``.

        )r   r    r   r   r   	magnitude  s    zVector.magnitudec                 C   s   t | jg  |   S )z9Returns a Vector of magnitude 1, codirectional with self.)r   r   r   r    r   r   r   	normalize  s    zVector.normalizec                 C   s>   t |stdi }| jD ]}|d |||d < qt|S )z/Apply a function to each component of a vector.z`f` must be callable.r   r   )callabler:   r   r   r   )r   fr   r   r   r   r   r     s    
zVector.applyfuncc                 C   s"   |   }|  }t||}|S )a  
        Returns the smallest angle between Vector 'vec' and self.

        Parameter
        =========

        vec : Vector
            The Vector between which angle is needed.

        Examples
        ========

        >>> from sympy.physics.vector import ReferenceFrame
        >>> A = ReferenceFrame("A")
        >>> v1 = A.x
        >>> v2 = A.y
        >>> v1.angle_between(v2)
        pi/2

        >>> v3 = A.x + A.y + A.z
        >>> v1.angle_between(v3)
        acos(sqrt(3)/3)

        Warnings
        ========

        Python ignores the leading negative sign so that might give wrong
        results. ``-A.x.angle_between()`` would be treated as
        ``-(A.x.angle_between())``, instead of ``(-A.x).angle_between()``.

        )r   r   r   )r   ZvecZvec1Zvec2Zangler   r   r   angle_between  s    !zVector.angle_betweenc                 C   s   |  |jS )a  Returns the free symbols in the measure numbers of the vector
        expressed in the given reference frame.

        Parameters
        ==========
        reference_frame : ReferenceFrame
            The frame with respect to which the free symbols of the given
            vector is to be determined.

        Returns
        =======
        set of Symbol
            set of symbols present in the measure numbers of
            ``reference_frame``.

        )r   free_symbolsr   r   r   r   r     s    zVector.free_symbolsc                 C   s   ddl m} || |dS )a  Returns the free dynamic symbols (functions of time ``t``) in the
        measure numbers of the vector expressed in the given reference frame.

        Parameters
        ==========
        reference_frame : ReferenceFrame
            The frame with respect to which the free dynamic symbols of the
            given vector is to be determined.

        Returns
        =======
        set
            Set of functions of time ``t``, e.g.
            ``Function('f')(me.dynamicsymbols._t)``.

        r   )find_dynamicsymbols)r   )Z!sympy.physics.mechanics.functionsr   )r   r   r   r   r   r   free_dynamicsymbols  s    zVector.free_dynamicsymbolsc                 C   sD   | j s
| S g }t|}| j D ]\}}||j|d|g qt|S )N)n)r   r   r   Zevalfr   )r   precnew_argsZdpsr   r;   r   r   r   _eval_evalf  s    zVector._eval_evalfc                 C   s4   g }| j D ] \}}||}|||g q
t|S )an  Replace occurrences of objects within the measure numbers of the
        vector.

        Parameters
        ==========

        rule : dict-like
            Expresses a replacement rule.

        Returns
        =======

        Vector
            Result of the replacement.

        Examples
        ========

        >>> from sympy import symbols, pi
        >>> from sympy.physics.vector import ReferenceFrame
        >>> A = ReferenceFrame('A')
        >>> x, y, z = symbols('x y z')
        >>> ((1 + x*y) * A.x).xreplace({x: pi})
        (pi*y + 1)*A.x
        >>> ((1 + x*y) * A.x).xreplace({x: pi, y: 2})
        (1 + 2*pi)*A.x

        Replacements occur only if an entire node in the expression tree is
        matched:

        >>> ((x*y + z) * A.x).xreplace({x*y: pi})
        (z + pi)*A.x
        >>> ((x*y*z) * A.x).xreplace({x*y: pi})
        x*y*z*A.x

        )r   xreplacer   r   )r   ruler   r   r;   r   r   r   r   "  s
    &
zVector.xreplaceN)T)T)F).ro   rp   rq   __doc__r2   Z	is_numberr   propertyr!   r%   r)   r7   r9   r<   r8   r@   rJ   r]   rs   rt   ru   r   r   r   __radd____rand____rmul__r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r      s\   
+("/(
(>
D
(
&	c                       s   e Zd Z fddZ  ZS )VectorTypeErrorc                    s*   t dt||t|f }t | d S )Nz;Expected an instance of %s, but received object '%s' of %s.)r   typesuperr   )r   r(   Zwantmsg	__class__r   r   r   Q  s    zVectorTypeError.__init__)ro   rp   rq   r   __classcell__r   r   r   r   r   O  s   r   c                 C   s   t | tstd| S )NzA Vector must be supplied)r   r   r:   )r(   r   r   r   r&   W  s    
r&   N)Zsympy.core.backendr   r   r   r   r   r   r   r	   r   r
   Zsympy.simplify.trigsimpr   Zsympy.printing.defaultsr   Zsympy.utilities.miscr   Zsympy.core.evalfr   Zmpmath.libmp.libmpfr   __all__r   r:   r   r&   r   r   r   r   <module>   s   ,      G