Beispiel #1
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]
Beispiel #2
0
def getNumeratorEquation(f, g):
    """
    returns the coefficients of the equation for the numerator of y
    DTQ' + (AT-DT')Q = BD(T^2)/E
    returns (a,b,c) with aQ' + bQ = c
    """
    (A, D, B, E, G) = getADBEG(f, g)
    T = getDenominator(f, g)

    (s, r) = Pol.PolyDiv(D * T * T, E)
    if r == 0 or r.isZero():
        raise NoRischDESolutionError("E doesn't divide D *T^2")
    return (D * T, A * T - D * T.differentiate(), B * s)
Beispiel #3
0
 def asPolynomial(self):
     self.numerator.simplifyCoefficients()
     self.denominator.simplifyCoefficients()
     c = self.denominator.getConstant()
     if c == None:
         denom = self.denominator.reduceToLowestPossibleFieldTower()
         if denom.fieldTower.towerHeight < self.numerator.fieldTower.towerHeight:
             return self.numerator / denom
         (q, r) = Pol.PolyDiv(self.numerator, self.denominator)
         if r == 0:
             return q
         return None
     return self.numerator * (1 / c)
Beispiel #4
0
def Integrate(func):
    if isNumber(func):
        func = Pol.Polynomial([func])
    #else:
    #    func = func.reduceToLowestPossibleFieldTower()
    if isPoly(func):
        quot = func
        rat = 0
    else:
        (quot, rem) = Pol.PolyDiv(func.numerator, func.denominator)
        rat = Rat.RationalFunction(rem,func.denominator)
    
    if func!=0:
        Log("---------------\nBegin: Integrate {}.".format(str(func)))
        Log("Split up in polynomial/rational part: [{}] + [{}]".format(quot,rat))
    fieldTower = func.fieldTower
    lastExtension = fieldTower.getLastExtension()
    try:
        if fieldTower.towerHeight==1:
            out1 = IntegratePolynomialPart(quot)
            out2 = IntegrateRationalFunction(rat)
        elif lastExtension.extensionType==FE.TRANS_LOG:
            out1 = IntegratePolynomialPartLogExt(quot, fieldTower)
            out2 = IntegrateRationalPartLogExt(rat, fieldTower)
        elif lastExtension.extensionType==FE.TRANS_EXP:
            out1 = IntegratePolynomialPartExpExt(quot, fieldTower)
            out2 = IntegrateRationalPartExpExt(rat, fieldTower)
    except Int.IntegralNotElementaryError as e:
        if type(e) == Int.IntegralNotElementaryError:
            return None#Int.Integral("Integral is not elementary")
        else:
            print(e)
            raise e
        out1 = None
        out2 = None
    
    if out1==None or out2==None: return None
    integral = out1+out2
    if func !=0:
        Log("Finished integrating {} : {}\n---------------".format(str(func),str(integral)))
    return integral
Beispiel #5
0
def _PolyDivWithAlgebraicParameter(coeffsA, coeffsB, poly):
    degA = len(coeffsA) - 1
    degB = len(coeffsB) - 1
    if degA < degB:
        return ([0], coeffsA)
    power = degA - degB
    coeff = coeffsA[-1] / coeffsB[-1]
    if isNumber(coeffsB[-1]):
        coeff = coeffsA[-1] / coeffsB[-1]
    else:
        if isPoly(coeffsB[-1]):
            coeff = coeffsA[-1] * coeffsB[-1].asRational().Inverse()
        else:
            coeff = coeffsA[-1] * coeffsB[-1].Inverse()
    monomial = [0] * power + [coeff]
    sub = mulListWithList(monomial, mulObjectToListElements(-1, coeffsB))
    newA = addListToList(sub, coeffsA)
    newA = newA[0:len(newA) - 1]

    zPolys = []
    for coeff in newA:
        if not coeff.isConstant() or not coeff.isZero():
            zPolys.append(coeff)
    isZero = False
    if len(zPolys) == 1:
        zPoly = zPolys[0]
        if type(zPoly) == Rat.RationalFunction:
            zPoly = zPoly.numerator
        (s, r) = Pol.PolyDiv(poly, zPoly)
        if r == 0 or r.isZero():
            isZero = True

    if listIsZero(newA) or isZero:
        return (monomial, 0)
    else:
        (quot, remainder) = _PolyDivWithAlgebraicParameter(newA, coeffsB, poly)
        return (addListToList(quot, monomial), remainder)
Beispiel #6
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)