def prde_no_cancel_b_large(b, Q, n, DE): """ Parametric Poly Risch Differential Equation - No cancellation: deg(b) large enough. Given a derivation D on k[t], n in ZZ, and b, q1, ..., qm in k[t] with b != 0 and either D == d/dt or deg(b) > max(0, deg(D) - 1), returns h1, ..., hr in k[r] and a matrix A with coefficients in Const(k) such that if c1, ..., cm in Const(k) and q in k[t] satisfy deg(q) <= n and Dq + b*Q == Sum(ci*qi, (i, 1, m)), then q = Sum(dj*hj, (j, 1, r)), where d1, ..., dr in Const(k) and A*Matrix([[c1, ..., cm, d1, ..., dr]]).T == 0. """ db = b.degree(DE.t) m = len(Q) H = [Poly(0, DE.t)]*m for N in range(n, -1, -1): # [n, ..., 0] for i in range(m): si = Q[i].nth(N + db)/b.LC() sitn = Poly(si*DE.t**N, DE.t) H[i] = H[i] + sitn Q[i] = Q[i] - derivation(sitn, DE) - b*sitn if all(qi.is_zero for qi in Q): dc = -1 M = zeros(0, 2) else: dc = max([qi.degree(t) for qi in Q]) M = Matrix(dc + 1, m, lambda i, j: Q[j].nth(i)) A, u = constant_system(M, zeros(dc + 1, 1), DE) c = eye(m) A = A.row_join(zeros(A.rows, m)).col_join(c.row_join(-c)) return H, A
def RGS_generalized(m): """ Computes the m + 1 generalized unrestricted growth strings and returns them as rows in matrix. Examples ======== >>> from diofant.combinatorics.partitions import RGS_generalized >>> RGS_generalized(6) Matrix([ [ 1, 1, 1, 1, 1, 1, 1], [ 1, 2, 3, 4, 5, 6, 0], [ 2, 5, 10, 17, 26, 0, 0], [ 5, 15, 37, 77, 0, 0, 0], [ 15, 52, 151, 0, 0, 0, 0], [ 52, 203, 0, 0, 0, 0, 0], [203, 0, 0, 0, 0, 0, 0]]) """ d = zeros(m + 1) for i in range(0, m + 1): d[0, i] = 1 for i in range(1, m + 1): for j in range(m): if j <= m - i: d[i, j] = j * d[i - 1, j] + d[i - 1, j + 1] else: d[i, j] = 0 return d
def limited_integrate(fa, fd, G, DE): """ Solves the limited integration problem: f = Dv + Sum(ci*wi, (i, 1, n)) """ fa, fd = fa*Poly(1/fd.LC(), DE.t), fd.monic() A, B, h, N, g, V = limited_integrate_reduce(fa, fd, G, DE) V = [g] + V g = A.gcd(B) A, B, V = A.quo(g), B.quo(g), [via.cancel(vid*g, include=True) for via, vid in V] Q, M = prde_linear_constraints(A, B, V, DE) M, _ = constant_system(M, zeros(M.rows, 1), DE) l = M.nullspace() if M == Matrix() or len(l) > 1: # Continue with param_rischDE() raise NotImplementedError("param_rischDE() is required to solve this " "integral.") elif len(l) == 0: raise NonElementaryIntegralException elif len(l) == 1: # The c1 == 1. In this case, we can assume a normal Risch DE if l[0][0].is_zero: raise NonElementaryIntegralException else: l[0] *= 1/l[0][0] C = sum(Poly(i, DE.t)*q for (i, q) in zip(l[0], Q)) # Custom version of rischDE() that uses the already computed # denominator and degree bound from above. B, C, m, alpha, beta = spde(A, B, C, N, DE) y = solve_poly_rde(B, C, m, DE) return (alpha*y + beta, h), list(l[0][1:]) else: raise NotImplementedError
def eqs_to_matrix(eqs, ring): """Transform from equations to matrix form. """ m = zeros(len(eqs), len(ring.gens) + 1, cls=RawMatrix) for j, e_j in enumerate(eqs): for i, x_i in enumerate(ring.gens): m[j, i] = e_j.coeff(x_i) m[j, -1] = -e_j.coeff(1) return m
def prde_no_cancel_b_small(b, Q, n, DE): """ Parametric Poly Risch Differential Equation - No cancellation: deg(b) small enough. Given a derivation D on k[t], n in ZZ, and b, q1, ..., qm in k[t] with deg(b) < deg(D) - 1 and either D == d/dt or deg(D) >= 2, returns h1, ..., hr in k[t] and a matrix A with coefficients in Const(k) such that if c1, ..., cm in Const(k) and q in k[t] satisfy deg(q) <= n and Dq + b*q == Sum(ci*qi, (i, 1, m)) then q = Sum(dj*hj, (j, 1, r)) where d1, ..., dr in Const(k) and A*Matrix([[c1, ..., cm, d1, ..., dr]]).T == 0. """ m = len(Q) H = [Poly(0, DE.t)]*m for N in range(n, 0, -1): # [n, ..., 1] for i in range(m): si = Q[i].nth(N + DE.d.degree(DE.t) - 1)/(N*DE.d.LC()) sitn = Poly(si*DE.t**N, DE.t) H[i] = H[i] + sitn Q[i] = Q[i] - derivation(sitn, DE) - b*sitn if b.degree(DE.t) > 0: for i in range(m): si = Poly(Q[i].nth(b.degree(DE.t))/b.LC(), DE.t) H[i] = H[i] + si Q[i] = Q[i] - derivation(si, DE) - b*si if all(qi.is_zero for qi in Q): dc = -1 M = Matrix() else: dc = max([qi.degree(DE.t) for qi in Q]) M = Matrix(dc + 1, m, lambda i, j: Q[j].nth(i)) A, u = constant_system(M, zeros(dc + 1, 1), DE) c = eye(m) A = A.row_join(zeros(A.rows, m)).col_join(c.row_join(-c)) return H, A else: # TODO: implement this (requires recursive param_rischDE() call) raise NotImplementedError
def param_rischDE(fa, fd, G, DE): """ Solve a Parametric Risch Differential Equation: Dy + f*y == Sum(ci*Gi, (i, 1, m)). """ _, (fa, fd) = weak_normalizer(fa, fd, DE) a, (ba, bd), G, hn = prde_normal_denom(ga, gd, G, DE) A, B, G, hs = prde_special_denom(a, ba, bd, G, DE) g = gcd(A, B) A, B, G = A.quo(g), B.quo(g), [gia.cancel(gid*g, include=True) for gia, gid in G] Q, M = prde_linear_constraints(A, B, G, DE) M, _ = constant_system(M, zeros(M.rows, 1), DE) # Reduce number of constants at this point try: # Similar to rischDE(), we try oo, even though it might lead to # non-termination when there is no solution. At least for prde_spde, # it will always terminate no matter what n is. n = bound_degree(A, B, G, DE, parametric=True) except NotImplementedError: debug("param_rischDE: Proceeding with n = oo; may cause " "non-termination.") n = oo A, B, Q, R, n1 = prde_spde(A, B, Q, n, DE)
def test_sparse_zeros_sparse_eye(): assert SparseMatrix.eye(3) == eye(3, cls=SparseMatrix) assert len(SparseMatrix.eye(3)._smat) == 3 assert SparseMatrix.zeros(3) == zeros(3, cls=SparseMatrix) assert len(SparseMatrix.zeros(3)._smat) == 0
def test_eq(): A = SparseMatrix(((1, 2), (3, 4))) assert A != 1 assert A != zeros(2, 1)