Integer Range¶
AUTHORS:
Nicolas Borie (2010-03): First release.
Florent Hivert (2010-03): Added a class factory + cardinality method.
Vincent Delecroix (2012-02): add methods rank/unrank, make it compliant with Python int.
- class sage.sets.integer_range.IntegerRange[source]¶
Bases:
UniqueRepresentation
,Parent
The class of
Integer
ranges.Returns an enumerated set containing an arithmetic progression of integers.
INPUT:
begin
– integer, Infinity or -Infinityend
– integer, Infinity or -Infinitystep
– a nonzero integer (default: 1)middle_point
– integer inside the set (default:None
)
OUTPUT:
A parent in the category
FiniteEnumeratedSets()
orInfiniteEnumeratedSets()
depending on the arguments definingself
.IntegerRange(i, j)
returns the set of \(\{i, i+1, i+2, \dots , j-1\}\).start
(!) defaults to 0. Whenstep
is given, it specifies the increment. The default increment is \(1\). IntegerRange allowsbegin
andend
to be infinite.IntegerRange
is designed to have similar interface Python range. However, whereasrange
accept and returns Pythonint
,IntegerRange
deals withInteger
.If
middle_point
is given, then the elements are generated starting from it, in a alternating way: \(\{m, m+1, m-2, m+2, m-2 \dots \}\).EXAMPLES:
sage: list(IntegerRange(5)) [0, 1, 2, 3, 4] sage: list(IntegerRange(2,5)) [2, 3, 4] sage: I = IntegerRange(2,100,5); I {2, 7, ..., 97} sage: list(I) [2, 7, 12, 17, 22, 27, 32, 37, 42, 47, 52, 57, 62, 67, 72, 77, 82, 87, 92, 97] sage: I.category() Category of facade finite enumerated sets sage: I[1].parent() Integer Ring
>>> from sage.all import * >>> list(IntegerRange(Integer(5))) [0, 1, 2, 3, 4] >>> list(IntegerRange(Integer(2),Integer(5))) [2, 3, 4] >>> I = IntegerRange(Integer(2),Integer(100),Integer(5)); I {2, 7, ..., 97} >>> list(I) [2, 7, 12, 17, 22, 27, 32, 37, 42, 47, 52, 57, 62, 67, 72, 77, 82, 87, 92, 97] >>> I.category() Category of facade finite enumerated sets >>> I[Integer(1)].parent() Integer Ring
When
begin
andend
are both finite,IntegerRange(begin, end, step)
is the set whose list of elements is equivalent to the python constructionrange(begin, end, step)
:sage: list(IntegerRange(4,105,3)) == list(range(4,105,3)) True sage: list(IntegerRange(-54,13,12)) == list(range(-54,13,12)) True
>>> from sage.all import * >>> list(IntegerRange(Integer(4),Integer(105),Integer(3))) == list(range(Integer(4),Integer(105),Integer(3))) True >>> list(IntegerRange(-Integer(54),Integer(13),Integer(12))) == list(range(-Integer(54),Integer(13),Integer(12))) True
Except for the type of the numbers:
sage: type(IntegerRange(-54,13,12)[0]), type(list(range(-54,13,12))[0]) (<... 'sage.rings.integer.Integer'>, <... 'int'>)
>>> from sage.all import * >>> type(IntegerRange(-Integer(54),Integer(13),Integer(12))[Integer(0)]), type(list(range(-Integer(54),Integer(13),Integer(12)))[Integer(0)]) (<... 'sage.rings.integer.Integer'>, <... 'int'>)
When
begin
is finite andend
is +Infinity,self
is the infinite arithmetic progression starting from thebegin
by stepstep
:sage: I = IntegerRange(54,Infinity,3); I {54, 57, ...} sage: I.category() Category of facade infinite enumerated sets sage: p = iter(I) sage: (next(p), next(p), next(p), next(p), next(p), next(p)) (54, 57, 60, 63, 66, 69) sage: I = IntegerRange(54,-Infinity,-3); I {54, 51, ...} sage: I.category() Category of facade infinite enumerated sets sage: p = iter(I) sage: (next(p), next(p), next(p), next(p), next(p), next(p)) (54, 51, 48, 45, 42, 39)
>>> from sage.all import * >>> I = IntegerRange(Integer(54),Infinity,Integer(3)); I {54, 57, ...} >>> I.category() Category of facade infinite enumerated sets >>> p = iter(I) >>> (next(p), next(p), next(p), next(p), next(p), next(p)) (54, 57, 60, 63, 66, 69) >>> I = IntegerRange(Integer(54),-Infinity,-Integer(3)); I {54, 51, ...} >>> I.category() Category of facade infinite enumerated sets >>> p = iter(I) >>> (next(p), next(p), next(p), next(p), next(p), next(p)) (54, 51, 48, 45, 42, 39)
When
begin
andend
are both infinite, you will have to specify the extra argumentmiddle_point
.self
is then defined by a point and a progression/regression setting bystep
. The enumeration is done this way: (let us call \(m\) themiddle_point
) \(\{m, m+step, m-step, m+2step, m-2step, m+3step, \dots \}\):sage: I = IntegerRange(-Infinity,Infinity,37,-12); I Integer progression containing -12 with increment 37 and bounded with -Infinity and +Infinity sage: I.category() Category of facade infinite enumerated sets sage: -12 in I True sage: -15 in I False sage: p = iter(I) sage: (next(p), next(p), next(p), next(p), next(p), next(p), next(p), next(p)) (-12, 25, -49, 62, -86, 99, -123, 136)
>>> from sage.all import * >>> I = IntegerRange(-Infinity,Infinity,Integer(37),-Integer(12)); I Integer progression containing -12 with increment 37 and bounded with -Infinity and +Infinity >>> I.category() Category of facade infinite enumerated sets >>> -Integer(12) in I True >>> -Integer(15) in I False >>> p = iter(I) >>> (next(p), next(p), next(p), next(p), next(p), next(p), next(p), next(p)) (-12, 25, -49, 62, -86, 99, -123, 136)
It is also possible to use the argument
middle_point
for other cases, finite or infinite. The set will be the same as if you didn’t give this extra argument but the enumeration will begin with thismiddle_point
:sage: I = IntegerRange(123,-12,-14); I {123, 109, ..., -3} sage: list(I) [123, 109, 95, 81, 67, 53, 39, 25, 11, -3] sage: J = IntegerRange(123,-12,-14,25); J Integer progression containing 25 with increment -14 and bounded with 123 and -12 sage: list(J) [25, 11, 39, -3, 53, 67, 81, 95, 109, 123]
>>> from sage.all import * >>> I = IntegerRange(Integer(123),-Integer(12),-Integer(14)); I {123, 109, ..., -3} >>> list(I) [123, 109, 95, 81, 67, 53, 39, 25, 11, -3] >>> J = IntegerRange(Integer(123),-Integer(12),-Integer(14),Integer(25)); J Integer progression containing 25 with increment -14 and bounded with 123 and -12 >>> list(J) [25, 11, 39, -3, 53, 67, 81, 95, 109, 123]
Remember that, like for range, if you define a non empty set,
begin
is supposed to be included andend
is supposed to be excluded. In the same way, when you define a set with amiddle_point
, thebegin
bound will be supposed to be included and theend
bound supposed to be excluded:sage: I = IntegerRange(-100,100,10,0) sage: J = list(range(-100,100,10)) sage: 100 in I False sage: 100 in J False sage: -100 in I True sage: -100 in J True sage: list(I) [0, 10, -10, 20, -20, 30, -30, 40, -40, 50, -50, 60, -60, 70, -70, 80, -80, 90, -90, -100]
>>> from sage.all import * >>> I = IntegerRange(-Integer(100),Integer(100),Integer(10),Integer(0)) >>> J = list(range(-Integer(100),Integer(100),Integer(10))) >>> Integer(100) in I False >>> Integer(100) in J False >>> -Integer(100) in I True >>> -Integer(100) in J True >>> list(I) [0, 10, -10, 20, -20, 30, -30, 40, -40, 50, -50, 60, -60, 70, -70, 80, -80, 90, -90, -100]
Note
The input is normalized so that:
sage: IntegerRange(1, 6, 2) is IntegerRange(1, 7, 2) True sage: IntegerRange(1, 8, 3) is IntegerRange(1, 10, 3) True
>>> from sage.all import * >>> IntegerRange(Integer(1), Integer(6), Integer(2)) is IntegerRange(Integer(1), Integer(7), Integer(2)) True >>> IntegerRange(Integer(1), Integer(8), Integer(3)) is IntegerRange(Integer(1), Integer(10), Integer(3)) True
- class sage.sets.integer_range.IntegerRangeEmpty(elements)[source]¶
Bases:
IntegerRange
,FiniteEnumeratedSet
A singleton class for empty integer ranges.
See
IntegerRange
for more details.
- class sage.sets.integer_range.IntegerRangeFinite(begin, end, step=1)[source]¶
Bases:
IntegerRange
The class of finite enumerated sets of integers defined by finite arithmetic progressions
See
IntegerRange
for more details.- cardinality()[source]¶
Return the cardinality of
self
.EXAMPLES:
sage: IntegerRange(123,12,-4).cardinality() 28 sage: IntegerRange(-57,12,8).cardinality() 9 sage: IntegerRange(123,12,4).cardinality() 0
>>> from sage.all import * >>> IntegerRange(Integer(123),Integer(12),-Integer(4)).cardinality() 28 >>> IntegerRange(-Integer(57),Integer(12),Integer(8)).cardinality() 9 >>> IntegerRange(Integer(123),Integer(12),Integer(4)).cardinality() 0
- rank(x)[source]¶
EXAMPLES:
sage: I = IntegerRange(-57,36,8) sage: I.rank(23) 10 sage: I.unrank(10) 23 sage: I.rank(22) Traceback (most recent call last): ... IndexError: 22 not in self sage: I.rank(87) Traceback (most recent call last): ... IndexError: 87 not in self
>>> from sage.all import * >>> I = IntegerRange(-Integer(57),Integer(36),Integer(8)) >>> I.rank(Integer(23)) 10 >>> I.unrank(Integer(10)) 23 >>> I.rank(Integer(22)) Traceback (most recent call last): ... IndexError: 22 not in self >>> I.rank(Integer(87)) Traceback (most recent call last): ... IndexError: 87 not in self
- unrank(i)[source]¶
Return the i-th element of this integer range.
EXAMPLES:
sage: I = IntegerRange(1,13,5) sage: I[0], I[1], I[2] (1, 6, 11) sage: I[3] Traceback (most recent call last): ... IndexError: out of range sage: I[-1] 11 sage: I[-4] Traceback (most recent call last): ... IndexError: out of range sage: I = IntegerRange(13,1,-1) sage: l = I.list() sage: [I[i] for i in range(I.cardinality())] == l True sage: l.reverse() sage: [I[i] for i in range(-1,-I.cardinality()-1,-1)] == l True
>>> from sage.all import * >>> I = IntegerRange(Integer(1),Integer(13),Integer(5)) >>> I[Integer(0)], I[Integer(1)], I[Integer(2)] (1, 6, 11) >>> I[Integer(3)] Traceback (most recent call last): ... IndexError: out of range >>> I[-Integer(1)] 11 >>> I[-Integer(4)] Traceback (most recent call last): ... IndexError: out of range >>> I = IntegerRange(Integer(13),Integer(1),-Integer(1)) >>> l = I.list() >>> [I[i] for i in range(I.cardinality())] == l True >>> l.reverse() >>> [I[i] for i in range(-Integer(1),-I.cardinality()-Integer(1),-Integer(1))] == l True
- class sage.sets.integer_range.IntegerRangeFromMiddle(begin, end, step=1, middle_point=1)[source]¶
Bases:
IntegerRange
The class of finite or infinite enumerated sets defined with an inside point, a progression and two limits.
See
IntegerRange
for more details.- next(elt)[source]¶
Return the next element of
elt
inself
.EXAMPLES:
sage: from sage.sets.integer_range import IntegerRangeFromMiddle sage: I = IntegerRangeFromMiddle(-100,100,10,0) sage: (I.next(0), I.next(10), I.next(-10), I.next(20), I.next(-100)) (10, -10, 20, -20, None) sage: I = IntegerRangeFromMiddle(-Infinity,Infinity,10,0) sage: (I.next(0), I.next(10), I.next(-10), I.next(20), I.next(-100)) (10, -10, 20, -20, 110) sage: I.next(1) Traceback (most recent call last): ... LookupError: 1 not in Integer progression containing 0 with increment 10 and bounded with -Infinity and +Infinity
>>> from sage.all import * >>> from sage.sets.integer_range import IntegerRangeFromMiddle >>> I = IntegerRangeFromMiddle(-Integer(100),Integer(100),Integer(10),Integer(0)) >>> (I.next(Integer(0)), I.next(Integer(10)), I.next(-Integer(10)), I.next(Integer(20)), I.next(-Integer(100))) (10, -10, 20, -20, None) >>> I = IntegerRangeFromMiddle(-Infinity,Infinity,Integer(10),Integer(0)) >>> (I.next(Integer(0)), I.next(Integer(10)), I.next(-Integer(10)), I.next(Integer(20)), I.next(-Integer(100))) (10, -10, 20, -20, 110) >>> I.next(Integer(1)) Traceback (most recent call last): ... LookupError: 1 not in Integer progression containing 0 with increment 10 and bounded with -Infinity and +Infinity
- class sage.sets.integer_range.IntegerRangeInfinite(begin, step=1)[source]¶
Bases:
IntegerRange
The class of infinite enumerated sets of integers defined by infinite arithmetic progressions.
See
IntegerRange
for more details.- rank(x)[source]¶
EXAMPLES:
sage: I = IntegerRange(-57,Infinity,8) sage: I.rank(23) 10 sage: I.unrank(10) 23 sage: I.rank(22) Traceback (most recent call last): ... IndexError: 22 not in self
>>> from sage.all import * >>> I = IntegerRange(-Integer(57),Infinity,Integer(8)) >>> I.rank(Integer(23)) 10 >>> I.unrank(Integer(10)) 23 >>> I.rank(Integer(22)) Traceback (most recent call last): ... IndexError: 22 not in self