12.1 Miscellaneous functions

Module: sage.misc.misc

Miscellaneous functions

Author Log:

Module-level Functions

add( )
sum(sequence, start=0) -> value

Returns the sum of a sequence of numbers (NOT strings) plus the value of parameter 'start'. When the sequence is empty, returns start.

alarm( seconds)

Raise a KeyboardInterrupt exception in a given number of seconds. This is useful for automatically interrupting long computations and can be trapped using exception handling (just catch KeyboardInterrupt).

Input:

seconds
- integer

TESTS:

sage: try: alarm(1); sleep(2)
... except KeyboardInterrupt: print "Alarm went off"
Alarm went off

banner( )

branch_current_hg( )

Return the current hg Mercurial branch name. If the branch is 'main', which is the default branch, then just '' is returned.

branch_current_hg_notice( branch)

Return a string describing the current branch and that the library is being loaded. This is called by the <SAGE_ROOT>/local/bin/sage-sage script.

Input:

string
- a representation of the name of the SAGE library branch.

Output: string

NOTE: If the branch is main, then return an empty string.

cancel_alarm( )

cmp_props( left, right, props)

coeff_repr( c, [is_latex=False])

cputime( [t=0])

Return the time in CPU second since SAGE started, or with optional argument t, return the time since time t. This is how much time SAGE has spent using the CPU. It does not count time spent by subprocesses spawned by SAGE (e.g., Gap, Singular, etc.).

This is done via a call to resource.getrusage, so it avoids the wraparound problems in time.clock() on Cygwin.

Input:

t
- (optional) float, time in CPU seconds
Output:
float
- time in CPU seconds

sage: t = cputime()
sage: F = factor(2^199-1)
sage: cputime(t)          # somewhat random
0.29000000000000004

sage: w = walltime()
sage: F = factor(2^199-1)
sage: walltime(w)         # somewhat random
0.8823847770690918

delete_tmpfiles( )

ellipsis_iter( )

Same as ellipsis_range, but as an iterator (and may end with an Ellipsis).

See also ellipsis_range.

Use (1,2,...) notation.

sage: A = ellipsis_iter(1,2,Ellipsis)
sage: [A.next() for _ in range(10)]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
sage: A.next()
11
sage: A = ellipsis_iter(1,3,5,Ellipsis)
sage: [A.next() for _ in range(10)]
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
sage: A = ellipsis_iter(1,2,Ellipsis,5,10,Ellipsis)
sage: [A.next() for _ in range(10)]
[1, 2, 3, 4, 5, 10, 11, 12, 13, 14]

TESTS:

These were carefully chosen tests, only to be changed if the semantics of ellipsis ranges change. In otherwords, if they don't pass it's probably a bug in the implementation, not in the doctest.

sage: list(1,..,10)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
sage: list(1,3,..,10)
[1, 3, 5, 7, 9]
sage: list(1,..,10,..,20)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
sage: list(1,3,..,10,..,20)
[1, 3, 5, 7, 9, 10, 12, 14, 16, 18, 20]
sage: list(1,3,..,10,10,..,20)
[1, 3, 5, 7, 9, 10, 12, 14, 16, 18, 20]
sage: list(0,2,..,10,10,..,20,20,..,25)
[0, 2, 4, 6, 8, 10, 10, 12, 14, 16, 18, 20, 20, 22, 24]
sage: list(10,..,1)
[]
sage: list(10,11,..,1)
[]
sage: list(10,9,..,1)
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
sage: list(100,..,10,..,20)
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
sage: list(0,..,10,..,-20)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
sage: list(100,..,10,..,-20)
[]
sage: list(100,102,..,10,..,20)
[10, 12, 14, 16, 18, 20]

ellipsis_range( )

Return arithmetic sequence determined by the numeric arguments and ellipsis. Best illustrated by examples.

Use [1,2,..,n] notation.

sage: ellipsis_range(1,Ellipsis,11,100)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 100]
sage: ellipsis_range(0,2,Ellipsis,10,Ellipsis,20)
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
sage: ellipsis_range(0,2,Ellipsis,11,Ellipsis,20)
[0, 2, 4, 6, 8, 10, 11, 13, 15, 17, 19]
sage: ellipsis_range(0,2,Ellipsis,11,Ellipsis,20, step=3)
[0, 2, 5, 8, 11, 14, 17, 20]
sage: ellipsis_range(10,Ellipsis,0)
[]

TESTS: These were carefully chosen tests, only to be changed if the semantics of ellipsis ranges change. In otherwords, if they don't pass it's probably a bug in the implementation, not in the doctest.

Note 10 only appears once (though it is in both ranges).

sage: ellipsis_range(0,Ellipsis,10,Ellipsis,20,step=2)
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

Sometimes one or more ranges is empty.

sage: ellipsis_range(100,Ellipsis,10,Ellipsis,20,step=2)
[10, 12, 14, 16, 18, 20]
sage: ellipsis_range(0,Ellipsis,10,Ellipsis,-20,step=2)
[0, 2, 4, 6, 8, 10]
sage: ellipsis_range(100,Ellipsis,10,Ellipsis,-20,step=2)
[]

We always start on the leftmost point of the range.

sage: ellipsis_range(0,Ellipsis,10,Ellipsis,20,step=3)
[0, 3, 6, 9, 10, 13, 16, 19]
sage: ellipsis_range(100,Ellipsis,10,Ellipsis,20,step=3)
[10, 13, 16, 19]
sage: ellipsis_range(0,Ellipsis,10,Ellipsis,-20,step=3)
[0, 3, 6, 9]
sage: ellipsis_range(100,Ellipsis,10,Ellipsis,-20,step=3)
[]
sage: ellipsis_range(0,1,Ellipsis,-10)
[]
sage: ellipsis_range(0,1,Ellipsis,-10,step=1)
[0]
sage: ellipsis_range(100,0,1,Ellipsis,-10)
[100]

Note the duplicate 5 in the output.

sage: ellipsis_range(0,Ellipsis,5,5,Ellipsis,10)
[0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10]

Examples in which the step determines the parent of the elements:

sage: [1..3, step=0.5]
[1.00000000000000, 1.50000000000000, 2.00000000000000, 2.50000000000000,
3.00000000000000]
sage: v = [1..5, step=1/1]; v
[1, 2, 3, 4, 5]
sage: parent(v[2])
Rational Field

embedded( )

Return True if this copy of Sage is running embedded in the Sage notebook.

sage: sage.misc.misc.embedded()    # output True if in the notebook
False

exists( S, P)

If S contains an element x such that P(x) is True, this function returns True and the element x. Otherwise it returns False and None.

Note that this function is NOT suitable to be used in an if-statement or in any place where a boolean expression is expected. For those situations, use the Python built-in

any(P(x) for x in S)

Input:

S
- object (that supports enumeration)
P
- function that returns True or False

Output:
bool
- whether or not P is True for some element x of S
object
- x

lambda functions are very useful when using the exists function:

sage: exists([1,2,5], lambda x : x > 7)
(False, None)
sage: exists([1,2,5], lambda x : x > 3)
(True, 5)

The following example is similar to one in the MAGMA handbook. We check whether certain integers are a sum of two (small) cubes:

sage: cubes = [t**3 for t in range(-10,11)]
sage: exists([(x,y) for x in cubes for y in cubes], lambda v : v[0]+v[1] == 218)
(True, (-125, 343))
sage: exists([(x,y) for x in cubes for y in cubes], lambda v : v[0]+v[1] == 219)
(False, None)

forall( S, P)

If P(x) is true every x in S, return True and None. If there is some element x in S such that P is not True, return False and x.

Note that this function is NOT suitable to be used in an if-statement or in any place where a boolean expression is expected. For those situations, use the Python built-in

all(P(x) for x in S)

Input:

S
- object (that supports enumeration)
P
- function that returns True or False

Output:
bool
- whether or not P is True for all elements of S
object
- x

lambda functions are very useful when using the forall function. As a toy example we test whether certain integers are >3.

sage: forall([1,2,5], lambda x : x > 3)
(False, 1)
sage: forall([1,2,5], lambda x : x > 0)
(True, None)

Next we ask whether every positive integer <100 is a product of at most 2 prime factors:

sage: forall(range(1,100),  lambda n : len(factor(n)) <= 2)
(False, 30)

The answer is no, and 30 is a counterexample. However, every positive integer < 100 is a product of at most 3 primes.

sage: forall(range(1,100),  lambda n : len(factor(n)) <= 3)
(True, None)

generic_xsrange( start, end, step)

get_verbose( )

Return the global SAGE verbosity level.

Input: int level: an integer between 0 and 2, inclusive.

Output: changes the state of the verbosity flag.

sage: get_verbose()
0
sage: set_verbose(2)
sage: get_verbose()
2
sage: set_verbose(0)

get_verbose_files( )

getitem( v, n)

Variant of getitem that coerces to an int if a TypeError is raised.

(This is not needed anymore - classes should define an __index__ method.)

Thus, e.g., getitem(v,n) will work even if $ v$ is a Python list and $ n$ is a SAGE integer.

sage: v = [1,2,3]

The following used to fail in SAGE <= 1.3.7. Now it works fine:

sage: v[ZZ(1)]          
2

This always worked.

sage: getitem(v, ZZ(1))
2

graphics_filename( [ext=png])

Return the next available canonical filename for a plot/graphics file.

mul( )

Return the product of the elements in the list x. If optional argument z is not given, start the product with the first element of the list, otherwise use z. The empty product is the int 1 if z is not specified, and is z if given.

This assumes that your multiplication is associative; we don't promise which end of the list we start at.

sage: prod([1,2,34])
68
sage: prod([2,3], 5)
30
sage: prod((1,2,3), 5)
30
sage: F = factor(-2006); F
-1 * 2 * 17 * 59
sage: prod(F)
-2006

Author Log:

newton_method_sizes( N)

Returns a sequence of integers $ 1 = a_1 \leq a_2 \leq \cdots \leq a_n = N$ such that $ a_j = \lceil a_{j+1} / 2 
ceil$ for all $ j$ .

This is useful for Newton-style algorithms that double the precision at each stage. For example if you start at precision 1 and want an answer to precision 17, then it's better to use the intermediate stages 1, 2, 3, 5, 9, 17 than to use 1, 2, 4, 8, 16, 17.

Input:

N
- positive integer

sage: newton_method_sizes(17)
 [1, 2, 3, 5, 9, 17]
sage: newton_method_sizes(16)
 [1, 2, 4, 8, 16]
sage: newton_method_sizes(1)
 [1]

Author: David Harvey (2006-09-09)

pad_zeros( s, [size=3])

sage: pad_zeros(100)
'100'
sage: pad_zeros(10)
'010'
sage: pad_zeros(10, 5)
'00010'
sage: pad_zeros(389, 5)
'00389'
sage: pad_zeros(389, 10)
'0000000389'

powerset( X)

Iterator over the list of all subsets of the iterable X, in no particular order. Each list appears exactly once, up to order.

Input:

X
- an iterable
Output: iterator of lists

sage: list(powerset([1,2,3]))
[[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]
sage: [z for z in powerset([0,[1,2]])]
[[], [0], [[1, 2]], [0, [1, 2]]]

Iterating over the power set of an infinite set is also allowed:

sage: i = 0
sage: for x in powerset(ZZ):
...    if i > 10:
...       break
...    else:
...       i += 1
...    print x,
[] [0] [1] [0, 1] [-1] [0, -1] [1, -1] [0, 1, -1] [2] [0, 2] [1, 2]

You may also use subsets as an alias for powerset:

sage: subsets([1,2,3])   # random object location in output
<generator object at 0xaeae418c>
sage: list(subsets([1,2,3]))
[[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]

Note: The reason we return lists instead of sets is that the elements of sets must be hashable and many structures on which one wants the powerset consist of non-hashable objects.

Author Log:

prod( )

Return the product of the elements in the list x. If optional argument z is not given, start the product with the first element of the list, otherwise use z. The empty product is the int 1 if z is not specified, and is z if given.

This assumes that your multiplication is associative; we don't promise which end of the list we start at.

sage: prod([1,2,34])
68
sage: prod([2,3], 5)
30
sage: prod((1,2,3), 5)
30
sage: F = factor(-2006); F
-1 * 2 * 17 * 59
sage: prod(F)
-2006

Author Log:

random_sublist( X, s)

Return a pseudo-random sublist of the list X where the probability of including a particular element is s.

Input:

X
- list
s
- floating point number between 0 and 1
Output: list

sage: S = [1,7,3,4,18]
sage: random_sublist(S, 0.5)
[1, 3, 4]
sage: random_sublist(S, 0.5)
[1, 3]

repr_lincomb( symbols, coeffs, [is_latex=False])

Compute a string representation of a linear combination of some formal symbols.

Input:

symbols
- list of symbols
coeffs
- list of coefficients of the symbols

Output:
str
- a string

sage: repr_lincomb(['a','b','c'], [1,2,3])
'a + 2*b + 3*c'
sage: repr_lincomb(['a','b','c'], [1,'2+3*x',3])
'a + (2+3*x)*b + 3*c'
sage: repr_lincomb(['a','b','c'], ['1+x^2','2+3*x',3])
'(1+x^2)*a + (2+3*x)*b + 3*c'
sage: repr_lincomb(['a','b','c'], ['1+x^2','-2+3*x',3])
'(1+x^2)*a + (-2+3*x)*b + 3*c'
sage: repr_lincomb(['a','b','c'], [1,-2,-3])
'a - 2*b - 3*c'
sage: t = PolynomialRing(RationalField(),'t').gen()
sage: repr_lincomb(['a', 's', ''], [-t,t-2,t**2+2])
'-t*a + (t-2)*s + (t^2+2)'

running_total( )

Returns a list where the i-th entry is the sum of all entries up to (and incling) i.

Input:

L
- the list
start
- (optional) a default start value

sage: running_total(range(5))
[0, 1, 3, 6, 10]
sage: running_total("abcdef")
['a', 'ab', 'abc', 'abcd', 'abcde', 'abcdef']
sage: running_total([1..10], start=100)
[101, 103, 106, 110, 115, 121, 128, 136, 145, 155]

set_trace( )

set_verbose( level, [files=all])

Set the global SAGE verbosity level.

Input: int level: an integer between 0 and 2, inclusive. files (default: 'all'): list of files to make verbose, or 'all' to make ALL files verbose (the default). Output: changes the state of the verbosity flag and possibly appends to the list of files that are verbose.

sage: set_verbose(2)
sage: verbose("This is SAGE.", level=1)  # not tested
VERBOSE1 (?): This is SAGE.
sage: verbose("This is SAGE.", level=2)  # not tested
VERBOSE2 (?): This is SAGE.
sage: verbose("This is SAGE.", level=3)  # not tested
[no output]
sage: set_verbose(0)

set_verbose_files( file_name)

sourcefile( object)
Work out which source or compiled file an object was defined in.

srange( start, [end=None], [step=1], [universe=None], [check=True], [include_endpoint=False])

Return list of numbers a, a+step, ..., a+k*step, where a+k*step < b and a+(k+1)*step > b.

This is the best way to get an iterator over SAGE integers as opposed to Python int's. It also allows you to specify step sizes to iterate. It is potentially much slower than the Python range statement, depending on your application.

Input:

a
- number
b
- number (default: None)
step
- number (default: 1)
include_endpoint
- whether or not to include the endpoint (default: False)

Output: list

If b is None, then b is set equal to a and a is set equal to the 0 in the parent of b.

Unlike range, a and b can be any type of numbers, and the resulting list involves numbers of that type.

NOTE: This function is called srange to distinguish it from the builtin Python range command. The s at the beginning of the name stands for ``SAGE''.

SEE ALSO: xsrange - iterator version

sage: v = srange(5); v
[0, 1, 2, 3, 4]
sage: type(v[2])
<type 'sage.rings.integer.Integer'>

sage: srange(1, 10)
[1, 2, 3, 4, 5, 6, 7, 8, 9]

sage: srange(10, 1, -1)
[10, 9, 8, 7, 6, 5, 4, 3, 2]

sage: srange(10,1,-1, include_endpoint=True)
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

sage: Q = RationalField()
sage: srange(1,10,Q('1/2'))
[1, 3/2, 2, 5/2, 3, 7/2, 4, 9/2, 5, 11/2, 6, 13/2, 7, 15/2, 8, 17/2, 9,
19/2]

sage: R = RealField()
sage: srange(1,5,R('0.5'))
[1.00000000000000, 1.50000000000000, 2.00000000000000, 2.50000000000000,
3.00000000000000, 3.50000000000000, 4.00000000000000, 4.50000000000000]
sage: srange(0,1,R('0.4'))
[0.000000000000000, 0.400000000000000, 0.800000000000000]
sage: srange(1.0, 5.0, include_endpoint=True)
[1.00000000000000, 2.00000000000000, 3.00000000000000, 4.00000000000000,
5.00000000000000]

sage: srange(1.0, 1.1)
[1.00000000000000]
sage: srange(1.0, 1.0)
[]

sage: V = VectorSpace(QQ, 2)
sage: srange(V([0,0]), V([5,5]), step=V([2,2]))
[(0, 0), (2, 2), (4, 4)]

subsets( X)

Iterator over the list of all subsets of the iterable X, in no particular order. Each list appears exactly once, up to order.

Input:

X
- an iterable
Output: iterator of lists

sage: list(powerset([1,2,3]))
[[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]
sage: [z for z in powerset([0,[1,2]])]
[[], [0], [[1, 2]], [0, [1, 2]]]

Iterating over the power set of an infinite set is also allowed:

sage: i = 0
sage: for x in powerset(ZZ):
...    if i > 10:
...       break
...    else:
...       i += 1
...    print x,
[] [0] [1] [0, 1] [-1] [0, -1] [1, -1] [0, 1, -1] [2] [0, 2] [1, 2]

You may also use subsets as an alias for powerset:

sage: subsets([1,2,3])   # random object location in output
<generator object at 0xaeae418c>
sage: list(subsets([1,2,3]))
[[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]

Note: The reason we return lists instead of sets is that the elements of sets must be hashable and many structures on which one wants the powerset consist of non-hashable objects.

Author Log:

sxrange( start, [end=None], [step=1], [universe=None], [check=True], [include_endpoint=False])

Return an iterator over numbers a, a+step, ..., a+k*step, where a+k*step < b and a+(k+1)*step > b.

Input:

a
- number
b
- number
step
- number (default: 1)
Output: iterator

Unlike range, a and b can be any type of numbers, and the resulting iterator involves numbers of that type.

SEE ALSO: srange.

NOTE: This function is called xsrange to distinguish it from the builtin Python xrange command.

sage: list(xsrange(1,10))
[1, 2, 3, 4, 5, 6, 7, 8, 9]

sage: Q = RationalField()
sage: list(xsrange(1, 10, Q('1/2')))
[1, 3/2, 2, 5/2, 3, 7/2, 4, 9/2, 5, 11/2, 6, 13/2, 7, 15/2, 8, 17/2, 9,
19/2]

sage: R = RealField()
sage: list(xsrange(1, 5, R(0.5)))
[1.00000000000000, 1.50000000000000, 2.00000000000000, 2.50000000000000,
3.00000000000000, 3.50000000000000, 4.00000000000000, 4.50000000000000]
sage: list(xsrange(0, 1, R('0.4')))
[0.000000000000000, 0.400000000000000, 0.800000000000000]

Negative ranges are also allowed:

sage: list(xrange(4,1,-1))
[4, 3, 2]
sage: list(sxrange(4,1,-1))
[4, 3, 2]
sage: list(sxrange(4,1,-1/2))
[4, 7/2, 3, 5/2, 2, 3/2]

tmp_dir( [name=dir])

Create and return a temporary directory in $HOME/.sage/temp/hostname/pid/

tmp_filename( [name=tmp])

union( x, [y=None])

Return the union of x and y, as a list. The resulting list need not be sorted and can change from call to call.

Input:

x
- iterable
y
- iterable (may optionally omitted)
Output: list

sage: answer = union([1,2,3,4], [5,6]); answer
[1, 2, 3, 4, 5, 6]
sage: union([1,2,3,4,5,6], [5,6]) == answer
True
sage: union((1,2,3,4,5,6), [5,6]) == answer
True
sage: union((1,2,3,4,5,6), set([5,6])) == answer
True

uniq( x)

Return the sublist of all elements in the list x that is sorted and is such that the entries in the sublist are unique.

sage: v = uniq([1,1,8,-5,3,-5,'a','x','a'])
sage: v            # potentially random ordering of output
['a', 'x', -5, 1, 3, 8]
sage: set(v) == set(['a', 'x', -5, 1, 3, 8])
True

unset_verbose_files( file_name)

verbose( [mesg=], [t=0], [level=1], [caller_name=None])

Print a message if the current verbosity is at least level.

Input:

mesg
- str, a message to print
t
- int, optional, if included, will also print cputime(t), - which is the time since time t. Thus t should have been obtained with t=cputime()
level
- int, (default: 1) the verbosity level of what we are printing
caller_name
- string (default: None), the name of the calling function; in most cases Python can deduce this, so it need not be provided.
Output: possibly prints a message to stdout; also returns cputime()

sage: set_verbose(1)
sage: t = cputime()
sage: t = verbose("This is SAGE.", t, level=1, caller_name="william")       # not tested
VERBOSE1 (william): This is SAGE. (time = 0.0)
sage: set_verbose(0)

version( [clone=False])

Return the version of SAGE.

Input: nothing Output: str

sage: version()    
'SAGE Version ..., Release Date: ...'
sage: version(clone=True)
('SAGE Version ..., Release Date: ...', 
 'Mercurial clone branch: ...')

walltime( [t=0])

Return the wall time in second, or with optional argument t, return the wall time since time t. "Wall time" means the time on a wall clock, i.e., the actual time.

Input:

t
- (optional) float, time in CPU seconds
Output:
float
- time in seconds

sage: w = walltime()
sage: F = factor(2^199-1)
sage: walltime(w)   # somewhat random
0.8823847770690918

word_wrap( s, [ncols=85])

xsrange( start, [end=None], [step=1], [universe=None], [check=True], [include_endpoint=False])

Return an iterator over numbers a, a+step, ..., a+k*step, where a+k*step < b and a+(k+1)*step > b.

Input:

a
- number
b
- number
step
- number (default: 1)
Output: iterator

Unlike range, a and b can be any type of numbers, and the resulting iterator involves numbers of that type.

SEE ALSO: srange.

NOTE: This function is called xsrange to distinguish it from the builtin Python xrange command.

sage: list(xsrange(1,10))
[1, 2, 3, 4, 5, 6, 7, 8, 9]

sage: Q = RationalField()
sage: list(xsrange(1, 10, Q('1/2')))
[1, 3/2, 2, 5/2, 3, 7/2, 4, 9/2, 5, 11/2, 6, 13/2, 7, 15/2, 8, 17/2, 9,
19/2]

sage: R = RealField()
sage: list(xsrange(1, 5, R(0.5)))
[1.00000000000000, 1.50000000000000, 2.00000000000000, 2.50000000000000,
3.00000000000000, 3.50000000000000, 4.00000000000000, 4.50000000000000]
sage: list(xsrange(0, 1, R('0.4')))
[0.000000000000000, 0.400000000000000, 0.800000000000000]

Negative ranges are also allowed:

sage: list(xrange(4,1,-1))
[4, 3, 2]
sage: list(sxrange(4,1,-1))
[4, 3, 2]
sage: list(sxrange(4,1,-1/2))
[4, 7/2, 3, 5/2, 2, 3/2]

See About this document... for information on suggesting changes.