o
    8VaK                     @   sT   d dl mZmZmZ d dlmZmZ d dlm	Z	 dgZ
G dd de	eZdd ZdS )	    )sympifyAddImmutableMatrix)
EvalfMixinprec_to_dps)	PrintableDyadicc                   @   s   e 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dd  Zd!d" Zd#d$ ZeZeZd8d&d'Zd8d(d)Zd*d+ Zd,d- Zd.d/ Zd0d1 Zd2d3 Ze	Z eZ!d4d5 Z"d6d7 Z#d%S )9r   ay  A Dyadic object.

    See:
    https://en.wikipedia.org/wiki/Dyadic_tensor
    Kane, T., Levinson, D. Dynamics Theory and Applications. 1985 McGraw-Hill

    A more powerful way to represent a rigid body's inertia. While it is more
    complex, by choosing Dyadic components to be in body fixed basis vectors,
    the resulting matrix is equivalent to the inertia tensor.

    Fc                 C   sx  g | _ |dkr	g }t|dkr|d}t| j D ]L\}}t|d d t| j | d krbt|d d t| j | d krb| j | d |d d  |d d |d d f| j |< ||d  d} nq|dkrv| j |d  ||d  t|dksd}|t| j k r| j | d dk| j | d dkB | j | d dkB r| j | j |  |d8 }|d7 }|t| j k sdS dS )a1  
        Just like Vector's init, you shouldn't call this unless creating a
        zero dyadic.

        zd = Dyadic(0)

        Stores a Dyadic as a list of lists; the inner list has the measure
        number and the two unit vectors; the outerlist holds each unique
        unit vector pair.

        r         N)argslen	enumeratestrremoveappend)selfinlistZaddediv r   =/usr/lib/python3/dist-packages/sympy/physics/vector/dyadic.py__init__   s:   " 
"zDyadic.__init__c                 C   s   t S )zReturns the class Dyadic. )r   r   r   r   r   func=   s   zDyadic.funcc                 C   s   t |}t| j|j S )zThe add operator for Dyadic. )_check_dyadicr   r   r   otherr   r   r   __add__B   s   zDyadic.__add__c           	      C   s   ddl m}m} t|trEt|}td}t| jD ](\}}t|jD ]\}}||d |d  |d |d @  |d |d B  7 }q#q|S ||}|d}t| jD ]\}}||d |d  |d |@  7 }qR|S )a  The inner product operator for a Dyadic and a Dyadic or Vector.

        Parameters
        ==========

        other : Dyadic or Vector
            The other Dyadic or Vector to take the inner product with

        Examples
        ========

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

        r   Vector_check_vectorr
   r	   )sympy.physics.vector.vectorr   r    
isinstancer   r   r   r   )	r   r   r   r    olr   r   Zi2Zv2r   r   r   __and__G   s   
6"zDyadic.__and__c                 C   s   |  d| S )z0Divides the Dyadic by a sympifyable expression. r	   )__mul__r   r   r   r   __truediv__k      zDyadic.__truediv__c                 C   s\   |dkrt d}t|}| jg kr|jg krdS | jg ks"|jg kr$dS t| jt|jkS )z[Tests for equality.

        Is currently weak; needs stronger comparison testing

        r   TF)r   r   r   setr   r   r   r   __eq__o   s   zDyadic.__eq__c                 C   sX   dd | j D }t|D ]\}}t||| d  || d || d f||< qt|S )a  Multiplies the Dyadic by a sympifyable expression.

        Parameters
        ==========

        other : Sympafiable
            The scalar to multiply this Dyadic with

        Examples
        ========

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

        c                 S   s   g | ]}|qS r   r   .0r   r   r   r   
<listcomp>   s    z"Dyadic.__mul__.<locals>.<listcomp>r   r	   r
   )r   r   r   r   )r   r   Znewlistr   r   r   r   r   r%      s   

zDyadic.__mul__c                 C   s
   | |k S Nr   r   r   r   r   __ne__   s   
zDyadic.__ne__c                 C   s   | d S Nr   r   r   r   r   __neg__   s   zDyadic.__neg__c           	      C   s  | j }t|dkrtdS g }t|D ]\}}|| d dkr9|d||| d  d ||| d   q|| d dkr[|d||| d  d ||| d   q|| d dkr||| d }t|| d tryd| }|d	r|dd  }d}nd}||| ||| d  d ||| d   qd
	|}|dr|dd  }|S |dr|dd  }|S )Nr   r	    + z\otimes r
   r0    - (%s)-     )
r   r   r   r   r   _printr"   r   
startswithjoin	r   printerarr#   r   r   arg_str	str_startoutstrr   r   r   _latex   sL   



zDyadic._latexc                    s   |  G  fddd}| S )Nc                       s   e Zd ZdZ fddZdS )zDyadic._pretty.<locals>.Faker   c                    s   j }}t|dkrtdS jrdnd}g }t|D ]\}}|| d dkr@|d||| d |||| d g q|| d dkr`|d||| d |||| d g q|| d dkrt|| d tr|	|| d 
 d }	n	||| d }	|	d	r|	dd  }	d}
nd}
||
|	d
||| d |||| d g qd|}|dr|dd  }|S |d
r|dd  }|S )Nr   u   ⊗|r	   r2   r
   r0   r3   r5   r8   r6   r7   )r   r   r   Z_use_unicoder   extendZdoprintr"   r   r9   Zparensr:   r;   )r   r   kwargsr>   ZmppZbarr#   r   r   r?   r@   rA   er=   r   r   render   sX   





z#Dyadic._pretty.<locals>.Fake.renderN)__name__
__module____qualname__ZbaselinerH   r   rF   r   r   Fake   s    rL   r   )r   r=   rL   r   rF   r   _pretty   s   1zDyadic._prettyc                 C   sX   ddl m}m} ||}|d}t| jD ]\}}||d |d  |d |@  7 }q|S )a  The inner product operator for a Vector or Dyadic, and a Dyadic

        This is for: Vector dot Dyadic

        Parameters
        ==========

        other : Vector
            The vector we are dotting with

        Examples
        ========

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

        r   r   r
   r	   )r!   r   r    r   r   )r   r   r   r    r#   r   r   r   r   r   __rand__   s   "zDyadic.__rand__c                 C   s   d|  | S r/   r   r   r   r   r   __rsub__  s   zDyadic.__rsub__c                 C   sT   ddl m} ||}td}t| jD ]\}}||d ||d A |d B  7 }q|S )a  For a cross product in the form: Vector x Dyadic

        Parameters
        ==========

        other : Vector
            The Vector that we are crossing this Dyadic with

        Examples
        ========

        >>> from sympy.physics.vector import ReferenceFrame, outer, cross
        >>> N = ReferenceFrame('N')
        >>> d = outer(N.x, N.x)
        >>> cross(N.y, d)
        - (N.z|N.x)

        r   r    r	   r
   r!   r    r   r   r   r   r   r    r#   r   r   r   r   r   __rxor__     "zDyadic.__rxor__c           	      C   s  | j }t|dkr|dS g }t|D ]\}}|| d dkr<|d||| d  d ||| d  d  q|| d dkr`|d||| d  d ||| d  d  q|| d dkr||| d }t|| d tr~d	| }|d d
kr|dd }d}nd}||| d ||| d  d ||| d  d  qd|}|dr|dd }|S |dr|dd }|S )zPrinting method. r   r	   z + (rC   r
   )r0   z - (r4   r5   Nr3   r2   z*(r6   r7   r8   )	r   r   r9   r   r   r"   r   r;   r:   r<   r   r   r   	_sympystr4  s@   
88 


zDyadic._sympystrc                 C   s   |  |d S )zThe subtraction operator. r0   )r   r   r   r   r   __sub__U  r'   zDyadic.__sub__c                 C   sT   ddl m} ||}td}t| jD ]\}}||d |d |d |A B  7 }q|S )a  For a cross product in the form: Dyadic x Vector.

        Parameters
        ==========

        other : Vector
            The Vector that we are crossing this Dyadic with

        Examples
        ========

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

        r   rP   r	   r
   rQ   rR   r   r   r   __xor__Y  rT   zDyadic.__xor__Nc                 C   s   ddl m} || ||S )a  Expresses this Dyadic in alternate frame(s)

        The first frame is the list side expression, the second frame is the
        right side; if Dyadic is in form A.x|B.y, you can express it in two
        different frames. If no second frame is given, the Dyadic is
        expressed in only one frame.

        Calls the global express function

        Parameters
        ==========

        frame1 : ReferenceFrame
            The frame to express the left side of the Dyadic in
        frame2 : ReferenceFrame
            If provided, the frame to express the right side of the Dyadic in

        Examples
        ========

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

        r   )express)sympy.physics.vector.functionsrY   )r   Zframe1Zframe2rY   r   r   r   rY   w  s    zDyadic.expressc                    s,    du r| t  fdd|D ddS )a  Returns the matrix form of the dyadic with respect to one or two
        reference frames.

        Parameters
        ----------
        reference_frame : ReferenceFrame
            The reference frame that the rows and columns of the matrix
            correspond to. If a second reference frame is provided, this
            only corresponds to the rows of the matrix.
        second_reference_frame : ReferenceFrame, optional, default=None
            The reference frame that the columns of the matrix correspond
            to.

        Returns
        -------
        matrix : ImmutableMatrix, shape(3,3)
            The matrix that gives the 2D tensor form.

        Examples
        ========

        >>> from sympy import symbols
        >>> from sympy.physics.vector import ReferenceFrame, Vector
        >>> Vector.simp = True
        >>> from sympy.physics.mechanics import inertia
        >>> Ixx, Iyy, Izz, Ixy, Iyz, Ixz = symbols('Ixx, Iyy, Izz, Ixy, Iyz, Ixz')
        >>> N = ReferenceFrame('N')
        >>> inertia_dyadic = inertia(N, Ixx, Iyy, Izz, Ixy, Iyz, Ixz)
        >>> inertia_dyadic.to_matrix(N)
        Matrix([
        [Ixx, Ixy, Ixz],
        [Ixy, Iyy, Iyz],
        [Ixz, Iyz, Izz]])
        >>> beta = symbols('beta')
        >>> A = N.orientnew('A', 'Axis', (beta, N.x))
        >>> inertia_dyadic.to_matrix(A)
        Matrix([
        [                           Ixx,                                           Ixy*cos(beta) + Ixz*sin(beta),                                           -Ixy*sin(beta) + Ixz*cos(beta)],
        [ Ixy*cos(beta) + Ixz*sin(beta), Iyy*cos(2*beta)/2 + Iyy/2 + Iyz*sin(2*beta) - Izz*cos(2*beta)/2 + Izz/2,                 -Iyy*sin(2*beta)/2 + Iyz*cos(2*beta) + Izz*sin(2*beta)/2],
        [-Ixy*sin(beta) + Ixz*cos(beta),                -Iyy*sin(2*beta)/2 + Iyz*cos(2*beta) + Izz*sin(2*beta)/2, -Iyy*cos(2*beta)/2 + Iyy/2 - Iyz*sin(2*beta) + Izz*cos(2*beta)/2 + Izz/2]])

        Nc                    s&   g | ]} D ]
}|  |qqS r   )dot)r+   r   jsecond_reference_framer   r   r   r,     s    z$Dyadic.to_matrix.<locals>.<listcomp>r7   )MatrixZreshape)r   Zreference_framer^   r   r]   r   	to_matrix  s
   ,zDyadic.to_matrixc                    s   t  fdd| jD tdS )z(Calls .doit() on each term in the Dyadicc                    s4   g | ]}t |d  jdi  |d |d fgqS )r   r	   r
   r   )r   doitr*   hintsr   r   r,         ,zDyadic.doit.<locals>.<listcomp>r   sumr   r   )r   rc   r   rb   r   ra     s
   zDyadic.doitc                 C   s   ddl m} || |S )a  Take the time derivative of this Dyadic in a frame.

        This function calls the global time_derivative method

        Parameters
        ==========

        frame : ReferenceFrame
            The frame to take the time derivative in

        Examples
        ========

        >>> from sympy.physics.vector import ReferenceFrame, outer, dynamicsymbols
        >>> from sympy.physics.vector import init_vprinting
        >>> init_vprinting(pretty_print=False)
        >>> N = ReferenceFrame('N')
        >>> q = dynamicsymbols('q')
        >>> B = N.orientnew('B', 'Axis', [q, N.z])
        >>> d = outer(N.x, N.x)
        >>> d.dt(B)
        - q'*(N.y|N.x) - q'*(N.x|N.y)

        r   )time_derivative)rZ   rg   )r   framerg   r   r   r   dt  s   
z	Dyadic.dtc                 C   s<   t d}| jD ]}|t |d  |d |d fg7 }q|S )zReturns a simplified Dyadic.r   r	   r
   )r   r   simplify)r   outr   r   r   r   rj     s   
&zDyadic.simplifyc                    s    t  fdd| jD tdS )a5  Substitution on the Dyadic.

        Examples
        ========

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

        c                    s4   g | ]}t |d  j i |d |d fgqS )r   r	   r
   )r   subsr*   r   rE   r   r   r,     rd   zDyadic.subs.<locals>.<listcomp>r   re   )r   r   rE   r   rm   r   rl     s
   zDyadic.subsc                 C   sB   t |stdtd}| jD ]\}}}|||||B  7 }q|S )z/Apply a function to each component of a Dyadic.z`f` must be callable.r   )callable	TypeErrorr   r   )r   frk   abcr   r   r   	applyfunc  s   zDyadic.applyfuncc                 C   sP   | j s| S g }| j D ]}t|}|d jt|d|d< |t| q
t|S )Nr   )n)r   listZevalfr   r   tupler   )r   Zprecnew_argsr   
new_inlistr   r   r   _eval_evalf  s   
zDyadic._eval_evalfc                 C   s@   g }| j D ]}t|}|d ||d< |t| qt|S )a  
        Replace occurrences of objects within the measure numbers of the Dyadic.

        Parameters
        ==========

        rule : dict-like
            Expresses a replacement rule.

        Returns
        =======

        Dyadic
            Result of the replacement.

        Examples
        ========

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

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

        >>> ((x*y + z) * D).xreplace({x*y: pi})
        (z + pi)*(N.x|N.x)
        >>> ((x*y*z) * D).xreplace({x*y: pi})
        x*y*z*(N.x|N.x)

        r   )r   rv   xreplacer   rw   r   )r   Zrulerx   r   ry   r   r   r   r{     s   '
zDyadic.xreplacer-   )$rI   rJ   rK   __doc__Z	is_numberr   propertyr   r   r$   r&   r)   r%   r.   r1   rB   rM   rN   rO   rS   rV   rW   rX   __radd____rmul__rY   r`   ra   ri   rj   rl   rt   r[   Zcrossrz   r{   r   r   r   r   r      sD    &
$$6!

#2

c                 C   s   t | ts	td| S )NzA Dyadic must be supplied)r"   r   ro   )r   r   r   r   r   L  s   
r   N)Zsympy.core.backendr   r   r   r_   Zsympy.core.evalfr   r   Zsympy.printing.defaultsr   __all__r   r   r   r   r   r   <module>   s        H