def cardinality(self): r""" Return the number of Baxter permutations of size ``self._n``. For any positive integer `n`, the number of Baxter permutations of size `n` equals .. MATH:: \sum_{k=1}^n \dfrac {\binom{n+1}{k-1} \binom{n+1}{k} \binom{n+1}{k+1}} {\binom{n+1}{1} \binom{n+1}{2}} . This is :oeis:`A001181`. EXAMPLES:: sage: [BaxterPermutations(n).cardinality() for n in range(13)] [1, 1, 2, 6, 22, 92, 422, 2074, 10754, 58202, 326240, 1882960, 11140560] sage: BaxterPermutations(3r).cardinality() 6 sage: parent(_) Integer Ring """ if self._n == 0: return 1 from sage.arith.all import binomial return sum((binomial(self._n + 1, k) * binomial(self._n + 1, k + 1) * binomial(self._n + 1, k + 2)) // ((self._n + 1) * binomial(self._n + 1, 2)) for k in range(self._n))
def __init__(self, R, elements): """ Initialize ``self``. EXAMPLES:: sage: R.<x,y,z> = QQ[] sage: K = KoszulComplex(R, [x,y]) sage: TestSuite(K).run() """ # Generate the differentials self._elements = elements n = len(elements) I = list(range(n)) diff = {} zero = R.zero() for i in I: M = matrix(R, binomial(n, i), binomial(n, i + 1), zero) j = 0 for comb in itertools.combinations(I, i + 1): for k, val in enumerate(comb): r = rank(comb[:k] + comb[k + 1:], n, False) M[r, j] = (-1)**k * elements[val] j += 1 M.set_immutable() diff[i + 1] = M diff[0] = matrix(R, 0, 1, zero) diff[0].set_immutable() diff[n + 1] = matrix(R, 1, 0, zero) diff[n + 1].set_immutable() ChainComplex_class.__init__(self, ZZ, ZZ(-1), R, diff)
def __init__(self, R, elements): """ Initialize ``self``. EXAMPLES:: sage: R.<x,y,z> = QQ[] sage: K = KoszulComplex(R, [x,y]) sage: TestSuite(K).run() """ # Generate the differentials self._elements = elements n = len(elements) I = range(n) diff = {} zero = R.zero() for i in I: M = matrix(R, binomial(n,i), binomial(n,i+1), zero) j = 0 for comb in itertools.combinations(I, i+1): for k,val in enumerate(comb): r = rank(comb[:k] + comb[k+1:], n, False) M[r,j] = (-1)**k * elements[val] j += 1 M.set_immutable() diff[i+1] = M diff[0] = matrix(R, 0, 1, zero) diff[0].set_immutable() diff[n+1] = matrix(R, 1, 0, zero) diff[n+1].set_immutable() ChainComplex_class.__init__(self, ZZ, ZZ(-1), R, diff)
def cardinality(self): """ EXAMPLES:: sage: IntegerVectors(3,3, min_part=1).cardinality() 1 sage: IntegerVectors(5,3, min_part=1).cardinality() 6 sage: IntegerVectors(13, 4, min_part=2, max_part=4).cardinality() 16 """ if not self._constraints: if self.k < 0: return +infinity if self.n >= 0: return binomial(self.n+self.k-1,self.n) else: return 0 else: if len(self._constraints) == 1 and 'max_part' in self._constraints and self._constraints['max_part'] != infinity: m = self._constraints['max_part'] if m >= self.n: return binomial(self.n+self.k-1,self.n) else: #do by inclusion / exclusion on the number #i of parts greater than m return sum( [(-1)**i * binomial(self.n+self.k-1-i*(m+1), self.k-1)*binomial(self.k,i) for i in range(0, self.n/(m+1)+1)]) else: return super(IntegerVectors_nkconstraints, self).cardinality()
def Z2(a, b, c, check_convergence=True): M = Multizetas(QQ) if a == 0 and b == 0: return M((c - 1, )) - M((c, )) else: return sum( binomial(a + i - 1, i) * M((b - i, c + a + i)) for i in range(b)) + sum( binomial(b + i - 1, i) * M((a - i, c + b + i)) for i in range(a))
def _induced_flags(self, n, tg, type_edges): flag_counts = {} flags = [] total = 0 for p in Tuples([0, 1], binomial(n, 2) - binomial(tg.n, 2)): edges = list(type_edges) c = 0 for i in range(tg.n + 1, n + 1): for j in range(1, i): if p[c] == 0: edges.append((i, j)) else: edges.append((j, i)) c += 1 ig = ThreeGraphFlag() ig.n = n ig.t = tg.n for s in Combinations(list(range(1, n + 1)), 3): if self._variant: if ((s[1], s[0]) in edges and (s[0], s[2]) in edges) or ((s[2], s[0]) in edges and (s[0], s[1]) in edges): ig.add_edge(s) else: if ((s[0], s[1]) in edges and (s[1], s[2]) in edges and (s[2], s[0]) in edges) or ((s[0], s[2]) in edges and (s[2], s[1]) in edges and (s[1], s[0]) in edges): ig.add_edge(s) it = ig.induced_subgraph(list(range(1, tg.n + 1))) if tg.is_labelled_isomorphic(it): ig.make_minimal_isomorph() ghash = hash(ig) if ghash in flag_counts: flag_counts[ghash] += 1 else: flags.append(ig) flag_counts[ghash] = 1 total += 1 return [(f, flag_counts[hash(f)] / Integer(total)) for f in flags]
def from_rank(r, n, k): r""" Returns the combination of rank ``r`` in the subsets of ``range(n)`` of size ``k`` when listed in lexicographic order. The algorithm used is based on combinadics and James McCaffrey's MSDN article. See: :wikipedia:`Combinadic` EXAMPLES:: sage: import sage.combinat.combination as combination sage: combination.from_rank(0,3,0) () sage: combination.from_rank(0,3,1) (0,) sage: combination.from_rank(1,3,1) (1,) sage: combination.from_rank(2,3,1) (2,) sage: combination.from_rank(0,3,2) (0, 1) sage: combination.from_rank(1,3,2) (0, 2) sage: combination.from_rank(2,3,2) (1, 2) sage: combination.from_rank(0,3,3) (0, 1, 2) """ if k < 0: raise ValueError("k must be > 0") if k > n: raise ValueError("k must be <= n") a = n b = k x = binomial(n, k) - 1 - r # x is the 'dual' of m comb = [None] * k for i in range(k): comb[i] = _comb_largest(a, b, x) x = x - binomial(comb[i], b) a = comb[i] b = b - 1 for i in range(k): comb[i] = (n - 1) - comb[i] return tuple(comb)
def from_rank(r, n, k): r""" Returns the combination of rank ``r`` in the subsets of ``range(n)`` of size ``k`` when listed in lexicographic order. The algorithm used is based on combinadics and James McCaffrey's MSDN article. See: :wikipedia:`Combinadic` EXAMPLES:: sage: import sage.combinat.combination as combination sage: combination.from_rank(0,3,0) () sage: combination.from_rank(0,3,1) (0,) sage: combination.from_rank(1,3,1) (1,) sage: combination.from_rank(2,3,1) (2,) sage: combination.from_rank(0,3,2) (0, 1) sage: combination.from_rank(1,3,2) (0, 2) sage: combination.from_rank(2,3,2) (1, 2) sage: combination.from_rank(0,3,3) (0, 1, 2) """ if k < 0: raise ValueError("k must be > 0") if k > n: raise ValueError("k must be <= n") a = n b = k x = binomial(n, k) - 1 - r # x is the 'dual' of m comb = [None] * k for i in xrange(k): comb[i] = _comb_largest(a, b, x) x = x - binomial(comb[i], b) a = comb[i] b = b - 1 for i in xrange(k): comb[i] = (n - 1) - comb[i] return tuple(comb)
def unrank(self, r): """ Return the subset of ``s`` that has rank ``k``. EXAMPLES:: sage: Subsets(3).unrank(0) {} sage: Subsets([2,4,5]).unrank(1) {2} sage: Subsets([1,2,3]).unrank(257) Traceback (most recent call last): ... IndexError: index out of range """ r = Integer(r) if r >= self.cardinality() or r < 0: raise IndexError("index out of range") else: k = ZZ_0 n = self._s.cardinality() bin = Integer(1) while r >= bin: r -= bin k += 1 bin = binomial(n,k) return self.element_class([self._s.unrank(i) for i in combination.from_rank(r, n, k)])
def rank(self, sub): """ Return the rank of ``sub`` as a subset of ``s``. EXAMPLES:: sage: Subsets(3).rank([]) 0 sage: Subsets(3).rank([1,2]) 4 sage: Subsets(3).rank([1,2,3]) 7 sage: Subsets(3).rank([2,3,4]) Traceback (most recent call last): ... ValueError: {2, 3, 4} is not a subset of {1, 2, 3} """ if sub not in Sets(): ssub = Set(sub) if len(sub) != len(ssub): raise ValueError("repeated elements in {}".format(sub)) sub = ssub try: index_list = sorted(self._s.rank(x) for x in sub) except (ValueError,IndexError): raise ValueError("{} is not a subset of {}".format( Set(sub), self._s)) n = self._s.cardinality() r = sum(binomial(n,i) for i in range(len(index_list))) return r + combination.rank(index_list,n)
def unrank(self, r): """ Return the subset of ``s`` that has rank ``k``. EXAMPLES:: sage: Subsets(3).unrank(0) {} sage: Subsets([2,4,5]).unrank(1) {2} sage: Subsets([1,2,3]).unrank(257) Traceback (most recent call last): ... IndexError: index out of range """ r = Integer(r) if r >= self.cardinality() or r < 0: raise IndexError("index out of range") else: k = ZZ_0 n = self._s.cardinality() bin = Integer(1) while r >= bin: r -= bin k += 1 bin = binomial(n, k) return self.element_class( [self._s.unrank(i) for i in combination.from_rank(r, n, k)])
def cardinality(self): r""" Return the number of words in the shuffle product of ``w1`` and ``w2``. This is understood as a multiset cardinality, not as a set cardinality; it does not count the distinct words only. It is given by `\binom{l_1+l_2}{l_1}`, where `l_1` is the length of ``w1`` and where `l_2` is the length of ``w2``. EXAMPLES:: sage: from sage.combinat.words.shuffle_product import ShuffleProduct_w1w2 sage: w, u = map(Words("abcd"), ["ab", "cd"]) sage: S = ShuffleProduct_w1w2(w,u) sage: S.cardinality() 6 sage: w, u = map(Words("ab"), ["ab", "ab"]) sage: S = ShuffleProduct_w1w2(w,u) sage: S.cardinality() 6 """ return binomial(self._w1.length()+self._w2.length(), self._w1.length())
def __init__(self, fmodule, degree, name=None, latex_name=None): r""" TESTS:: sage: from sage.tensor.modules.ext_pow_free_module import ExtPowerFreeModule sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: e = M.basis('e') sage: A = ExtPowerFreeModule(M, 2) ; A 2nd exterior power of the Rank-3 free module M over the Integer Ring sage: TestSuite(A).run() """ from sage.arith.all import binomial from sage.typeset.unicode_characters import unicode_bigwedge self._fmodule = fmodule self._degree = ZZ(degree) rank = binomial(fmodule._rank, degree) if name is None and fmodule._name is not None: name = unicode_bigwedge + r'^{}('.format(degree) \ + fmodule._name + ')' if latex_name is None and fmodule._latex_name is not None: latex_name = r'\Lambda^{' + str(degree) + r'}\left(' \ + fmodule._latex_name + r'\right)' FiniteRankFreeModule.__init__( self, fmodule._ring, rank, name=name, latex_name=latex_name, start_index=fmodule._sindex, output_formatter=fmodule._output_formatter) fmodule._all_modules.add(self)
def _basic_integral(self, a, j): r""" Return `\int_{a+pZ_p} (z-{a})^j d\Phi(0-infty)`. See formula in section 9.2 of [PS2011]_ INPUT: - ``a`` -- integer in range(p) - ``j`` -- integer in range(self.symbol().precision_relative()) EXAMPLES:: sage: from sage.modular.pollack_stevens.padic_lseries import pAdicLseries sage: E = EllipticCurve('11a3') sage: L = E.padic_lseries(5, implementation="pollackstevens", precision=4) #long time sage: L._basic_integral(1,2) # long time 2*5^2 + 5^3 + O(5^4) """ symb = self.symbol() M = symb.precision_relative() if j > M: raise PrecisionError("Too many moments requested") p = self.prime() ap = symb.Tq_eigenvalue(p) D = self._quadratic_twist ap = ap * kronecker(D, p) K = pAdicField(p, M) symb_twisted = symb.evaluate_twisted(a, D) return sum( binomial(j, r) * ((a - ZZ(K.teichmuller(a)))**(j - r)) * (p**r) * symb_twisted.moment(r) for r in range(j + 1)) / ap
def _basic_integral(self, a, j): r""" Return `\int_{a+pZ_p} (z-{a})^j d\Phi(0-infty)` -- see formula [Pollack-Stevens, sec 9.2] INPUT: - ``a`` -- integer in range(p) - ``j`` -- integer in range(self.symbol().precision_relative()) EXAMPLES:: sage: from sage.modular.pollack_stevens.padic_lseries import pAdicLseries sage: E = EllipticCurve('11a3') sage: L = E.padic_lseries(5, implementation="pollackstevens", precision=4) #long time sage: L._basic_integral(1,2) # long time 2*5^2 + 5^3 + O(5^4) """ symb = self.symbol() M = symb.precision_relative() if j > M: raise PrecisionError("Too many moments requested") p = self.prime() ap = symb.Tq_eigenvalue(p) D = self._quadratic_twist ap = ap * kronecker(D, p) K = pAdicField(p, M) symb_twisted = symb.evaluate_twisted(a, D) return ( sum( binomial(j, r) * ((a - ZZ(K.teichmuller(a))) ** (j - r)) * (p ** r) * symb_twisted.moment(r) for r in range(j + 1) ) / ap )
def rank(self, x): """ Returns the position of a given element. INPUT: - ``x`` - a list with ``sum(x) == n`` and ``len(x) == k`` TESTS:: sage: IV = IntegerVectors(4,5) sage: range(IV.cardinality()) == [IV.rank(x) for x in IV] True """ if x not in self: raise ValueError( "argument is not a member of IntegerVectors(%d,%d)" % (self.n, self.k)) n = self.n k = self.k r = 0 for i in range(k - 1): k -= 1 n -= x[i] r += binomial(k + n - 1, k) return r
def log_gamma_binomial(p, gamma, z, n, M): r""" Return the list of coefficients in the power series expansion (up to precision `M`) of `\binom{\log_p(z)/\log_p(\gamma)}{n}` INPUT: - ``p`` -- prime - ``gamma`` -- topological generator, e.g. `1+p` - ``z`` -- variable - ``n`` -- nonnegative integer - ``M`` -- precision OUTPUT: The list of coefficients in the power series expansion of `\binom{\log_p(z)/\log_p(\gamma)}{n}` EXAMPLES:: sage: R.<z> = QQ['z'] sage: from sage.modular.pollack_stevens.padic_lseries import log_gamma_binomial sage: log_gamma_binomial(5,1+5,z,2,4) [0, -3/205, 651/84050, -223/42025] sage: log_gamma_binomial(5,1+5,z,3,4) [0, 2/205, -223/42025, 95228/25845375] """ L = sum([ZZ(-1) ** j / j * z ** j for j in range(1, M)]) # log_p(1+z) loggam = L / (L(gamma - 1)) # log_{gamma}(1+z)= log_p(1+z)/log_p(gamma) return z.parent()(binomial(loggam, n)).truncate(M).list()
def rank(self, x): """ Returns the position of a given element. INPUT: - ``x`` - a list with ``sum(x) == n`` and ``len(x) == k`` TESTS:: sage: IV = IntegerVectors(4,5) sage: range(IV.cardinality()) == [IV.rank(x) for x in IV] True """ if x not in self: raise ValueError("argument is not a member of IntegerVectors(%d,%d)" % (self.n, self.k)) n = self.n k = self.k r = 0 for i in range(k-1): k -= 1 n -= x[i] r += binomial(k+n-1,k) return r
def upper_bound(min_length, max_length, floor, ceiling, min_slope, max_slope): """ Compute a coarse upper bound on the size of a vector satisfying the constraints. TESTS:: sage: import sage.combinat.integer_list_old as integer_list sage: f = lambda x: lambda i: x sage: integer_list.upper_bound(0,4,f(0), f(1),-infinity,infinity) 4 sage: integer_list.upper_bound(0, infinity, f(0), f(1), -infinity, infinity) inf sage: integer_list.upper_bound(0, infinity, f(0), f(1), -infinity, -1) 1 sage: integer_list.upper_bound(0, infinity, f(0), f(5), -infinity, -1) 15 sage: integer_list.upper_bound(0, infinity, f(0), f(5), -infinity, -2) 9 """ from sage.functions.all import floor as flr if max_length < float('inf'): return sum([ceiling(j) for j in range(max_length)]) elif max_slope < 0 and ceiling(1) < float('inf'): maxl = flr(-ceiling(1) / max_slope) return ceiling(1) * (maxl + 1) + binomial(maxl + 1, 2) * max_slope #FIXME: only checking the first 10000 values, but that should generally #be enough elif [ceiling(j) for j in range(10000)] == [0] * 10000: return 0 else: return float('inf')
def upper_bound(min_length, max_length, floor, ceiling, min_slope, max_slope): """ Compute a coarse upper bound on the size of a vector satisfying the constraints. TESTS:: sage: import sage.combinat.integer_list_old as integer_list sage: f = lambda x: lambda i: x sage: integer_list.upper_bound(0,4,f(0), f(1),-infinity,infinity) 4 sage: integer_list.upper_bound(0, infinity, f(0), f(1), -infinity, infinity) inf sage: integer_list.upper_bound(0, infinity, f(0), f(1), -infinity, -1) 1 sage: integer_list.upper_bound(0, infinity, f(0), f(5), -infinity, -1) 15 sage: integer_list.upper_bound(0, infinity, f(0), f(5), -infinity, -2) 9 """ from sage.functions.all import floor as flr if max_length < float('inf'): return sum( [ ceiling(j) for j in range(max_length)] ) elif max_slope < 0 and ceiling(1) < float('inf'): maxl = flr(-ceiling(1)/max_slope) return ceiling(1)*(maxl+1) + binomial(maxl+1,2)*max_slope #FIXME: only checking the first 10000 values, but that should generally #be enough elif [ceiling(j) for j in range(10000)] == [0]*10000: return 0 else: return float('inf')
def rank(self, sub): """ Return the rank of ``sub`` as a subset of ``s``. EXAMPLES:: sage: Subsets(3).rank([]) 0 sage: Subsets(3).rank([1,2]) 4 sage: Subsets(3).rank([1,2,3]) 7 sage: Subsets(3).rank([2,3,4]) Traceback (most recent call last): ... ValueError: {2, 3, 4} is not a subset of {1, 2, 3} """ if sub not in Sets(): ssub = Set(sub) if len(sub) != len(ssub): raise ValueError("repeated elements in {}".format(sub)) sub = ssub try: index_list = sorted(self._s.rank(x) for x in sub) except (ValueError, IndexError): raise ValueError("{} is not a subset of {}".format( Set(sub), self._s)) n = self._s.cardinality() r = sum(binomial(n, i) for i in range(len(index_list))) return r + combination.rank(index_list, n)
def _b_power_k_r(self, k, r): r""" An expression involving Moebius inversion in the powersum generators. For a positive value of ``k``, this expression is .. MATH:: \sum_{j=0}^r (-1)^{r-j}k^j\binom{r,j} \left( \frac{1}{k} \sum_{d|k} \mu(d/k) p_d \right)_k. INPUT: - ``k``, ``r`` -- positive integers OUTPUT: - an expression in the powersum basis of the symmetric functions EXAMPLES:: sage: st = SymmetricFunctions(QQ).st() sage: st._b_power_k_r(1,1) -p[] + p[1] sage: st._b_power_k_r(2,2) p[] + 4*p[1] + p[1, 1] - 4*p[2] - 2*p[2, 1] + p[2, 2] sage: st._b_power_k_r(3,2) p[] + 5*p[1] + p[1, 1] - 5*p[3] - 2*p[3, 1] + p[3, 3] """ p = self._p return p.sum( (-1)**(r - j) * k**j * binomial(r, j) * p.prod(self._b_power_k(k) - i * p.one() for i in range(j)) for j in range(r + 1))
def log_gamma_binomial(p, gamma, n, M): r""" Return the list of coefficients in the power series expansion (up to precision `M`) of `\binom{\log_p(z)/\log_p(\gamma)}{n}` INPUT: - ``p`` -- prime - ``gamma`` -- topological generator, e.g. `1+p` - ``n`` -- nonnegative integer - ``M`` -- precision OUTPUT: The list of coefficients in the power series expansion of `\binom{\log_p(z)/\log_p(\gamma)}{n}` EXAMPLES:: sage: from sage.modular.pollack_stevens.padic_lseries import log_gamma_binomial sage: log_gamma_binomial(5,1+5,2,4) [0, -3/205, 651/84050, -223/42025] sage: log_gamma_binomial(5,1+5,3,4) [0, 2/205, -223/42025, 95228/25845375] """ S = PowerSeriesRing(QQ, 'z') L = S([0] + [ZZ(-1)**j / j for j in range(1, M)]) # log_p(1+z) loggam = L.O(M) / L(gamma - 1) # log_{gamma}(1+z)= log_p(1+z)/log_p(gamma) return binomial(loggam, n).list()
def cardinality(self): r""" Return the number of words in the shuffle product of ``w1`` and ``w2``. This is understood as a multiset cardinality, not as a set cardinality; it does not count the distinct words only. It is given by `\binom{l_1+l_2}{l_1}`, where `l_1` is the length of ``w1`` and where `l_2` is the length of ``w2``. EXAMPLES:: sage: from sage.combinat.words.shuffle_product import ShuffleProduct_w1w2 sage: w, u = map(Words("abcd"), ["ab", "cd"]) sage: S = ShuffleProduct_w1w2(w,u) sage: S.cardinality() 6 sage: w, u = map(Words("ab"), ["ab", "ab"]) sage: S = ShuffleProduct_w1w2(w,u) sage: S.cardinality() 6 """ return binomial(self._w1.length() + self._w2.length(), self._w1.length())
def _induced_flags(self, n, tg, type_edges): flag_counts = {} flags = [] total = 0 for p in Tuples([0, 1], binomial(n, 2) - binomial(tg.n, 2)): edges = list(type_edges) c = 0 for i in range(tg.n + 1, n + 1): for j in range(1, i): if p[c] == 0: edges.append((i, j)) else: edges.append((j, i)) c += 1 ig = ThreeGraphFlag() ig.n = n ig.t = tg.n for s in Combinations(range(1, n + 1), 3): if self._variant: if ((s[1], s[0]) in edges and (s[0], s[2]) in edges) or ( (s[2], s[0]) in edges and (s[0], s[1]) in edges): ig.add_edge(s) else: if ((s[0], s[1]) in edges and (s[1], s[2]) in edges and (s[2], s[0]) in edges) or ( (s[0], s[2]) in edges and (s[2], s[1]) in edges and (s[1], s[0]) in edges): ig.add_edge(s) it = ig.induced_subgraph(range(1, tg.n + 1)) if tg.is_labelled_isomorphic(it): ig.make_minimal_isomorph() ghash = hash(ig) if ghash in flag_counts: flag_counts[ghash] += 1 else: flags.append(ig) flag_counts[ghash] = 1 total += 1 return [(f, flag_counts[hash(f)] / Integer(total)) for f in flags]
def unrank(self, r): """ EXAMPLES:: sage: c = Combinations([1,2,3]) sage: c.list() == list(map(c.unrank, range(c.cardinality()))) True """ k = 0 n = len(self.mset) b = binomial(n, k) while r >= b: r -= b k += 1 b = binomial(n, k) return [self.mset[i] for i in from_rank(r, n, k)]
def f(partition): n = 0 m = 1 for part in partition: n += part m *= q**binomial(part, 2)/q_factorial(part, q=q) return t**n * m
def unrank(self, r): """ EXAMPLES:: sage: c = Combinations([1,2,3]) sage: c.list() == map(c.unrank, range(c.cardinality())) True """ k = 0 n = len(self.mset) b = binomial(n, k) while r >= b: r -= b k += 1 b = binomial(n,k) return [self.mset[i] for i in from_rank(r, n, k)]
def cardinality(self): """ Return the cardinality of ``self``. EXAMPLES:: sage: IntegerVectors(3, 3, min_part=1).cardinality() 1 sage: IntegerVectors(5, 3, min_part=1).cardinality() 6 sage: IntegerVectors(13, 4, max_part=4).cardinality() 20 sage: IntegerVectors(k=4, max_part=3).cardinality() 256 sage: IntegerVectors(k=3, min_part=2, max_part=4).cardinality() 27 sage: IntegerVectors(13, 4, min_part=2, max_part=4).cardinality() 16 """ if self.k is None: if self.n is None: return PlusInfinity() if ('max_length' not in self.constraints and self.constraints.get('min_part', 0) <= 0): return PlusInfinity() elif ('max_part' in self.constraints and self.constraints['max_part'] != PlusInfinity()): if (self.n is None and len(self.constraints) == 2 and 'min_part' in self.constraints and self.constraints['min_part'] >= 0): num = self.constraints['max_part'] - self.constraints[ 'min_part'] + 1 return Integer(num**self.k) if len(self.constraints) == 1: m = self.constraints['max_part'] if self.n is None: return Integer((m + 1)**self.k) if m >= self.n: return Integer(binomial(self.n + self.k - 1, self.n)) # do by inclusion / exclusion on the number # i of parts greater than m return Integer(sum( (-1)**i * binomial(self.n+self.k-1-i*(m+1), self.k-1) \ * binomial(self.k,i) for i in range(self.n/(m+1)+1) )) return ZZ.sum(ZZ.one() for x in self)
def cardinality(self): """ Return the size of combinations(set, k). EXAMPLES:: sage: Combinations(range(16000), 5).cardinality() 8732673194560003200 """ return binomial(len(self.mset), self.k)
def cardinality(self): r""" Returns the number of subwords of w of length k. EXAMPLES:: sage: Subwords([1,2,3], 2).cardinality() 3 """ return arith.binomial(Integer(len(self._w)), self._k)
def tdesign_params(t, v, k, L): """ Return the design's parameters: `(t, v, b, r , k, L)`. Note that `t` must be given. EXAMPLES:: sage: BD = BlockDesign(7,[[0,1,2],[0,3,4],[0,5,6],[1,3,5],[1,4,6],[2,3,6],[2,4,5]]) sage: from sage.combinat.designs.block_design import tdesign_params sage: tdesign_params(2,7,3,1) (2, 7, 7, 3, 3, 1) """ x = binomial(v, t) y = binomial(k, t) b = divmod(L * x, y)[0] x = binomial(v-1, t-1) y = binomial(k-1, t-1) r = integer_floor(L * x/y) return (t, v, b, r, k, L)
def cardinality(self): """ Return the cardinality of ``self``. EXAMPLES:: sage: IntegerVectors(3, 3, min_part=1).cardinality() 1 sage: IntegerVectors(5, 3, min_part=1).cardinality() 6 sage: IntegerVectors(13, 4, max_part=4).cardinality() 20 sage: IntegerVectors(k=4, max_part=3).cardinality() 256 sage: IntegerVectors(k=3, min_part=2, max_part=4).cardinality() 27 sage: IntegerVectors(13, 4, min_part=2, max_part=4).cardinality() 16 """ if self.k is None: if self.n is None: return PlusInfinity() if ('max_length' not in self.constraints and self.constraints.get('min_part', 0) <= 0): return PlusInfinity() elif ('max_part' in self.constraints and self.constraints['max_part'] != PlusInfinity()): if (self.n is None and len(self.constraints) == 2 and 'min_part' in self.constraints and self.constraints['min_part'] >= 0): num = self.constraints['max_part'] - self.constraints['min_part'] + 1 return Integer(num ** self.k) if len(self.constraints) == 1: m = self.constraints['max_part'] if self.n is None: return Integer((m + 1) ** self.k) if m >= self.n: return Integer(binomial(self.n + self.k - 1, self.n)) # do by inclusion / exclusion on the number # i of parts greater than m return Integer(sum( (-1)**i * binomial(self.n+self.k-1-i*(m+1), self.k-1) \ * binomial(self.k,i) for i in range(self.n/(m+1)+1) )) return ZZ.sum(ZZ.one() for x in self)
def tdesign_params(t, v, k, L): """ Return the design's parameters: `(t, v, b, r , k, L)`. Note that `t` must be given. EXAMPLES:: sage: BD = BlockDesign(7,[[0,1,2],[0,3,4],[0,5,6],[1,3,5],[1,4,6],[2,3,6],[2,4,5]]) sage: from sage.combinat.designs.block_design import tdesign_params sage: tdesign_params(2,7,3,1) (2, 7, 7, 3, 3, 1) """ x = binomial(v, t) y = binomial(k, t) b = divmod(L * x, y)[0] x = binomial(v - 1, t - 1) y = binomial(k - 1, t - 1) r = integer_floor(L * x / y) return (t, v, b, r, k, L)
def by_taylor_expansion(self, fs, k, is_integral=False): r""" We combine the theta decomposition and the heat operator as in [Sko]. This yields a bijections of Jacobi forms of weight `k` and `M_k \times S_{k+2} \times .. \times S_{k+2m}`. """ ## we introduce an abbreviations if is_integral: PS = self.integral_power_series_ring() else: PS = self.power_series_ring() if not len(fs) == self.__precision.jacobi_index() + 1: raise ValueError( "fs must be a list of m + 1 elliptic modular forms or their fourier expansion" ) qexp_prec = self._qexp_precision() if qexp_prec is None: # there are no forms below the precision return dict() f_divs = dict() for (i, f) in enumerate(fs): f_divs[(i, 0)] = PS(f(qexp_prec), qexp_prec) if self.__precision.jacobi_index() == 1: return self._by_taylor_expansion_m1(f_divs, k, is_integral) for i in xrange(self.__precision.jacobi_index() + 1): for j in xrange(1, self.__precision.jacobi_index() - i + 1): f_divs[(i, j)] = f_divs[(i, j - 1)].derivative().shift(1) phi_divs = list() for i in xrange(self.__precision.jacobi_index() + 1): ## This is the formula in Skoruppas thesis. He uses d/ d tau instead of d / dz which yields ## a factor 4 m phi_divs.append( sum(f_divs[(j, i - j)] * (4 * self.__precision.jacobi_index())**i * binomial(i, j) / 2**i #2**(self.__precision.jacobi_index() - i + 1) * prod(2 * (i - l) + 1 for l in xrange(1, i)) / factorial(i + k + j - 1) * factorial(2 * self.__precision.jacobi_index() + k - 1) for j in xrange(i + 1))) phi_coeffs = dict() for r in xrange(self.__precision.jacobi_index() + 1): series = sum(map(operator.mul, self._theta_factors()[r], phi_divs)) series = self._eta_factor() * series for n in xrange(qexp_prec): phi_coeffs[(n, r)] = series[n] return phi_coeffs
def cardinality(self): """ Returns the number of multichoices of k things from a list of n things. EXAMPLES:: sage: MultichooseNK(3,2).cardinality() 6 """ n, k = self._n, self._k return binomial(n + k - 1, k)
def cardinality(self): """ Returns the number of multichoices of k things from a list of n things. EXAMPLES:: sage: MultichooseNK(3,2).cardinality() 6 """ n,k = self._n, self._k return binomial(n+k-1,k)
def cardinality(self): r""" Return the cardinality of ``self``. EXAMPLES:: sage: from sage.combinat.blob_algebra import BlobDiagrams sage: BD4 = BlobDiagrams(4) sage: BD4.cardinality() 70 """ return binomial(2 * self._n, self._n)
def _induced_flags(self, n, tg, type_edges): flag_counts = {} flags = [] total = 0 for p in Tuples([0, 1], binomial(n, 2) - binomial(tg.n, 2)): edges = list(type_edges) c = 0 for i in range(tg.n + 1, n + 1): for j in range(1, i): if p[c] == 1: edges.append((j, i)) c += 1 ig = ThreeGraphFlag() ig.n = n ig.t = tg.n for s in Combinations(range(1, n + 1), 3): ind_edges = [e for e in edges if e[0] in s and e[1] in s] if len(ind_edges) == 1 or len(ind_edges) == 3: ig.add_edge(s) it = ig.induced_subgraph(range(1, tg.n + 1)) if tg.is_labelled_isomorphic(it): ig.make_minimal_isomorph() ghash = hash(ig) if ghash in flag_counts: flag_counts[ghash] += 1 else: flags.append(ig) flag_counts[ghash] = 1 total += 1 return [(f, flag_counts[hash(f)] / Integer(total)) for f in flags]
def volume_hamming(n, q, r): r""" Return the number of elements in a Hamming ball. Return the number of elements in a Hamming ball of radius `r` in `\GF{q}^n`. EXAMPLES:: sage: codes.bounds.volume_hamming(10,2,3) 176 """ return sum([binomial(n, i) * (q - 1)**i for i in range(r + 1)])
def by_taylor_expansion(self, fs, k, is_integral=False) : r""" We combine the theta decomposition and the heat operator as in [Sko]. This yields a bijections of Jacobi forms of weight `k` and `M_k \times S_{k+2} \times .. \times S_{k+2m}`. """ ## we introduce an abbreviations if is_integral : PS = self.integral_power_series_ring() else : PS = self.power_series_ring() if not len(fs) == self.__precision.jacobi_index() + 1 : raise ValueError("fs must be a list of m + 1 elliptic modular forms or their fourier expansion") qexp_prec = self._qexp_precision() if qexp_prec is None : # there are no forms below the precision return dict() f_divs = dict() for (i, f) in enumerate(fs) : f_divs[(i, 0)] = PS(f(qexp_prec), qexp_prec) if self.__precision.jacobi_index() == 1 : return self._by_taylor_expansion_m1(f_divs, k, is_integral) for i in xrange(self.__precision.jacobi_index() + 1) : for j in xrange(1, self.__precision.jacobi_index() - i + 1) : f_divs[(i,j)] = f_divs[(i, j - 1)].derivative().shift(1) phi_divs = list() for i in xrange(self.__precision.jacobi_index() + 1) : ## This is the formula in Skoruppas thesis. He uses d/ d tau instead of d / dz which yields ## a factor 4 m phi_divs.append( sum( f_divs[(j, i - j)] * (4 * self.__precision.jacobi_index())**i * binomial(i,j) / 2**i#2**(self.__precision.jacobi_index() - i + 1) * prod(2*(i - l) + 1 for l in xrange(1, i)) / factorial(i + k + j - 1) * factorial(2*self.__precision.jacobi_index() + k - 1) for j in xrange(i + 1) ) ) phi_coeffs = dict() for r in xrange(self.__precision.jacobi_index() + 1) : series = sum( map(operator.mul, self._theta_factors()[r], phi_divs) ) series = self._eta_factor() * series for n in xrange(qexp_prec) : phi_coeffs[(n, r)] = series[n] return phi_coeffs
def rank(self, x): """ EXAMPLES:: sage: c = Combinations([1,2,3]) sage: range(c.cardinality()) == map(c.rank, c) True """ x = [self.mset.index(_) for _ in x] r = 0 n = len(self.mset) for i in range(len(x)): r += binomial(n, i) r += rank(x, n) return r
def cardinality(self): """ EXAMPLES:: sage: IntegerVectors(3,3, min_part=1).cardinality() 1 sage: IntegerVectors(5,3, min_part=1).cardinality() 6 sage: IntegerVectors(13, 4, min_part=2, max_part=4).cardinality() 16 """ if not self._constraints: if self.k < 0: return +infinity if self.n >= 0: return binomial(self.n + self.k - 1, self.n) else: return 0 else: if len( self._constraints ) == 1 and 'max_part' in self._constraints and self._constraints[ 'max_part'] != infinity: m = self._constraints['max_part'] if m >= self.n: return binomial(self.n + self.k - 1, self.n) else: #do by inclusion / exclusion on the number #i of parts greater than m return sum([ (-1)**i * binomial(self.n + self.k - 1 - i * (m + 1), self.k - 1) * binomial(self.k, i) for i in range(self.n // (m + 1) + 1) ]) else: return super(IntegerVectors_nkconstraints, self).cardinality()
def rank(self, x): """ EXAMPLES:: sage: c = Combinations([1,2,3]) sage: list(range(c.cardinality())) == list(map(c.rank, c)) True """ x = [self.mset.index(_) for _ in x] r = 0 n = len(self.mset) for i in range(len(x)): r += binomial(n, i) r += rank(x, n) return r
def s(f,k): """Given f monic of degree n with distinct roots, returns the monic polynomial of degree binomial(n,k) whose roots are all products of k distinct roots of f. """ n = f.degree() x = f.variables()[0] if k==0: return x-1 if k==1: return f c = (-1)**n * f(0) if k==n: return x-c if k>n-k: # use s(f,n-k) g = s(f,n-k) from sage.arith.all import binomial return ((-x)**binomial(n,k) * g(c/x) / c**binomial(n-1,k)).numerator() if k==2: return (star(f,f)//r(f,2)).nth_root(2) if k==3: f2 = s(f,2) return (star(f2,f)*r(f,3) // star(r(f,2),f)).nth_root(3) fkn = fkd = 1 for j in range(1,k+1): g = star(r(f,j), s(f,k-j)) if j%2: fkn *= g else: fkd *= g fk = fkn//fkd assert fk*fkd==fkn return fk.nth_root(k)
def cardinality(self): """ Returns the number of multichoices of k things from a list of n things. EXAMPLES:: sage: MultichooseNK(3,2).cardinality() doctest:...: DeprecationWarning: MultichooseNK should be replaced by itertools.combinations_with_replacement See http://trac.sagemath.org/16473 for details. 6 """ n, k = self._n, self._k return binomial(n + k - 1, k)
def _deflated(cls, self, a, b, z): """ Private helper to return list of deflated terms. EXAMPLES:: sage: x = hypergeometric([5], [4], 3) sage: y = x.deflated() sage: y 7/4*hypergeometric((), (), 3) sage: x.n(); y.n() 35.1496896155784 35.1496896155784 """ new = self.eliminate_parameters() aa = new.operands()[0].operands() bb = new.operands()[1].operands() for i, aaa in enumerate(aa): for j, bbb in enumerate(bb): m = aaa - bbb if m in ZZ and m > 0: aaaa = aa[:i] + aa[i + 1:] bbbb = bb[:j] + bb[j + 1:] terms = [] for k in xrange(m + 1): # TODO: could rewrite prefactors as recurrence term = binomial(m, k) for c in aaaa: term *= rising_factorial(c, k) for c in bbbb: term /= rising_factorial(c, k) term *= z ** k term /= rising_factorial(aaa - m, k) F = hypergeometric([c + k for c in aaaa], [c + k for c in bbbb], z) unique = [] counts = [] for c, f in F._deflated(): if f in unique: counts[unique.index(f)] += c else: unique.append(f) counts.append(c) Fterms = zip(counts, unique) terms += [(term * termG, G) for (termG, G) in Fterms] return terms return ((1, new),)
def cardinality(self): r""" Return the number of shuffles of `l_1` and `l_2`, respectively of lengths `m` and `n`, which is `\binom{m+n}{n}`. TESTS:: sage: from sage.combinat.shuffle import ShuffleProduct sage: ShuffleProduct([3,1,2], [4,2,1,3]).cardinality() 35 sage: ShuffleProduct([3,1,2,5,6,4], [4,2,1,3]).cardinality() == binomial(10,4) True """ ll1 = len(self._l1) ll2 = len(self._l2) return binomial(ll1 + ll2, ll1)
def linial(self, n, K=QQ, names=None): r""" Return the linial hyperplane arrangement. INPUT: - ``n`` -- integer - ``K`` -- field (default: `\QQ`) - ``names`` -- tuple of strings or ``None`` (default); the variable names for the ambient space OUTPUT: The linial hyperplane arrangement is the set of hyperplanes `\{x_i - x_j = 1 : 1\leq i < j \leq n\}`. EXAMPLES:: sage: a = hyperplane_arrangements.linial(4); a Arrangement of 6 hyperplanes of dimension 4 and rank 3 sage: a.characteristic_polynomial() x^4 - 6*x^3 + 15*x^2 - 14*x TESTS:: sage: h = hyperplane_arrangements.linial(5) sage: h.characteristic_polynomial() x^5 - 10*x^4 + 45*x^3 - 100*x^2 + 90*x sage: h.characteristic_polynomial.clear_cache() # long time sage: h.characteristic_polynomial() # long time x^5 - 10*x^4 + 45*x^3 - 100*x^2 + 90*x """ H = make_parent(K, n, names) x = H.gens() hyperplanes = [] for i in range(n): for j in range(i+1, n): hyperplanes.append(x[i] - x[j] - 1) A = H(*hyperplanes) x = polygen(QQ, 'x') charpoly = x * sum(binomial(n, k)*(x - k)**(n - 1) for k in range(n + 1)) / 2**n A.characteristic_polynomial.set_cache(charpoly) return A
def _comb_largest(a,b,x): r""" Returns the largest `w < a` such that `binomial(w,b) <= x`. EXAMPLES:: sage: from sage.combinat.combination import _comb_largest sage: _comb_largest(6,3,10) 5 sage: _comb_largest(6,3,5) 4 """ w = a - 1 while binomial(w,b) > x: w -= 1 return w
def cardinality(self): r""" Return the number of elements in ``self``. The number of signed compositions of `n` is equal to .. MATH:: \sum_{i=1}^{n+1} \binom{n-1}{i-1} 2^i TESTS:: sage: SC4 = SignedCompositions(4) sage: SC4.cardinality() == len(SC4.list()) True sage: SignedCompositions(3).cardinality() 18 """ return sum([binomial(self.n-1, i-1)*2**(i) for i in range(1, self.n+1)])
def generating_series(self, weight = None): r""" Returns a length generating series for the elements of ``self`` EXAMPLES:: sage: W = WeylGroup(["A", 3, 1]) sage: W.pieri_factors().cardinality() 15 sage: W.pieri_factors().generating_series() 4*z^3 + 6*z^2 + 4*z + 1 """ if weight is None: weight = self.default_weight() l_min = len(self._min_support) l_max = len(self._max_support) return sum(binomial(l_max-l_min, l-l_min) * weight(l) for l in range(self._min_length, self._max_length+1))
def zero_eigenvectors(self, tg, flags): rows = set() for p in Tuples([0, 1], binomial(tg.n, 2)): edges = [] c = 0 for i in range(1, tg.n + 1): for j in range(1, i): if p[c] == 1: edges.append((j, i)) c += 1 graphs = self._induced_flags(flags[0].n, tg, edges) row = [0 for f in flags] for pair in graphs: g, den = pair for i in range(len(flags)): if g.is_labelled_isomorphic(flags[i]): row[i] = den break rows.add(tuple(row)) return matrix_of_independent_rows(self._field, list(rows), len(flags))
def unrank(self, r): """ Return the subset which has rank ``r``. EXAMPLES:: sage: from sage.combinat.subset import SubsetsSorted sage: S = SubsetsSorted(range(3)) sage: S.unrank(4) (0, 1) """ r = Integer(r) if r >= self.cardinality() or r < 0: raise IndexError("index out of range") k = ZZ_0 n = self._s.cardinality() binom = ZZ.one() while r >= binom: r -= binom k += 1 binom = binomial(n,k) C = combination.from_rank(r, n, k) return self.element_class(sorted([self._s.unrank(i) for i in C]))
def cardinality(self): """ EXAMPLES:: sage: Subsets(Set([1,2,3]), 2).cardinality() 3 sage: Subsets([1,2,3,3], 2).cardinality() 3 sage: Subsets([1,2,3], 1).cardinality() 3 sage: Subsets([1,2,3], 3).cardinality() 1 sage: Subsets([1,2,3], 0).cardinality() 1 sage: Subsets([1,2,3], 4).cardinality() 0 sage: Subsets(3,2).cardinality() 3 sage: Subsets(3,4).cardinality() 0 """ if self._k > self._s.cardinality(): return ZZ_0 return binomial(self._s.cardinality(), self._k)
def saturation(A, proof=True, p=0, max_dets=5): """ Compute a saturation matrix of A. INPUT: - A -- a matrix over ZZ - proof -- bool (default: True) - p -- int (default: 0); if not 0 only guarantees that output is p-saturated - max_dets -- int (default: 4) max number of dets of submatrices to compute. OUTPUT: matrix -- saturation of the matrix A. EXAMPLES:: sage: from sage.matrix.matrix_integer_dense_saturation import saturation sage: A = matrix(ZZ, 2, 2, [3,2,3,4]); B = matrix(ZZ, 2,3,[1,2,3,4,5,6]); C = A*B sage: C [11 16 21] [19 26 33] sage: C.index_in_saturation() 18 sage: S = saturation(C); S [11 16 21] [-2 -3 -4] sage: S.index_in_saturation() 1 sage: saturation(C, proof=False) [11 16 21] [-2 -3 -4] sage: saturation(C, p=2) [11 16 21] [-2 -3 -4] sage: saturation(C, p=2, max_dets=1) [11 16 21] [-2 -3 -4] """ # Find a submatrix of full rank and instead saturate that matrix. r = A.rank() if A.is_square() and r == A.nrows(): return identity_matrix(ZZ, r) if A.nrows() > r: P = [] while len(P) < r: P = matrix_integer_dense_hnf.probable_pivot_rows(A) A = A.matrix_from_rows(P) # Factor out all common factors from all rows, just in case. A = copy(A) A._factor_out_common_factors_from_each_row() if A.nrows() <= 1: return A A, zero_cols = A._delete_zero_columns() if max_dets > 0: # Take the GCD of at most num_dets randomly chosen determinants. nr = A.nrows(); nc = A.ncols() d = 0 trials = min(binomial(nc, nr), max_dets) already_tried = [] while len(already_tried) < trials: v = random_sublist_of_size(nc, nr) tm = verbose('saturation -- checking det condition on submatrix') d = gcd(d, A.matrix_from_columns(v).determinant(proof=proof)) verbose('saturation -- got det down to %s'%d, tm) if gcd(d, p) == 1: return A._insert_zero_columns(zero_cols) already_tried.append(v) if gcd(d, p) == 1: # already p-saturated return A._insert_zero_columns(zero_cols) # Factor and p-saturate at each p. # This is not a good algorithm, because all the HNF's in it are really slow! # #tm = verbose('factoring gcd %s of determinants'%d) #limit = 2**31-1 #F = d.factor(limit = limit) #D = [p for p, e in F if p <= limit] #B = [n for n, e in F if n > limit] # all big factors -- there will only be at most one #assert len(B) <= 1 #C = B[0] #for p in D: # A = p_saturation(A, p=p, proof=proof) # This is a really simple but powerful algorithm. # FACT: If A is a matrix of full rank, then hnf(transpose(A))^(-1)*A is a saturation of A. # To make this practical we use solve_system_with_difficult_last_row, since the # last column of HNF's are typically the only really big ones. B = A.transpose().hermite_form(include_zero_rows=False, proof=proof) B = B.transpose() # Now compute B^(-1) * A C = solve_system_with_difficult_last_row(B, A) return C.change_ring(ZZ)._insert_zero_columns(zero_cols)