Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
r""" Miscellaneous """ #***************************************************************************** # Copyright (C) 2007 Mike Hansen <mhansen@gmail.com>, # # Distributed under the terms of the GNU General Public License (GPL) # # This code is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # The full text of the GPL is available at: # # http://www.gnu.org/licenses/ #***************************************************************************** from __future__ import print_function
from six.moves import range from sage.misc.all import prod
class DoublyLinkedList(): """ A doubly linked list class that provides constant time hiding and unhiding of entries.
Note that this list's indexing is 1-based.
EXAMPLES::
sage: dll = sage.combinat.misc.DoublyLinkedList([1,2,3]); dll Doubly linked list of [1, 2, 3]: [1, 2, 3] sage: dll.hide(1); dll Doubly linked list of [1, 2, 3]: [2, 3] sage: dll.unhide(1); dll Doubly linked list of [1, 2, 3]: [1, 2, 3] sage: dll.hide(2); dll Doubly linked list of [1, 2, 3]: [1, 3] sage: dll.unhide(2); dll Doubly linked list of [1, 2, 3]: [1, 2, 3] """ def __init__(self, l): """ TESTS::
sage: dll = sage.combinat.misc.DoublyLinkedList([1,2,3]) sage: dll == loads(dumps(dll)) True """
def __eq__(self, other): """ TESTS::
sage: dll = sage.combinat.misc.DoublyLinkedList([1,2,3]) sage: dll2 = sage.combinat.misc.DoublyLinkedList([1,2,3]) sage: dll == dll2 True sage: dll.hide(1) sage: dll == dll2 False """ self.l == other.l and self.next_value == other.next_value and self.prev_value == other.prev_value)
def __ne__(self, other): """ TESTS::
sage: dll = sage.combinat.misc.DoublyLinkedList([1,2,3]) sage: dll2 = sage.combinat.misc.DoublyLinkedList([1,2,3]) sage: dll != dll2 False sage: dll.hide(1) sage: dll != dll2 True """
def __repr__(self): """ TESTS::
sage: repr(sage.combinat.misc.DoublyLinkedList([1,2,3])) 'Doubly linked list of [1, 2, 3]: [1, 2, 3]' """
def __iter__(self): """ TESTS::
sage: dll = sage.combinat.misc.DoublyLinkedList([1,2,3]) sage: list(dll) [1, 2, 3] """
def hide(self, i): """ TESTS::
sage: dll = sage.combinat.misc.DoublyLinkedList([1,2,3]) sage: dll.hide(1) sage: list(dll) [2, 3] """
def unhide(self,i): """ TESTS::
sage: dll = sage.combinat.misc.DoublyLinkedList([1,2,3]) sage: dll.hide(1); dll.unhide(1) sage: list(dll) [1, 2, 3] """
def head(self): """ TESTS::
sage: dll = sage.combinat.misc.DoublyLinkedList([1,2,3]) sage: dll.head() 1 sage: dll.hide(1) sage: dll.head() 2 """
def next(self, j): """ TESTS::
sage: dll = sage.combinat.misc.DoublyLinkedList([1,2,3]) sage: dll.next(1) 2 sage: dll.hide(2) sage: dll.next(1) 3 """
def prev(self, j): """ TESTS::
sage: dll = sage.combinat.misc.DoublyLinkedList([1,2,3]) sage: dll.prev(3) 2 sage: dll.hide(2) sage: dll.prev(3) 1 """
def _monomial_exponent_to_lower_factorial(me, x): r""" Converts a tuple of exponents to the monomial obtained by replacing each me[i] with `x_i*(x_i - 1)*\cdots*(x_i - a_i + 1)`
EXAMPLES::
sage: from sage.combinat.misc import _monomial_exponent_to_lower_factorial sage: R.<x,y,z> = QQ[] sage: a = R.gens() sage: _monomial_exponent_to_lower_factorial(([1,0,0]),a) x sage: _monomial_exponent_to_lower_factorial(([2,0,0]),a) x^2 - x sage: _monomial_exponent_to_lower_factorial(([0,2,0]),a) y^2 - y sage: _monomial_exponent_to_lower_factorial(([1,1,0]),a) x*y sage: _monomial_exponent_to_lower_factorial(([1,1,2]),a) x*y*z^2 - x*y*z sage: _monomial_exponent_to_lower_factorial(([2,2,2]),a) x^2*y^2*z^2 - x^2*y^2*z - x^2*y*z^2 - x*y^2*z^2 + x^2*y*z + x*y^2*z + x*y*z^2 - x*y*z """
def umbral_operation(poly): r""" Returns the umbral operation `\downarrow` applied to poly.
The umbral operation replaces each instance of `x_i^{a_i}` with `x_i*(x_i - 1)*\cdots*(x_i - a_i + 1)`.
EXAMPLES::
sage: P = PolynomialRing(QQ, 2, 'x') sage: x = P.gens() sage: from sage.combinat.misc import umbral_operation sage: umbral_operation(x[0]^3) == x[0]*(x[0]-1)*(x[0]-2) True sage: umbral_operation(x[0]*x[1]) x0*x1 sage: umbral_operation(x[0]+x[1]) x0 + x1 sage: umbral_operation(x[0]^2*x[1]^2) == x[0]*(x[0]-1)*x[1]*(x[1]-1) True """
class IterableFunctionCall: """ This class wraps functions with a yield statement (generators) by an object that can be iterated over. For example,
EXAMPLES::
sage: def f(): yield 'a'; yield 'b'
This does not work::
sage: for z in f: print(z) Traceback (most recent call last): ... TypeError: 'function' object is not iterable
Use IterableFunctionCall if you want something like the above to work::
sage: from sage.combinat.misc import IterableFunctionCall sage: g = IterableFunctionCall(f) sage: for z in g: print(z) a b
If your function takes arguments, just put them after the function name. You needn't enclose them in a tuple or anything, just put them there::
sage: def f(n, m): yield 'a' * n; yield 'b' * m; yield 'foo' sage: g = IterableFunctionCall(f, 2, 3) sage: for z in g: print(z) aa bbb foo """ def __init__(self, f, *args, **kwargs): """ EXAMPLES::
sage: from sage.combinat.misc import IterableFunctionCall sage: IterableFunctionCall(iter, [1,2,3]) Iterable function call <built-in function iter> with args=([1, 2, 3],) and kwargs={} """
def __iter__(self): """ EXAMPLES::
sage: from sage.combinat.misc import IterableFunctionCall sage: list(iter(IterableFunctionCall(iter, [1,2,3]))) [1, 2, 3] """
def __repr__(self): """ EXAMPLES::
sage: from sage.combinat.misc import IterableFunctionCall sage: repr(IterableFunctionCall(iter, [1,2,3])) 'Iterable function call <built-in function iter> with args=([1, 2, 3],) and kwargs={}' """
def check_integer_list_constraints(l, **kwargs): """ EXAMPLES::
sage: from sage.combinat.misc import check_integer_list_constraints sage: cilc = check_integer_list_constraints sage: l = [[2,1,3],[1,2],[3,3],[4,1,1]] sage: cilc(l, min_part=2) [[3, 3]] sage: cilc(l, max_part=2) [[1, 2]] sage: cilc(l, length=2) [[1, 2], [3, 3]] sage: cilc(l, max_length=2) [[1, 2], [3, 3]] sage: cilc(l, min_length=3) [[2, 1, 3], [4, 1, 1]] sage: cilc(l, max_slope=0) [[3, 3], [4, 1, 1]] sage: cilc(l, min_slope=1) [[1, 2]] sage: cilc(l, outer=[2,2]) [[1, 2]] sage: cilc(l, inner=[2,2]) [[3, 3]]
::
sage: cilc([1,2,3], length=3, singleton=True) [1, 2, 3] sage: cilc([1,2,3], length=2, singleton=True) is None True """ else: else: return []
# Preprocess the constraints outer[i] = n+1
else:
|