ó
¡¼™\c           @   s‰   d  d l  Z  d  d l m Z m Z m Z d  d l m Z d  d l m Z d  d l	 m
 Z
 d „  Z d „  Z d „  Z d	 „  Z d
 „  Z d S(   iÿÿÿÿN(   t   St   Tuplet   diff(   t   Iterable(   t   ImmutableDenseNDimArray(   t	   NDimArrayc         C   sL   d d l  m } t |  t ƒ r# |  St |  | t t t f ƒ rH t |  ƒ S|  S(   Niÿÿÿÿ(   t
   MatrixBase(   t   sympy.matricesR   t
   isinstanceR   t   listt   tupleR   R   (   t   aR   (    (    s9   lib/python2.7/site-packages/sympy/tensor/array/arrayop.pyt   _arrayfy	   s    
c          G   s  t  |  ƒ d k r t j St  |  ƒ d k r9 t |  d ƒ St  |  ƒ d k rm t t |  d |  d ƒ |  d Œ St t |  ƒ \ } } t | t ƒ s¢ t | t ƒ rª | | St | ƒ } t | ƒ } g  | D] } | D] } | | ^ qÓ qÉ } t	 | | j
 | j
 ƒ S(   s§  
    Tensor product among scalars or array-like objects.

    Examples
    ========

    >>> from sympy.tensor.array import tensorproduct, Array
    >>> from sympy.abc import x, y, z, t
    >>> A = Array([[1, 2], [3, 4]])
    >>> B = Array([x, y])
    >>> tensorproduct(A, B)
    [[[x, y], [2*x, 2*y]], [[3*x, 3*y], [4*x, 4*y]]]
    >>> tensorproduct(A, x)
    [[x, 2*x], [3*x, 4*x]]
    >>> tensorproduct(A, B, B)
    [[[[x**2, x*y], [x*y, y**2]], [[2*x**2, 2*x*y], [2*x*y, 2*y**2]]], [[[3*x**2, 3*x*y], [3*x*y, 3*y**2]], [[4*x**2, 4*x*y], [4*x*y, 4*y**2]]]]

    Applying this function on two matrices will result in a rank 4 array.

    >>> from sympy import Matrix, eye
    >>> m = Matrix([[x, y], [z, t]])
    >>> p = tensorproduct(eye(3), m)
    >>> p
    [[[[x, y], [z, t]], [[0, 0], [0, 0]], [[0, 0], [0, 0]]], [[[0, 0], [0, 0]], [[x, y], [z, t]], [[0, 0], [0, 0]]], [[[0, 0], [0, 0]], [[0, 0], [0, 0]], [[x, y], [z, t]]]]
    i    i   i   (   t   lenR    t   OneR   t   tensorproductt   mapR   R   R	   R   t   shape(   t   argsR   t   bt   alt   blt   it   jt   product_list(    (    s9   lib/python2.7/site-packages/sympy/tensor/array/arrayop.pyR      s    " *c         G   sÔ  t  |  ƒ }  t g  ƒ } x˜ | D] } t | t ƒ sC t d ƒ ‚ n  |  j | d } xX | D]P } | | k r| t d ƒ ‚ n  | |  j | k rž t d ƒ ‚ n  | j | ƒ q[ Wq W|  j ƒ  } g  t |  j ƒ D] \ } } | | k rÏ | ^ qÏ } d g | }	 d }
 xE t	 | ƒ D]7 } |
 |	 | | d <|
 t
 |  j | | d ƒ 9}
 qWg  t	 | ƒ D]@ } | | k r[g  t	 |  j | ƒ D] } |	 | | ^ q^ q[} g  } xq | D]i } g  } xM t	 |  j | d ƒ D]4 } | j t g  | D] } |	 | | ^ qèƒ ƒ qÒW| j | ƒ q®Wg  } xk t j | Œ  D]Z } t | ƒ } t j } x/ t j | Œ  D] } | |  | t | ƒ 7} q\W| j | ƒ q1Wt | ƒ d k rÁt | ƒ d k s¹t ‚ | d St |  ƒ | | ƒ S(   s  
    Contraction of an array-like object on the specified axes.

    Examples
    ========

    >>> from sympy import Array, tensorcontraction
    >>> from sympy import Matrix, eye
    >>> tensorcontraction(eye(3), (0, 1))
    3
    >>> A = Array(range(18), (3, 2, 3))
    >>> A
    [[[0, 1, 2], [3, 4, 5]], [[6, 7, 8], [9, 10, 11]], [[12, 13, 14], [15, 16, 17]]]
    >>> tensorcontraction(A, (0, 2))
    [21, 30]

    Matrix multiplication may be emulated with a proper combination of
    ``tensorcontraction`` and ``tensorproduct``

    >>> from sympy import tensorproduct
    >>> from sympy.abc import a,b,c,d,e,f,g,h
    >>> m1 = Matrix([[a, b], [c, d]])
    >>> m2 = Matrix([[e, f], [g, h]])
    >>> p = tensorproduct(m1, m2)
    >>> p
    [[[[a*e, a*f], [a*g, a*h]], [[b*e, b*f], [b*g, b*h]]], [[[c*e, c*f], [c*g, c*h]], [[d*e, d*f], [d*g, d*h]]]]
    >>> tensorcontraction(p, (1, 2))
    [[a*e + b*g, a*f + b*h], [c*e + d*g, c*f + d*h]]
    >>> m1*m2
    Matrix([
    [a*e + b*g, a*f + b*h],
    [c*e + d*g, c*f + d*h]])
    s(   collections of contraction axes expectedi    s"   dimension specified more than onces3   cannot contract between axes of different dimensioni   (   R   t   setR   R   t
   ValueErrorR   t   addt   rankt	   enumeratet   ranget   intt   appendt   sumt	   itertoolst   productR    t   ZeroR   t   AssertionErrort   type(   t   arrayt   contraction_axest
   taken_dimst
   axes_groupt   dimt   dR   R   t   remaining_shapet	   cum_shapet   _cumulR   t   remaining_indicest   summed_deltast   lidxt   jst   igt   contracted_arrayt   icontribt   index_base_positiont   isumt   sum_to_index(    (    s9   lib/python2.7/site-packages/sympy/tensor/array/arrayop.pyt   tensorcontractionA   sL    "4#	P2
	c         C   s>  d d l  m } t | t f } t | | ƒ rf t | ƒ } x) | D] } | j sA t d ƒ ‚ qA qA Wn  t |  | ƒ rò t |  ƒ }  t | | ƒ râ g  | D]( } g  |  D] } | j | ƒ ^ q¤ ^ q— } t	 |  ƒ | | j
 |  j
 ƒ S|  j | ƒ SnH t | | ƒ r-t g  | D] } |  j | ƒ ^ q| j
 ƒ St |  | ƒ Sd S(   s¶  
    Derivative by arrays. Supports both arrays and scalars.

    Given the array `A_{i_1, \ldots, i_N}` and the array `X_{j_1, \ldots, j_M}`
    this function will return a new array `B` defined by

    `B_{j_1,\ldots,j_M,i_1,\ldots,i_N} := \frac{\partial A_{i_1,\ldots,i_N}}{\partial X_{j_1,\ldots,j_M}}`

    Examples
    ========

    >>> from sympy import derive_by_array
    >>> from sympy.abc import x, y, z, t
    >>> from sympy import cos
    >>> derive_by_array(cos(x*t), x)
    -t*sin(t*x)
    >>> derive_by_array(cos(x*t), [x, y, z, t])
    [-t*sin(t*x), 0, 0, -x*sin(t*x)]
    >>> derive_by_array([x, y**2*z], [[x, y], [z, t]])
    [[[1, 0], [0, 2*y*z]], [[0, y**2], [0, 0]]]

    iÿÿÿÿ(   R   s   cannot derive by this arrayN(   R   R   R   R   R   R   t	   _diff_wrtR   R   R&   R   (   t   exprt   dxR   t   array_typesR   t   xt   yt	   new_array(    (    s9   lib/python2.7/site-packages/sympy/tensor/array/arrayop.pyt   derive_by_array§   s     	5,c   
      C   s  t  |  t ƒ s t d ƒ ‚ n  d d l m } t  | | ƒ sR | t | ƒ ƒ } n  | j |  j ƒ  k rv t d ƒ ‚ n  | } | g  |  j	 D] } t
 | ƒ ^ qŠ ƒ } d g t |  ƒ } x= t t j | Œ  ƒ D]& \ } } | | ƒ } |  | | | <qÎ W| |  j	 ƒ }	 t |  ƒ | |	 ƒ S(   sÛ  
    Permutes the indices of an array.

    Parameter specifies the permutation of the indices.

    Examples
    ========

    >>> from sympy.abc import x, y, z, t
    >>> from sympy import sin
    >>> from sympy import Array, permutedims
    >>> a = Array([[x, y, z], [t, sin(x), 0]])
    >>> a
    [[x, y, z], [t, sin(x), 0]]
    >>> permutedims(a, (1, 0))
    [[x, t], [y, sin(x)], [z, 0]]

    If the array is of second order, ``transpose`` can be used:

    >>> from sympy import transpose
    >>> transpose(a)
    [[x, t], [y, sin(x)], [z, 0]]

    Examples on higher dimensions:

    >>> b = Array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
    >>> permutedims(b, (2, 1, 0))
    [[[1, 5], [3, 7]], [[2, 6], [4, 8]]]
    >>> permutedims(b, (1, 2, 0))
    [[[1, 5], [2, 6]], [[3, 7], [4, 8]]]

    ``Permutation`` objects are also allowed:

    >>> from sympy.combinatorics import Permutation
    >>> permutedims(b, Permutation([1, 2, 0]))
    [[[1, 5], [2, 6]], [[3, 7], [4, 8]]]

    s#   expression has to be an N-dim arrayiÿÿÿÿ(   t   Permutations   wrong permutation sizeN(   R   R   t	   TypeErrort   sympy.combinatoricsRC   R	   t   sizeR   R   R   R   t   NoneR   R   R"   R#   R&   (
   R<   t   permRC   t   ipermR   t   indices_spanRA   t   idxt   tt	   new_shape(    (    s9   lib/python2.7/site-packages/sympy/tensor/array/arrayop.pyt   permutedimsÕ   s    '("(   R"   t   sympyR    R   R   t   sympy.core.compatibilityR   t   sympy.tensor.arrayR   t   sympy.tensor.array.ndim_arrayR   R   R   R:   RB   RN   (    (    (    s9   lib/python2.7/site-packages/sympy/tensor/array/arrayop.pyt   <module>   s   	
	.	f	.