U
    L?hH                     @   s   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 dl
mZ d dlmZ G dd	 d	eZed
d ZG dd deZdS )    )Iterable)singledispatch)Expr)Mul)Ssympify)global_parametersc                   @   s@   e Zd ZdZdZdd Zdd Zdd Zed	d
 Z	dd Z
dS )TensorProductz,
    Generic class for tensor products.
    Fc                 O   s  ddl m}m}m} ddlm} ddlm} ddlm	} dd |D }|
dtj}	|	sltj| f| }
|
S g }g }tj}|D ]D}t|t||fr||| q~t||fr|| q~||9 }q~|||  }t|dkr|S |d	kr|g| }n|}tj| f||}
||
S )
Nr   )	NDimArraytensorproductArray)
MatrixExpr)
MatrixBase)flattenc                 S   s   g | ]}t |qS  r   ).0argr   r   H/var/www/html/venv/lib/python3.8/site-packages/sympy/tensor/functions.py
<listcomp>   s     z)TensorProduct.__new__.<locals>.<listcomp>evaluate   )sympy.tensor.arrayr   r   r   Z"sympy.matrices.expressions.matexprr   Zsympy.matrices.matrixbaser   Zsympy.strategiesr   getr	   r   r   __new__r   ZOne
isinstancer   appendlen)clsargskwargsr   r   r   r   r   r   r   objZarraysotherZscalarr   ZcoeffZnewargsr   r   r   r      s4    
zTensorProduct.__new__c                 C   s
   t | jS N)r   shapeselfr   r   r   rank3   s    zTensorProduct.rankc                    s    ddl m   fdd| jD S )Nr   r   c                    s&   g | ]}t |d r|jn |jqS )r$   )hasattrr$   r   ir(   r   r   r   8   s     z2TensorProduct._get_args_shapes.<locals>.<listcomp>)r   r   r   r%   r   r(   r   _get_args_shapes6   s    zTensorProduct._get_args_shapesc                 C   s   |   }t|dS )Nr   )r,   sum)r&   Z
shape_listr   r   r   r$   :   s    zTensorProduct.shapec                    s,   t   t fddt| j|  D S )Nc                 3   s.   | ]&\}}| t fd d|D V  qdS )c                 3   s   | ]}t  V  qd S r#   )nextr*   indexr   r   	<genexpr>B   s     z6TensorProduct.__getitem__.<locals>.<genexpr>.<genexpr>N)__getitem__tuple)r   r   Zshpr/   r   r   r1   A   s   z,TensorProduct.__getitem__.<locals>.<genexpr>)iterr   Zfromiterzipr   r,   )r&   r0   r   r/   r   r2   ?   s    zTensorProduct.__getitem__N)__name__
__module____qualname____doc__Z	is_numberr   r'   r,   propertyr$   r2   r   r   r   r   r
      s   "
r
   c                 C   s    t | dr| jS td|  dS )a  
    Return the shape of the *expr* as a tuple. *expr* should represent
    suitable object such as matrix or array.

    Parameters
    ==========

    expr : SymPy object having ``MatrixKind`` or ``ArrayKind``.

    Raises
    ======

    NoShapeError : Raised when object with wrong kind is passed.

    Examples
    ========

    This function returns the shape of any object representing matrix or array.

    >>> from sympy import shape, Array, ImmutableDenseMatrix, Integral
    >>> from sympy.abc import x
    >>> A = Array([1, 2])
    >>> shape(A)
    (2,)
    >>> shape(Integral(A, x))
    (2,)
    >>> M = ImmutableDenseMatrix([1, 2])
    >>> shape(M)
    (2, 1)
    >>> shape(Integral(M, x))
    (2, 1)

    You can support new type by dispatching.

    >>> from sympy import Expr
    >>> class NewExpr(Expr):
    ...     pass
    >>> @shape.register(NewExpr)
    ... def _(expr):
    ...     return shape(expr.args[0])
    >>> shape(NewExpr(M))
    (2, 1)

    If unsuitable expression is passed, ``NoShapeError()`` will be raised.

    >>> shape(Integral(x, x))
    Traceback (most recent call last):
      ...
    sympy.tensor.functions.NoShapeError: shape() called on non-array object: Integral(x, x)

    Notes
    =====

    Array-like classes (such as ``Matrix`` or ``NDimArray``) has ``shape``
    property which returns its shape, but it cannot be used for non-array
    classes containing array. This function returns the shape of any
    registered object representing array.

    r$   zA%s does not have shape, or its type is not registered to shape().N)r)   r$   NoShapeError)exprr   r   r   r$   G   s
    =
r$   c                   @   s   e Zd ZdZdS )r;   an  
    Raised when ``shape()`` is called on non-array object.

    This error can be imported from ``sympy.tensor.functions``.

    Examples
    ========

    >>> from sympy import shape
    >>> from sympy.abc import x
    >>> shape(x)
    Traceback (most recent call last):
      ...
    sympy.tensor.functions.NoShapeError: shape() called on non-array object: x
    N)r6   r7   r8   r9   r   r   r   r   r;      s   r;   N)collections.abcr   	functoolsr   Zsympy.core.exprr   Zsympy.core.mulr   Zsympy.core.singletonr   Zsympy.core.sympifyr   Zsympy.core.parametersr	   r
   r$   	Exceptionr;   r   r   r   r   <module>   s   <
B