#NEWLINE# @ cacheit #NEWLINE# def _remove_multiple_delta( expr ) : #NEWLINE# #INDENT# "\n    Evaluate products of KroneckerDelta's.\n    " #NEWLINE# from sympy.solvers import solve #NEWLINE# if expr . is_Add : #NEWLINE# #INDENT# return expr . func ( * list ( map ( _remove_multiple_delta , expr . args ) ) ) #NEWLINE# #UNINDENT# if ( not expr . is_Mul ) : #NEWLINE# #INDENT# return expr #NEWLINE# #UNINDENT# eqs = [ ] #NEWLINE# newargs = [ ] #NEWLINE# for arg in expr . args : #NEWLINE# #INDENT# if isinstance ( arg , KroneckerDelta ) : #NEWLINE# #INDENT# eqs . append ( ( arg . args [ 0 ] - arg . args [ 1 ] ) ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# newargs . append ( arg ) #NEWLINE# #UNINDENT# #UNINDENT# if ( not eqs ) : #NEWLINE# #INDENT# return expr #NEWLINE# #UNINDENT# solns = solve ( eqs , dict = True ) #NEWLINE# if ( len ( solns ) == 0 ) : #NEWLINE# #INDENT# return S . Zero #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( len ( solns ) == 1 ) : #NEWLINE# #INDENT# for key in solns [ 0 ] . keys ( ) : #NEWLINE# #INDENT# newargs . append ( KroneckerDelta ( key , solns [ 0 ] [ key ] ) ) #NEWLINE# #UNINDENT# expr2 = expr . func ( * newargs ) #NEWLINE# if ( expr != expr2 ) : #NEWLINE# #INDENT# return _remove_multiple_delta ( expr2 ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# return expr