def dup_mul(f, g, K): """ Multiply dense polynomials in ``K[x]``. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x = ring("x", ZZ) >>> R.dup_mul(x - 2, x + 2) x**2 - 4 """ if f == g: return dup_sqr(f, K) if not (f and g): return [] df = dup_degree(f) dg = dup_degree(g) h = [] for i in xrange(0, df + dg + 1): coeff = K.zero for j in xrange(max(0, i - dg), min(df, i) + 1): coeff += f[j]*g[i - j] h.append(coeff) return dup_strip(h)
def LU(matlist, K, reverse=0): """ It computes the LU decomposition of a matrix and returns L and U matrices. Examples ======== >>> from sympy.matrices.densesolve import LU >>> from sympy import QQ >>> a = [ ... [QQ(1), QQ(2), QQ(3)], ... [QQ(2), QQ(-4), QQ(6)], ... [QQ(3), QQ(-9), QQ(-3)]] >>> LU(a, QQ) ([[1, 0, 0], [2, 1, 0], [3, 15/8, 1]], [[1, 2, 3], [0, -8, 0], [0, 0, -12]]) See Also ======== upper_triangle lower_triangle """ nrow = len(matlist) new_matlist1, new_matlist2 = eye(nrow, K), copy.deepcopy(matlist) for i in xrange(nrow): for j in xrange(i + 1, nrow): if new_matlist2[j][i] != 0: new_matlist1[j][i] = new_matlist2[j][i] / new_matlist2[i][i] rowadd(new_matlist2, j, i, -new_matlist2[j][i] / new_matlist2[i][i], K) return new_matlist1, new_matlist2
def _eval_expand_func(self, **hints): from sympy import exp, I, floor, Add, Poly, Dummy, exp_polar, unpolarify z, s, a = self.args if z == 1: return zeta(s, a) if s.is_Integer and s <= 0: t = Dummy('t') p = Poly((t + a)**(-s), t) start = 1/(1 - t) res = S(0) for c in reversed(p.all_coeffs()): res += c*start start = t*start.diff(t) return res.subs(t, z) if a.is_Rational: # See section 18 of # Kelly B. Roach. Hypergeometric Function Representations. # In: Proceedings of the 1997 International Symposium on Symbolic and # Algebraic Computation, pages 205-211, New York, 1997. ACM. # TODO should something be polarified here? add = S(0) mul = S(1) # First reduce a to the interaval (0, 1] if a > 1: n = floor(a) if n == a: n -= 1 a -= n mul = z**(-n) add = Add(*[-z**(k - n)/(a + k)**s for k in xrange(n)]) elif a <= 0: n = floor(-a) + 1 a += n mul = z**n add = Add(*[z**(n - 1 - k)/(a - k - 1)**s for k in xrange(n)]) m, n = S([a.p, a.q]) zet = exp_polar(2*pi*I/n) root = z**(1/n) return add + mul*n**(s - 1)*Add( *[polylog(s, zet**k*root)._eval_expand_func(**hints) / (unpolarify(zet)**k*root)**m for k in xrange(n)]) # TODO use minpoly instead of ad-hoc methods when issue 2789 is fixed if z.func is exp and (z.args[0]/(pi*I)).is_Rational or z in [-1, I, -I]: # TODO reference? if z == -1: p, q = S([1, 2]) elif z == I: p, q = S([1, 4]) elif z == -I: p, q = S([-1, 4]) else: arg = z.args[0]/(2*pi*I) p, q = S([arg.p, arg.q]) return Add(*[exp(2*pi*I*k*p/q)/q**s*zeta(s, (k + a)/q) for k in xrange(q)]) return lerchphi(z, s, a)
def interpolating_poly(n, x, X='x', Y='y'): """Construct Lagrange interpolating polynomial for ``n`` data points. """ if isinstance(X, str): X = symbols("%s:%s" % (X, n)) if isinstance(Y, str): Y = symbols("%s:%s" % (Y, n)) coeffs = [] for i in xrange(0, n): numer = [] denom = [] for j in xrange(0, n): if i == j: continue numer.append(x - X[j]) denom.append(X[i] - X[j]) numer = Mul(*numer) denom = Mul(*denom) coeffs.append(numer/denom) return Add(*[ coeff*y for coeff, y in zip(coeffs, Y) ])
def decrement_part(self, part): """Decrements part (a subrange of pstack), if possible, returning True iff the part was successfully decremented. If you think of the v values in the part as a multi-digit integer (least significant digit on the right) this is basically decrementing that integer, but with the extra constraint that the leftmost digit cannot be decremented to 0. Parameters ========== part The part, represented as a list of PartComponent objects, which is to be decremented. """ plen = len(part) for j in xrange(plen - 1, -1, -1): if (j == 0 and part[j].v > 1) or (j > 0 and part[j].v > 0): # found val to decrement part[j].v -= 1 # Reset trailing parts back to maximum for k in xrange(j + 1, plen): part[k].v = part[k].u return True return False
def _initialize_enumeration(self, multiplicities): """Allocates and initializes the partition stack. This is called from the enumeration/counting routines, so there is no need to call it separately.""" num_components = len(multiplicities) # cardinality is the total number of elements, whether or not distinct cardinality = sum(multiplicities) # pstack is the partition stack, which is segmented by # f into parts. self.pstack = [PartComponent() for i in xrange(num_components * cardinality + 1)] self.f = [0] * (cardinality + 1) # Initial state - entire multiset in one part. for j in xrange(num_components): ps = self.pstack[j] ps.c = j ps.u = multiplicities[j] ps.v = multiplicities[j] self.f[0] = 0 self.f[1] = num_components self.lpart = 0
def dup_from_dict(f, K): """ Create a ``K[x]`` polynomial from a ``dict``. Examples ======== >>> from sympy.polys.domains import ZZ >>> from sympy.polys.densebasic import dup_from_dict >>> dup_from_dict({(0,): ZZ(7), (2,): ZZ(5), (4,): ZZ(1)}, ZZ) [1, 0, 5, 0, 7] >>> dup_from_dict({}, ZZ) [] """ if not f: return [] n, h = max(f.keys()), [] if type(n) is int: for k in xrange(n, -1, -1): h.append(f.get(k, K.zero)) else: (n,) = n for k in xrange(n, -1, -1): h.append(f.get((k,), K.zero)) return dup_strip(h)
def _a(n, j, prec): """Compute the inner sum in the HRR formula.""" if j == 1: return fone s = fzero pi = pi_fixed(prec) for h in xrange(1, j): if igcd(h, j) != 1: continue # & with mask to compute fractional part of fixed-point number one = 1 << prec onemask = one - 1 half = one >> 1 g = 0 if j >= 3: for k in xrange(1, j): t = h*k*one//j if t > 0: frac = t & onemask else: frac = -((-t) & onemask) g += k*(frac - half) g = ((g - 2*h*n*one)*pi//j) >> prec s = mpf_add(s, mpf_cos(from_man_exp(g, -prec), prec), prec) return s
def RGS_generalized(m): """ Computes the m + 1 generalized unrestricted growth strings and returns them as rows in matrix. Examples ======== >>> from sympy.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 xrange(0, m + 1): d[0, i] = 1 for i in xrange(1, m + 1): for j in xrange(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 dmp_fateman_poly_F_1(n, K): """Fateman's GCD benchmark: trivial GCD """ u = [K(1), K(0)] for i in xrange(0, n): u = [dmp_one(i, K), u] v = [K(1), K(0), K(0)] for i in xrange(0, n): v = [dmp_one(i, K), dmp_zero(i), v] m = n - 1 U = dmp_add_term(u, dmp_ground(K(1), m), 0, n, K) V = dmp_add_term(u, dmp_ground(K(2), m), 0, n, K) f = [[-K(3), K(0)], [], [K(1), K(0), -K(1)]] W = dmp_add_term(v, dmp_ground(K(1), m), 0, n, K) Y = dmp_raise(f, m, 1, K) F = dmp_mul(U, V, n, K) G = dmp_mul(W, Y, n, K) H = dmp_one(n, K) return F, G, H
def _match_common_args(Func, funcs): if order != 'none': funcs = list(ordered(funcs)) else: funcs = sorted(funcs, key=lambda x: len(x.args)) func_args = [set(e.args) for e in funcs] for i in xrange(len(func_args)): for j in xrange(i + 1, len(func_args)): com_args = func_args[i].intersection(func_args[j]) if len(com_args) > 1: com_func = Func(*com_args) # for all sets, replace the common symbols by the function # over them, to allow recursive matches diff_i = func_args[i].difference(com_args) func_args[i] = diff_i | set([com_func]) if diff_i: opt_subs[funcs[i]] = Func(Func(*diff_i), com_func, evaluate=False) diff_j = func_args[j].difference(com_args) func_args[j] = diff_j | set([com_func]) opt_subs[funcs[j]] = Func(Func(*diff_j), com_func, evaluate=False) for k in xrange(j + 1, len(func_args)): if not com_args.difference(func_args[k]): diff_k = func_args[k].difference(com_args) func_args[k] = diff_k | set([com_func]) opt_subs[funcs[k]] = Func(Func(*diff_k), com_func, evaluate=False)
def _dup_right_decompose(f, s, K): """Helper function for :func:`_dup_decompose`.""" n = len(f) - 1 lc = dup_LC(f, K) f = dup_to_raw_dict(f) g = { s: K.one } r = n // s for i in xrange(1, s): coeff = K.zero for j in xrange(0, i): if not n + j - i in f: continue if not s - j in g: continue fc, gc = f[n + j - i], g[s - j] coeff += (i - r*j)*fc*gc g[s - i] = K.quo(coeff, i*r*lc) return dup_from_raw_dict(g, K)
def eval_levicivita(*args): """Evaluate Levi-Civita symbol.""" from sympy import factorial n = len(args) return prod( prod(args[j] - args[i] for j in xrange(i + 1, n)) / factorial(i) for i in xrange(n))
def _eval_expand_func(self, **hints): n = self.args[0] m = self.args[1] if len(self.args) == 2 else 1 if m == S.One: if n.is_Add: off = n.args[0] nnew = n - off if off.is_Integer and off.is_positive: result = [S.One/(nnew + i) for i in xrange(off, 0, -1)] + [harmonic(nnew)] return Add(*result) elif off.is_Integer and off.is_negative: result = [-S.One/(nnew + i) for i in xrange(0, off, -1)] + [harmonic(nnew)] return Add(*result) if n.is_Rational: # Expansions for harmonic numbers at general rational arguments (u + p/q) # Split n as u + p/q with p < q p, q = n.as_numer_denom() u = p // q p = p - u * q if u.is_nonnegative and p.is_positive and q.is_positive and p < q: k = Dummy("k") t1 = q * C.Sum(1 / (q * k + p), (k, 0, u)) t2 = 2 * C.Sum(cos((2 * pi * p * k) / S(q)) * log(sin((pi * k) / S(q))), (k, 1, floor((q - 1) / S(2)))) t3 = (pi / 2) * cot((pi * p) / q) + log(2 * q) return t1 + t2 - t3 return self
def _eval_expand_func(self, **hints): n, z = self.args if n.is_Integer and n.is_nonnegative: if z.is_Add: coeff = z.args[0] if coeff.is_Integer: e = -(n + 1) if coeff > 0: tail = Add(*[C.Pow(z - i, e) for i in xrange(1, int(coeff) + 1)]) else: tail = -Add(*[C.Pow(z + i, e) for i in xrange(0, int(-coeff))]) return polygamma(n, z - coeff) + (-1) ** n * C.factorial(n) * tail elif z.is_Mul: coeff, z = z.as_two_terms() if coeff.is_Integer and coeff.is_positive: tail = [polygamma(n, z + C.Rational(i, coeff)) for i in xrange(0, int(coeff))] if n == 0: return Add(*tail) / coeff + log(coeff) else: return Add(*tail) / coeff ** (n + 1) z *= coeff return polygamma(n, z)
def roots_cyclotomic(f, factor=False): """Compute roots of cyclotomic polynomials. """ L, U = _inv_totient_estimate(f.degree()) for n in xrange(L, U + 1): g = cyclotomic_poly(n, f.gen, polys=True) if f == g: break else: # pragma: no cover raise RuntimeError("failed to find index of a cyclotomic polynomial") roots = [] if not factor: # get the indices in the right order so the computed # roots will be sorted h = n//2 ks = [i for i in xrange(1, n + 1) if igcd(i, n) == 1] ks.sort(key=lambda x: (x, -1) if x <= h else (abs(x - n), 1)) d = 2*I*pi/n for k in reversed(ks): roots.append(exp(k*d).expand(complex=True)) else: g = Poly(f, extension=root(-1, n)) for h, _ in ordered(g.factor_list()[1]): roots.append(-h.TC()) return roots
def roots_cyclotomic(f, factor=False): """Compute roots of cyclotomic polynomials. """ L, U = _inv_totient_estimate(f.degree()) for n in xrange(L, U + 1): g = cyclotomic_poly(n, f.gen, polys=True) if f == g: break else: # pragma: no cover raise RuntimeError("failed to find index of a cyclotomic polynomial") roots = [] if not factor: for k in xrange(1, n + 1): if igcd(k, n) == 1: roots.append(exp(2*k*S.Pi*I/n).expand(complex=True)) else: g = Poly(f, extension=(-1)**Rational(1, n)) for h, _ in g.factor_list()[1]: roots.append(-h.TC()) return sorted(roots, key=default_sort_key)
def eval(cls, x, k): x = sympify(x) k = sympify(k) if x is S.NaN: return S.NaN elif k.is_Integer: if k is S.NaN: return S.NaN elif k is S.Zero: return S.One else: if k.is_positive: if x is S.Infinity: return S.Infinity elif x is S.NegativeInfinity: if k.is_odd: return S.NegativeInfinity else: return S.Infinity else: return reduce(lambda r, i: r*(x - i), xrange(0, int(k)), 1) else: if x is S.Infinity: return S.Infinity elif x is S.NegativeInfinity: return S.Infinity else: return 1/reduce(lambda r, i: r*(x + i), xrange(1, abs(int(k)) + 1), 1)
def _identity_matrix(n, domain): M = [[domain.zero]*n for _ in xrange(n)] for i in xrange(n): M[i][i] = domain.one return M
def mdft(n): r""" Returns an expression of a discrete Fourier transform as a matrix multiplication. It is an n X n matrix. References ========== .. [1] https://en.wikipedia.org/wiki/DFT_matrix Examples ======== >>> from sympy.physics.matrices import mdft >>> mdft(3) Matrix([ [sqrt(3)/3, sqrt(3)/3, sqrt(3)/3], [sqrt(3)/3, sqrt(3)*exp(-2*I*pi/3)/3, sqrt(3)*exp(-4*I*pi/3)/3], [sqrt(3)/3, sqrt(3)*exp(-4*I*pi/3)/3, sqrt(3)*exp(-8*I*pi/3)/3]]) """ mat = [[None for x in xrange(n)] for y in xrange(n)] base = exp(-2*pi*I/n) mat[0] = [1]*n for i in range(n): mat[i][0] = 1 for i in xrange(1, n): for j in xrange(i, n): mat[i][j] = mat[j][i] = base**(i*j) return (1/sqrt(n))*Matrix(mat)
def __init__(self, *args): if len(args) == 2: self.colors = list(args) self.intervals = [0.0, 1.0] elif len(args) > 0: assert len(args) % 2 == 0 self.colors = [args[i] for i in xrange(1, len(args), 2)] self.intervals = [args[i] for i in xrange(0, len(args), 2)] assert len(self.colors) == len(self.intervals)
def ratint_ratpart(f, g, x): """ Horowitz-Ostrogradsky algorithm. Given a field K and polynomials f and g in K[x], such that f and g are coprime and deg(f) < deg(g), returns fractions A and B in K(x), such that f/g = A' + B and B has square-free denominator. Examples ======== >>> from sympy.integrals.rationaltools import ratint_ratpart >>> from sympy.abc import x, y >>> from sympy import Poly >>> ratint_ratpart(Poly(1, x, domain='ZZ'), ... Poly(x + 1, x, domain='ZZ'), x) (0, 1/(x + 1)) >>> ratint_ratpart(Poly(1, x, domain='EX'), ... Poly(x**2 + y**2, x, domain='EX'), x) (0, 1/(x**2 + y**2)) >>> ratint_ratpart(Poly(36, x, domain='ZZ'), ... Poly(x**5 - 2*x**4 - 2*x**3 + 4*x**2 + x - 2, x, domain='ZZ'), x) ((12*x + 6)/(x**2 - 1), 12/(x**2 - x - 2)) See Also ======== ratint, ratint_logpart """ f = Poly(f, x) g = Poly(g, x) u, v, _ = g.cofactors(g.diff()) n = u.degree() m = v.degree() A_coeffs = [ Dummy('a' + str(n - i)) for i in xrange(0, n) ] B_coeffs = [ Dummy('b' + str(m - i)) for i in xrange(0, m) ] C_coeffs = A_coeffs + B_coeffs A = Poly(A_coeffs, x, domain=ZZ[C_coeffs]) B = Poly(B_coeffs, x, domain=ZZ[C_coeffs]) H = f - A.diff()*v + A*(u.diff()*v).quo(u) - B*u result = solve(H.coeffs(), C_coeffs) A = A.as_expr().subs(result) B = B.as_expr().subs(result) rat_part = cancel(A/u.as_expr(), x) log_part = cancel(B/v.as_expr(), x) return rat_part, log_part
def multinomial_coefficients0(m, n, _tuple=tuple, _zip=zip): """Return a dictionary containing pairs ``{(k1,k2,..,km) : C_kn}`` where ``C_kn`` are multinomial coefficients such that ``n=k1+k2+..+km``. For example: >>> from sympy import multinomial_coefficients >>> multinomial_coefficients(2, 5) # indirect doctest {(0, 5): 1, (1, 4): 5, (2, 3): 10, (3, 2): 10, (4, 1): 5, (5, 0): 1} The algorithm is based on the following result: Consider a polynomial and its ``n``-th exponent:: P(x) = sum_{i=0}^m p_i x^i P(x)^n = sum_{k=0}^{m n} a(n,k) x^k The coefficients ``a(n,k)`` can be computed using the J.C.P. Miller Pure Recurrence [see D.E.Knuth, Seminumerical Algorithms, The art of Computer Programming v.2, Addison Wesley, Reading, 1981;]:: a(n,k) = 1/(k p_0) sum_{i=1}^m p_i ((n+1)i-k) a(n,k-i), where ``a(n,0) = p_0^n``. """ if not m: if n: return {} return {(): 1} if m == 2: return binomial_coefficients(n) symbols = [(0,)*i + (1,) + (0,)*(m - i - 1) for i in range(m)] s0 = symbols[0] p0 = [_tuple(aa - bb for aa, bb in _zip(s, s0)) for s in symbols] r = {_tuple(aa*n for aa in s0): 1} l = [0] * (n*(m - 1) + 1) l[0] = r.items() for k in xrange(1, n*(m - 1) + 1): d = defaultdict(int) for i in xrange(1, min(m, k + 1)): nn = (n + 1)*i - k if not nn: continue t = p0[i] for t2, c2 in l[k - i]: tt = _tuple([aa + bb for aa, bb in _zip(t2, t)]) d[tt] += nn*c2 if not d[tt]: del d[tt] r1 = [(t, c//k) for (t, c) in d.items()] l[k] = r1 r.update(r1) return r
def __init__(self, *args): if len(args) == 2: self.colors = list(args) self.intervals = [0.0, 1.0] elif len(args) > 0: if len(args) % 2 != 0: raise ValueError("len(args) should be even") self.colors = [args[i] for i in xrange(1, len(args), 2)] self.intervals = [args[i] for i in xrange(0, len(args), 2)] assert len(self.colors) == len(self.intervals)
def dup_mul(f, g, K): """ Multiply dense polynomials in ``K[x]``. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x = ring("x", ZZ) >>> R.dup_mul(x - 2, x + 2) x**2 - 4 """ if f == g: return dup_sqr(f, K) if not (f and g): return [] df = dup_degree(f) dg = dup_degree(g) n = max(df, dg) + 1 if n < 100: h = [] for i in xrange(0, df + dg + 1): coeff = K.zero for j in xrange(max(0, i - dg), min(df, i) + 1): coeff += f[j]*g[i - j] h.append(coeff) return dup_strip(h) else: # Use Karatsuba's algorithm (divide and conquer), see e.g.: # Joris van der Hoeven, Relax But Don't Be Too Lazy, # J. Symbolic Computation, 11 (2002), section 3.1.1. n2 = n//2 fl, gl = dup_slice(f, 0, n2, K), dup_slice(g, 0, n2, K) fh = dup_rshift(dup_slice(f, n2, n, K), n2, K) gh = dup_rshift(dup_slice(g, n2, n, K), n2, K) lo, hi = dup_mul(fl, gl, K), dup_mul(fh, gh, K) mid = dup_mul(dup_add(fl, fh, K), dup_add(gl, gh, K), K) mid = dup_sub(mid, dup_add(lo, hi, K), K) return dup_add(dup_add(lo, dup_lshift(mid, n2, K), K), dup_lshift(hi, 2*n2, K), K)
def is_groebner(G, ring): """ Check if G is a Groebner basis. """ for i in xrange(len(G)): for j in xrange(i + 1, len(G)): s = spoly(G[i], G[j]) s = s.rem(G) if s: return False return True
def _base_ordering(base, degree): r""" Order `\{0, 1, ..., n-1\}` so that base points come first and in order. Parameters ========== ``base`` - the base ``degree`` - the degree of the associated permutation group Returns ======= A list ``base_ordering`` such that ``base_ordering[point]`` is the number of ``point`` in the ordering. Examples ======== >>> from sympy.combinatorics.named_groups import SymmetricGroup >>> from sympy.combinatorics.util import _base_ordering >>> S = SymmetricGroup(4) >>> S.schreier_sims() >>> _base_ordering(S.base, S.degree) [0, 1, 2, 3] Notes ===== This is used in backtrack searches, when we define a relation `<<` on the underlying set for a permutation group of degree `n`, `\{0, 1, ..., n-1\}`, so that if `(b_1, b_2, ..., b_k)` is a base we have `b_i << b_j` whenever `i<j` and `b_i << a` for all `i\in\{1,2, ..., k\}` and `a` is not in the base. The idea is developed and applied to backtracking algorithms in [1], pp.108-132. The points that are not in the base are taken in increasing order. References ========== [1] Holt, D., Eick, B., O'Brien, E. "Handbook of computational group theory" """ base_len = len(base) ordering = [0]*degree for i in xrange(base_len): ordering[base[i]] = i current = base_len for i in xrange(degree): if i not in base: ordering[i] = current current += 1 return ordering
def DirectProduct(*groups): """ Returns the direct product of several groups as a permutation group. This is implemented much like the __mul__ procedure for taking the direct product of two permutation groups, but the idea of shifting the generators is realized in the case of an arbitrary number of groups. A call to DirectProduct(G1, G2, ..., Gn) is generally expected to be faster than a call to G1*G2*...*Gn (and thus the need for this algorithm). Examples ======== >>> from sympy.combinatorics.group_constructs import DirectProduct >>> from sympy.combinatorics.named_groups import CyclicGroup >>> C = CyclicGroup(4) >>> G = DirectProduct(C,C,C) >>> G.order() 64 See Also ======== __mul__ """ degrees = [] gens_count = [] total_degree = 0 total_gens = 0 for group in groups: current_deg = group.degree current_num_gens = len(group.generators) degrees.append(current_deg) total_degree += current_deg gens_count.append(current_num_gens) total_gens += current_num_gens array_gens = [] for i in range(total_gens): array_gens.append(list(range(total_degree))) current_gen = 0 current_deg = 0 for i in xrange(len(gens_count)): for j in xrange(current_gen, current_gen + gens_count[i]): gen = ((groups[i].generators)[j - current_gen]).array_form array_gens[j][current_deg:current_deg + degrees[i]] = \ [ x + current_deg for x in gen] current_gen += gens_count[i] current_deg += degrees[i] perm_gens = list(uniq([_af_new(list(a)) for a in array_gens])) return PermutationGroup(perm_gens, dups=False)
def _update(s, _lambda, P): """ Update ``P`` such that for the updated `P'` `P' v = e_{s}`. """ k = min([j for j in xrange(s, len(_lambda)) if _lambda[j] != 0]) for r in xrange(len(_lambda)): if r != k: P[r] = [P[r][j] - (P[k][j] * _lambda[r]) / _lambda[k] for j in xrange(len(P[r]))] P[k] = [P[k][j] / _lambda[k] for j in xrange(len(P[k]))] P[k], P[s] = P[s], P[k] return P
def dmp_zz_wang_hensel_lifting(f, H, LC, A, p, u, K): """Wang/EEZ: Parallel Hensel lifting algorithm. """ S, n, v = [f], len(A), u - 1 H = list(H) for i, a in enumerate(reversed(A[1:])): s = dmp_eval_in(S[0], a, n - i, u - i, K) S.insert(0, dmp_ground_trunc(s, p, v - i, K)) d = max(dmp_degree_list(f, u)[1:]) for j, s, a in zip(xrange(2, n + 2), S, A): G, w = list(H), j - 1 I, J = A[: j - 2], A[j - 1 :] for i, (h, lc) in enumerate(zip(H, LC)): lc = dmp_ground_trunc(dmp_eval_tail(lc, J, v, K), p, w - 1, K) H[i] = [lc] + dmp_raise(h[1:], 1, w - 1, K) m = dmp_nest([K.one, -a], w, K) M = dmp_one(w, K) c = dmp_sub(s, dmp_expand(H, w, K), w, K) dj = dmp_degree_in(s, w, w) for k in K.map(xrange(0, dj)): if dmp_zero_p(c, w): break M = dmp_mul(M, m, w, K) C = dmp_diff_eval_in(c, k + 1, a, w, w, K) if not dmp_zero_p(C, w - 1): C = dmp_quo_ground(C, K.factorial(k + 1), w - 1, K) T = dmp_zz_diophantine(G, C, I, d, p, w - 1, K) for i, (h, t) in enumerate(zip(H, T)): h = dmp_add_mul(h, dmp_raise(t, 1, w - 1, K), M, w, K) H[i] = dmp_ground_trunc(h, p, w, K) h = dmp_sub(s, dmp_expand(H, w, K), w, K) c = dmp_ground_trunc(h, p, w, K) if dmp_expand(H, u, K) != f: raise ExtraneousFactors # pragma: no cover else: return H
def quadratic_residues(p): """ Returns the list of quadratic residues. Examples ======== >>> from sympy.ntheory.residue_ntheory import quadratic_residues >>> quadratic_residues(7) [0, 1, 2, 4] """ r = set() for i in xrange(p // 2 + 1): r.add(pow(i, 2, p)) return sorted(list(r))
def dup_jacobi(n, a, b, K): """Low-level implementation of Jacobi polynomials. """ seq = [[K.one], [(a + b + K(2))/K(2), (a - b)/K(2)]] for i in xrange(2, n + 1): den = K(i)*(a + b + i)*(a + b + K(2)*i - K(2)) f0 = (a + b + K(2)*i - K.one) * (a*a - b*b) / (K(2)*den) f1 = (a + b + K(2)*i - K.one) * (a + b + K(2)*i - K(2)) * (a + b + K(2)*i) / (K(2)*den) f2 = (a + i - K.one)*(b + i - K.one)*(a + b + K(2)*i) / den p0 = dup_mul_ground(seq[-1], f0, K) p1 = dup_mul_ground(dup_lshift(seq[-1], 1, K), f1, K) p2 = dup_mul_ground(seq[-2], f2, K) seq.append(dup_sub(dup_add(p0, p1, K), p2, K)) return seq[n]
def is_in(expr): if expr == self: return True elif not isinstance(expr, Basic): return False elif isinstance(expr, cls): _c, _nc = _ncsplit(expr) if (c & _c) == c: if not nc: return True elif len(nc) <= len(_nc): for i in xrange(len(_nc) - len(nc)): if _nc[i:i + len(nc)] == nc: return True return False
def _reduced_density(self, matrix, qubit, **options): """Compute the reduced density matrix by tracing out one qubit. The qubit argument should be of type python int, since it is used in bit operations """ def find_index_that_is_projected(j, k, qubit): bit_mask = 2**qubit - 1 return ((j >> qubit) << (1 + qubit)) + (j & bit_mask) + (k << qubit) old_matrix = represent(matrix, **options) old_size = old_matrix.cols #we expect the old_size to be even new_size = old_size // 2 new_matrix = Matrix().zeros(new_size) for i in xrange(new_size): for j in xrange(new_size): for k in range(2): col = find_index_that_is_projected(j, k, qubit) row = find_index_that_is_projected(i, k, qubit) new_matrix[i, j] += old_matrix[row, col] return new_matrix
def test_prefab_sampling(): N = Normal('X', 0, 1) L = LogNormal('L', 0, 1) E = Exponential('Ex', 1) P = Pareto('P', 1, 3) W = Weibull('W', 1, 1) U = Uniform('U', 0, 1) B = Beta('B', 2, 5) G = Gamma('G', 1, 3) variables = [N, L, E, P, W, U, B, G] niter = 10 for var in variables: for i in xrange(niter): assert sample(var) in var.pspace.domain.set
def fateman_poly_F_1(n): """Fateman's GCD benchmark: trivial GCD """ Y = [ Symbol('y_' + str(i)) for i in xrange(0, n + 1) ] y_0, y_1 = Y[0], Y[1] u = y_0 + Add(*[ y for y in Y[1:] ]) v = y_0**2 + Add(*[ y**2 for y in Y[1:] ]) F = ((u + 1)*(u + 2)).as_poly(*Y) G = ((v + 1)*(-3*y_1*y_0**2 + y_1**2 - 1)).as_poly(*Y) H = Poly(1, *Y) return F, G, H
def test_sincos_rewrite_sqrt(): # equivalent to testing rewrite(pow) for p in [1, 3, 5, 17]: for t in [1, 8]: n = t*p for i in xrange(1, (n + 1)//2 + 1): if 1 == gcd(i, n): x = i*pi/n s1 = sin(x).rewrite(sqrt) c1 = cos(x).rewrite(sqrt) assert not s1.has(cos, sin), "fails for %d*pi/%d" % (i, n) assert not c1.has(cos, sin), "fails for %d*pi/%d" % (i, n) assert 1e-3 > abs(sin(x.evalf(5)) - s1.evalf(2)), "fails for %d*pi/%d" % (i, n) assert 1e-3 > abs(cos(x.evalf(5)) - c1.evalf(2)), "fails for %d*pi/%d" % (i, n) assert cos(pi/14).rewrite(sqrt) == sqrt(cos(pi/7)/2 + S.Half)
def _as_dummy(self): """ Replace instances of the given dummy variables with explicit dummy counterparts to make clear what are dummy variables and what are real-world symbols in an object. Examples ======== >>> from sympy import Integral >>> from sympy.abc import x, y >>> Integral(x, (x, x, y), (y, x, y)).as_dummy() Integral(_x, (_x, x, _y), (_y, x, y)) If the object supperts the "integral at" limit ``(x,)`` it is not treated as a dummy, but the explicit form, ``(x, x)`` of length 2 does treat the variable as a dummy. >>> Integral(x, x).as_dummy() Integral(x, x) >>> Integral(x, (x, x)).as_dummy() Integral(_x, (_x, x)) If there were no dummies in the original expression, then the the symbols which cannot be changed by subs() are clearly seen as those with an underscore prefix. See Also ======== variables : Lists the integration variables transform : Perform mapping on the integration variable """ reps = {} f = self.function limits = list(self.limits) for i in xrange(-1, -len(limits) - 1, -1): xab = list(limits[i]) if len(xab) == 1: continue x = xab[0] xab[0] = x.as_dummy() for j in range(1, len(xab)): xab[j] = xab[j].subs(reps) reps[x] = xab[0] limits[i] = xab f = f.subs(reps) return self.func(f, *limits)
def generate_gray(self, **hints): """ Generates the sequence of bit vectors of a Gray Code. [1] Knuth, D. (2011). The Art of Computer Programming, Vol 4, Addison Wesley Examples ======== >>> from sympy.combinatorics.graycode import GrayCode >>> a = GrayCode(3) >>> list(a.generate_gray()) ['000', '001', '011', '010', '110', '111', '101', '100'] >>> list(a.generate_gray(start='011')) ['011', '010', '110', '111', '101', '100'] >>> list(a.generate_gray(rank=4)) ['110', '111', '101', '100'] See Also ======== skip """ bits = self.n start = None if "start" in hints: start = hints["start"] elif "rank" in hints: start = GrayCode.unrank(self.n, hints["rank"]) if start is not None: self._current = start current = self.current graycode_bin = gray_to_bin(current) if len(graycode_bin) > self.n: raise ValueError('Gray code start has length %i but should ' 'not be greater than %i' % (len(graycode_bin), bits)) self._current = int(current, 2) graycode_int = int(''.join(graycode_bin), 2) for i in xrange(graycode_int, 1 << bits): if self._skip: self._skip = False else: yield self.current bbtc = (i ^ (i + 1)) gbtc = (bbtc ^ (bbtc >> 1)) self._current = (self._current ^ gbtc) self._current = 0
def test_tancot_rewrite_sqrt(): # equivalent to testing rewrite(pow) for p in [1, 3, 5, 17]: for t in [1, 8]: n = t*p for i in xrange(1, (n + 1)//2 + 1): if 1 == gcd(i, n): x = i*pi/n if 2*i != n and 3*i != 2*n: t1 = tan(x).rewrite(sqrt) assert not t1.has(cot, tan), "fails for %d*pi/%d" % (i, n) assert 1e-3 > abs( tan(x.evalf(7)) - t1.evalf(4) ), "fails for %d*pi/%d" % (i, n) if i != 0 and i != n: c1 = cot(x).rewrite(sqrt) assert not c1.has(cot, tan), "fails for %d*pi/%d" % (i, n) assert 1e-3 > abs( cot(x.evalf(7)) - c1.evalf(4) ), "fails for %d*pi/%d" % (i, n)
def f(): glBegin(GL_LINE_STRIP) for t in xrange(len(self.t_set)): p = self.verts[t] if p is None: glEnd() glBegin(GL_LINE_STRIP) continue if use_cverts: c = self.cverts[t] if c is None: c = (0, 0, 0) glColor3f(*c) else: glColor3f(*self.default_wireframe_color) glVertex3f(*p) glEnd()
def _dup_decompose(f, K): """Helper function for :func:`dup_decompose`.""" df = len(f) - 1 for s in xrange(2, df): if df % s != 0: continue h = _dup_right_decompose(f, s, K) if h is not None: g = _dup_left_decompose(f, h, K) if g is not None: return g, h return None
def dmp_exclude(f, u, K): """ Exclude useless levels from ``f``. Return the levels excluded, the new excluded ``f``, and the new ``u``. Examples ======== >>> from sympy.polys.domains import ZZ >>> from sympy.polys.densebasic import dmp_exclude >>> f = ZZ.map([[[1]], [[1], [2]]]) >>> dmp_exclude(f, 2, ZZ) ([2], [[1], [1, 2]], 1) """ if not u or dmp_ground_p(f, None, u): return [], f, u J, F = [], dmp_to_dict(f, u) for j in xrange(0, u + 1): for monom in F.keys(): if monom[j]: break else: J.append(j) if not J: return [], f, u f = {} for monom, coeff in F.items(): monom = list(monom) for j in reversed(J): del monom[j] f[tuple(monom)] = coeff u -= len(J) return J, dmp_from_dict(f, u, K), u
def roots_binomial(f): """Returns a list of roots of a binomial polynomial.""" n = f.degree() a, b = f.nth(n), f.nth(0) alpha = (-cancel(b / a))**Rational(1, n) if alpha.is_number: alpha = alpha.expand(complex=True) roots, I = [], S.ImaginaryUnit for k in xrange(n): zeta = exp(2 * k * S.Pi * I / n).expand(complex=True) roots.append((alpha * zeta).expand(power_base=False)) return sorted(roots, key=default_sort_key)
def dmp_diff(f, m, u, K): """ ``m``-th order derivative in ``x_0`` of a polynomial in ``K[X]``. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x,y = ring("x,y", ZZ) >>> f = x*y**2 + 2*x*y + 3*x + 2*y**2 + 3*y + 1 >>> R.dmp_diff(f, 1) y**2 + 2*y + 3 >>> R.dmp_diff(f, 2) 0 """ if not u: return dup_diff(f, m, K) if m <= 0: return f n = dmp_degree(f, u) if n < m: return dmp_zero(u) deriv, v = [], u - 1 if m == 1: for coeff in f[:-m]: deriv.append(dmp_mul_ground(coeff, K(n), v, K)) n -= 1 else: for coeff in f[:-m]: k = n for i in xrange(n - 1, n - m, -1): k *= i deriv.append(dmp_mul_ground(coeff, K(k), v, K)) n -= 1 return dmp_strip(deriv, u)
def _test(n, base, s, t): """Miller-Rabin strong pseudoprime test for one base. Return False if n is definitely composite, True if n is probably prime, with a probability greater than 3/4. """ # do the Fermat test b = pow(base, t, n) if b == 1 or b == n - 1: return True else: for j in xrange(1, s): b = pow(b, 2, n) if b == n - 1: return True # see I. Niven et al. "An Introduction to Theory of Numbers", page 78 if b == 1: return False return False
def dmp_fateman_poly_F_3(n, K): """Fateman's GCD benchmark: sparse inputs (deg f ~ vars f) """ u = dup_from_raw_dict({n + 1: K.one}, K) for i in xrange(0, n - 1): u = dmp_add_term([u], dmp_one(i, K), n + 1, i + 1, K) v = dmp_add_term(u, dmp_ground(K(2), n - 2), 0, n, K) f = dmp_sqr( dmp_add_term([dmp_neg(v, n - 1, K)], dmp_one(n - 1, K), n + 1, n, K), n, K) g = dmp_sqr(dmp_add_term([v], dmp_one(n - 1, K), n + 1, n, K), n, K) v = dmp_add_term(u, dmp_one(n - 2, K), 0, n - 1, K) h = dmp_sqr(dmp_add_term([v], dmp_one(n - 1, K), n + 1, n, K), n, K) return dmp_mul(f, h, n, K), dmp_mul(g, h, n, K), h
def _check_cycles_alt_sym(perm): """ Checks for cycles of prime length p with n/2 < p < n-2. Here `n` is the degree of the permutation. This is a helper function for the function is_alt_sym from sympy.combinatorics.perm_groups. Examples ======== >>> from sympy.combinatorics.util import _check_cycles_alt_sym >>> from sympy.combinatorics.permutations import Permutation >>> a = Permutation([[0,1,2,3,4,5,6,7,8,9,10], [11, 12]]) >>> _check_cycles_alt_sym(a) False >>> b = Permutation([[0,1,2,3,4,5,6], [7,8,9,10]]) >>> _check_cycles_alt_sym(b) True See Also ======== sympy.combinatorics.perm_groups.PermutationGroup.is_alt_sym """ n = perm.size af = perm.array_form current_len = 0 total_len = 0 used = set() for i in xrange(n // 2): if not i in used and i < n // 2 - total_len: current_len = 1 used.add(i) j = i while (af[j] != i): current_len += 1 j = af[j] used.add(j) total_len += current_len if current_len > n // 2 and current_len < n - 2 and isprime( current_len): return True return False
def spread_part_multiplicity(self): """Returns True if a new part has been created, and adjusts pstack, f and lpart as needed. Notes ===== Spreads unallocated multiplicity from the current top part into a new part created above the current on the stack. This new part is constrained to be less than or equal to the old in terms of the part ordering. This call does nothing (and returns False) if the current top part has no unallocated multiplicity. """ j = self.f[self.lpart] # base of current top part k = self.f[self.lpart + 1] # ub of current; potential base of next base = k # save for later comparison changed = False # Set to true when the new part (so far) is # strictly less than (as opposed to less than # or equal) to the old. for j in xrange(self.f[self.lpart], self.f[self.lpart + 1]): self.pstack[k].u = self.pstack[j].u - self.pstack[j].v if self.pstack[k].u == 0: changed = True else: self.pstack[k].c = self.pstack[j].c if changed: # Put all available multiplicity in this part self.pstack[k].v = self.pstack[k].u else: # Still maintaining ordering constraint if self.pstack[k].u < self.pstack[j].v: self.pstack[k].v = self.pstack[k].u changed = True else: self.pstack[k].v = self.pstack[j].v k = k + 1 if k > base: # Adjust for the new part on stack self.lpart = self.lpart + 1 self.f[self.lpart + 1] = k return True return False
def dmp_fateman_poly_F_2(n, K): """Fateman's GCD benchmark: linearly dense quartic inputs """ u = [K(1), K(0)] for i in xrange(0, n - 1): u = [dmp_one(i, K), u] m = n - 1 v = dmp_add_term(u, dmp_ground(K(2), m - 1), 0, n, K) f = dmp_sqr([dmp_one(m, K), dmp_neg(v, m, K)], n, K) g = dmp_sqr([dmp_one(m, K), v], n, K) v = dmp_add_term(u, dmp_one(m - 1, K), 0, n, K) h = dmp_sqr([dmp_one(m, K), v], n, K) return dmp_mul(f, h, n, K), dmp_mul(g, h, n, K), h
def dmp_zero(u): """ Return a multivariate zero. Examples ======== >>> from sympy.polys.densebasic import dmp_zero >>> dmp_zero(4) [[[[[]]]]] """ r = [] for i in xrange(u): r = [r] return r
def dmp_from_dict(f, u, K): """ Create a ``K[X]`` polynomial from a ``dict``. Examples ======== >>> from sympy.polys.domains import ZZ >>> from sympy.polys.densebasic import dmp_from_dict >>> dmp_from_dict({(0, 0): ZZ(3), (0, 1): ZZ(2), (2, 1): ZZ(1)}, 1, ZZ) [[1, 0], [], [2, 3]] >>> dmp_from_dict({}, 0, ZZ) [] """ if not u: return dup_from_dict(f, K) if not f: return dmp_zero(u) coeffs = {} for monom, coeff in f.items(): head, tail = monom[0], monom[1:] if head in coeffs: coeffs[head][tail] = coeff else: coeffs[head] = {tail: coeff} n, v, h = max(coeffs.keys()), u - 1, [] for k in xrange(n, -1, -1): coeff = coeffs.get(k) if coeff is not None: h.append(dmp_from_dict(coeff, v, K)) else: h.append(dmp_zero(v)) return dmp_strip(h, u)
def telescopic_direct(L, R, n, limits): """Returns the direct summation of the terms of a telescopic sum L is the term with lower index R is the term with higher index n difference between the indexes of L and R For example: >>> from sympy.concrete.summations import telescopic_direct >>> from sympy.abc import k, a, b >>> telescopic_direct(1/k, -1/(k+2), 2, (k, a, b)) -1/(b + 2) - 1/(b + 1) + 1/(a + 1) + 1/a """ (i, a, b) = limits s = 0 for m in xrange(n): s += L.subs(i, a + m) + R.subs(i, b - m) return s
def dup_scale(f, a, K): """ Evaluate efficiently composition ``f(a*x)`` in ``K[x]``. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x = ring("x", ZZ) >>> R.dup_scale(x**2 - 2*x + 1, ZZ(2)) 4*x**2 - 4*x + 1 """ f, n, b = list(f), len(f) - 1, a for i in xrange(n - 1, -1, -1): f[i], b = b * f[i], b * a return f
def dup_mirror(f, K): """ Evaluate efficiently the composition ``f(-x)`` in ``K[x]``. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x = ring("x", ZZ) >>> R.dup_mirror(x**3 + 2*x**2 - 4*x + 2) -x**3 + 2*x**2 + 4*x + 2 """ f, n, a = list(f), len(f) - 1, -K.one for i in xrange(n - 1, -1, -1): f[i], a = a * f[i], -a return f
def dup_random(n, a, b, K): """ Return a polynomial of degree ``n`` with coefficients in ``[a, b]``. Examples ======== >>> from sympy.polys.domains import ZZ >>> from sympy.polys.densebasic import dup_random >>> dup_random(3, -10, 10, ZZ) #doctest: +SKIP [-2, -8, 9, -4] """ f = [K.convert(random.randint(a, b)) for _ in xrange(0, n + 1)] while not f[0]: f[0] = K.convert(random.randint(a, b)) return f
def _rec_inflate(g, M, v, i, K): """Recursive helper for :func:`dmp_inflate`.""" if not v: return dup_inflate(g, M[i], K) if M[i] <= 0: raise IndexError("all M[i] must be positive, got %s" % M[i]) w, j = v - 1, i + 1 g = [_rec_inflate(c, M, w, j, K) for c in g] result = [g[0]] for coeff in g[1:]: for _ in xrange(1, M[i]): result.append(dmp_zero(w)) result.append(coeff) return result
def n_order(a, n): """Returns the order of ``a`` modulo ``n``. The order of ``a`` modulo ``n`` is the smallest integer ``k`` such that ``a**k`` leaves a remainder of 1 with ``n``. Examples ======== >>> from sympy.ntheory import n_order >>> n_order(3, 7) 6 >>> n_order(4, 7) 3 """ from collections import defaultdict a, n = as_int(a), as_int(n) if igcd(a, n) != 1: raise ValueError("The two numbers should be relatively prime") factors = defaultdict(int) f = factorint(n) for px, kx in f.items(): if kx > 1: factors[px] += kx - 1 fpx = factorint(px - 1) for py, ky in fpx.items(): factors[py] += ky group_order = 1 for px, kx in factors.items(): group_order *= px**kx order = 1 if a > n: a = a % n for p, e in factors.items(): exponent = group_order for f in xrange(e + 1): if pow(a, exponent, n) != 1: order *= p**(e - f + 1) break exponent = exponent // p return order
def dup_diff(f, m, K): """ ``m``-th order derivative of a polynomial in ``K[x]``. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x = ring("x", ZZ) >>> R.dup_diff(x**3 + 2*x**2 + 3*x + 4, 1) 3*x**2 + 4*x + 3 >>> R.dup_diff(x**3 + 2*x**2 + 3*x + 4, 2) 6*x + 4 """ if m <= 0: return f n = dup_degree(f) if n < m: return [] deriv = [] if m == 1: for coeff in f[:-m]: deriv.append(K(n) * coeff) n -= 1 else: for coeff in f[:-m]: k = n for i in xrange(n - 1, n - m, -1): k *= i deriv.append(K(k) * coeff) n -= 1 return dup_strip(deriv)