示例#1
0
def getADBEG(p, q):
    A = p.numerator
    D = p.denominator
    B = q.numerator
    E = q.denominator

    G = Pol.PolyGCD(D, E)
    return (A, D, B, E, G)
示例#2
0
 def removeCommonFactors(self):
     """
     cancels common factors, so that: numerator/denominator = p/q with gcd(p,q)=1
     """
     gcd = Pol.PolyGCD(self.numerator, self.denominator)
     if not gcd == 1:
         self.numerator = Pol.PolyDiv(self.numerator, gcd)[0]
         self.denominator = Pol.PolyDiv(self.denominator, gcd)[0]
示例#3
0
def IntegrateRationalFunction(func):  # field=0, func element C(x)
    """
    integrate func el C(x)
    """
    if func == 0:
        return Int.Integral()
    if isPoly(func):
        return IntegratePolynomialPart(func)
    if func.numerator.degree >= func.denominator.degree:
        (poly, rem) = Pol.PolyDiv(func.numerator, func.denominator)
        if rem == 0:
            return IntegratePolynomialPart(poly) + IntegrateRationalFunction(0)
        else:
            return IntegratePolynomialPart(poly) + IntegrateRationalFunction(
                rem / func.denominator)

    Log("Integrate rational part: {}.".format(func.printFull()))
    sqrFree = func.denominator.isSquareFree()
    Log("Denominator is squarefree: {}".format(sqrFree))
    if sqrFree:
        Log("Denominator is squarefree -> use Rothstein/Trager method.")
        a = func.numerator
        b = func.denominator
        bp = b.differentiate()
        bpm = bp * (-1)

        zvar = FE.Variable('z')
        zExtension = FE.FieldExtension(FE.TRANSCENDENTAL_SYMBOL, None, zvar)
        newFieldTower = FE.FieldTower(zExtension)

        poly = Pol.Polynomial([a, bpm], variable=zvar)
        Log("Calculate resultant: res_x[{},{}]".format(poly, b))

        coeffsA = []
        Adeg = max(a.degree, bp.degree)
        for i in range(Adeg + 1):
            polZ = Pol.Polynomial([a.getCoefficient(i),
                                   bpm.getCoefficient(i)],
                                  variable=zvar)
            coeffsA.append(polZ)

        b_coeffs = b.getCoefficients()
        coeffsB = []
        for bc in b_coeffs:
            coeffsB.append(Pol.Polynomial([bc], variable=zvar))
        res = Resultant(coeffsA, coeffsB)  # res_T (a-z*b',b)

        if res != 0:
            primitivePart = res.makeMonic()
        if res == 0 or res.isZero():
            primitivePart = 0

        Log("Resultant: {}, {}".format(res, primitivePart))

        sqrfreeFact = primitivePart.factorSquareFree()
        Log("Squarefree factorization of resultant: {}".format(
            Pol.printFactorization(sqrfreeFact)))
        integral = Int.Integral()
        #zExtension = FE.FieldExtension(FE.TRANSCENDENTAL_SYMBOL,1,"z")
        #newFieldTower = FE.FieldTower(zExtension)

        # gcd_x(a-z*b',b)
        coeffsA = []
        Adeg = max(a.degree, bp.degree)
        for i in range(Adeg + 1):
            polZ = Pol.Polynomial(
                [a.getCoefficient(i),
                 bp.getCoefficient(i) * (-1)],
                variable=zvar)
            coeffsA.append(polZ)

        b_coeffs = b.getCoefficients()
        coeffsB = []
        for bc in b_coeffs:
            coeffsB.append(Pol.Polynomial([bc], variable=zvar))
        #v = Pol._PolyGCD(coeffsA, coeffsB)

        LOOK_FOR_RATIONAL_ROOTS = True

        #only consider distinct roots: all roots that have same multiplicity are n are in a factor of form f^n, it will only calculate the roots of f, so only the distinct
        for fac in sqrfreeFact:
            if fac[0] == 1:
                continue
            d = fac[0].degree
            if d == b.degree and d >= 3:  # can't simplify, need full splitting field of b: # TODO: Test for rational roots
                if LOOK_FOR_RATIONAL_ROOTS:
                    ratRoots = fac[0].getRationalRoots()
                    hasRatRoots = len(ratRoots) > 0
                    if hasRatRoots:
                        div = 1
                        for root in ratRoots:
                            p = Pol.Polynomial([-root, 1], variable=zvar)
                            div *= p
                            sqrfreeFact.append((p, 1))

                        (s, r) = Pol.PolyDiv(fac[0], div)
                        if r != 0:
                            raise Exception(str(r))
                        sqrfreeFact.append(
                            (s, 1)
                        )  # s has no rational roots, but it will be tested again -> TODO
                if not LOOK_FOR_RATIONAL_ROOTS or not hasRatRoots:
                    coeff_rat = a / bp
                    coeff_str = coeff_rat.strCustomVar("y")
                    yvar = FE.Variable('y')
                    yExtension = FE.FieldExtension(FE.TRANSCENDENTAL_SYMBOL,
                                                   None, yvar)
                    logFunction = Int.LogFunction(
                        Pol.Polynomial([Pol.Polynomial([0, 1]), -1],
                                       variable=yvar), coeff_rat)
                    rootSum = RS.RootSum(b, logFunction, exprVar="y")
                    return Int.Integral([], [], [rootSum])
                continue
            if d <= 2:
                roots = fac[0].getRoots()
                for c in roots:
                    v = Pol.PolyGCD(a + (-c) * bp, b)
                    log = Int.LogFunction(v, c)
                    integral += Int.Integral(logs=[log])
            else:
                if LOOK_FOR_RATIONAL_ROOTS:
                    ratRoots = fac[0].getRationalRoots()
                    hasRatRoots = len(ratRoots) > 0
                    if hasRatRoots:
                        div = 1
                        for root in ratRoots:
                            p = Pol.Polynomial([-root, 1], variable=zvar)
                            div *= p
                            sqrfreeFact.append((p, 1))

                        (s, r) = Pol.PolyDiv(fac[0], div)
                        if r != 0:
                            raise Exception(str(r))
                        sqrfreeFact.append(
                            (s, 1)
                        )  # s has no rational roots, but it will be tested again -> TODO

                if not LOOK_FOR_RATIONAL_ROOTS or not hasRatRoots:
                    v = Pol.Polynomial(
                        _PolyGCDWithAlgebraicParameter(
                            coeffsA, coeffsB,
                            fac[0]))  #,callUpdateCoeffs =False)
                    rootSum = RS.RootSum(fac[0],
                                         "z*{}".format(logExpression(v)),
                                         exprVar="z")
                    integral += Int.Integral(rootSums=[rootSum])

        return integral

        #roots = primitivePart.getRoots()
        """if func.denominator.degree>2:
            poly = func.denominator
            coeff_rat = func.numerator/func.denominator.differentiate()
            coeff_str = coeff_rat.strCustomVar("y")
            rootSum = RS.RootSum(poly,"({}){}".format(coeff_str, logExpression("x-y")),exprVar="y")
            return Int.Integral([],[],[rootSum])
        """
    else:
        Log("Use Hermite-Reduction to make the denominator squarefree")
        return HermiteReduction(func)
示例#4
0
def IntegrateRationalPartExpExt(func, fieldTower):
    if func==0 or func.numerator==0 or func.numerator.isZero():
        return Int.Integral()

    func = func.makeDenominatorMonic()
    l = func.denominator.lowestDegree
    if l!=0:
        powerPol = Pol.Polynomial([0,Number.Rational(1,1)],variable=fieldTower.getLastVariable())**l # T^l
        qs = func.denominator/powerPol #q=T^l*qs
        (rs,w) = Pol.extendedEuclidGenF(powerPol, qs, func.numerator)
        w_ext = ExtPol.extPolyFromPol_power(w, l) # w/T^l
        #rat = rs/qs
        #if type(rat) is Pol.Polynomial:
        #    ratInt = Integrate()
        return IntegratePolynomialPartExpExt(w_ext,fieldTower) + Integrate(rs/qs)
        #raise NotImplementedError()
    
    sqrFreeFactorization = func.denominator.factorSquareFree()
    partialFractions = func.BasicPartialFraction(sqrFreeFactorization)
    integral = Int.Integral()
    integratedPart = 0
    toIntegratePart = 0 # squarefree part

    for frac in partialFractions:
        j = frac[2]
        q_i = frac[1]
        r_ij = frac[0]
        integrand = r_ij/(q_i**j)
        while j>1:
            j = Rational.fromFloat(j)
            (s,t) = Pol.extendedEuclidGenF(q_i, q_i.differentiate(), r_ij)
            #p1 = Int.Integral(poly_rationals=[(-1)*t/(j-1)/(q_i**(j-1))])
            integratedPart += (-1)*t*(1/(j-1))/(q_i**(j-1))
            tPrime = 0 if isNumber(t) else t.differentiate()
            num = s+tPrime*(1/(j-1))
            integrand = num/(q_i**(j-1))
            r_ij = num
            j -= 1
        toIntegratePart += integrand
    
    integral += Int.Integral(poly_rationals=[integratedPart])
    if toIntegratePart==0:
        return integral
    
    r = toIntegratePart.reduceToLowestPossibleFieldTower()
    if r.fieldTower!=toIntegratePart.fieldTower:
        integral += Integrate(r)
    else:   
        a = toIntegratePart.numerator
        b = toIntegratePart.denominator
        bp = b.differentiate()
        
        zvar = FE.Variable('z')
        zExtension = FE.FieldExtension(FE.TRANSCENDENTAL_SYMBOL,None,zvar)
        newFieldTower = fieldTower.getStrippedTower(fieldTower.towerHeight-1).addFieldExtension(zExtension)
        
        coeffsA = []
        Adeg = max(a.degree,bp.degree)
        for i in range(Adeg+1):
            polZ = Pol.Polynomial([a.getCoefficient(i),bp.getCoefficient(i)*(-1)],variable=zvar)
            coeffsA.append(polZ)
            
        b_coeffs = b.getCoefficients()
        coeffsB = []
        for bc in b_coeffs:
            coeffsB.append(Pol.Polynomial([bc],variable=zvar))
        res = Resultant(coeffsA, coeffsB) # res_T (a-z*b',b)
        
        if res!=0:
            primitivePart = res.makeMonic().reduceToLowestPossibleFieldTower()
            constantRoots = primitivePart.hasOnlyConstantCoefficients()
        if res==0 or res.isZero():
            constantRoots = False # TODO
            primitivePart = 0
                
        Log("Resultant: {}, {}".format(res,primitivePart))
        #print("Only constant coefficients in primitive part {}: {}".format(primitivePart,constantRoots))
        
        if not constantRoots:
            raise Int.IntegralNotElementaryError("Integral is not elementary")
        
        
        roots = primitivePart.getRoots()
        vfunc = []
        rootsDone = []
        for c in roots:
            if c in rootsDone:
                continue
            rootsDone.append(c) # only consider distinct roots
            x = a+bp*(-c)
            vfunc.append(Pol.PolyGCD(x, b))
        intPart = Int.Integral()
        for (c,v) in zip(rootsDone,vfunc):
            logExpr = Int.LogFunction(v,c)
            intPart += Int.Integral(logs=[logExpr])
            vd = v.degree
            k = c*vd*(-1)
            polyPart = k*fieldTower.getLastExtension().argFunction
            intPart += Int.Integral(poly_rationals=[polyPart])
        integral += intPart
    
    return integral
示例#5
0
def IntegrateRationalPartLogExt(func, fieldTower): # Hermite Reduction
    if func.numerator==0 or func.numerator.isZero():
        return Int.Integral()
    func = func.reduceToLowestPossibleFieldTower()
    if func.fieldTower.towerHeight<fieldTower.towerHeight:
        return Integrate(func)
    func = func.makeDenominatorMonic()
    sqrFreeFactorization = func.denominator.factorSquareFree()
    partialFractions = func.BasicPartialFraction(sqrFreeFactorization)
    integral = Int.Integral()
    integratedPart = 0
    toIntegratePart = 0 # squarefree part
    #1/(x+1)^2 *(1/log(x+1)) + -x/(x+1)^2 * 1/(log(x+1)^2)
    Log("Integrate Rational part {}".format(func))
    for frac in partialFractions:
        j = frac[2]
        q_i = frac[1]
        r_ij = frac[0]
        integrand = r_ij/(q_i**j)
        while j>1:
            j = Rational.fromFloat(j)
            (s,t) = Pol.extendedEuclidGenF(q_i, q_i.differentiate(), r_ij)
            #p1 = Int.Integral(poly_rationals=[(-1)*t/(j-1)/(q_i**(j-1))])
            integratedPart += (-1)*t*(1/(j-1))/(q_i**(j-1))
            tPrime = 0 if isNumber(t) else t.differentiate()
            num = s+tPrime*(1/(j-1))
            integrand = num/(q_i**(j-1))
            r_ij = num
            j -= 1
        toIntegratePart += integrand
    
    integral += Int.Integral(poly_rationals=[integratedPart])
    if toIntegratePart==0:
        return integral
    
    r = toIntegratePart.reduceToLowestPossibleFieldTower()
    if r.fieldTower!=toIntegratePart.fieldTower:
        integral += Integrate(r)
    else:   
        if not toIntegratePart.denominator.isSquareFree():
            raise Exception() # tests
        a = toIntegratePart.numerator
        b = toIntegratePart.denominator
        bp = b.differentiate()
        
        zvar = FE.Variable('z')
        zExtension = FE.FieldExtension(FE.TRANSCENDENTAL_SYMBOL,None,zvar)
        newFieldTower = fieldTower.getStrippedTower(fieldTower.towerHeight-1).addFieldExtension(zExtension)
        
        
        coeffsA = []
        Adeg = max(a.degree,bp.degree)   
        for i in range(Adeg+1):
            ai = a.getCoefficient(i)
            mbi = bp.getCoefficient(i)*(-1)
            polZ = Pol.Polynomial([ai,mbi],variable=zvar)
            coeffsA.append(polZ)
            
        b_coeffs = b.getCoefficients()
        coeffsB = []
        for bc in b_coeffs:
            coeffsB.append(Pol.Polynomial([bc],variable=zvar))
        res = Resultant(coeffsA, coeffsB) # res_T (a-z*b',b)
        if res!=0:
            primitivePart = res.makeMonic()
            constantRoots = primitivePart.hasOnlyConstantCoefficients()
        if res==0 or res.isZero():
            constantRoots = False
            primitivePart = 0
                
        Log("Resultant: {}, {}".format(res,primitivePart))
        #print("Only constant coefficients in primitive part {}: {}".format(primitivePart,constantRoots))
        
        if not constantRoots:
            raise Int.IntegralNotElementaryError("Integral is not elementary")
        
        roots = primitivePart.getRoots()
        vfunc = []
        rootsDone = []
        for c in roots:
            if c in rootsDone:
                continue
            rootsDone.append(c) # only want distinct roots
            vfunc.append(Pol.PolyGCD(a+bp*(-c), b))
        intPart = Int.Integral()
        for (c,v) in zip(rootsDone,vfunc):
            logExpr = Int.LogFunction(v,c)
            intPart += Int.Integral(logs=[logExpr])
        integral += intPart
    
    return integral