def test_NumPyPrinter(): from sympy import ( Lambda, ZeroMatrix, OneMatrix, FunctionMatrix, HadamardProduct, KroneckerProduct, Adjoint, DiagonalOf, DiagMatrix, DiagonalMatrix, ) from sympy.abc import a, b p = NumPyPrinter() assert p.doprint(sign(x)) == "numpy.sign(x)" A = MatrixSymbol("A", 2, 2) B = MatrixSymbol("B", 2, 2) C = MatrixSymbol("C", 1, 5) D = MatrixSymbol("D", 3, 4) assert p.doprint(A**(-1)) == "numpy.linalg.inv(A)" assert p.doprint(A**5) == "numpy.linalg.matrix_power(A, 5)" assert p.doprint(Identity(3)) == "numpy.eye(3)" u = MatrixSymbol("x", 2, 1) v = MatrixSymbol("y", 2, 1) assert p.doprint(MatrixSolve(A, u)) == "numpy.linalg.solve(A, x)" assert p.doprint(MatrixSolve(A, u) + v) == "numpy.linalg.solve(A, x) + y" assert p.doprint(ZeroMatrix(2, 3)) == "numpy.zeros((2, 3))" assert p.doprint(OneMatrix(2, 3)) == "numpy.ones((2, 3))" assert (p.doprint(FunctionMatrix(4, 5, Lambda( (a, b), a + b))) == "numpy.fromfunction(lambda a, b: a + b, (4, 5))") assert p.doprint(HadamardProduct(A, B)) == "numpy.multiply(A, B)" assert p.doprint(KroneckerProduct(A, B)) == "numpy.kron(A, B)" assert p.doprint(Adjoint(A)) == "numpy.conjugate(numpy.transpose(A))" assert p.doprint(DiagonalOf(A)) == "numpy.reshape(numpy.diag(A), (-1, 1))" assert p.doprint(DiagMatrix(C)) == "numpy.diagflat(C)" assert p.doprint(DiagonalMatrix(D)) == "numpy.multiply(D, numpy.eye(3, 4))" # Workaround for numpy negative integer power errors assert p.doprint(x**-1) == "x**(-1.0)" assert p.doprint(x**-2) == "x**(-2.0)" assert p.doprint(S.Exp1) == "numpy.e" assert p.doprint(S.Pi) == "numpy.pi" assert p.doprint(S.EulerGamma) == "numpy.euler_gamma" assert p.doprint(S.NaN) == "numpy.nan" assert p.doprint(S.Infinity) == "numpy.PINF" assert p.doprint(S.NegativeInfinity) == "numpy.NINF"
def fillTensorDic(self, coupling, expTerm, content): subTerms = expTerm.as_coeff_add()[1] tensorInds = () coeff = 0 fermions = () scalars = () coupling = Symbol(coupling, complex=True) cType = self.model.allCouplings[str(coupling)] if type(cType) == tuple: cType = cType[0] for subTerm in subTerms: subTerm = list(subTerm.as_coeff_mul()) rationalFactors = [el for el in subTerm[1] if el.is_number] subTerm[1] = tuple( [el for el in subTerm[1] if el not in rationalFactors]) subTerm[0] *= Mul(*rationalFactors) subTerm[1] = splitPow(subTerm[1]) #For fermions, we have to be careful that the order in which the user wrote the terms # is preserved here. Inverting them would transpose the Yukawa / mass matrix fermions = [ self.model.allFermions[str(el)] for el in subTerm[1] if str(el) in self.model.allFermions ] if fermions != []: # Sort fermions according to their pos in the potential term fermionSortKey = {} fermionNames = sorted([str(el[1]) for el in fermions], key=lambda x: len(x), reverse=True) potStr = self.currentPotentialDic[str(coupling)] for el in fermionNames: fermionSortKey[el] = potStr.find(el) potStr = potStr.replace(el, ' ' * len(el)) fermions = sorted(fermions, key=lambda x: fermionSortKey[str(x[1])]) fGen = [f[1].gen for f in fermions] fermions = [f[0] for f in fermions] scalars = [ self.model.allScalars[str(el)][0] for el in subTerm[1] if str(el) in self.model.allScalars ] # sGen = [self.model.allScalars[str(el)][1].gen for el in subTerm[1] if str(el) in self.model.allScalars] if content == (2, 1): #Yukawa if len(fermions) != 2 or len(scalars) != 1: loggingCritical( f"Error in term {str(coupling)} : \n\tYukawa terms must contain exactly 2 fermions and 1 scalar." ) exit() tensorInds = tuple(scalars + fermions) coeff = subTerm[0] * 2 / len( set(itertools.permutations(fermions, 2))) # # Fermion1 = Fermion2 : the matrix is symmetric # if self.allFermionsValues[fermions[0]][1] == self.allFermionsValues[fermions[1]][1]: # self.model.assumptions[str(coupling)]['symmetric'] = True # # Fermion1 = Fermion2bar : the matrix is hermitian # if self.allFermionsValues[fermions[0]][1] == self.allFermionsValues[self.antiFermionPos(fermions[1])][1]: # self.model.assumptions[str(coupling)]['hermitian'] = True assumptionDic = self.model.assumptions[str(coupling)] coupling = mSymbol(str(coupling), fGen[0], fGen[1], **assumptionDic) if coupling not in self.model.couplingStructure: self.model.couplingStructure[str(coupling)] = (fGen[0], fGen[1]) if content == (0, 4): #Quartic if len(fermions) != 0 or len(scalars) != 4: loggingCritical( f"\nError in term {str(coupling)} : \n\tQuartic terms must contain exactly 0 fermion and 4 scalars." ) exit() tensorInds = tuple(sorted(scalars)) coeff = subTerm[0] * 24 / len( set(itertools.permutations( tensorInds, 4))) #/len(set(itertools.permutations(tensorInds, 4))) if content == (0, 3): #Trilinear if len(fermions) != 0 or len(scalars) != 3: loggingCritical( f"\nError in term {str(coupling)} : \n\tTrinilear terms must contain exactly 0 fermion and 3 scalars." ) exit() tensorInds = tuple(sorted(scalars)) coeff = subTerm[0] * 6 / len( set(itertools.permutations(tensorInds, 3))) if content == (0, 2): #Scalar Mass if len(fermions) != 0 or len(scalars) != 2: loggingCritical( f"\nError in term {str(coupling)} : \n\tScalar mass terms must contain exactly 0 fermion and 2 scalars." ) exit() tensorInds = tuple(sorted(scalars)) coeff = subTerm[0] * 2 / len( set(itertools.permutations(tensorInds, 2))) if content == (2, 0): #Fermion Mass if len(fermions) != 2 or len(scalars) != 0: loggingCritical( f"\nError in term {str(coupling)} : \n\tFermion mass terms must contain exactly 2 fermions and 0 scalar." ) exit() tensorInds = tuple(fermions) coeff = subTerm[0] * 2 / len( set(itertools.permutations(tensorInds, 2))) # # Fermion1 = Fermion2 : the matrix is symmetric # if fermions[0] == fermions[1]: # self.model.assumptions[str(coupling)]['symmetric'] = True # # Fermion1 = Fermion2bar : the matrix is hermitian # if fermions[0] == self.antiFermionPos(fermions[1]): # self.model.assumptions[str(coupling)]['hermitian'] = True assumptionDic = self.model.assumptions[str(coupling)] coupling = mSymbol(str(coupling), fGen[0], fGen[1], **assumptionDic) if coupling not in self.model.couplingStructure: self.model.couplingStructure[str(coupling)] = (fGen[0], fGen[1]) if tensorInds not in self.dicToFill: self.dicToFill[tensorInds] = coupling * coeff else: self.dicToFill[tensorInds] += coupling * coeff #Update the 'AllCouplings' dictionary if type(self.model.allCouplings[str(coupling)]) != tuple: tmp = [cType, coupling] if isinstance(coupling, mSymbol): orderedFermions = [ str(list(self.model.allFermions.values())[f][1]) for f in fermions ] tmp.append(tuple(orderedFermions)) self.model.allCouplings[str(coupling)] = tuple(tmp) # If Yukawa / Fermion mass, add the hermitian conjugate to Dic if content == (2, 1) or content == (2, 0): antiFermions = [self.antiFermionPos(f) for f in fermions] antiFermions.reverse() tensorInds = tuple(scalars + antiFermions + [True]) coeff = conjugate(coeff) adjCoupling = Adjoint(coupling).doit() if tensorInds not in self.dicToFill: self.dicToFill[tensorInds] = adjCoupling * coeff else: self.dicToFill[tensorInds] += adjCoupling * coeff