Rankers - Combinatorics

Skip to content
Back to top
View this page
Edit this page

# Rankers

sage.combinat.ranker.from_list(l)

  Return a ranker from the list l.

  INPUT:

  - `l` – list

  OUTPUT: `[rank, unrank]` – functions

  EXAMPLES:

  Sage

      sage: import sage.combinat.ranker as ranker
      sage: l = [1,2,3]
      sage: r,u = ranker.from_list(l)
      sage: r(1)
      0
      sage: r(3)
      2
      sage: u(2)
      3
      sage: u(0)
      1

  Python

      >>> from sage.all import *
      >>> import sage.combinat.ranker as ranker
      >>> l = [Integer(1),Integer(2),Integer(3)]
      >>> r,u = ranker.from_list(l)
      >>> r(Integer(1))
      0
      >>> r(Integer(3))
      2
      >>> u(Integer(2))
      3
      >>> u(Integer(0))
      1

sage.combinat.ranker.on_fly()

  Return a pair of enumeration functions rank / unrank.

  rank assigns on the fly an integer, starting from 0, to any object passed as argument. The object should be hashable. unrank is the inverse function; it returns None for indices that have not yet been assigned.

  EXAMPLES:

  Sage

      sage: [rank, unrank] = sage.combinat.ranker.on_fly()
      sage: rank('a')
      0
      sage: rank('b')
      1
      sage: rank('c')
      2
      sage: rank('a')
      0
      sage: unrank(2)
      'c'
      sage: unrank(3)
      sage: rank('d')
      3
      sage: unrank(3)
      'd'

  Python

      >>> from sage.all import *
      >>> [rank, unrank] = sage.combinat.ranker.on_fly()
      >>> rank('a')
      0
      >>> rank('b')
      1
      >>> rank('c')
      2
      >>> rank('a')
      0
      >>> unrank(Integer(2))
      'c'
      >>> unrank(Integer(3))
      >>> rank('d')
      3
      >>> unrank(Integer(3))
      'd'

  Todo

  add tests as in combinat::rankers

sage.combinat.ranker.rank_from_list(l)

  Return a rank function for the elements of `l`.

  INPUT:

  - `l` – a duplicate free list (or iterable) of hashable objects

  OUTPUT:

  - a function from the elements of `l` to `0,...,len(l)`

  EXAMPLES:

  Sage

      sage: import sage.combinat.ranker as ranker
      sage: l = ['a', 'b', 'c']
      sage: r = ranker.rank_from_list(l)
      sage: r('a')
      0
      sage: r('c')
      2

  Python

      >>> from sage.all import *
      >>> import sage.combinat.ranker as ranker
      >>> l = ['a', 'b', 'c']
      >>> r = ranker.rank_from_list(l)
      >>> r('a')
      0
      >>> r('c')
      2

  For non elements a `ValueError` is raised, as with the usual `index` method of lists:

  Sage

      sage: r('blah')
      Traceback (most recent call last):
      ...
      ValueError: 'blah' is not in dict

  [Python]

      >>> from sage.all import *
      >>> r('blah')
      Traceback (most recent call last):
      ...
      ValueError: 'blah' is not in dict

  Currently, the rank function is a `CallableDict`; but this is an implementation detail:

  Sage

      sage: type(r)
      <class 'sage.misc.callable_dict.CallableDict'>
      sage: r
      {'a': 0, 'b': 1, 'c': 2}

  Python

      >>> from sage.all import *
      >>> type(r)
      <class 'sage.misc.callable_dict.CallableDict'>
      >>> r
      {'a': 0, 'b': 1, 'c': 2}

  With the current implementation, no error is issued in case of duplicate value in `l`. Instead, the rank function returns the position of some of the duplicates:

  Sage

      sage: r = ranker.rank_from_list(['a', 'b', 'a', 'c'])
      sage: r('a')
      2

  [Python]

      >>> from sage.all import *
      >>> r = ranker.rank_from_list(['a', 'b', 'a', 'c'])
      >>> r('a')
      2

  Constructing the rank function itself is of complexity `O(len(l))`. Then, each call to the rank function consists of an essentially constant time dictionary lookup.

sage.combinat.ranker.unrank(L, i)

  Return the \(i\)-th element of \(L\).

  INPUT:

  - `L` – list, tuple, finite enumerated set, etc.

  - `i` – integer

  The purpose of this utility is to give a uniform idiom to recover the \(i\)-th element of an object `L`, whether `L` is a list, tuple (or more generally a `collections.abc.Sequence`), an enumerated set, some old parent of Sage still implementing unranking in the method `__getitem__`, or an iterable (see `collections.abc.Iterable`). See Issue #15919.

  EXAMPLES:

  Lists, tuples, and other `sequences`:

  Sage

      sage: from sage.combinat.ranker import unrank
      sage: unrank(['a','b','c'], 2)
      'c'
      sage: unrank(('a','b','c'), 1)
      'b'
      sage: unrank(range(3,13,2), 1)
      5

  Python

      >>> from sage.all import *
      >>> from sage.combinat.ranker import unrank
      >>> unrank(['a','b','c'], Integer(2))
      'c'
      >>> unrank(('a','b','c'), Integer(1))
      'b'
      >>> unrank(range(Integer(3),Integer(13),Integer(2)), Integer(1))
      5

  Enumerated sets:

  Sage

      sage: unrank(GF(7), 2)
      2
      sage: unrank(IntegerModRing(29), 10)
      10

  [Python]

      >>> from sage.all import *
      >>> unrank(GF(Integer(7)), Integer(2))
      2
      >>> unrank(IntegerModRing(Integer(29)), Integer(10))
      10

  An iterable:

  Sage

      sage: unrank(NN,4)
      4

  Python

      >>> from sage.all import *
      >>> unrank(NN,Integer(4))
      4

  An iterator:

  Sage

      sage: unrank(('a{}'.format(i) for i in range(20)), 0)
      'a0'
      sage: unrank(('a{}'.format(i) for i in range(20)), 2)
      'a2'

  [Python]

      >>> from sage.all import *
      >>> unrank(('a{}'.format(i) for i in range(Integer(20))), Integer(0))
      'a0'
      >>> unrank(('a{}'.format(i) for i in range(Integer(20))), Integer(2))
      'a2'

  Warning

  When unranking an iterator, it returns the `i`-th element beyond where it is currently at:

  Sage

      sage: from sage.combinat.ranker import unrank
      sage: it = iter(range(20))
      sage: unrank(it, 2)
      2
      sage: unrank(it, 2)
      5

  Python

      >>> from sage.all import *
      >>> from sage.combinat.ranker import unrank
      >>> it = iter(range(Integer(20)))
      >>> unrank(it, Integer(2))
      2
      >>> unrank(it, Integer(2))
      5

sage.combinat.ranker.unrank_from_list(l)

  Return an unrank function from a list.

  EXAMPLES:

  Sage

      sage: import sage.combinat.ranker as ranker
      sage: l = [1,2,3]
      sage: u = ranker.unrank_from_list(l)
      sage: u(2)
      3
      sage: u(0)
      1

  Python

      >>> from sage.all import *
      >>> import sage.combinat.ranker as ranker
      >>> l = [Integer(1),Integer(2),Integer(3)]
      >>> u = ranker.unrank_from_list(l)
      >>> u(Integer(2))
      3
      >>> u(Integer(0))
      1