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 xrange(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.rings.arith 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 xrange(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 = 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.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 len(self.list())
def parameters(self, t=None): """ Returns `(t,v,k,lambda)`. Does not check if the input is a block design. INPUT: - ``t`` -- `t` such that the design is a `t`-design. EXAMPLES:: sage: from sage.combinat.designs.block_design import BlockDesign 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]], name="FanoPlane") sage: BD.parameters(t=2) (2, 7, 3, 1) sage: BD.parameters(t=3) (3, 7, 3, 0) """ if t is None: from sage.misc.superseded import deprecation deprecation( 15664, "the 't' argument will become mandatory soon. 2" + " is used when none is provided.") t = 2 v = len(self.points()) blks = self.blocks() k = len(blks[int(0)]) b = len(blks) #A = self.incidence_matrix() #r = sum(A.rows()[0]) lmbda = int(b / (binomial(v, t) / binomial(k, t))) return (t, v, k, lmbda)
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.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 len(self.list())
def parameters(self, t=None): """ Returns `(t,v,k,lambda)`. Does not check if the input is a block design. INPUT: - ``t`` -- `t` such that the design is a `t`-design. EXAMPLES:: sage: from sage.combinat.designs.block_design import BlockDesign 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]], name="FanoPlane") sage: BD.parameters(t=2) (2, 7, 3, 1) sage: BD.parameters(t=3) (3, 7, 3, 0) """ if t is None: from sage.misc.superseded import deprecation deprecation(15664, "the 't' argument will become mandatory soon. 2"+ " is used when none is provided.") t = 2 v = len(self.points()) blks = self.blocks() k = len(blks[int(0)]) b = len(blks) #A = self.incidence_matrix() #r = sum(A.rows()[0]) lmbda = int(b/(binomial(v, t)/binomial(k, t))) return (t, v, k, lmbda)
def _basic_integral(self, a, j, twist=None): r""" Computes the integral .. MATH:: \int_{a+p\ZZ_p}(z-\omega(a))^jd\mu_\chi. If ``twist`` is ``None``, `\\chi` is the trivial character. Otherwise, ``twist`` can be a primitive quadratic character of conductor prime to `p`. """ #is this the negative of what we want? #if Phis is fixed for this p-adic L-function, we should make this method cached p = self._Phis.parent().prime() if twist is None: pass elif twist in ZZ: twist = kronecker_character(twist) if twist.is_trivial(): twist = None else: D = twist.level() assert(D.gcd(p) == 1) else: if twist.is_trivial(): twist = None else: assert((twist**2).is_trivial()) twist = twist.primitive_character() D = twist.level() assert(D.gcd(p) == 1) onDa = self._on_Da(a, twist)#self._Phis(Da) aminusat = a - self._Phis.parent().base_ring().base_ring().teichmuller(a) #aminusat = a - self._coefficient_ring.base_ring().teichmuller(a) try: ap = self._ap except AttributeError: self._ap = self._Phis.Tq_eigenvalue(p) #catch exception if not eigensymbol ap = self._ap if not twist is None: ap *= twist(p) if j == 0: return (~ap) * onDa.moment(0) if a == 1: #aminusat is 0, so only the j=r term is non-zero return (~ap) * (p ** j) * onDa.moment(j) #print "j =", j, "a = ", a ans = onDa.moment(0) * (aminusat ** j) #ans = onDa.moment(0) #print "\tr =", 0, " ans =", ans for r in range(1, j+1): if r == j: ans += binomial(j, r) * (p ** r) * onDa.moment(r) else: ans += binomial(j, r) * (aminusat ** (j - r)) * (p ** r) * onDa.moment(r) #print "\tr =", r, " ans =", ans #print " " return (~ap) * ans
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 from_rank(r, n, k): """ 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: http://en.wikipedia.org/wiki/Combinadic EXAMPLES:: sage: import sage.combinat.choose_nk as choose_nk sage: choose_nk.from_rank(0,3,0) () sage: choose_nk.from_rank(0,3,1) (0,) sage: choose_nk.from_rank(1,3,1) (1,) sage: choose_nk.from_rank(2,3,1) (2,) sage: choose_nk.from_rank(0,3,2) (0, 1) sage: choose_nk.from_rank(1,3,2) (0, 2) sage: choose_nk.from_rank(2,3,2) (1, 2) sage: choose_nk.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 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 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 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 __getitem__(self, key): """ EXAMPLES:: sage: a, b, c, q, z = var('a b c q z') sage: bhs = BasicHypergeometricSeries([a, b], [c], q, z) sage: for i in range(4): print bhs[i] 1 (b - 1)*(a - 1)*z/((q - 1)*(c - 1)) (b - 1)*(a - 1)*(b*q - 1)*(a*q - 1)*z^2/((q - 1)*(c - 1)*(q^2 - 1)*(c*q - 1)) (b - 1)*(a - 1)*(b*q - 1)*(a*q - 1)*(b*q^2 - 1)*(a*q^2 - 1)*z^3/((q - 1)*(c - 1)*(q^2 - 1)*(c*q - 1)*(q^3 - 1)*(c*q^2 - 1)) """ if key >= 0: j, k = len(self.list_a), len(self.list_b) nominator = qPochhammerSymbol(self.list_a, self.q, key).evaluate() if nominator == 0: return 0 denominator = ( qPochhammerSymbol(self.list_b, self.q, key).evaluate() * qPochhammerSymbol(self.q, self.q, key).evaluate() ) return nominator / denominator * ((-1) ** key * self.q ** (binomial(key, 2))) ** (1 + k - j) * self.z ** key else: return 0
def loggam_binom(p,gam,z,n,M): r""" Returns the list of coefficients in the power series expansion (up to precision `M`) of `{\log_p(z)/\log_p(\gamma) \choose n}` INPUT: - ``p`` -- prime - ``gam`` -- topological generator e.g., `1+p` - ``z`` -- variable - ``n`` -- nonnegative integer - ``M`` -- precision OUTPUT: The list of coefficients in the power series expansion of `{\log_p(z)/\log_p(\gamma) \choose n}` EXAMPLES: sage: R.<z> = QQ['z'] sage: loggam_binom(5,1+5,z,2,4) [0, -3/205, 651/84050, -223/42025] sage: loggam_binom(5,1+5,z,3,4) [0, 2/205, -223/42025, 95228/25845375] """ L = logp(p,z,M) logpgam = L.substitute(z = (gam-1)) #log base p of gamma loggam = L/logpgam #log base gamma return z.parent()(binomial(loggam,n)).truncate(M).list()
def rank(self, sub): """ Returns 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]) == None True """ subset = Set(sub) lset = __builtin__.list(self.s) lsubset = __builtin__.list(subset) try: index_list = sorted(map(lambda x: lset.index(x), lsubset)) except ValueError: return None n = len(self.s) r = 0 for i in range(len(index_list)): r += binomial(n,i) return r + choose_nk.rank(index_list,n)
def rank(self, sub): """ Returns 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 xrange(len(index_list))) return r + choose_nk.rank(index_list, n)
def log_gamma_binomial(p,gamma,z,n,M): r""" Returns the list of coefficients in the power series expansion (up to precision `M`) of `{\log_p(z)/\log_p(\gamma) \choose 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 `{\log_p(z)/\log_p(\gamma) \choose 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 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 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 basic_integral(Phi,a,j,ap,D): """ Returns `\int_{a+pZ_p} (z-{a})^j d\Phi(0-infty)` -- see formula [Pollack-Stevens, sec 9.2] INPUT: - ``Phi`` -- overconvergnt `U_p`-eigensymbol - ``a`` -- integer in [0..p-1] - ``j`` -- positive integer - ``ap`` -- Hecke eigenvalue? - ``D`` -- conductor of the quadratic twist `\chi` OUTPUT: `\int_{a+pZ_p} (z-{a})^j d\Phi(0-\infty)` EXAMPLES: """ M = Phi.num_moments() p = Phi.p() ap = ap*kronecker(D,p) ans = 0 for r in range(j+1): ans = ans+binomial(j,r)*((a-teich(a,p,M))**(j-r))*(p**r)*phi_on_Da(Phi,a,D).moment(r) return ans/ap
def rank(self, sub): """ Returns 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]) is None True """ subset = Set(sub) lset = __builtin__.list(self.s) lsubset = __builtin__.list(subset) try: index_list = sorted(map(lambda x: lset.index(x), lsubset)) except ValueError: return None n = len(self.s) r = 0 for i in range(len(index_list)): r += binomial(n, i) return r + choose_nk.rank(index_list, n)
def unrank(self, r): """ Returns 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 choose_nk.from_rank(r, n, k)])
def rank(self, sub): """ Returns 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 xrange(len(index_list))) return r + choose_nk.rank(index_list,n)
def Krawtchouk(n,q,l,i): """ Compute ``K^{n,q}_l(i)``, the Krawtchouk polynomial: see :wikipedia:`Kravchuk_polynomials`. It is given by .. math:: K^{n,q}_l(i)=\sum_{j=0}^l (-1)^j(q-1)^{(l-j)}{i \choose j}{n-i \choose l-j} EXAMPLES:: sage: Krawtchouk(24,2,5,4) 2224 sage: Krawtchouk(12300,4,5,6) 567785569973042442072 """ from sage.rings.arith import binomial # Use the expression in equation (55) of MacWilliams & Sloane, pg 151 # We write jth term = some_factor * (j-1)th term kraw = jth_term = (q-1)**l * binomial(n, l) # j=0 for j in range(1,l+1): jth_term *= -q*(l-j+1)*(i-j+1)/((q-1)*j*(n-j+1)) kraw += jth_term return kraw
def unrank(self, r): """ Returns 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 choose_nk.from_rank(r, n, k)])
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 not in range(len(self.s) + 1): return 0 else: return binomial(len(self.s), self.k)
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 not in range(len(self.s)+1): return 0 else: return binomial(len(self.s),self.k)
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 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, 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 rank(comb, n): """ Returns the rank of comb in the subsets of range(n) of size k. The algorithm used is based on combinadics and James McCaffrey's MSDN article. See: http://en.wikipedia.org/wiki/Combinadic EXAMPLES:: sage: import sage.combinat.choose_nk as choose_nk sage: choose_nk.rank([], 3) 0 sage: choose_nk.rank([0], 3) 0 sage: choose_nk.rank([1], 3) 1 sage: choose_nk.rank([2], 3) 2 sage: choose_nk.rank([0,1], 3) 0 sage: choose_nk.rank([0,2], 3) 1 sage: choose_nk.rank([1,2], 3) 2 sage: choose_nk.rank([0,1,2], 3) 0 """ k = len(comb) if k > n: raise ValueError, "len(comb) must be <= n" #Generate the combinadic from the #combination w = [0]*k for i in range(k): w[i] = (n-1) - comb[i] #Calculate the integer that is the dual of #the lexicographic index of the combination r = k t = 0 for i in range(k): t += binomial(w[i],r) r -= 1 return binomial(n,k)-t-1
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 rank(comb, n): """ Returns the rank of comb in the subsets of range(n) of size k. The algorithm used is based on combinadics and James McCaffrey's MSDN article. See: http://en.wikipedia.org/wiki/Combinadic EXAMPLES:: sage: import sage.combinat.choose_nk as choose_nk sage: choose_nk.rank([], 3) 0 sage: choose_nk.rank([0], 3) 0 sage: choose_nk.rank([1], 3) 1 sage: choose_nk.rank([2], 3) 2 sage: choose_nk.rank([0,1], 3) 0 sage: choose_nk.rank([0,2], 3) 1 sage: choose_nk.rank([1,2], 3) 2 sage: choose_nk.rank([0,1,2], 3) 0 """ k = len(comb) if k > n: raise ValueError, "len(comb) must be <= n" #Generate the combinadic from the #combination w = [0] * k for i in range(k): w[i] = (n - 1) - comb[i] #Calculate the integer that is the dual of #the lexicographic index of the combination r = k t = 0 for i in range(k): t += binomial(w[i], r) r -= 1 return binomial(n, k) - t - 1
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 map(lambda i: self.mset[i], from_rank(r, n, k))
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 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 = designs.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): 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 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 specialize(self): """specializes to weight k -- i.e. projects to Sym^k""" k=self.weight if k==0: # R.<X,Y>=PolynomialRing(QQ,2) R = PolynomialRing(QQ,('X','Y')) X,Y = R.gens() P=0 for j in range(0,k+1): P=P+binomial(k,j)*((-1)**j)*self.moment(j)*(X**j)*(Y**(k-j)) return symk(k,P)
def dcoeff(l,m,N): """Returns the 'D' coefficient for partitions l, m having exactly N parts. See \cite{Fulton:Intersection_Theory}""" # make padded copies of l, m l1 = copy(l) m1 = copy(m) l1.extend([0]*(N-len(l))) m1.extend([0]*(N-len(m))) # for the defining matrix M = Matrix( [ [ binomial(l1[i]+N-(i+1), m1[j]+N-(j+1)) for j in range(N) ] for i in range(N) ]) return det(M)
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): """ Returns the number of choices of set partitions of range(n) into a set of size k and a set of size n-k. EXAMPLES:: sage: from sage.combinat.split_nk import SplitNK sage: SplitNK(5,2).cardinality() 10 """ return binomial(self._n,self._k)
def parameters(self, t=2): """ Returns (t,v,k,lambda). Does not check if the input is a block design. Uses t=2 by default. EXAMPLES:: sage: from sage.combinat.designs.block_design import BlockDesign 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]], name="FanoPlane") sage: BD.parameters() (2, 7, 3, 1) sage: BD.parameters(t=3) (3, 7, 3, 0) """ v = len(self.points()) blks = self.blocks() k = len(blks[int(0)]) b = len(blks) #A = self.incidence_matrix() #r = sum(A.rows()[0]) lmbda = int(b/(binomial(v,t)/binomial(k,t))) return (t,v,k,lmbda)
def specialize(self): """specializes to weight k -- i.e. projects to Sym^k -- NO CHARACTER HERE!!""" assert 0==1, "didn't program character here yet" k=self.weight if k==0: return symk(0,self.moments[0]) else: # R.<X,Y>=PolynomialRing(QQ,2) R = PolynomialRing(QQ,('X','Y')) P=0 for j in range(0,k+1): P=P+binomial(k,j)*((-1)**j)*self.moments[j]*(X**j)*(Y**(k-j)) return symk(k,P)
def cardinality(self): """ Returns the number of choices of k things from a list of n things. EXAMPLES:: sage: from sage.combinat.choose_nk import ChooseNK sage: ChooseNK(3,2).cardinality() 3 sage: ChooseNK(5,2).cardinality() 10 """ return binomial(self._n, self._k)
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 _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 _comb_largest(a, b, x): """ Returns the largest w < a such that binomial(w,b) <= x. EXAMPLES:: sage: from sage.combinat.choose_nk 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 _check_pbd(B, v, S): r""" Checks that ``B`` is a PBD on `v` points with given block sizes. INPUT: - ``bibd`` -- a list of blocks - ``v`` (integer) -- number of points - ``S`` -- list of integers EXAMPLE:: sage: designs.BalancedIncompleteBlockDesign(40,4).blocks() # indirect doctest [[0, 1, 2, 12], [0, 3, 6, 9], [0, 4, 8, 11], [0, 5, 7, 10], [0, 13, 26, 39], [0, 14, 28, 38], [0, 15, 25, 27], [0, 16, 32, 35], [0, 17, 34, 37], [0, 18, 33, 36], ... """ from itertools import combinations from sage.graphs.graph import Graph if not all(len(X) in S for X in B): raise RuntimeError( "This is not a nice honest PBD from the good old days !") g = Graph() m = 0 for X in B: g.add_edges(list(combinations(X, 2))) if g.size() != m + binomial(len(X), 2): raise RuntimeError( "This is not a nice honest PBD from the good old days !") m = g.size() if not (g.is_clique() and g.vertices() == range(v)): raise RuntimeError( "This is not a nice honest PBD from the good old days !") return B