B
    [@=                 @   s   d dl mZ d dlmZ d dlmZ d dlmZmZ d dl	m
Z
mZmZ d dlmZmZmZmZ d dlmZ d dlmZ d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	S )     )
CoordSys3D)Del)
BaseScalar)Vector
BaseVector)gradientcurl
divergence)diff	integrateSsimplify)sympify)DyadicNFc          	   C   s$  | dks| t jkr| S t|ts(tdt| t r|dk	rDtd|rg }x*| ttD ]}|j	|krZ|
|j	 qZW t|}i }x|D ]}||| qW | |} t j}|  }	xH|	D ]@}||kr|||	| | }
|t|
|7 }q||	| 7 }qW |S t| tr|dkr"|}t|ts6tdtj}|}xR| j D ]D\}}|t|||dt|jd ||dt|jd ||dB  7 }qLW |S |dk	rtd|rtg }t| } x,| tD ]}|j	|kr||j	 qW i }x|D ]}||| qW | |S | S dS )aK  
    Global function for 'express' functionality.

    Re-expresses a Vector, Dyadic or scalar(sympyfiable) in the given
    coordinate system.

    If 'variables' is True, then the coordinate variables (base scalars)
    of other coordinate systems present in the vector/scalar field or
    dyadic are also substituted in terms of the base scalars of the
    given system.

    Parameters
    ==========

    expr : Vector/Dyadic/scalar(sympyfiable)
        The expression to re-express in CoordSys3D 'system'

    system: CoordSys3D
        The coordinate system the expr is to be expressed in

    system2: CoordSys3D
        The other coordinate system required for re-expression
        (only for a Dyadic Expr)

    variables : boolean
        Specifies whether to substitute the coordinate variables present
        in expr, in terms of those of parameter system

    Examples
    ========

    >>> from sympy.vector import CoordSys3D
    >>> from sympy import Symbol, cos, sin
    >>> N = CoordSys3D('N')
    >>> q = Symbol('q')
    >>> B = N.orient_new_axis('B', q, N.k)
    >>> from sympy.vector import express
    >>> express(B.i, N)
    (cos(q))*N.i + (sin(q))*N.j
    >>> express(N.x, B, variables=True)
    B.x*cos(q) - B.y*sin(q)
    >>> d = N.i.outer(N.i)
    >>> express(d, B, N) == (cos(q))*(B.i|N.i) + (-sin(q))*(B.j|N.i)
    True

    r   z>system should be a CoordSys3D                         instanceNzJsystem2 should not be provided for                                 VectorszCsystem2 should be a CoordSys3D                             instance)	variables   )r   zero
isinstancer   	TypeError
ValueErrorZatomsr   r   systemappendsetupdateZ
scalar_mapsubsZseparateZrotation_matrixZ	to_matrixmatrix_to_vectorr   Z
componentsitemsexpressargsr   add)exprr   Zsystem2r   Zsystem_listxZ	subs_dictfoutvecpartsZtempZoutdyadvarkvZ
system_set r(   5lib/python3.7/site-packages/sympy/vector/functions.pyr      sl    0





 


r   c             C   s   ddl m} || }t|dkrtt|}t| |dd} | \}}}| \}}}	t	||t
| | }
|
t	||t
| | 7 }
|
t	||t
| |	 7 }
|
dkrt| trtj}
|
S t| trtjS tdS dS )a  
    Returns the directional derivative of a scalar or vector field computed
    along a given vector in coordinate system which parameters are expressed.

    Parameters
    ==========

    field : Vector or Scalar
        The scalar or vector field to compute the directional derivative of

    direction_vector : Vector
        The vector to calculated directional derivative along them.


    Examples
    ========

    >>> from sympy.vector import CoordSys3D, directional_derivative
    >>> R = CoordSys3D('R')
    >>> f1 = R.x*R.y*R.z
    >>> v1 = 3*R.i + 4*R.j + R.k
    >>> directional_derivative(f1, v1)
    R.x*R.y + 4*R.x*R.z + 3*R.y*R.z
    >>> f2 = 5*R.x**2*R.z
    >>> directional_derivative(f2, v1)
    5*R.x**2 + 30*R.x*R.z

    r   )_get_coord_sys_from_exprT)r   N)sympy.vector.operatorsr*   lennextiterr   base_vectorsbase_scalarsr   dotr
   r   r   r   )fieldZdirection_vectorr*   	coord_sysijr&   r!   yzoutr(   r(   r)   directional_derivative   s     
r9   c             C   s:   t  }| jr(tt| tt|   S |||  S )a!  
    Return the laplacian of the given field computed in terms of
    the base scalars of the given coordinate system.

    Parameters
    ==========

    expr : SymPy Expr or Vector
        expr denotes a scalar or vector field.

    Examples
    ========

    >>> from sympy.vector import CoordSys3D, laplacian
    >>> R = CoordSys3D('R')
    >>> f = R.x**2*R.y**5*R.z
    >>> laplacian(f)
    20*R.x**2*R.y**3*R.z + 2*R.y**5*R.z
    >>> f = R.x**2*R.i + R.y**3*R.j + R.z**4*R.k
    >>> laplacian(f)
    2*R.i + 6*R.y*R.j + 12*R.z**2*R.k

    )r   Z	is_Vectorr   r	   r   Zdoitr1   )r    Zdelopr(   r(   r)   	laplacian   s    r:   c             C   s2   t | tstd| tjkr dS t|  tjkS )a  
    Checks if a field is conservative.

    Parameters
    ==========

    field : Vector
        The field to check for conservative property

    Examples
    ========

    >>> from sympy.vector import CoordSys3D
    >>> from sympy.vector import is_conservative
    >>> R = CoordSys3D('R')
    >>> is_conservative(R.y*R.z*R.i + R.x*R.z*R.j + R.x*R.y*R.k)
    True
    >>> is_conservative(R.z*R.j)
    False

    zfield should be a VectorT)r   r   r   r   r   r   )r2   r(   r(   r)   is_conservative   s
    

r;   c             C   s4   t | tstd| tjkr dS t|  tdkS )a  
    Checks if a field is solenoidal.

    Parameters
    ==========

    field : Vector
        The field to check for solenoidal property

    Examples
    ========

    >>> from sympy.vector import CoordSys3D
    >>> from sympy.vector import is_solenoidal
    >>> R = CoordSys3D('R')
    >>> is_solenoidal(R.y*R.z*R.i + R.x*R.z*R.j + R.x*R.y*R.k)
    True
    >>> is_solenoidal(R.y * R.j)
    False

    zfield should be a VectorTr   )r   r   r   r   r	   r   r   )r2   r(   r(   r)   is_solenoidal   s
    

r<   c             C   s   t | std| tjkr"tdS t|ts4tdt| |dd} |	 }|
 }t| |d |d }xRt|dd D ]>\}}t|||d  }| || }|t|||d  7 }q|W |S )a  
    Returns the scalar potential function of a field in a given
    coordinate system (without the added integration constant).

    Parameters
    ==========

    field : Vector
        The vector field whose scalar potential function is to be
        calculated

    coord_sys : CoordSys3D
        The coordinate system to do the calculation in

    Examples
    ========

    >>> from sympy.vector import CoordSys3D
    >>> from sympy.vector import scalar_potential, gradient
    >>> R = CoordSys3D('R')
    >>> scalar_potential(R.k, R) == R.z
    True
    >>> scalar_field = 2*R.x**2*R.y*R.z
    >>> grad_field = gradient(scalar_field)
    >>> scalar_potential(grad_field, R)
    2*R.x**2*R.y*R.z

    zField is not conservativer   zcoord_sys must be a CoordSys3DT)r   r   N)r;   r   r   r   r   r   r   r   r   r/   r0   r   r1   	enumerater
   )r2   r3   Z
dimensionsscalarsZtemp_functionr4   ZdimZpartial_diffr(   r(   r)   scalar_potential  s    

r?   c             C   s   t |tstdt | tr(t| |}n| }|j}t|||dd}t|||dd}i }i }	| }
x<t	|
 D ],\}}||||
| < |||	|
| < qxW ||	|| S )a0  
    Returns the scalar potential difference between two points in a
    certain coordinate system, wrt a given field.

    If a scalar field is provided, its values at the two points are
    considered. If a conservative vector field is provided, the values
    of its scalar potential function at the two points are used.

    Returns (potential at point2) - (potential at point1)

    The position vectors of the two Points are calculated wrt the
    origin of the coordinate system provided.

    Parameters
    ==========

    field : Vector/Expr
        The field to calculate wrt

    coord_sys : CoordSys3D
        The coordinate system to do the calculations in

    point1 : Point
        The initial Point in given coordinate system

    position2 : Point
        The second Point in the given coordinate system

    Examples
    ========

    >>> from sympy.vector import CoordSys3D, Point
    >>> from sympy.vector import scalar_potential_difference
    >>> R = CoordSys3D('R')
    >>> P = R.origin.locate_new('P', R.x*R.i + R.y*R.j + R.z*R.k)
    >>> vectfield = 4*R.x*R.y*R.i + 2*R.x**2*R.j
    >>> scalar_potential_difference(vectfield, R, R.origin, P)
    2*R.x**2*R.y
    >>> Q = R.origin.locate_new('O', 3*R.i + R.j + 2*R.k)
    >>> scalar_potential_difference(vectfield, R, P, Q)
    -2*R.x**2*R.y + 18

    zcoord_sys must be a CoordSys3DT)r   )r   r   r   r   r?   originr   Zposition_wrtr0   r=   r/   r1   r   )r2   r3   Zpoint1Zpoint2Z	scalar_fnr@   Z	position1Z	position2Z
subs_dict1Z
subs_dict2r>   r4   r!   r(   r(   r)   scalar_potential_differenceD  s"    -

rA   c             C   s8   t j}| }x$t| D ]\}}||||  7 }qW |S )a  
    Converts a vector in matrix form to a Vector instance.

    It is assumed that the elements of the Matrix represent the
    measure numbers of the components of the vector along basis
    vectors of 'system'.

    Parameters
    ==========

    matrix : SymPy Matrix, Dimensions: (3, 1)
        The matrix to be converted to a vector

    system : CoordSys3D
        The coordinate system the vector is to be defined in

    Examples
    ========

    >>> from sympy import ImmutableMatrix as Matrix
    >>> m = Matrix([1, 2, 3])
    >>> from sympy.vector import CoordSys3D, matrix_to_vector
    >>> C = CoordSys3D('C')
    >>> v = matrix_to_vector(m, C)
    >>> v
    C.i + 2*C.j + 3*C.k
    >>> v.to_matrix(C) == m
    True

    )r   r   r/   r=   )Zmatrixr   r#   Zvectsr4   r!   r(   r(   r)   r     s
     r   c             C   s   | j |j kr(tdt|  d t| g }|}x|jdk	rN|| |j}q2W || t|}g }| }x||kr|| |j}qlW t|}||}x"|dkr|||  |d8 }qW ||fS )z
    Calculates the 'path' of objects starting from 'from_object'
    to 'to_object', along with the index of the first common
    ancestor in the tree.

    Returns (index, list) tuple.
    z!No connecting path found between z and Nr   r   )Z_rootr   strZ_parentr   r   r,   index)Zfrom_objectZ	to_objectZ
other_pathobjZ
object_setZ	from_pathrC   r4   r(   r(   r)   _path  s*    	







rE   c              O   s   | dd}tdd | D s&tdg }x^t| D ]R\}}x&t|D ]}||| | | 8 }qFW t|tj	r|t
d|| q4W |rdd |D }|S )	a  
    Takes a sequence of independent vectors and orthogonalizes them
    using the Gram - Schmidt process. Returns a list of
    orthogonal or orthonormal vectors.

    Parameters
    ==========

    vlist : sequence of independent vectors to be made orthogonal.

    orthonormal : Optional parameter
                  Set to True if the vectors returned should be
                  orthonormal.
                  Default: False

    Examples
    ========

    >>> from sympy.vector.coordsysrect import CoordSys3D
    >>> from sympy.vector.vector import Vector, BaseVector
    >>> from sympy.vector.functions import orthogonalize
    >>> C = CoordSys3D('C')
    >>> i, j, k = C.base_vectors()
    >>> v1 = i + 2*j
    >>> v2 = 2*i + 3*j
    >>> orthogonalize(v1, v2)
    [C.i + 2*C.j, 2/5*C.i + (-1/5)*C.j]

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Gram-Schmidt_process

    orthonormalFc             s   s   | ]}t |tV  qd S )N)r   r   ).0vecr(   r(   r)   	<genexpr>  s    z orthogonalize.<locals>.<genexpr>z#Each element must be of Type Vectorz#Vector set not linearly independentc             S   s   g | ]}|  qS r(   )Z	normalize)rG   rH   r(   r(   r)   
<listcomp>  s    z!orthogonalize.<locals>.<listcomp>)getallr   r=   rangeZ
projectionr   Zequalsr   r   r   r   )ZvlistkwargsrF   Zortho_vlistr4   Ztermr5   r(   r(   r)   orthogonalize  s    #rO   )NF) Zsympy.vector.coordsysrectr   Zsympy.vector.deloperatorr   Zsympy.vector.scalarr   Zsympy.vector.vectorr   r   r+   r   r   r	   Zsympyr
   r   r   r   Z
sympy.corer   Zsympy.vector.dyadicr   r   r9   r:   r;   r<   r?   rA   r   rE   rO   r(   r(   r(   r)   <module>   s"   
u1!!3E'!