o
    oh^                     @   s   d 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
mZmZmZmZmZmZmZ e
ddd	d
ZedegedddZdd Zdd Zd ddZdd Zdd Zdd Zdd Zdd ZdS )!a  
    Module to handle gamma matrices expressed as tensor objects.

    Examples
    ========

    >>> from sympy.physics.hep.gamma_matrices import GammaMatrix as G, LorentzIndex
    >>> from sympy.tensor.tensor import tensor_indices
    >>> i = tensor_indices('i', LorentzIndex)
    >>> G(i)
    GammaMatrix(i)

    Note that there is already an instance of GammaMatrixHead in four dimensions:
    GammaMatrix, which is simply declare as

    >>> from sympy.physics.hep.gamma_matrices import GammaMatrix
    >>> from sympy.tensor.tensor import tensor_indices
    >>> i = tensor_indices('i', LorentzIndex)
    >>> GammaMatrix(i)
    GammaMatrix(i)

    To access the metric tensor

    >>> LorentzIndex.metric
    metric(LorentzIndex,LorentzIndex)

    )Mul)S)eye)trace)TensorIndexTypeTensorIndexTensMulTensAdd
tensor_mulTensor
TensorHeadTensorSymmetryLorentzIndex   L)dim
dummy_nameGammaMatrix   N)commc                 C   sp   t | tr	| g}nt | tr| j}ntdtj}tj}|D ]}t |tr/|j|kr/||9 }q||9 }q||fS )z
    Extract from a ``TensExpr`` all tensors with `component`.

    Returns two tensor expressions:

    * the first contains all ``Tensor`` of having `component`.
    * the second contains all remaining.


    z
wrong type)
isinstancer   r   args
ValueErrorr   One	component)
expressionr   spnew_exprresidual_expri r    t/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/sympy/physics/hep/gamma_matrices.pyextract_type_tens.   s   



r"   c                 C   s   t | t\}}t|}|| S )N)r"   r   _simplify_single_line)r   extracted_exprr   res_exprr    r    r!   simplify_gamma_expressionK   s   r&   Tc                 C   s2   dd }|r
|   } 	 || }|| kr|} n|S q)a  
    simplify products ``G(i)*p(-i)*G(j)*p(-j) -> p(i)*p(-i)``

    Examples
    ========

    >>> from sympy.physics.hep.gamma_matrices import GammaMatrix as G,         LorentzIndex, simplify_gpgp
    >>> from sympy.tensor.tensor import tensor_indices, tensor_heads
    >>> p, q = tensor_heads('p, q', [LorentzIndex])
    >>> i0,i1,i2,i3,i4,i5 = tensor_indices('i0:6', LorentzIndex)
    >>> ps = p(i0)*G(-i0)
    >>> qs = q(i0)*G(-i0)
    >>> simplify_gpgp(ps*qs*qs)
    GammaMatrix(-L_0)*p(L_0)*q(L_1)*q(-L_1)
    c                    sH  | j }g }g  t|D ]\}} |g|j  q fdd| jD }tt|D ]:}|| tkr2q)|D ].}|d |krA|d }n|d |krL|d }nq4|| }|jdkrb|jdkrb|	||f q4q)|sh| S t
 g }	d}
tj}d }|
rd}
t|d d	 D ]\}}|d v rq|d ||d  d d krq||d  |||d  d  krq|d  |d  ||d  d  ||d  d  |s|  }td
t}d}
|dkr| j}||d  |||d  |  }t|dkr|d9 }|		|  |
sw|	r"fddt|D }||	 t| | }|S | S )Nc                    s0   g | ]}|d  |d  |d    |d  fqS )r   r   r    .0r   )comp_mapr    r!   
<listcomp>h   s   0 z9simplify_gpgp.<locals>._simplify_gpgp.<locals>.<listcomp>      r   r   TFmur   c                    s   g | ]
\}}| vr|qS r    r    )r(   jx)elimr    r!   r*          )
components	enumerateextendrankdumrangelenr   r   appendsetr   r   addsplitr   r   coeffr
   )exr3   ar   compr7   dxp_pos1comp1tvhitr>   taair.   txtr    )r)   r1   r!   _simplify_gpgpb   st   


 
"

z%simplify_gpgp.<locals>._simplify_gpgp)sorted_components)r?   sortrK   rJ   r    r    r!   simplify_gpgpQ   s   =rN   c                 C   s6   t | trtdd | jD  }|S t| } t| }|S )aY  
    trace of a single line of gamma matrices

    Examples
    ========

    >>> from sympy.physics.hep.gamma_matrices import GammaMatrix as G,         gamma_trace, LorentzIndex
    >>> from sympy.tensor.tensor import tensor_indices, tensor_heads
    >>> p, q = tensor_heads('p, q', [LorentzIndex])
    >>> i0,i1,i2,i3,i4,i5 = tensor_indices('i0:6', LorentzIndex)
    >>> ps = p(i0)*G(-i0)
    >>> qs = q(i0)*G(-i0)
    >>> gamma_trace(G(i0)*G(i1))
    4*metric(i0, i1)
    >>> gamma_trace(ps*ps) - 4*p(i0)*p(-i0)
    0
    >>> gamma_trace(ps*qs + ps*ps) - 4*p(i0)*p(-i0) - 4*p(i0)*q(-i0)
    0

    c                 S      g | ]}t |qS r    )gamma_tracer(   r0   r    r    r!   r*          zgamma_trace.<locals>.<listcomp>)r   r	   r   r#   _trace_single_line)rJ   resr    r    r!   rP      s   
rP   c                 C   s*   t | t\}}|dkrt|}|| }|S )a  
    Simplify single-line product of gamma matrices.

    Examples
    ========

    >>> from sympy.physics.hep.gamma_matrices import GammaMatrix as G,         LorentzIndex, _simplify_single_line
    >>> from sympy.tensor.tensor import tensor_indices, TensorHead
    >>> p = TensorHead('p', [LorentzIndex])
    >>> i0,i1 = tensor_indices('i0:2', LorentzIndex)
    >>> _simplify_single_line(G(i0)*G(i1)*p(-i1)*G(-i0)) + 2*G(i0)*p(-i0)
    0

    r   )r"   r   kahane_simplify)r   t1t2rT   r    r    r!   r#      s
   r#   c                    s^   dd  |   } t| tr fdd| jD }t| S t| ttfr+| j |  }|S t| S )a  
    Evaluate the trace of a single gamma matrix line inside a ``TensExpr``.

    Notes
    =====

    If there are ``DiracSpinorIndex.auto_left`` and ``DiracSpinorIndex.auto_right``
    indices trace over them; otherwise traces are not implied (explain)


    Examples
    ========

    >>> from sympy.physics.hep.gamma_matrices import GammaMatrix as G,         LorentzIndex, _trace_single_line
    >>> from sympy.tensor.tensor import tensor_indices, TensorHead
    >>> p = TensorHead('p', [LorentzIndex])
    >>> i0,i1,i2,i3,i4,i5 = tensor_indices('i0:6', LorentzIndex)
    >>> _trace_single_line(G(i0)*G(i1))
    4*metric(i0, i1)
    >>> _trace_single_line(G(i0)*p(-i0)*G(i1)*p(-i1)) - 4*p(i0)*p(-i0)
    0

    c                 S   s  |   } | j}t|}tj}d}t|D ]}|| tkr d} nqt|| |D ]
}|| tkr2 nq(|}|| }|dkrG| j}|rE| jS | S |d dkrVt	
tjg g g S |dkr|  }	|	|  d }
|	|d   d }|	d | |	|d d   }t| ||
| }||}|g}d}t|d |D ]=}| }|	|  d }|	d | |	|d |  |	|d d   }|t|  ||
| }||}t|d}|| qt| }t|}|S |  }	t|	||  }|	d | |	|d   }t| }|| }|s|S ||}|S )Nr   r   r+   r   F)rL   r3   r9   r   metricr8   r   r>   nocoeffr   	from_datar   Zeror=   get_indicesr
   contract_metricrN   r:   r	   rS   _gamma_trace1)rJ   r3   ncompsgrF   r   r/   numGtcoeffr@   ind1ind2aarV   r   signkrW   t3a2r    r    r!   _trace_single_line1   sd   
,


z/_trace_single_line.<locals>._trace_single_line1c                    s   g | ]	} ||j  qS r    )r>   rQ   rj   r    r!   r*   1  s    z&_trace_single_line.<locals>.<listcomp>)expandr   r	   r   r   r   r>   r   )rJ   r@   rr    rk   r!   rS      s   7
rS   c                  G   s   d}t j}| s	|S t| }|d dkrtjS |dkr1| d  d }| d  d }|||| S |dkru| d  d }| d  d }| d  d }| d  d }||||||| ||||||  ||||||   S d S )Nr   r+   r   r   r,   )r   rX   r9   r   r[   r\   )r@   gctrr`   nind0rc   rd   ind3r    r    r!   r^   :  s,   r^   c           !         s  t | tr| S t | trtdd | jD  S t | tr| S t | ts$J | j}|D ]	}|jtks2J q)| j}g }| j	D ]}| j
|d  tkrQ||d |d f q;t|}t|dkr^| S ttt|t|t|d  }t|}dg| |D ]
}|d |d < qzdg| }	t|D ]
\}}
d|	|
d < qd	d
 t|D }d}dg| }d}tj}g g}d}t|	D ]\}}|k rq|r|d7 }|dkr||d  | || |d  nd||d rdnd9 }|dkr|kr|dkrd| d g|d| < d| g|d| d < || |v r@|kr"|| ||  |dkr@|| t|	k r@|	||  r@|||  | d}|||< q|D ]}|d }|d }|| | || | |||  }|||  }||krtqI||kr{qI|k rqI|k rqId| |v rd| }d| |v rd| }|dkr|	| s|}|dkr|	| s|}||| vr|| | ||| vr|| | qI}d}	 ||v r||}nn6||v r|| |}|r|d }nn!||krn|dkr| dur|D ]
}||  qq|r|d7 }t| }|}g }	 ||v r9||}nn0||v rKt|dkrK|| |}|rT|d }|krh| durh|d|  q.t|dkrv|d9 }n| tt| fdd|D }|s||| d d rdnd9 }|d| 9 }fdd|D }tj}|D ]}tj}|D ]	}|t|9 }q||7 }q|| }d} t |tr|jd } nt |tr|} | r	 |S td| }|S )a	  
    This function cancels contracted elements in a product of four
    dimensional gamma matrices, resulting in an expression equal to the given
    one, without the contracted gamma matrices.

    Parameters
    ==========

    `expression`    the tensor expression containing the gamma matrices to simplify.

    Notes
    =====

    If spinor indices are given, the matrices must be given in
    the order given in the product.

    Algorithm
    =========

    The idea behind the algorithm is to use some well-known identities,
    i.e., for contractions enclosing an even number of `\gamma` matrices

    `\gamma^\mu \gamma_{a_1} \cdots \gamma_{a_{2N}} \gamma_\mu = 2 (\gamma_{a_{2N}} \gamma_{a_1} \cdots \gamma_{a_{2N-1}} + \gamma_{a_{2N-1}} \cdots \gamma_{a_1} \gamma_{a_{2N}} )`

    for an odd number of `\gamma` matrices

    `\gamma^\mu \gamma_{a_1} \cdots \gamma_{a_{2N+1}} \gamma_\mu = -2 \gamma_{a_{2N+1}} \gamma_{a_{2N}} \cdots \gamma_{a_{1}}`

    Instead of repeatedly applying these identities to cancel out all contracted indices,
    it is possible to recognize the links that would result from such an operation,
    the problem is thus reduced to a simple rearrangement of free gamma matrices.

    Examples
    ========

    When using, always remember that the original expression coefficient
    has to be handled separately

    >>> from sympy.physics.hep.gamma_matrices import GammaMatrix as G, LorentzIndex
    >>> from sympy.physics.hep.gamma_matrices import kahane_simplify
    >>> from sympy.tensor.tensor import tensor_indices
    >>> i0, i1, i2 = tensor_indices('i0:3', LorentzIndex)
    >>> ta = G(i0)*G(-i0)
    >>> kahane_simplify(ta)
    Matrix([
    [4, 0, 0, 0],
    [0, 4, 0, 0],
    [0, 0, 4, 0],
    [0, 0, 0, 4]])
    >>> tb = G(i0)*G(i1)*G(-i0)
    >>> kahane_simplify(tb)
    -2*GammaMatrix(i1)
    >>> t = G(i0)*G(-i0)
    >>> kahane_simplify(t)
    Matrix([
    [4, 0, 0, 0],
    [0, 4, 0, 0],
    [0, 0, 4, 0],
    [0, 0, 0, 4]])
    >>> t = G(i0)*G(-i0)
    >>> kahane_simplify(t)
    Matrix([
    [4, 0, 0, 0],
    [0, 4, 0, 0],
    [0, 0, 4, 0],
    [0, 0, 0, 4]])

    If there are no contractions, the same expression is returned

    >>> tc = G(i0)*G(i1)
    >>> kahane_simplify(tc)
    GammaMatrix(i0)*GammaMatrix(i1)

    References
    ==========

    [1] Algorithm for Reducing Contracted Products of gamma Matrices,
    Joseph Kahane, Journal of Mathematical Physics, Vol. 9, No. 10, October 1968.
    c                 S   rO   r    )rU   )r(   argr    r    r!   r*     rR   z#kahane_simplify.<locals>.<listcomp>r   r   r+   NFTc                 S   s   i | ]}|g qS r    r    r'   r    r    r!   
<dictcomp>  s    z#kahane_simplify.<locals>.<dictcomp>r-   c                    s"   g | ]} fD ]}|| qqS r    r    )r(   riexpri)expr1expr2r    r!   r*     s   " c                    s   g | ]
}d   | qS )r   r    )r(   rt   )first_dum_posfree_posr    r!   r*     r2   r   )r   r   r	   r   r   r   r   r   freer7   index_typesr   r:   sortedr9   minmapr4   r8   r   r   popremovekeysinsertlistreversedr[   r   )!r   gammasgammarz   r7   dum_pairtotal_numbernumber_of_contractionsr   index_is_freeindxlinkscum_signcum_sign_listblock_free_countresulting_coeffresulting_indicesconnected_componentsis_freepos1pos2linkpos1linkpos2pointerprevious_pointer	next_onesrt   prepend_indicesresulting_expr	temp_exprr/   rJ   rV   r    )rv   rw   rx   ry   r!   rU   Q  s(  
Q



	



	


	








%



&rU   )T)__doc__sympy.core.mulr   sympy.core.singletonr   sympy.matrices.denser    sympy.matrices.expressions.tracer   sympy.tensor.tensorr   r   r   r	   r
   r   r   r   r   no_symmetryr   r"   r&   rN   rP   r#   rS   r^   rU   r    r    r    r!   <module>   s$    (

Y[