def test_to_Sequence_Initial_Coniditons(): x = symbols('x') R, Dx = DifferentialOperators(QQ.old_poly_ring(x), 'Dx') n = symbols('n', integer=True) _, Sn = RecurrenceOperators(QQ.old_poly_ring(n), 'Sn') p = HolonomicFunction(Dx - 1, x, 0, [1]).to_sequence() q = [(HolonomicSequence(-1 + (n + 1)*Sn, 1), 0)] assert p == q p = HolonomicFunction(Dx**2 + 1, x, 0, [0, 1]).to_sequence() q = [(HolonomicSequence(1 + (n**2 + 3*n + 2)*Sn**2, [0, 1]), 0)] assert p == q p = HolonomicFunction(Dx**2 + 1 + x**3*Dx, x, 0, [2, 3]).to_sequence() q = [(HolonomicSequence(n + Sn**2 + (n**2 + 7*n + 12)*Sn**4, [2, 3, -1, -1/2, 1/12]), 1)] assert p == q p = HolonomicFunction(x**3*Dx**5 + 1 + Dx, x).to_sequence() q = [(HolonomicSequence(1 + (n + 1)*Sn + (n**5 - 5*n**3 + 4*n)*Sn**2), 0, 3)] assert p == q C_0, C_1, C_2, C_3 = symbols('C_0, C_1, C_2, C_3') p = expr_to_holonomic(log(1+x**2)) q = [(HolonomicSequence(n**2 + (n**2 + 2*n)*Sn**2, [0, 0, C_2]), 0, 1)] assert p.to_sequence() == q p = p.diff() q = [(HolonomicSequence((n + 2) + (n + 2)*Sn**2, [C_0, 0]), 1, 0)] assert p.to_sequence() == q p = expr_to_holonomic(erf(x) + x).to_sequence() q = [(HolonomicSequence((2*n**2 - 2*n) + (n**3 + 2*n**2 - n - 2)*Sn**2, [0, 1 + 2/sqrt(pi), 0, C_3]), 0, 2)] assert p == q
def test_operations(): F = QQ.old_poly_ring(x).free_module(2) G = QQ.old_poly_ring(x).free_module(3) f = F.identity_hom() g = homomorphism(F, F, [0, [1, x]]) h = homomorphism(F, F, [[1, 0], 0]) i = homomorphism(F, G, [[1, 0, 0], [0, 1, 0]]) assert f == f assert f != g assert f != i assert (f != F.identity_hom()) is False assert 2*f == f*2 == homomorphism(F, F, [[2, 0], [0, 2]]) assert f/2 == homomorphism(F, F, [[S.Half, 0], [0, S.Half]]) assert f + g == homomorphism(F, F, [[1, 0], [1, x + 1]]) assert f - g == homomorphism(F, F, [[1, 0], [-1, 1 - x]]) assert f*g == g == g*f assert h*g == homomorphism(F, F, [0, [1, 0]]) assert g*h == homomorphism(F, F, [0, 0]) assert i*f == i assert f([1, 2]) == [1, 2] assert g([1, 2]) == [2, 2*x] assert i.restrict_domain(F.submodule([x, x]))([x, x]) == i([x, x]) h1 = h.quotient_domain(F.submodule([0, 1])) assert h1([1, 0]) == h([1, 0]) assert h1.restrict_domain(h1.domain.submodule([x, 0]))([x, 0]) == h([x, 0]) raises(TypeError, lambda: f/g) raises(TypeError, lambda: f + 1) raises(TypeError, lambda: f + i) raises(TypeError, lambda: f - 1) raises(TypeError, lambda: f*i)
def rational_reconstruction_sage(a, m): """ Rational number reconstruction implementation borrowed from Sage Input a and m are integers Output a "simple" rational number that is congruent a modulo m """ a %= m if a == 0 or m == 0: return QQ(0, 1) if m < 0: m = -m if a < 0: a = m - a if a == 1: return QQ(1, 1) u = m v = a bnd = math.sqrt(m / 2) U = (1, 0, u) V = (0, 1, v) while abs(V[2]) >= bnd: q = U[2] // V[2] T = (U[0] - q * V[0], U[1] - q * V[1], U[2] - q * V[2]) U = V V = T x = abs(V[1]) y = V[2] if V[1] < 0: y *= -1 if x <= bnd and gcd(x, y) == 1: return QQ(y, x) raise ValueError(f"Rational reconstruction of {a} (mod {m}) does not exist.")
def test_operations(): F = QQ.old_poly_ring(x).free_module(2) G = QQ.old_poly_ring(x).free_module(3) f = F.identity_hom() g = homomorphism(F, F, [0, [1, x]]) h = homomorphism(F, F, [[1, 0], 0]) i = homomorphism(F, G, [[1, 0, 0], [0, 1, 0]]) assert f == f assert f != g assert f != i assert (f != F.identity_hom()) is False assert 2*f == f*2 == homomorphism(F, F, [[2, 0], [0, 2]]) assert f/2 == homomorphism(F, F, [[S(1)/2, 0], [0, S(1)/2]]) assert f + g == homomorphism(F, F, [[1, 0], [1, x + 1]]) assert f - g == homomorphism(F, F, [[1, 0], [-1, 1 - x]]) assert f*g == g == g*f assert h*g == homomorphism(F, F, [0, [1, 0]]) assert g*h == homomorphism(F, F, [0, 0]) assert i*f == i assert f([1, 2]) == [1, 2] assert g([1, 2]) == [2, 2*x] assert i.restrict_domain(F.submodule([x, x]))([x, x]) == i([x, x]) h1 = h.quotient_domain(F.submodule([0, 1])) assert h1([1, 0]) == h([1, 0]) assert h1.restrict_domain(h1.domain.submodule([x, 0]))([x, 0]) == h([x, 0]) raises(TypeError, lambda: f/g) raises(TypeError, lambda: f + 1) raises(TypeError, lambda: f + i) raises(TypeError, lambda: f - 1) raises(TypeError, lambda: f*i)
def test_QuotientRing(): I = QQ.old_poly_ring(x).ideal(x**2 + 1) R = QQ.old_poly_ring(x) / I assert R == QQ.old_poly_ring(x) / [x**2 + 1] assert R == QQ.old_poly_ring(x) / QQ.old_poly_ring(x).ideal(x**2 + 1) assert R != QQ.old_poly_ring(x) assert R.convert(1) / x == -x + I assert -1 + I == x**2 + I assert R.convert(ZZ(1), ZZ) == 1 + I assert R.convert(R.convert(x), R) == R.convert(x) X = R.convert(x) Y = QQ.old_poly_ring(x).convert(x) assert -1 + I == X**2 + I assert -1 + I == Y**2 + I assert R.to_sympy(X) == x raises(ValueError, lambda: QQ.old_poly_ring(x) / QQ.old_poly_ring(x, y).ideal(x)) R = QQ.old_poly_ring(x, order="ilex") I = R.ideal(x) assert R.convert(1) + I == (R / I).convert(1)
def test_to_Sequence_Initial_Coniditons(): x = symbols('x') R, Dx = DifferentialOperators(QQ.old_poly_ring(x), 'Dx') n = symbols('n', integer=True) _, Sn = RecurrenceOperators(QQ.old_poly_ring(n), 'Sn') p = HolonomicFunction(Dx - 1, x, 0, 1).to_sequence() q = [(HolonomicSequence(-1 + (n + 1) * Sn, 1), 0)] assert p == q p = HolonomicFunction(Dx**2 + 1, x, 0, [0, 1]).to_sequence() q = [(HolonomicSequence(1 + (n**2 + 3 * n + 2) * Sn**2, [0, 1]), 0)] assert p == q p = HolonomicFunction(Dx**2 + 1 + x**3 * Dx, x, 0, [2, 3]).to_sequence() q = [(HolonomicSequence(n + Sn**2 + (n**2 + 7 * n + 12) * Sn**4, [2, 3, -1, -1 / 2, 1 / 12]), 1)] assert p == q p = HolonomicFunction(x**3 * Dx**5 + 1 + Dx, x).to_sequence() q = [(HolonomicSequence(1 + (n + 1) * Sn + (n**5 - 5 * n**3 + 4 * n) * Sn**2), 0, 3)] assert p == q C_0, C_1, C_2, C_3 = symbols('C_0, C_1, C_2, C_3') p = expr_to_holonomic(log(1 + x**2)) q = [(HolonomicSequence(n**2 + (n**2 + 2 * n) * Sn**2, [0, 0, C_2]), 0, 1)] assert p.to_sequence() == q p = p.diff() q = [(HolonomicSequence((n + 2) + (n + 2) * Sn**2, [C_0, 0]), 1, 0)] assert p.to_sequence() == q p = expr_to_holonomic(erf(x) + x).to_sequence() q = [(HolonomicSequence( (2 * n**2 - 2 * n) + (n**3 + 2 * n**2 - n - 2) * Sn**2, [0, 1 + 2 / sqrt(pi), 0, C_3]), 0, 2)] assert p == q
def test_SDM_mul(): A = SDM({0: {0: ZZ(2)}}, (2, 2), ZZ) B = SDM({0: {0: ZZ(4)}}, (2, 2), ZZ) assert A * ZZ(2) == B assert ZZ(2) * A == B raises(TypeError, lambda: A * QQ(1, 2)) raises(TypeError, lambda: QQ(1, 2) * A)
def test_pickling_polys_polyclasses(): from sympy.polys.polyclasses import DMP, DMF, ANP for c in (DMP, DMP([[ZZ(1)], [ZZ(2)], [ZZ(3)]], ZZ)): check(c) for c in (DMF, DMF(([ZZ(1), ZZ(2)], [ZZ(1), ZZ(3)]), ZZ)): check(c) for c in (ANP, ANP([QQ(1), QQ(2)], [QQ(1), QQ(2), QQ(3)], QQ)): check(c)
def test_SDM_convert_to(): A = SDM({0: {1: ZZ(1)}, 1: {0: ZZ(2), 1: ZZ(3)}}, (2, 2), ZZ) B = SDM({0: {1: QQ(1)}, 1: {0: QQ(2), 1: QQ(3)}}, (2, 2), QQ) C = A.convert_to(QQ) assert C == B assert C.domain == QQ D = A.convert_to(ZZ) assert D == A assert D.domain == ZZ
def get_test_points(): points=[IMat([QQ(3),QQ(0),QQ(0)]),IMat([QQ(2),QQ(2),QQ(0)]),IMat([QQ(-2),QQ(2),QQ(0)]),IMat([QQ(3,2),QQ(-3,2),QQ(2)]),IMat([QQ(3,2),QQ(3,2),QQ(2)]),IMat([QQ(-3,2),QQ(-3,2),QQ(2)]),IMat([QQ(-3,2),QQ(3,2),QQ(2)]),IMat([QQ(0),QQ(0),QQ(3)])] all_points=[] for p in points: all_points.append(p) all_points.append(-p) return all_points
def to_rational(s): denom = 1 extra_num = 1 if ('E' in s) or ('e' in s): s, exp = re.split("[Ee]", s) if exp[0] == "-": denom = 10**(-int(exp)) else: extra_num = 10**(int(exp)) frac = s.split(".") if len(frac) == 1: return QQ(int(s) * extra_num, denom) return QQ(int(frac[0] + frac[1]) * extra_num, denom * 10**(len(frac[1])))
def parse_reactions(lines, varnames): """ Input: lines with reactions, each reaction of the form "reactants -> products, rate" and varnames Output: the list of corresponding equations """ raw_reactions = [] var_to_ind = {v: i for i, v in enumerate(varnames)} for l in lines: if "," not in l: continue reaction, rate = separate_reation_rate(l) lhs, rhs = reaction.split("->") raw_reactions.append((lhs.strip(), rhs.strip(), rate.strip())) eqs = {v: SparsePolynomial(varnames, QQ) for v in varnames} for lhs, rhs, rate in raw_reactions: rate_poly = SparsePolynomial.from_string(rate, varnames, var_to_ind) ldict = species_to_multiset(lhs) rdict = species_to_multiset(rhs) monomial = tuple((var_to_ind[v], mult) for v, mult in ldict.items()) reaction_poly = rate_poly * SparsePolynomial(varnames, QQ, {monomial: QQ(1)}) for v, mult in rdict.items(): eqs[v] += reaction_poly * mult for v, mult in ldict.items(): eqs[v] += reaction_poly * (-mult) return [eqs[v] for v in varnames]
def test_from_sympy(): x = symbols("x") R, Dx = DifferentialOperators(QQ.old_poly_ring(x), "Dx") p = from_sympy((sin(x) / x) ** 2) q = HolonomicFunction( 8 * x + (4 * x ** 2 + 6) * Dx + 6 * x * Dx ** 2 + x ** 2 * Dx ** 3, x, 1, [sin(1) ** 2, -2 * sin(1) ** 2 + 2 * sin(1) * cos(1), -8 * sin(1) * cos(1) + 2 * cos(1) ** 2 + 4 * sin(1) ** 2], ) assert p == q p = from_sympy(1 / (1 + x ** 2) ** 2) q = HolonomicFunction(4 * x + (x ** 2 + 1) * Dx, x, 0, 1) assert p == q p = from_sympy(exp(x) * sin(x) + x * log(1 + x)) q = HolonomicFunction( (4 * x ** 3 + 20 * x ** 2 + 40 * x + 36) + (-4 * x ** 4 - 20 * x ** 3 - 40 * x ** 2 - 36 * x) * Dx + (4 * x ** 5 + 12 * x ** 4 + 14 * x ** 3 + 16 * x ** 2 + 20 * x - 8) * Dx ** 2 + (-4 * x ** 5 - 10 * x ** 4 - 4 * x ** 3 + 4 * x ** 2 - 2 * x + 8) * Dx ** 3 + (2 * x ** 5 + 4 * x ** 4 - 2 * x ** 3 - 7 * x ** 2 + 2 * x + 5) * Dx ** 4, x, 0, [0, 1, 4, -1], ) assert p == q p = from_sympy(x * exp(x) + cos(x) + 1) q = HolonomicFunction( (-x - 3) * Dx + (x + 2) * Dx ** 2 + (-x - 3) * Dx ** 3 + (x + 2) * Dx ** 4, x, 0, [2, 1, 1, 3] ) assert p == q assert (x * exp(x) + cos(x) + 1).series(n=10) == p.series(n=10) p = from_sympy(log(1 + x) ** 2 + 1) q = HolonomicFunction(Dx + (3 * x + 3) * Dx ** 2 + (x ** 2 + 2 * x + 1) * Dx ** 3, x, 0, [1, 0, 2]) assert p == q p = from_sympy(erf(x) ** 2 + x) q = HolonomicFunction( (32 * x ** 4 - 8 * x ** 2 + 8) * Dx ** 2 + (24 * x ** 3 - 2 * x) * Dx ** 3 + (4 * x ** 2 + 1) * Dx ** 4, x, 0, [0, 1, 8 / pi, 0], ) assert p == q p = from_sympy(cosh(x) * x) q = HolonomicFunction((-x ** 2 + 2) - 2 * x * Dx + x ** 2 * Dx ** 2, x, 0, [0, 1]) assert p == q p = from_sympy(besselj(2, x)) q = HolonomicFunction((x ** 2 - 4) + x * Dx + x ** 2 * Dx ** 2, x, 0, [0, 0]) assert p == q p = from_sympy(besselj(0, x) + exp(x)) q = HolonomicFunction( (-2 * x ** 2 - x + 1) + (2 * x ** 2 - x - 3) * Dx + (-2 * x ** 2 + x + 2) * Dx ** 2 + (2 * x ** 2 + x) * Dx ** 3, x, 0, [2, 1, 1 / 2], ) assert p == q
def test_multiplication_initial_condition(): x = symbols('x') R, Dx = DifferentialOperators(QQ.old_poly_ring(x), 'Dx') p = HolonomicFunction(Dx**2 + x*Dx - 1, x, 0, [3, 1]) q = HolonomicFunction(Dx**2 + 1, x, 0, [1, 1]) r = HolonomicFunction((x**4 + 14*x**2 + 60) + 4*x*Dx + (x**4 + 9*x**2 + 20)*Dx**2 + \ (2*x**3 + 18*x)*Dx**3 + (x**2 + 10)*Dx**4, x, 0, [3, 4, 2, 3]) assert p * q == r p = HolonomicFunction(Dx**2 + x, x, 0, [1, 0]) q = HolonomicFunction(Dx**3 - x**2, x, 0, [3, 3, 3]) r = HolonomicFunction((27*x**8 - 37*x**7 - 10*x**6 - 492*x**5 - 552*x**4 + 160*x**3 + \ 1212*x**2 + 216*x + 360) + (162*x**7 - 384*x**6 - 294*x**5 - 84*x**4 + 24*x**3 + \ 756*x**2 + 120*x - 1080)*Dx + (81*x**6 - 246*x**5 + 228*x**4 + 36*x**3 + \ 660*x**2 - 720*x)*Dx**2 + (-54*x**6 + 128*x**5 - 18*x**4 - 240*x**2 + 600)*Dx**3 + \ (81*x**5 - 192*x**4 - 84*x**3 + 162*x**2 - 60*x - 180)*Dx**4 + (-108*x**3 + \ 192*x**2 + 72*x)*Dx**5 + (27*x**4 - 64*x**3 - 36*x**2 + 60)*Dx**6, x, 0, [3, 3, 3, -3, -12, -24]) assert p * q == r p = HolonomicFunction(Dx - 1, x, 0, [2]) q = HolonomicFunction(Dx**2 + 1, x, 0, [0, 1]) r = HolonomicFunction(2 -2*Dx + Dx**2, x, 0, [0, 2]) assert p * q == r q = HolonomicFunction(x*Dx**2 + 1 + 2*Dx, x, 0,[0, 1]) r = HolonomicFunction((x - 1) + (-2*x + 2)*Dx + x*Dx**2, x, 0, [0, 2]) assert p * q == r p = HolonomicFunction(Dx**2 - 1, x, 0, [1, 3]) q = HolonomicFunction(Dx**3 + 1, x, 0, [1, 2, 1]) r = HolonomicFunction(6*Dx + 3*Dx**2 + 2*Dx**3 - 3*Dx**4 + Dx**6, x, 0, [1, 5, 14, 17, 17, 2]) assert p * q == r
def test_to_hyper(): x = symbols('x') R, Dx = DifferentialOperators(QQ.old_poly_ring(x), 'Dx') p = HolonomicFunction(Dx - 2, x, 0, 3).to_hyper() q = 3 * hyper([], [], 2 * x) assert p == q p = hyperexpand(HolonomicFunction((1 + x) * Dx - 3, x, 0, 2).to_hyper()).expand() q = 2 * x**3 + 6 * x**2 + 6 * x + 2 assert p == q p = HolonomicFunction((1 + x) * Dx**2 + Dx, x, 0, [0, 1]).to_hyper() q = -x**2 * hyper((2, 2, 1), (2, 3), -x) / 2 + x assert p == q p = HolonomicFunction(2 * x * Dx + Dx**2, x, 0, [0, 2 / sqrt(pi)]).to_hyper() q = 2 * x * hyper((1 / 2, ), (3 / 2, ), -x**2) / sqrt(pi) assert p == q p = hyperexpand( HolonomicFunction(2 * x * Dx + Dx**2, x, 0, [1, -2 / sqrt(pi)]).to_hyper()) q = erfc(x) assert p.rewrite(erfc) == q p = hyperexpand( HolonomicFunction((x**2 - 1) + x * Dx + x**2 * Dx**2, x, 0, [0, S(1) / 2]).to_hyper()) q = besselj(1, x) assert p == q p = hyperexpand( HolonomicFunction(x * Dx**2 + Dx + x, x, 0, [1, 0]).to_hyper()) q = besselj(0, x) assert p == q
def evaluate_stack(s): op = s.pop() if op == "unary -": return -evaluate_stack(s) if op in "+-*/": # note: operands are pushed onto the stack in reverse order op2 = evaluate_stack(s) op1 = evaluate_stack(s) if op == "+": if op1.size < op2.size: op1, op2 = op2, op1 op1 += op2 return op1 if op == "-": op1 -= op2 return op1 if op == "*": return op1 * op2 if op == "/": raise NotImplementedError if op == "^" or op == "**": exp = int(s.pop()) base = evaluate_stack(s) return base.exp(exp) if re.match(r"^[+-]?\d+(?:\.\d*)?(?:[eE][+-]?\d+)?$", op): return SparsePolynomial.from_const(to_rational(op), varnames) return SparsePolynomial(varnames, QQ, {((var_ind_map[op], 1),): QQ(1)})
def test_addition_initial_condition(): x = symbols('x') R, Dx = DifferentialOperators(QQ.old_poly_ring(x), 'Dx') p = HolonomicFunction(Dx - 1, x, 0, [3]) q = HolonomicFunction(Dx**2 + 1, x, 0, [1, 0]) r = HolonomicFunction(-1 + Dx - Dx**2 + Dx**3, x, 0, [4, 3, 2]) assert p + q == r p = HolonomicFunction(Dx - x + Dx**2, x, 0, [1, 2]) q = HolonomicFunction(Dx**2 + x, x, 0, [1, 0]) r = HolonomicFunction((-x**4 - x**3/4 - x**2 + Rational(1, 4)) + (x**3 + x**2/4 + x*Rational(3, 4) + 1)*Dx + \ (x*Rational(-3, 2) + Rational(7, 4))*Dx**2 + (x**2 - x*Rational(7, 4) + Rational(1, 4))*Dx**3 + (x**2 + x/4 + S.Half)*Dx**4, x, 0, [2, 2, -2, 2]) assert p + q == r p = HolonomicFunction(Dx**2 + 4 * x * Dx + x**2, x, 0, [3, 4]) q = HolonomicFunction(Dx**2 + 1, x, 0, [1, 1]) r = HolonomicFunction((x**6 + 2*x**4 - 5*x**2 - 6) + (4*x**5 + 36*x**3 - 32*x)*Dx + \ (x**6 + 3*x**4 + 5*x**2 - 9)*Dx**2 + (4*x**5 + 36*x**3 - 32*x)*Dx**3 + (x**4 + \ 10*x**2 - 3)*Dx**4, x, 0, [4, 5, -1, -17]) assert p + q == r q = HolonomicFunction(Dx**3 + x, x, 2, [3, 0, 1]) p = HolonomicFunction(Dx - 1, x, 2, [1]) r = HolonomicFunction((-x**2 - x + 1) + (x**2 + x)*Dx + (-x - 2)*Dx**3 + \ (x + 1)*Dx**4, x, 2, [4, 1, 2, -5 ]) assert p + q == r p = expr_to_holonomic(sin(x)) q = expr_to_holonomic(1 / x, x0=1) r = HolonomicFunction((x**2 + 6) + (x**3 + 2*x)*Dx + (x**2 + 6)*Dx**2 + (x**3 + 2*x)*Dx**3, \ x, 1, [sin(1) + 1, -1 + cos(1), -sin(1) + 2]) assert p + q == r C_1 = symbols('C_1') p = expr_to_holonomic(sqrt(x)) q = expr_to_holonomic(sqrt(x**2 - x)) r = (p + q).to_expr().subs(C_1, -I / 2).expand() assert r == I * sqrt(x) * sqrt(-x + 1) + sqrt(x)
def test_negative_power(): x = symbols("x") _, Dx = DifferentialOperators(QQ.old_poly_ring(x), 'Dx') h1 = HolonomicFunction((-1) + (x)*Dx, x) ** -2 h2 = HolonomicFunction((2) + (x)*Dx, x) assert h1 == h2
def test_negative_power(): x = symbols("x") _, Dx = DifferentialOperators(QQ.old_poly_ring(x), 'Dx') h1 = HolonomicFunction((-1) + (x) * Dx, x)**-2 h2 = HolonomicFunction((2) + (x) * Dx, x) assert h1 == h2
def test_evalf(): x = symbols('x') R, Dx = DifferentialOperators(QQ.old_poly_ring(x), 'Dx') # a straight line on real axis r = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1] p = HolonomicFunction((1 + x)*Dx**2 + Dx, x, 0, [0, 1]) s = '0.699525841805253' assert sstr(p.evalf(r)[-1]) == s # a traingle with vertices (0, 1+i, 2) r = [0.1 + 0.1*I] for i in range(9): r.append(r[-1]+0.1+0.1*I) for i in range(10): r.append(r[-1]+0.1-0.1*I) s = '1.07530466271334 - 0.0251200594793912*I' assert sstr(p.evalf(r)[-1]) == s p = HolonomicFunction(Dx**2 + 1, x, 0, [0, 1]) s = '0.905546532085401 - 6.93889390390723e-18*I' assert sstr(p.evalf(r)[-1]) == s # a rectangular path (0 -> i -> 2+i -> 2) r = [0.1*I] for i in range(9): r.append(r[-1]+0.1*I) for i in range(20): r.append(r[-1]+0.1) for i in range(10): r.append(r[-1]-0.1*I) p = HolonomicFunction(Dx**2 + 1, x, 0, [1,1]).evalf(r) s = '0.501421652861245 - 3.88578058618805e-16*I' assert sstr(p[-1]) == s
def test_addition_initial_condition(): x = symbols('x') R, Dx = DifferentialOperators(QQ.old_poly_ring(x), 'Dx') p = HolonomicFunction(Dx-1, x, 0, 3) q = HolonomicFunction(Dx**2+1, x, 0, [1, 0]) r = HolonomicFunction(-1 + Dx - Dx**2 + Dx**3, x, 0, [4, 3, 2]) assert p + q == r p = HolonomicFunction(Dx - x + Dx**2, x, 0, [1, 2]) q = HolonomicFunction(Dx**2 + x, x, 0, [1, 0]) r = HolonomicFunction((-x**4 - x**3/4 - x**2 + 1/4) + (x**3 + x**2/4 + 3*x/4 + 1)*Dx + \ (-3*x/2 + 7/4)*Dx**2 + (x**2 - 7*x/4 + 1/4)*Dx**3 + (x**2 + x/4 + 1/2)*Dx**4, x, 0, [2, 2, -2, 2]) assert p + q == r p = HolonomicFunction(Dx**2 + 4*x*Dx + x**2, x, 0, [3, 4]) q = HolonomicFunction(Dx**2 + 1, x, 0, [1, 1]) r = HolonomicFunction((x**6 + 2*x**4 - 5*x**2 - 6) + (4*x**5 + 36*x**3 - 32*x)*Dx + \ (x**6 + 3*x**4 + 5*x**2 - 9)*Dx**2 + (4*x**5 + 36*x**3 - 32*x)*Dx**3 + (x**4 + \ 10*x**2 - 3)*Dx**4, x, 0, [4, 5, -1, -17]) assert p + q == r q = HolonomicFunction(Dx**3 + x, x, 2, [3, 0, 1]) p = HolonomicFunction(Dx - 1, x, 2, [1]) r = HolonomicFunction((-x**2 - x + 1) + (x**2 + x)*Dx + (-x - 2)*Dx**3 + \ (x + 1)*Dx**4, x, 2, [4, 1, 2, -5 ]) assert p + q == r p = from_sympy(sin(x)) q = from_sympy(1/x) r = HolonomicFunction((x**2 + 6) + (x**3 + 2*x)*Dx + (x**2 + 6)*Dx**2 + (x**3 + 2*x)*Dx**3, \ x, 1, [sin(1) + 1, -1 + cos(1), -sin(1) + 2]) assert p + q == r
def test_multiplication_initial_condition(): x = symbols('x') R, Dx = DifferentialOperators(QQ.old_poly_ring(x), 'Dx') p = HolonomicFunction(Dx**2 + x * Dx - 1, x, 0, [3, 1]) q = HolonomicFunction(Dx**2 + 1, x, 0, [1, 1]) r = HolonomicFunction((x**4 + 14*x**2 + 60) + 4*x*Dx + (x**4 + 9*x**2 + 20)*Dx**2 + \ (2*x**3 + 18*x)*Dx**3 + (x**2 + 10)*Dx**4, x, 0, [3, 4, 2, 3]) assert p * q == r p = HolonomicFunction(Dx**2 + x, x, 0, [1, 0]) q = HolonomicFunction(Dx**3 - x**2, x, 0, [3, 3, 3]) r = HolonomicFunction((x**8 - 37*x**7/27 - 10*x**6/27 - 164*x**5/9 - 184*x**4/9 + \ 160*x**3/27 + 404*x**2/9 + 8*x + 40/3) + (6*x**7 - 128*x**6/9 - 98*x**5/9 - 28*x**4/9 + \ 8*x**3/9 + 28*x**2 + 40*x/9 - 40)*Dx + (3*x**6 - 82*x**5/9 + 76*x**4/9 + 4*x**3/3 + \ 220*x**2/9 - 80*x/3)*Dx**2 + (-2*x**6 + 128*x**5/27 - 2*x**4/3 -80*x**2/9 + 200/9)*Dx**3 + \ (3*x**5 - 64*x**4/9 - 28*x**3/9 + 6*x**2 - 20*x/9 - 20/3)*Dx**4 + (-4*x**3 + 64*x**2/9 + \ 8*x/3)*Dx**5 + (x**4 - 64*x**3/27 - 4*x**2/3 + 20/9)*Dx**6, x, 0, [3, 3, 3, -3, -12, -24]) assert p * q == r p = HolonomicFunction(Dx - 1, x, 0, [2]) q = HolonomicFunction(Dx**2 + 1, x, 0, [0, 1]) r = HolonomicFunction(2 - 2 * Dx + Dx**2, x, 0, [0, 2]) assert p * q == r q = HolonomicFunction(x * Dx**2 + 1 + 2 * Dx, x, 0, [0, 1]) r = HolonomicFunction((x - 1) + (-2 * x + 2) * Dx + x * Dx**2, x, 0, [0, 2]) assert p * q == r p = HolonomicFunction(Dx**2 - 1, x, 0, [1, 3]) q = HolonomicFunction(Dx**3 + 1, x, 0, [1, 2, 1]) r = HolonomicFunction(6 * Dx + 3 * Dx**2 + 2 * Dx**3 - 3 * Dx**4 + Dx**6, x, 0, [1, 5, 14, 17, 17, 2]) assert p * q == r p = expr_to_holonomic(sin(x)) q = expr_to_holonomic(1 / x) r = HolonomicFunction(x + 2 * Dx + x * Dx**2, x, 1, [sin(1), -sin(1) + cos(1)]) assert p * q == r
def test_addition_initial_condition(): x = symbols('x') R, Dx = DifferentialOperators(QQ.old_poly_ring(x), 'Dx') p = HolonomicFunction(Dx - 1, x, 0, 3) q = HolonomicFunction(Dx**2 + 1, x, 0, [1, 0]) r = HolonomicFunction(-1 + Dx - Dx**2 + Dx**3, x, 0, [4, 3, 2]) assert p + q == r p = HolonomicFunction(Dx - x + Dx**2, x, 0, [1, 2]) q = HolonomicFunction(Dx**2 + x, x, 0, [1, 0]) r = HolonomicFunction((-x**4 - x**3/4 - x**2 + 1/4) + (x**3 + x**2/4 + 3*x/4 + 1)*Dx + \ (-3*x/2 + 7/4)*Dx**2 + (x**2 - 7*x/4 + 1/4)*Dx**3 + (x**2 + x/4 + 1/2)*Dx**4, x, 0, [2, 2, -2, 2]) assert p + q == r p = HolonomicFunction(Dx**2 + 4 * x * Dx + x**2, x, 0, [3, 4]) q = HolonomicFunction(Dx**2 + 1, x, 0, [1, 1]) r = HolonomicFunction((x**6 + 2*x**4 - 5*x**2 - 6) + (4*x**5 + 36*x**3 - 32*x)*Dx + \ (x**6 + 3*x**4 + 5*x**2 - 9)*Dx**2 + (4*x**5 + 36*x**3 - 32*x)*Dx**3 + (x**4 + \ 10*x**2 - 3)*Dx**4, x, 0, [4, 5, -1, -17]) assert p + q == r q = HolonomicFunction(Dx**3 + x, x, 2, [3, 0, 1]) p = HolonomicFunction(Dx - 1, x, 2, [1]) r = HolonomicFunction((-x**2 - x + 1) + (x**2 + x)*Dx + (-x - 2)*Dx**3 + \ (x + 1)*Dx**4, x, 2, [4, 1, 2, -5 ]) assert p + q == r p = expr_to_holonomic(sin(x)) q = expr_to_holonomic(1 / x) r = HolonomicFunction((x**2 + 6) + (x**3 + 2*x)*Dx + (x**2 + 6)*Dx**2 + (x**3 + 2*x)*Dx**3, \ x, 1, [sin(1) + 1, -1 + cos(1), -sin(1) + 2]) assert p + q == r
def test_evalf(): x = symbols('x') R, Dx = DifferentialOperators(QQ.old_poly_ring(x), 'Dx') # a straight line on real axis r = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1] p = HolonomicFunction((1 + x) * Dx**2 + Dx, x, 0, [0, 1]) s = '0.699525841805253' assert sstr(p.evalf(r)[-1]) == s # a traingle with vertices (0, 1+i, 2) r = [0.1 + 0.1 * I] for i in range(9): r.append(r[-1] + 0.1 + 0.1 * I) for i in range(10): r.append(r[-1] + 0.1 - 0.1 * I) s = '1.07530466271334 - 0.0251200594793912*I' assert sstr(p.evalf(r)[-1]) == s p = HolonomicFunction(Dx**2 + 1, x, 0, [0, 1]) s = '0.905546532085401 - 6.93889390390723e-18*I' assert sstr(p.evalf(r)[-1]) == s # a rectangular path (0 -> i -> 2+i -> 2) r = [0.1 * I] for i in range(9): r.append(r[-1] + 0.1 * I) for i in range(20): r.append(r[-1] + 0.1) for i in range(10): r.append(r[-1] - 0.1 * I) p = HolonomicFunction(Dx**2 + 1, x, 0, [1, 1]).evalf(r) s = '0.501421652861245 - 3.88578058618805e-16*I' assert sstr(p[-1]) == s
def test_multiplication_initial_condition(): x = symbols('x') R, Dx = DifferentialOperators(QQ.old_poly_ring(x), 'Dx') p = HolonomicFunction(Dx**2 + x * Dx - 1, x, 0, [3, 1]) q = HolonomicFunction(Dx**2 + 1, x, 0, [1, 1]) r = HolonomicFunction((x**4 + 14*x**2 + 60) + 4*x*Dx + (x**4 + 9*x**2 + 20)*Dx**2 + \ (2*x**3 + 18*x)*Dx**3 + (x**2 + 10)*Dx**4, x, 0, [3, 4, 2, 3]) assert p * q == r p = HolonomicFunction(Dx**2 + x, x, 0, [1, 0]) q = HolonomicFunction(Dx**3 - x**2, x, 0, [3, 3, 3]) r = HolonomicFunction((27*x**8 - 37*x**7 - 10*x**6 - 492*x**5 - 552*x**4 + 160*x**3 + \ 1212*x**2 + 216*x + 360) + (162*x**7 - 384*x**6 - 294*x**5 - 84*x**4 + 24*x**3 + \ 756*x**2 + 120*x - 1080)*Dx + (81*x**6 - 246*x**5 + 228*x**4 + 36*x**3 + \ 660*x**2 - 720*x)*Dx**2 + (-54*x**6 + 128*x**5 - 18*x**4 - 240*x**2 + 600)*Dx**3 + \ (81*x**5 - 192*x**4 - 84*x**3 + 162*x**2 - 60*x - 180)*Dx**4 + (-108*x**3 + \ 192*x**2 + 72*x)*Dx**5 + (27*x**4 - 64*x**3 - 36*x**2 + 60)*Dx**6, x, 0, [3, 3, 3, -3, -12, -24]) assert p * q == r p = HolonomicFunction(Dx - 1, x, 0, [2]) q = HolonomicFunction(Dx**2 + 1, x, 0, [0, 1]) r = HolonomicFunction(2 - 2 * Dx + Dx**2, x, 0, [0, 2]) assert p * q == r q = HolonomicFunction(x * Dx**2 + 1 + 2 * Dx, x, 0, [0, 1]) r = HolonomicFunction((x - 1) + (-2 * x + 2) * Dx + x * Dx**2, x, 0, [0, 2]) assert p * q == r p = HolonomicFunction(Dx**2 - 1, x, 0, [1, 3]) q = HolonomicFunction(Dx**3 + 1, x, 0, [1, 2, 1]) r = HolonomicFunction(6 * Dx + 3 * Dx**2 + 2 * Dx**3 - 3 * Dx**4 + Dx**6, x, 0, [1, 5, 14, 17, 17, 2]) assert p * q == r
def test_to_hyper(): x = symbols('x') R, Dx = DifferentialOperators(QQ.old_poly_ring(x), 'Dx') p = HolonomicFunction(Dx - 2, x, 0, [3]).to_hyper() q = 3 * hyper([], [], 2*x) assert p == q p = hyperexpand(HolonomicFunction((1 + x) * Dx - 3, x, 0, [2]).to_hyper()).expand() q = 2*x**3 + 6*x**2 + 6*x + 2 assert p == q p = HolonomicFunction((1 + x)*Dx**2 + Dx, x, 0, [0, 1]).to_hyper() q = -x**2*hyper((2, 2, 1), (2, 3), -x)/2 + x assert p == q p = HolonomicFunction(2*x*Dx + Dx**2, x, 0, [0, 2/sqrt(pi)]).to_hyper() q = 2*x*hyper((1/2,), (3/2,), -x**2)/sqrt(pi) assert p == q p = hyperexpand(HolonomicFunction(2*x*Dx + Dx**2, x, 0, [1, -2/sqrt(pi)]).to_hyper()) q = erfc(x) assert p.rewrite(erfc) == q p = hyperexpand(HolonomicFunction((x**2 - 1) + x*Dx + x**2*Dx**2, x, 0, [0, S(1)/2]).to_hyper()) q = besselj(1, x) assert p == q p = hyperexpand(HolonomicFunction(x*Dx**2 + Dx + x, x, 0, [1, 0]).to_hyper()) q = besselj(0, x) assert p == q
def test_addition_initial_condition(): x = symbols('x') R, Dx = DifferentialOperators(QQ.old_poly_ring(x), 'Dx') p = HolonomicFunction(Dx-1, x, 0, [3]) q = HolonomicFunction(Dx**2+1, x, 0, [1, 0]) r = HolonomicFunction(-1 + Dx - Dx**2 + Dx**3, x, 0, [4, 3, 2]) assert p + q == r p = HolonomicFunction(Dx - x + Dx**2, x, 0, [1, 2]) q = HolonomicFunction(Dx**2 + x, x, 0, [1, 0]) r = HolonomicFunction((-x**4 - x**3/4 - x**2 + 1/4) + (x**3 + x**2/4 + 3*x/4 + 1)*Dx + \ (-3*x/2 + 7/4)*Dx**2 + (x**2 - 7*x/4 + 1/4)*Dx**3 + (x**2 + x/4 + 1/2)*Dx**4, x, 0, [2, 2, -2, 2]) assert p + q == r p = HolonomicFunction(Dx**2 + 4*x*Dx + x**2, x, 0, [3, 4]) q = HolonomicFunction(Dx**2 + 1, x, 0, [1, 1]) r = HolonomicFunction((x**6 + 2*x**4 - 5*x**2 - 6) + (4*x**5 + 36*x**3 - 32*x)*Dx + \ (x**6 + 3*x**4 + 5*x**2 - 9)*Dx**2 + (4*x**5 + 36*x**3 - 32*x)*Dx**3 + (x**4 + \ 10*x**2 - 3)*Dx**4, x, 0, [4, 5, -1, -17]) assert p + q == r q = HolonomicFunction(Dx**3 + x, x, 2, [3, 0, 1]) p = HolonomicFunction(Dx - 1, x, 2, [1]) r = HolonomicFunction((-x**2 - x + 1) + (x**2 + x)*Dx + (-x - 2)*Dx**3 + \ (x + 1)*Dx**4, x, 2, [4, 1, 2, -5 ]) assert p + q == r p = expr_to_holonomic(sin(x)) q = expr_to_holonomic(1/x, x0=1) r = HolonomicFunction((x**2 + 6) + (x**3 + 2*x)*Dx + (x**2 + 6)*Dx**2 + (x**3 + 2*x)*Dx**3, \ x, 1, [sin(1) + 1, -1 + cos(1), -sin(1) + 2]) assert p + q == r C_1 = symbols('C_1') p = expr_to_holonomic(sqrt(x)) q = expr_to_holonomic(sqrt(x**2-x)) r = (p + q).to_expr().subs(C_1, -I/2).expand() assert r == I*sqrt(x)*sqrt(-x + 1) + sqrt(x)
def test_multiplication_initial_condition(): x = symbols('x') R, Dx = DifferentialOperators(QQ.old_poly_ring(x), 'Dx') p = HolonomicFunction(Dx**2 + x*Dx - 1, x, 0, [3, 1]) q = HolonomicFunction(Dx**2 + 1, x, 0, [1, 1]) r = HolonomicFunction((x**4 + 14*x**2 + 60) + 4*x*Dx + (x**4 + 9*x**2 + 20)*Dx**2 + \ (2*x**3 + 18*x)*Dx**3 + (x**2 + 10)*Dx**4, x, 0, [3, 4, 2, 3]) assert p * q == r p = HolonomicFunction(Dx**2 + x, x, 0, [1, 0]) q = HolonomicFunction(Dx**3 - x**2, x, 0, [3, 3, 3]) r = HolonomicFunction((x**8 - 37*x**7/27 - 10*x**6/27 - 164*x**5/9 - 184*x**4/9 + \ 160*x**3/27 + 404*x**2/9 + 8*x + 40/3) + (6*x**7 - 128*x**6/9 - 98*x**5/9 - 28*x**4/9 + \ 8*x**3/9 + 28*x**2 + 40*x/9 - 40)*Dx + (3*x**6 - 82*x**5/9 + 76*x**4/9 + 4*x**3/3 + \ 220*x**2/9 - 80*x/3)*Dx**2 + (-2*x**6 + 128*x**5/27 - 2*x**4/3 -80*x**2/9 + 200/9)*Dx**3 + \ (3*x**5 - 64*x**4/9 - 28*x**3/9 + 6*x**2 - 20*x/9 - 20/3)*Dx**4 + (-4*x**3 + 64*x**2/9 + \ 8*x/3)*Dx**5 + (x**4 - 64*x**3/27 - 4*x**2/3 + 20/9)*Dx**6, x, 0, [3, 3, 3, -3, -12, -24]) assert p * q == r p = HolonomicFunction(Dx - 1, x, 0, [2]) q = HolonomicFunction(Dx**2 + 1, x, 0, [0, 1]) r = HolonomicFunction(2 -2*Dx + Dx**2, x, 0, [0, 2]) assert p * q == r q = HolonomicFunction(x*Dx**2 + 1 + 2*Dx, x, 0,[0, 1]) r = HolonomicFunction((x - 1) + (-2*x + 2)*Dx + x*Dx**2, x, 0, [0, 2]) assert p * q == r p = HolonomicFunction(Dx**2 - 1, x, 0, [1, 3]) q = HolonomicFunction(Dx**3 + 1, x, 0, [1, 2, 1]) r = HolonomicFunction(6*Dx + 3*Dx**2 + 2*Dx**3 - 3*Dx**4 + Dx**6, x, 0, [1, 5, 14, 17, 17, 2]) assert p * q == r p = expr_to_holonomic(sin(x)) q = expr_to_holonomic(1/x) r = HolonomicFunction(x + 2*Dx + x*Dx**2, x, 1, [sin(1), -sin(1) + cos(1)]) assert p * q == r
def test_str(): # Without alias: k = QQ.alg_field_from_poly(Poly(x**2 + 7)) frp = k.primes_above(2)[0] assert str(frp) == '(2, 3*_x/2 + 1/2)' frp = k.primes_above(3)[0] assert str(frp) == '(3)' # With alias: k = QQ.alg_field_from_poly(Poly(x**2 + 7), alias='alpha') frp = k.primes_above(2)[0] assert str(frp) == '(2, 3*alpha/2 + 1/2)' frp = k.primes_above(3)[0] assert str(frp) == '(3)'
def test_from_sympy(): x = symbols('x') R, Dx = DifferentialOperators(QQ.old_poly_ring(x), 'Dx') p = from_sympy((sin(x) / x)**2) q = HolonomicFunction(8*x + (4*x**2 + 6)*Dx + 6*x*Dx**2 + x**2*Dx**3, x, 0, \ [1, 0, -2/3]) assert p == q p = from_sympy(1 / (1 + x**2)**2) q = HolonomicFunction(4 * x + (x**2 + 1) * Dx, x, 0, 1) assert p == q p = from_sympy(exp(x) * sin(x) + x * log(1 + x)) q = HolonomicFunction((2*x**3 + 10*x**2 + 20*x + 18) + (-2*x**4 - 10*x**3 - 20*x**2 \ - 18*x)*Dx + (2*x**5 + 6*x**4 + 7*x**3 + 8*x**2 + 10*x - 4)*Dx**2 + \ (-2*x**5 - 5*x**4 - 2*x**3 + 2*x**2 - x + 4)*Dx**3 + (x**5 + 2*x**4 - x**3 - \ 7*x**2/2 + x + 5/2)*Dx**4, x, 0, [0, 1, 4, -1]) assert p == q p = from_sympy(x * exp(x) + cos(x) + 1) q = HolonomicFunction((-x - 3)*Dx + (x + 2)*Dx**2 + (-x - 3)*Dx**3 + (x + 2)*Dx**4, x, \ 0, [2, 1, 1, 3]) assert p == q assert (x * exp(x) + cos(x) + 1).series(n=10) == p.series(n=10) p = from_sympy(log(1 + x)**2 + 1) q = HolonomicFunction( Dx + (3 * x + 3) * Dx**2 + (x**2 + 2 * x + 1) * Dx**3, x, 0, [1, 0, 2]) assert p == q p = from_sympy(erf(x)**2 + x) q = HolonomicFunction((8*x**4 - 2*x**2 + 2)*Dx**2 + (6*x**3 - x/2)*Dx**3 + \ (x**2+ 1/4)*Dx**4, x, 0, [0, 1, 8/pi, 0]) assert p == q p = from_sympy(cosh(x) * x) q = HolonomicFunction((-x**2 + 2) - 2 * x * Dx + x**2 * Dx**2, x, 0, [0, 1]) assert p == q p = from_sympy(besselj(2, x)) q = HolonomicFunction((x**2 - 4) + x * Dx + x**2 * Dx**2, x, 0, [0, 0]) assert p == q p = from_sympy(besselj(0, x) + exp(x)) q = HolonomicFunction((-x**2 - x/2 + 1/2) + (x**2 - x/2 - 3/2)*Dx + (-x**2 + x/2 + 1)*Dx**2 +\ (x**2 + x/2)*Dx**3, x, 0, [2, 1, 1/2]) assert p == q p = from_sympy(sin(x)**2 / x) q = HolonomicFunction(4 + 4 * x * Dx + 3 * Dx**2 + x * Dx**3, x, 0, [0, 1, 0]) assert p == q p = from_sympy(sin(x)**2 / x, x0=2) q = HolonomicFunction((4) + (4 * x) * Dx + (3) * Dx**2 + (x) * Dx**3, x, 2, [ sin(2)**2 / 2, sin(2) * cos(2) - sin(2)**2 / 4, -3 * sin(2)**2 / 4 + cos(2)**2 - sin(2) * cos(2) ]) assert p == q p = from_sympy(log(x) / 2 - Ci(2 * x) / 2 + Ci(2) / 2) q = HolonomicFunction(4*Dx + 4*x*Dx**2 + 3*Dx**3 + x*Dx**4, x, 0, \ [-log(2)/2 - EulerGamma/2 + Ci(2)/2, 0, 1, 0]) assert p == q p = p.to_sympy() q = log(x) / 2 - Ci(2 * x) / 2 + Ci(2) / 2 assert p == q
def test_to_Sequence_Initial_Coniditons(): x = symbols('x') R, Dx = DifferentialOperators(QQ.old_poly_ring(x), 'Dx') n = symbols('n', integer=True) _, Sn = RecurrenceOperators(QQ.old_poly_ring(n), 'Sn') p = HolonomicFunction(Dx - 1, x, 0, 1).to_sequence() q = HolonomicSequence(-1 + (n + 1)*Sn, 1) assert p == q p = HolonomicFunction(Dx**2 + 1, x, 0, [0, 1]).to_sequence() q = HolonomicSequence(1 + (n**2 + 3*n + 2)*Sn**2, [0, 1]) assert p == q p = HolonomicFunction(Dx**2 + 1 + x**3*Dx, x, 0, [2, 3]).to_sequence() q = HolonomicSequence(n + Sn**2 + (n**2 + 7*n + 12)*Sn**4, [2, 3, -1, -1/2]) assert p == q p = HolonomicFunction(x**3*Dx**5 + 1 + Dx, x).to_sequence() q = HolonomicSequence(1 + (n + 1)*Sn + (n**5 - 5*n**3 + 4*n)*Sn**2) assert p == q
def test_properties(): R = QQ.old_poly_ring(x, y) F = R.free_module(2) h = homomorphism(F, F, [[x, 0], [y, 0]]) assert h.kernel() == F.submodule([-y, x]) assert h.image() == F.submodule([x, 0], [y, 0]) assert not h.is_injective() assert not h.is_surjective() assert h.restrict_codomain(h.image()).is_surjective() assert h.restrict_domain(F.submodule([1, 0])).is_injective() assert h.quotient_domain( h.kernel()).restrict_codomain(h.image()).is_isomorphism() R2 = QQ.old_poly_ring(x, y, order=(("lex", x), ("ilex", y))) / [x**2 + 1] F = R2.free_module(2) h = homomorphism(F, F, [[x, 0], [y, y + 1]]) assert h.is_isomorphism()
def test_prde_no_cancel(): # b large DE = DifferentialExtension(extension={'D': [Poly(1, x)]}) assert prde_no_cancel_b_large(Poly(1, x), [Poly(x**2, x), Poly(1, x)], 2, DE) == \ ([Poly(x**2 - 2*x + 2, x), Poly(1, x)], Matrix([[1, 0, -1, 0], [0, 1, 0, -1]], x)) assert prde_no_cancel_b_large(Poly(1, x), [Poly(x**3, x), Poly(1, x)], 3, DE) == \ ([Poly(x**3 - 3*x**2 + 6*x - 6, x), Poly(1, x)], Matrix([[1, 0, -1, 0], [0, 1, 0, -1]], x)) assert prde_no_cancel_b_large(Poly(x, x), [Poly(x**2, x), Poly(1, x)], 1, DE) == \ ([Poly(x, x, domain='ZZ'), Poly(0, x, domain='ZZ')], Matrix([[1, -1, 0, 0], [1, 0, -1, 0], [0, 1, 0, -1]], x)) # b small # XXX: Is there a better example of a monomial with D.degree() > 2? DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(t**3 + 1, t)]}) # My original q was t**4 + t + 1, but this solution implies q == t**4 # (c1 = 4), with some of the ci for the original q equal to 0. G = [Poly(t**6, t), Poly(x*t**5, t), Poly(t**3, t), Poly(x*t**2, t), Poly(1 + x, t)] R = QQ.frac_field(x)[t] assert prde_no_cancel_b_small(Poly(x*t, t), G, 4, DE) == \ ([Poly(t**4/4 - x/12*t**3 + x**2/24*t**2 + (Rational(-11, 12) - x**3/24)*t + x/24, t), Poly(x/3*t**3 - x**2/6*t**2 + (Rational(-1, 3) + x**3/6)*t - x/6, t), Poly(t, t), Poly(0, t), Poly(0, t)], Matrix([[1, 0, -1, 0, 0, 0, 0, 0, 0, 0], [0, 1, Rational(-1, 4), 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, -1, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, -1, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, -1, 0, 0], [0, 0, 0, 1, 0, 0, 0, 0, -1, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0, -1]], ring=R)) # TODO: Add test for deg(b) <= 0 with b small DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(1 + t**2, t)]}) b = Poly(-1/x**2, t, field=True) # deg(b) == 0 q = [Poly(x**i*t**j, t, field=True) for i in range(2) for j in range(3)] h, A = prde_no_cancel_b_small(b, q, 3, DE) V = A.nullspace() R = QQ.frac_field(x)[t] assert len(V) == 1 assert V[0] == Matrix([Rational(-1, 2), 0, 0, 1, 0, 0]*3, ring=R) assert (Matrix([h])*V[0][6:, :])[0] == Poly(x**2/2, t, domain='QQ(x)') assert (Matrix([q])*V[0][:6, :])[0] == Poly(x - S.Half, t, domain='QQ(x)')
def test_expr_to_holonomic(): x = symbols('x') R, Dx = DifferentialOperators(QQ.old_poly_ring(x), 'Dx') p = expr_to_holonomic((sin(x)/x)**2) q = HolonomicFunction(8*x + (4*x**2 + 6)*Dx + 6*x*Dx**2 + x**2*Dx**3, x, 0, \ [1, 0, -2/3]) assert p == q p = expr_to_holonomic(1/(1+x**2)**2) q = HolonomicFunction(4*x + (x**2 + 1)*Dx, x, 0, 1) assert p == q p = expr_to_holonomic(exp(x)*sin(x)+x*log(1+x)) q = HolonomicFunction((2*x**3 + 10*x**2 + 20*x + 18) + (-2*x**4 - 10*x**3 - 20*x**2 \ - 18*x)*Dx + (2*x**5 + 6*x**4 + 7*x**3 + 8*x**2 + 10*x - 4)*Dx**2 + \ (-2*x**5 - 5*x**4 - 2*x**3 + 2*x**2 - x + 4)*Dx**3 + (x**5 + 2*x**4 - x**3 - \ 7*x**2/2 + x + 5/2)*Dx**4, x, 0, [0, 1, 4, -1]) assert p == q p = expr_to_holonomic(x*exp(x)+cos(x)+1) q = HolonomicFunction((-x - 3)*Dx + (x + 2)*Dx**2 + (-x - 3)*Dx**3 + (x + 2)*Dx**4, x, \ 0, [2, 1, 1, 3]) assert p == q assert (x*exp(x)+cos(x)+1).series(n=10) == p.series(n=10) p = expr_to_holonomic(log(1 + x)**2 + 1) q = HolonomicFunction(Dx + (3*x + 3)*Dx**2 + (x**2 + 2*x + 1)*Dx**3, x, 0, [1, 0, 2]) assert p == q p = expr_to_holonomic(erf(x)**2 + x) q = HolonomicFunction((8*x**4 - 2*x**2 + 2)*Dx**2 + (6*x**3 - x/2)*Dx**3 + \ (x**2+ 1/4)*Dx**4, x, 0, [0, 1, 8/pi, 0]) assert p == q p = expr_to_holonomic(cosh(x)*x) q = HolonomicFunction((-x**2 + 2) -2*x*Dx + x**2*Dx**2, x, 0, [0, 1]) assert p == q p = expr_to_holonomic(besselj(2, x)) q = HolonomicFunction((x**2 - 4) + x*Dx + x**2*Dx**2, x, 0, [0, 0]) assert p == q p = expr_to_holonomic(besselj(0, x) + exp(x)) q = HolonomicFunction((-x**2 - x/2 + 1/2) + (x**2 - x/2 - 3/2)*Dx + (-x**2 + x/2 + 1)*Dx**2 +\ (x**2 + x/2)*Dx**3, x, 0, [2, 1, 1/2]) assert p == q p = expr_to_holonomic(sin(x)**2/x) q = HolonomicFunction(4 + 4*x*Dx + 3*Dx**2 + x*Dx**3, x, 0, [0, 1, 0]) assert p == q p = expr_to_holonomic(sin(x)**2/x, x0=2) q = HolonomicFunction((4) + (4*x)*Dx + (3)*Dx**2 + (x)*Dx**3, x, 2, [sin(2)**2/2, sin(2)*cos(2) - sin(2)**2/4, -3*sin(2)**2/4 + cos(2)**2 - sin(2)*cos(2)]) assert p == q p = expr_to_holonomic(log(x)/2 - Ci(2*x)/2 + Ci(2)/2) q = HolonomicFunction(4*Dx + 4*x*Dx**2 + 3*Dx**3 + x*Dx**4, x, 0, \ [-log(2)/2 - EulerGamma/2 + Ci(2)/2, 0, 1, 0]) assert p == q p = p.to_expr() q = log(x)/2 - Ci(2*x)/2 + Ci(2)/2 assert p == q p = expr_to_holonomic(x**(S(1)/2), x0=1) q = HolonomicFunction(x*Dx - 1/2, x, 1, 1) assert p == q p = expr_to_holonomic(sqrt(1 + x**2)) q = HolonomicFunction((-x) + (x**2 + 1)*Dx, x, 0, 1) assert p == q
def test_SDM_lu(): A = SDM({0: {0: QQ(1), 1: QQ(2)}, 1: {0: QQ(3), 1: QQ(4)}}, (2, 2), QQ) L = SDM({0: {0: QQ(1)}, 1: {0: QQ(3), 1: QQ(1)}}, (2, 2), QQ) #U = SDM({0:{0:QQ(1), 1:QQ(2)}, 1:{0:QQ(3), 1:QQ(-2)}}, (2, 2), QQ) #swaps = [] # This doesn't quite work. U has some nonzero elements in the lower part. #assert A.lu() == (L, U, swaps) assert A.lu()[0] == L
def test_printing(): R = QQ.old_poly_ring(x) assert str(homomorphism(R.free_module(1), R.free_module(1), [0])) == \ 'Matrix([[0]]) : QQ[x]**1 -> QQ[x]**1' assert str(homomorphism(R.free_module(2), R.free_module(2), [0, 0])) == \ 'Matrix([ \n[0, 0], : QQ[x]**2 -> QQ[x]**2\n[0, 0]]) ' assert str(homomorphism(R.free_module(1), R.free_module(1) / [[x]], [0])) == \ 'Matrix([[0]]) : QQ[x]**1 -> QQ[x]**1/<[x]>' assert str(R.free_module(0).identity_hom()) == 'Matrix(0, 0, []) : QQ[x]**0 -> QQ[x]**0'
def test_RecurrenceOperator(): n = symbols('n', integer=True) R, Sn = RecurrenceOperators(QQ.old_poly_ring(n), 'Sn') assert Sn*n == (n + 1)*Sn assert Sn*n**2 == (n**2+1+2*n)*Sn assert Sn**2*n**2 == (n**2 + 4*n + 4)*Sn**2 p = (Sn**3*n**2 + Sn*n)**2 q = (n**2 + 3*n + 2)*Sn**2 + (2*n**3 + 19*n**2 + 57*n + 52)*Sn**4 + (n**4 + 18*n**3 + \ 117*n**2 + 324*n + 324)*Sn**6 assert p == q
def test_decomp_7(): # Try working through an AlgebraicField T = Poly(x**3 + x**2 - 2 * x + 8) K = QQ.alg_field_from_poly(T) p = 2 P = K.primes_above(p) ZK = K.maximal_order() assert len(P) == 3 assert all(Pi.e == Pi.f == 1 for Pi in P) assert prod(Pi**Pi.e for Pi in P) == p * ZK
def test_RecurrenceOperator(): n = symbols('n', integer=True) R, Sn = RecurrenceOperators(QQ.old_poly_ring(n), 'Sn') assert Sn * n == (n + 1) * Sn assert Sn * n**2 == (n**2 + 1 + 2 * n) * Sn assert Sn**2 * n**2 == (n**2 + 4 * n + 4) * Sn**2 p = (Sn**3 * n**2 + Sn * n)**2 q = (n**2 + 3*n + 2)*Sn**2 + (2*n**3 + 19*n**2 + 57*n + 52)*Sn**4 + (n**4 + 18*n**3 + \ 117*n**2 + 324*n + 324)*Sn**6 assert p == q
def test_creation(): F = QQ.old_poly_ring(x).free_module(3) G = QQ.old_poly_ring(x).free_module(2) SM = F.submodule([1, 1, 1]) Q = F / SM SQ = Q.submodule([1, 0, 0]) matrix = [[1, 0], [0, 1], [-1, -1]] h = homomorphism(F, G, matrix) h2 = homomorphism(Q, G, matrix) assert h.quotient_domain(SM) == h2 raises(ValueError, lambda: h.quotient_domain(F.submodule([1, 0, 0]))) assert h2.restrict_domain(SQ) == homomorphism(SQ, G, matrix) raises(ValueError, lambda: h.restrict_domain(G)) raises(ValueError, lambda: h.restrict_codomain(G.submodule([1, 0]))) raises(ValueError, lambda: h.quotient_codomain(F)) im = [[1, 0, 0], [0, 1, 0], [0, 0, 1]] for M in [F, SM, Q, SQ]: assert M.identity_hom() == homomorphism(M, M, im) assert SM.inclusion_hom() == homomorphism(SM, F, im) assert SQ.inclusion_hom() == homomorphism(SQ, Q, im) assert Q.quotient_hom() == homomorphism(F, Q, im) assert SQ.quotient_hom() == homomorphism(SQ.base, SQ, im) class conv(object): def convert(x, y=None): return x class dummy(object): container = conv() def submodule(*args): return None raises(TypeError, lambda: homomorphism(dummy(), G, matrix)) raises(TypeError, lambda: homomorphism(F, dummy(), matrix)) raises( ValueError, lambda: homomorphism(QQ.old_poly_ring(x, y).free_module(3), G, matrix), ) raises(ValueError, lambda: homomorphism(F, G, [0, 0]))
def test_from_sympy(): x = symbols('x') R, Dx = DifferentialOperators(QQ.old_poly_ring(x), 'Dx') p = from_sympy((sin(x)/x)**2) q = HolonomicFunction(24*x + (24*x**2 + 12)*Dx + (4*x**3 + 24*x)*Dx**2 + \ 10*x**2*Dx**3 + x**3*Dx**4, x, 1, [-cos(2)/2 + 1/2, -1 + cos(2) + sin(2), \ -4*sin(2) - cos(2) + 3, -12 + 14*sin(2)]) assert p == q p = from_sympy(1/(1+x**2)**2) q = HolonomicFunction(4*x + (x**2 + 1)*Dx, x, 0, 1) assert p == q
def test_from_sympy(): x = symbols('x') R, Dx = DifferentialOperators(QQ.old_poly_ring(x), 'Dx') p = from_sympy((sin(x) / x)**2) q = HolonomicFunction(24*x + (24*x**2 + 12)*Dx + (4*x**3 + 24*x)*Dx**2 + \ 10*x**2*Dx**3 + x**3*Dx**4, x, 1, [-cos(2)/2 + 1/2, -1 + cos(2) + sin(2), \ -4*sin(2) - cos(2) + 3, -12 + 14*sin(2)]) assert p == q p = from_sympy(1 / (1 + x**2)**2) q = HolonomicFunction(4 * x + (x**2 + 1) * Dx, x, 0, 1) assert p == q
def test_SDM_inv(): A = SDM({0: {0: QQ(1), 1: QQ(2)}, 1: {0: QQ(3), 1: QQ(4)}}, (2, 2), QQ) B = SDM({ 0: { 0: QQ(-2), 1: QQ(1) }, 1: { 0: QQ(3, 2), 1: QQ(-1, 2) } }, (2, 2), QQ) assert A.inv() == B
def test_creation(): F = QQ.old_poly_ring(x).free_module(3) G = QQ.old_poly_ring(x).free_module(2) SM = F.submodule([1, 1, 1]) Q = F / SM SQ = Q.submodule([1, 0, 0]) matrix = [[1, 0], [0, 1], [-1, -1]] h = homomorphism(F, G, matrix) h2 = homomorphism(Q, G, matrix) assert h.quotient_domain(SM) == h2 raises(ValueError, lambda: h.quotient_domain(F.submodule([1, 0, 0]))) assert h2.restrict_domain(SQ) == homomorphism(SQ, G, matrix) raises(ValueError, lambda: h.restrict_domain(G)) raises(ValueError, lambda: h.restrict_codomain(G.submodule([1, 0]))) raises(ValueError, lambda: h.quotient_codomain(F)) im = [[1, 0, 0], [0, 1, 0], [0, 0, 1]] for M in [F, SM, Q, SQ]: assert M.identity_hom() == homomorphism(M, M, im) assert SM.inclusion_hom() == homomorphism(SM, F, im) assert SQ.inclusion_hom() == homomorphism(SQ, Q, im) assert Q.quotient_hom() == homomorphism(F, Q, im) assert SQ.quotient_hom() == homomorphism(SQ.base, SQ, im) class conv(object): def convert(x, y=None): return x class dummy(object): container = conv() def submodule(*args): return None raises(TypeError, lambda: homomorphism(dummy(), G, matrix)) raises(TypeError, lambda: homomorphism(F, dummy(), matrix)) raises( ValueError, lambda: homomorphism(QQ.old_poly_ring(x, y).free_module(3), G, matrix)) raises(ValueError, lambda: homomorphism(F, G, [0, 0]))
def test_from_hyper(): x = symbols('x') R, Dx = DifferentialOperators(QQ.old_poly_ring(x), 'Dx') p = hyper([1, 1], [S(3)/2], x**2/4) q = HolonomicFunction((4*x) + (5*x**2 - 8)*Dx + (x**3 - 4*x)*Dx**2, x, 1, [2*sqrt(3)*pi/9, -4*sqrt(3)*pi/27 + 4/3]) r = from_hyper(p) assert r == q p = from_hyper(hyper([1], [S(3)/2], x**2/4)) q = HolonomicFunction(-x + (-x**2/2 + 2)*Dx + x*Dx**2, x) x0 = 1 y0 = '[sqrt(pi)*exp(1/4)*erf(1/2), -sqrt(pi)*exp(1/4)*erf(1/2)/2 + 1]' assert sstr(p.y0) == y0 assert q.annihilator == p.annihilator
def test_RecurrenceOperatorEqPoly(): n = symbols('n', integer=True) R, Sn = RecurrenceOperators(QQ.old_poly_ring(n), 'Sn') rr = RecurrenceOperator([n**2, 0, 0], R) rr2 = RecurrenceOperator([n**2, 1, n], R) assert not rr == rr2 # polynomial comparison issue, see https://github.com/sympy/sympy/pull/15799 # should work once that is solved # d = rr.listofpoly[0] # assert rr == d d2 = rr2.listofpoly[0] assert not rr2 == d2
def test_solve_triangualted(): f_1 = x**2 + y + z - 1 f_2 = x + y**2 + z - 1 f_3 = x + y + z**2 - 1 a, b = -sqrt(2) - 1, sqrt(2) - 1 assert solve_triangulated([f_1, f_2, f_3], x, y, z) == \ [(0, 0, 1), (0, 1, 0), (1, 0, 0)] dom = QQ.algebraic_field(sqrt(2)) assert solve_triangulated([f_1, f_2, f_3], x, y, z, domain=dom) == \ [(a, a, a), (0, 0, 1), (0, 1, 0), (b, b, b), (1, 0, 0)]
def test_DifferentialOperator(): x = symbols('x') R, Dx = DifferentialOperators(QQ.old_poly_ring(x), 'Dx') assert Dx == R.derivative_operator assert Dx == DifferentialOperator([R.base.zero, R.base.one], R) assert x * Dx + x**2 * Dx**2 == DifferentialOperator([0, x, x**2], R) assert (x**2 + 1) + Dx + x * \ Dx**5 == DifferentialOperator([x**2 + 1, 1, 0, 0, 0, x], R) assert (x * Dx + x**2 + 1 - Dx * (x**3 + x))**3 == (-48 * x**6) + \ (-57 * x**7) * Dx + (-15 * x**8) * Dx**2 + (-x**9) * Dx**3 p = (x * Dx**2 + (x**2 + 3) * Dx**5) * (Dx + x**2) q = (2 * x) + (4 * x**2) * Dx + (x**3) * Dx**2 + \ (20 * x**2 + x + 60) * Dx**3 + (10 * x**3 + 30 * x) * Dx**4 + \ (x**4 + 3 * x**2) * Dx**5 + (x**2 + 3) * Dx**6 assert p == q
def test_QuotientRingElement(): R = QQ.old_poly_ring(x)/[x**10] X = R.convert(x) assert X*(X + 1) == R.convert(x**2 + x) assert X*x == R.convert(x**2) assert x*X == R.convert(x**2) assert X + x == R.convert(2*x) assert x + X == 2*X assert X**2 == R.convert(x**2) assert 1/(1 - X) == R.convert(sum(x**i for i in range(10))) assert X**10 == R.zero assert X != x raises(NotReversible, lambda: 1/X)
def test_QuotientRing(): I = QQ.old_poly_ring(x).ideal(x**2 + 1) R = QQ.old_poly_ring(x)/I assert R == QQ.old_poly_ring(x)/[x**2 + 1] assert R == QQ.old_poly_ring(x)/QQ.old_poly_ring(x).ideal(x**2 + 1) assert R != QQ.old_poly_ring(x) assert R.convert(1)/x == -x + I assert -1 + I == x**2 + I assert R.convert(ZZ(1), ZZ) == 1 + I assert R.convert(R.convert(x), R) == R.convert(x) X = R.convert(x) Y = QQ.old_poly_ring(x).convert(x) assert -1 + I == X**2 + I assert -1 + I == Y**2 + I assert R.to_sympy(X) == x raises(ValueError, lambda: QQ.old_poly_ring(x)/QQ.old_poly_ring(x, y).ideal(x)) R = QQ.old_poly_ring(x, order="ilex") I = R.ideal(x) assert R.convert(1) + I == (R/I).convert(1)
def test_from_meijerg(): x = symbols('x') R, Dx = DifferentialOperators(QQ.old_poly_ring(x), 'Dx') p = from_meijerg(meijerg(([], [S(3)/2]), ([S(1)/2], [S(1)/2, 1]), x)) q = HolonomicFunction(x/2 - 1/4 + (-x**2 + x/4)*Dx + x**2*Dx**2 + x**3*Dx**3, x, 1, \ [1/sqrt(pi), 1/(2*sqrt(pi)), -1/(4*sqrt(pi))]) assert p == q p = from_meijerg(meijerg(([], []), ([0], []), x)) q = HolonomicFunction(1 + Dx, x, 0, [1]) assert p == q p = from_meijerg(meijerg(([1], []), ([S(1)/2], [0]), x)) q = HolonomicFunction((x + 1/2)*Dx + x*Dx**2, x, 1, [sqrt(pi)*erf(1), exp(-1)]) assert p == q p = from_meijerg(meijerg(([0], [1]), ([0], []), 2*x**2)) q = HolonomicFunction((3*x**2 - 1)*Dx + x**3*Dx**2, x, 1, [-exp(-S(1)/2) + 1, -exp(-S(1)/2)]) assert p == q
def test_from_meijerg(): x = symbols("x") R, Dx = DifferentialOperators(QQ.old_poly_ring(x), "Dx") p = from_meijerg(meijerg(([], [S(3) / 2]), ([S(1) / 2], [S(1) / 2, 1]), x)) q = HolonomicFunction( 2 * x - 1 + (-4 * x ** 2 + x) * Dx + 4 * x ** 2 * Dx ** 2 + 4 * x ** 3 * Dx ** 3, x, 1, [1 / sqrt(pi), 1 / (2 * sqrt(pi)), -1 / (4 * sqrt(pi))], ) assert p == q p = from_meijerg(meijerg(([], []), ([0], []), x)) q = HolonomicFunction(1 + Dx, x, 0, 1) assert p == q p = from_meijerg(meijerg(([1], []), ([S(1) / 2], [0]), x)) q = HolonomicFunction((2 * x + 1) * Dx + 2 * x * Dx ** 2, x, 1, [sqrt(pi) * erf(1), exp(-1)]) assert p == q p = from_meijerg(meijerg(([0], [1]), ([0], []), 2 * x ** 2)) q = HolonomicFunction((3 * x ** 2 - 1) * Dx + x ** 3 * Dx ** 2, x, 1, [-exp(-S(1) / 2) + 1, -exp(-S(1) / 2)]) assert p == q
def test_addition_initial_condition(): x = symbols("x") R, Dx = DifferentialOperators(QQ.old_poly_ring(x), "Dx") p = HolonomicFunction(Dx - 1, x, 0, 3) q = HolonomicFunction(Dx ** 2 + 1, x, 0, [1, 0]) r = HolonomicFunction(-1 + Dx - Dx ** 2 + Dx ** 3, x, 0, [4, 3, 2]) assert p + q == r p = HolonomicFunction(Dx - x + Dx ** 2, x, 0, [1, 2]) q = HolonomicFunction(Dx ** 2 + x, x, 0, [1, 0]) r = HolonomicFunction( (-4 * x ** 4 - x ** 3 - 4 * x ** 2 + 1) + (4 * x ** 3 + x ** 2 + 3 * x + 4) * Dx + (-6 * x + 7) * Dx ** 2 + (4 * x ** 2 - 7 * x + 1) * Dx ** 3 + (4 * x ** 2 + x + 2) * Dx ** 4, x, 0, [2, 2, -2, 2], ) assert p + q == r p = HolonomicFunction(Dx ** 2 + 4 * x * Dx + x ** 2, x, 0, [3, 4]) q = HolonomicFunction(Dx ** 2 + 1, x, 0, [1, 1]) r = HolonomicFunction( (x ** 6 + 2 * x ** 4 - 5 * x ** 2 - 6) + (4 * x ** 5 + 36 * x ** 3 - 32 * x) * Dx + (x ** 6 + 3 * x ** 4 + 5 * x ** 2 - 9) * Dx ** 2 + (4 * x ** 5 + 36 * x ** 3 - 32 * x) * Dx ** 3 + (x ** 4 + 10 * x ** 2 - 3) * Dx ** 4, x, 0, [4, 5, -1, -17], ) assert p + q == r q = HolonomicFunction(Dx ** 3 + x, x, 2, [3, 0, 1]) p = HolonomicFunction(Dx - 1, x, 2, [1]) r = HolonomicFunction( (-x ** 2 - x + 1) + (x ** 2 + x) * Dx + (-x - 2) * Dx ** 3 + (x + 1) * Dx ** 4, x, 2, [4, 1, 2, -5] ) assert p + q == r
def test_evalf_euler(): x = symbols('x') R, Dx = DifferentialOperators(QQ.old_poly_ring(x), 'Dx') # log(1+x) p = HolonomicFunction((1 + x)*Dx**2 + Dx, x, 0, [0, 1]) # path taken is a straight line from 0 to 1, on the real axis r = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1] s = '0.699525841805253' # approx. equal to log(2) i.e. 0.693147180559945 assert sstr(p.evalf(r, method='Euler')[-1]) == s # path taken is a traingle 0-->1+i-->2 r = [0.1 + 0.1*I] for i in range(9): r.append(r[-1]+0.1+0.1*I) for i in range(10): r.append(r[-1]+0.1-0.1*I) # close to the exact solution 1.09861228866811 # imaginary part also close to zero s = '1.07530466271334 - 0.0251200594793912*I' assert sstr(p.evalf(r, method='Euler')[-1]) == s # sin(x) p = HolonomicFunction(Dx**2 + 1, x, 0, [0, 1]) s = '0.905546532085401 - 6.93889390390723e-18*I' assert sstr(p.evalf(r, method='Euler')[-1]) == s # computing sin(pi/2) using this method # using a linear path from 0 to pi/2 r = [0.1] for i in range(14): r.append(r[-1] + 0.1) r.append(pi/2) s = '1.08016557252834' # close to 1.0 (exact solution) assert sstr(p.evalf(r, method='Euler')[-1]) == s # trying different path, a rectangle (0-->i-->pi/2 + i-->pi/2) # computing the same value sin(pi/2) using different path r = [0.1*I] for i in range(9): r.append(r[-1]+0.1*I) for i in range(15): r.append(r[-1]+0.1) r.append(pi/2+I) for i in range(10): r.append(r[-1]-0.1*I) # close to 1.0 s = '0.976882381836257 - 1.65557671738537e-16*I' assert sstr(p.evalf(r, method='Euler')[-1]) == s # cos(x) p = HolonomicFunction(Dx**2 + 1, x, 0, [1, 0]) # compute cos(pi) along 0-->pi r = [0.05] for i in range(61): r.append(r[-1]+0.05) r.append(pi) # close to -1 (exact answer) s = '-1.08140824719196' assert sstr(p.evalf(r, method='Euler')[-1]) == s # a rectangular path (0 -> i -> 2+i -> 2) r = [0.1*I] for i in range(9): r.append(r[-1]+0.1*I) for i in range(20): r.append(r[-1]+0.1) for i in range(10): r.append(r[-1]-0.1*I) p = HolonomicFunction(Dx**2 + 1, x, 0, [1,1]).evalf(r, method='Euler') s = '0.501421652861245 - 3.88578058618805e-16*I' assert sstr(p[-1]) == s
def test_evalf_rk4(): x = symbols('x') R, Dx = DifferentialOperators(QQ.old_poly_ring(x), 'Dx') # log(1+x) p = HolonomicFunction((1 + x)*Dx**2 + Dx, x, 0, [0, 1]) # path taken is a straight line from 0 to 1, on the real axis r = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1] s = '0.693146363174626' # approx. equal to log(2) i.e. 0.693147180559945 assert sstr(p.evalf(r)[-1]) == s # path taken is a traingle 0-->1+i-->2 r = [0.1 + 0.1*I] for i in range(9): r.append(r[-1]+0.1+0.1*I) for i in range(10): r.append(r[-1]+0.1-0.1*I) # close to the exact solution 1.09861228866811 # imaginary part also close to zero s = '1.09861574485151 + 1.36082967699958e-7*I' assert sstr(p.evalf(r)[-1]) == s # sin(x) p = HolonomicFunction(Dx**2 + 1, x, 0, [0, 1]) s = '0.90929463522785 + 1.52655665885959e-16*I' assert sstr(p.evalf(r)[-1]) == s # computing sin(pi/2) using this method # using a linear path from 0 to pi/2 r = [0.1] for i in range(14): r.append(r[-1] + 0.1) r.append(pi/2) s = '0.999999895088917' # close to 1.0 (exact solution) assert sstr(p.evalf(r)[-1]) == s # trying different path, a rectangle (0-->i-->pi/2 + i-->pi/2) # computing the same value sin(pi/2) using different path r = [0.1*I] for i in range(9): r.append(r[-1]+0.1*I) for i in range(15): r.append(r[-1]+0.1) r.append(pi/2+I) for i in range(10): r.append(r[-1]-0.1*I) # close to 1.0 s = '1.00000003415141 + 6.11940487991086e-16*I' assert sstr(p.evalf(r)[-1]) == s # cos(x) p = HolonomicFunction(Dx**2 + 1, x, 0, [1, 0]) # compute cos(pi) along 0-->pi r = [0.05] for i in range(61): r.append(r[-1]+0.05) r.append(pi) # close to -1 (exact answer) s = '-0.999999993238714' assert sstr(p.evalf(r)[-1]) == s # a rectangular path (0 -> i -> 2+i -> 2) r = [0.1*I] for i in range(9): r.append(r[-1]+0.1*I) for i in range(20): r.append(r[-1]+0.1) for i in range(10): r.append(r[-1]-0.1*I) p = HolonomicFunction(Dx**2 + 1, x, 0, [1,1]).evalf(r) s = '0.493152791638442 - 1.41553435639707e-15*I' assert sstr(p[-1]) == s