예제 #1
0
파일: test_pycode.py 프로젝트: msgoff/sympy
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"
예제 #2
0
    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