Miscellaneous functions¶
AUTHORS:
William Stein
William Stein (2006-04-26): added workaround for Windows where most users’ home directory has a space in it.
Robert Bradshaw (2007-09-20): Ellipsis range/iterator.
- class sage.misc.misc.BackslashOperator[source]¶
Bases:
objectImplement Matlab-style backslash operator for solving systems:
A \ bThe preparser converts this to multiplications using
BackslashOperator().EXAMPLES:
sage: preparse("A \\ matrix(QQ,2,1,[1/3,'2/3'])") "A * BackslashOperator() * matrix(QQ,Integer(2),Integer(1),[Integer(1)/Integer(3),'2/3'])" sage: preparse("A \\ matrix(QQ,2,1,[1/3,2*3])") 'A * BackslashOperator() * matrix(QQ,Integer(2),Integer(1),[Integer(1)/Integer(3),Integer(2)*Integer(3)])' sage: preparse("A \\ B + C") 'A * BackslashOperator() * B + C' sage: preparse("A \\ eval('C+D')") "A * BackslashOperator() * eval('C+D')" sage: preparse("A \\ x / 5") 'A * BackslashOperator() * x / Integer(5)' sage: preparse("A^3 \\ b") 'A**Integer(3) * BackslashOperator() * b'
>>> from sage.all import * >>> preparse("A \\ matrix(QQ,2,1,[1/3,'2/3'])") "A * BackslashOperator() * matrix(QQ,Integer(2),Integer(1),[Integer(1)/Integer(3),'2/3'])" >>> preparse("A \\ matrix(QQ,2,1,[1/3,2*3])") 'A * BackslashOperator() * matrix(QQ,Integer(2),Integer(1),[Integer(1)/Integer(3),Integer(2)*Integer(3)])' >>> preparse("A \\ B + C") 'A * BackslashOperator() * B + C' >>> preparse("A \\ eval('C+D')") "A * BackslashOperator() * eval('C+D')" >>> preparse("A \\ x / 5") 'A * BackslashOperator() * x / Integer(5)' >>> preparse("A^3 \\ b") 'A**Integer(3) * BackslashOperator() * b'
- sage.misc.misc.compose(f, g)[source]¶
Return the composition of one-variable functions: \(f \circ g\).
See also
nest()INPUT:
f– a function of one variableg– another function of one variable
OUTPUT: a function, such that compose(f,g)(x) = f(g(x))
EXAMPLES:
sage: def g(x): return 3*x sage: def f(x): return x + 1 sage: h1 = compose(f, g) sage: h2 = compose(g, f) sage: _ = var('x') # needs sage.symbolic sage: h1(x) # needs sage.symbolic 3*x + 1 sage: h2(x) # needs sage.symbolic 3*x + 3
>>> from sage.all import * >>> def g(x): return Integer(3)*x >>> def f(x): return x + Integer(1) >>> h1 = compose(f, g) >>> h2 = compose(g, f) >>> _ = var('x') # needs sage.symbolic >>> h1(x) # needs sage.symbolic 3*x + 1 >>> h2(x) # needs sage.symbolic 3*x + 3
sage: _ = function('f g') # needs sage.symbolic sage: _ = var('x') # needs sage.symbolic sage: compose(f, g)(x) # needs sage.symbolic f(g(x))
>>> from sage.all import * >>> _ = function('f g') # needs sage.symbolic >>> _ = var('x') # needs sage.symbolic >>> compose(f, g)(x) # needs sage.symbolic f(g(x))
- sage.misc.misc.exactly_one_is_true(iterable)[source]¶
Return whether exactly one element of
iterableevaluatesTrue.INPUT:
iterable– an iterable object
OUTPUT: boolean
Note
The implementation is suggested by stackoverflow entry.
EXAMPLES:
sage: from sage.misc.misc import exactly_one_is_true sage: exactly_one_is_true([]) False sage: exactly_one_is_true([True]) True sage: exactly_one_is_true([False]) False sage: exactly_one_is_true([True, True]) False sage: exactly_one_is_true([False, True]) True sage: exactly_one_is_true([True, False, True]) False sage: exactly_one_is_true([False, True, False]) True
>>> from sage.all import * >>> from sage.misc.misc import exactly_one_is_true >>> exactly_one_is_true([]) False >>> exactly_one_is_true([True]) True >>> exactly_one_is_true([False]) False >>> exactly_one_is_true([True, True]) False >>> exactly_one_is_true([False, True]) True >>> exactly_one_is_true([True, False, True]) False >>> exactly_one_is_true([False, True, False]) True
- sage.misc.misc.exists(S, P)[source]¶
If S contains an element x such that P(x) is
True, this function returnsTrueand the element x. Otherwise it returnsFalseand 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 returnsTrueorFalse
OUTPUT:
bool– whether or not P isTruefor some element x of Sobject– x
EXAMPLES: 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)
>>> from sage.all import * >>> exists([Integer(1),Integer(2),Integer(5)], lambda x : x > Integer(7)) (False, None) >>> exists([Integer(1),Integer(2),Integer(5)], lambda x : x > Integer(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)
>>> from sage.all import * >>> cubes = [t**Integer(3) for t in range(-Integer(10),Integer(11))] >>> exists([(x,y) for x in cubes for y in cubes], lambda v : v[Integer(0)]+v[Integer(1)] == Integer(218)) (True, (-125, 343)) >>> exists([(x,y) for x in cubes for y in cubes], lambda v : v[Integer(0)]+v[Integer(1)] == Integer(219)) (False, None)
- sage.misc.misc.forall(S, P)[source]¶
If \(P(x)\) is true every x in S, return
TrueandNone. If there is some element x in S such that P is notTrue, returnFalseand \(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 returnsTrueorFalse
OUTPUT:
bool– whether or not P isTruefor all elements of Sobject– x
EXAMPLES: lambda functions are very useful when using the forall function. As a toy example we test whether certain integers are greater than 3.
sage: forall([1,2,5], lambda x : x > 3) (False, 1) sage: forall([1,2,5], lambda x : x > 0) (True, None)
>>> from sage.all import * >>> forall([Integer(1),Integer(2),Integer(5)], lambda x : x > Integer(3)) (False, 1) >>> forall([Integer(1),Integer(2),Integer(5)], lambda x : x > Integer(0)) (True, None)
Next we ask whether every positive integer less than 100 is a product of at most 2 prime factors:
sage: forall(range(1,100), lambda n : len(factor(n)) <= 2) (False, 30)
>>> from sage.all import * >>> forall(range(Integer(1),Integer(100)), lambda n : len(factor(n)) <= Integer(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)
>>> from sage.all import * >>> forall(range(Integer(1),Integer(100)), lambda n : len(factor(n)) <= Integer(3)) (True, None)
- sage.misc.misc.get_main_globals()[source]¶
Return the main global namespace.
EXAMPLES:
sage: from sage.misc.misc import get_main_globals sage: G = get_main_globals() sage: bla = 1 sage: G['bla'] 1 sage: bla = 2 sage: G['bla'] 2 sage: G['ble'] = 5 sage: ble 5
>>> from sage.all import * >>> from sage.misc.misc import get_main_globals >>> G = get_main_globals() >>> bla = Integer(1) >>> G['bla'] 1 >>> bla = Integer(2) >>> G['bla'] 2 >>> G['ble'] = Integer(5) >>> ble 5
This is analogous to
globals(), except that it can be called from any function, even if it is in a Python module:sage: def f(): ....: G = get_main_globals() ....: assert G['bli'] == 14 ....: G['blo'] = 42 sage: bli = 14 sage: f() sage: blo 42
>>> from sage.all import * >>> def f(): ... G = get_main_globals() ... assert G['bli'] == Integer(14) ... G['blo'] = Integer(42) >>> bli = Integer(14) >>> f() >>> blo 42
ALGORITHM:
The main global namespace is discovered by going up the frame stack until the frame for the
__main__module is found. Should this frame not be found (this should not occur in normal operation), an exception “ValueError: call stack is not deep enough” will be raised by_getframe.See
inject_variable_test()for a real test that this works within deeply nested calls in a function defined in a Python module.
- sage.misc.misc.increase_recursion_limit(*args, **kwds)[source]¶
Context manager to temporarily change the Python maximum recursion depth.
INPUT:
increment– increment to add to the current limit
EXAMPLES:
sage: from sage.misc.misc import increase_recursion_limit sage: def rec(n): None if n == 0 else rec(n-1) sage: rec(10000) Traceback (most recent call last): ... RecursionError: maximum recursion depth exceeded... sage: with increase_recursion_limit(10000): rec(10000) sage: rec(10000) Traceback (most recent call last): ... RecursionError: maximum recursion depth exceeded...
>>> from sage.all import * >>> from sage.misc.misc import increase_recursion_limit >>> def rec(n): None if n == Integer(0) else rec(n-Integer(1)) >>> rec(Integer(10000)) Traceback (most recent call last): ... RecursionError: maximum recursion depth exceeded... >>> with increase_recursion_limit(Integer(10000)): rec(Integer(10000)) >>> rec(Integer(10000)) Traceback (most recent call last): ... RecursionError: maximum recursion depth exceeded...
- sage.misc.misc.inject_variable(name, value, warn=True)[source]¶
Inject a variable into the main global namespace.
INPUT:
name– stringvalue– anythingwarn– boolean (default:False)
EXAMPLES:
sage: from sage.misc.misc import inject_variable sage: inject_variable("a", 314) sage: a 314
>>> from sage.all import * >>> from sage.misc.misc import inject_variable >>> inject_variable("a", Integer(314)) >>> a 314
A warning is issued the first time an existing value is overwritten:
sage: inject_variable("a", 271) doctest:...: RuntimeWarning: redefining global value `a` sage: a 271 sage: inject_variable("a", 272) sage: a 272
>>> from sage.all import * >>> inject_variable("a", Integer(271)) doctest:...: RuntimeWarning: redefining global value `a` >>> a 271 >>> inject_variable("a", Integer(272)) >>> a 272
That’s because warn seem to not reissue twice the same warning:
sage: from warnings import warn sage: warn("blah") doctest:...: UserWarning: blah sage: warn("blah")
>>> from sage.all import * >>> from warnings import warn >>> warn("blah") doctest:...: UserWarning: blah >>> warn("blah")
Warnings can be disabled:
sage: b = 3 sage: inject_variable("b", 42, warn=False) sage: b 42
>>> from sage.all import * >>> b = Integer(3) >>> inject_variable("b", Integer(42), warn=False) >>> b 42
Use with care!
- sage.misc.misc.inject_variable_test(name, value, depth)[source]¶
A function for testing deep calls to
inject_variable.EXAMPLES:
sage: from sage.misc.misc import inject_variable_test sage: inject_variable_test("a0", 314, 0) sage: a0 314 sage: inject_variable_test("a1", 314, 1) sage: a1 314 sage: inject_variable_test("a2", 314, 2) sage: a2 314 sage: inject_variable_test("a2", 271, 2) doctest:...: RuntimeWarning: redefining global value `a2` sage: a2 271
>>> from sage.all import * >>> from sage.misc.misc import inject_variable_test >>> inject_variable_test("a0", Integer(314), Integer(0)) >>> a0 314 >>> inject_variable_test("a1", Integer(314), Integer(1)) >>> a1 314 >>> inject_variable_test("a2", Integer(314), Integer(2)) >>> a2 314 >>> inject_variable_test("a2", Integer(271), Integer(2)) doctest:...: RuntimeWarning: redefining global value `a2` >>> a2 271
- sage.misc.misc.is_in_string(line, pos)[source]¶
Return
Trueif the character at positionposinlineoccurs within a string.EXAMPLES:
sage: from sage.misc.misc import is_in_string sage: line = 'test(\'#\')' sage: is_in_string(line, line.rfind('#')) True sage: is_in_string(line, line.rfind(')')) False
>>> from sage.all import * >>> from sage.misc.misc import is_in_string >>> line = 'test(\'#\')' >>> is_in_string(line, line.rfind('#')) True >>> is_in_string(line, line.rfind(')')) False
- sage.misc.misc.is_iterator(it)[source]¶
Test if it is an iterator.
The mantra
if hasattr(it, 'next')was used to tests ifitis an iterator. This is not quite correct sinceitcould have anextmethods with a different semantic.EXAMPLES:
sage: it = iter([1,2,3]) sage: is_iterator(it) True sage: class wrong(): ....: def __init__(self): self.n = 5 ....: def __next__(self): ....: self.n -= 1 ....: if self.n == 0: raise StopIteration ....: return self.n sage: x = wrong() sage: is_iterator(x) False sage: list(x) Traceback (most recent call last): ... TypeError: 'wrong' object is not iterable sage: class good(wrong): ....: def __iter__(self): return self sage: x = good() sage: is_iterator(x) True sage: list(x) [4, 3, 2, 1] sage: P = Partitions(3) # needs sage.combinat sage: is_iterator(P) # needs sage.combinat False sage: is_iterator(iter(P)) # needs sage.combinat True
>>> from sage.all import * >>> it = iter([Integer(1),Integer(2),Integer(3)]) >>> is_iterator(it) True >>> class wrong(): ... def __init__(self): self.n = Integer(5) ... def __next__(self): ... self.n -= Integer(1) ... if self.n == Integer(0): raise StopIteration ... return self.n >>> x = wrong() >>> is_iterator(x) False >>> list(x) Traceback (most recent call last): ... TypeError: 'wrong' object is not iterable >>> class good(wrong): ... def __iter__(self): return self >>> x = good() >>> is_iterator(x) True >>> list(x) [4, 3, 2, 1] >>> P = Partitions(Integer(3)) # needs sage.combinat >>> is_iterator(P) # needs sage.combinat False >>> is_iterator(iter(P)) # needs sage.combinat True
- sage.misc.misc.is_sublist(X, Y)[source]¶
Test whether
Xis a sublist ofY.EXAMPLES:
sage: from sage.misc.misc import is_sublist sage: S = [1, 7, 3, 4, 18] sage: is_sublist([1, 7], S) True sage: is_sublist([1, 3, 4], S) True sage: is_sublist([1, 4, 3], S) False sage: is_sublist(S, S) True
>>> from sage.all import * >>> from sage.misc.misc import is_sublist >>> S = [Integer(1), Integer(7), Integer(3), Integer(4), Integer(18)] >>> is_sublist([Integer(1), Integer(7)], S) True >>> is_sublist([Integer(1), Integer(3), Integer(4)], S) True >>> is_sublist([Integer(1), Integer(4), Integer(3)], S) False >>> is_sublist(S, S) True
- sage.misc.misc.nest(f, n, x)[source]¶
Return \(f(f(...f(x)...))\), where the composition occurs n times.
See also
compose()andself_compose()INPUT:
f– a function of one variablen– nonnegative integerx– any input for \(f\)
OUTPUT: \(f(f(...f(x)...))\), where the composition occurs n times
EXAMPLES:
sage: def f(x): return x^2 + 1 sage: x = var('x') # needs sage.symbolic sage: nest(f, 3, x) # needs sage.symbolic ((x^2 + 1)^2 + 1)^2 + 1
>>> from sage.all import * >>> def f(x): return x**Integer(2) + Integer(1) >>> x = var('x') # needs sage.symbolic >>> nest(f, Integer(3), x) # needs sage.symbolic ((x^2 + 1)^2 + 1)^2 + 1
sage: _ = function('f') # needs sage.symbolic sage: _ = var('x') # needs sage.symbolic sage: nest(f, 10, x) # needs sage.symbolic f(f(f(f(f(f(f(f(f(f(x))))))))))
>>> from sage.all import * >>> _ = function('f') # needs sage.symbolic >>> _ = var('x') # needs sage.symbolic >>> nest(f, Integer(10), x) # needs sage.symbolic f(f(f(f(f(f(f(f(f(f(x))))))))))
sage: _ = function('f') # needs sage.symbolic sage: _ = var('x') # needs sage.symbolic sage: nest(f, 0, x) # needs sage.symbolic x
>>> from sage.all import * >>> _ = function('f') # needs sage.symbolic >>> _ = var('x') # needs sage.symbolic >>> nest(f, Integer(0), x) # needs sage.symbolic x
- sage.misc.misc.newton_method_sizes(N)[source]¶
Return 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 \rceil\) 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
EXAMPLES:
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]
>>> from sage.all import * >>> newton_method_sizes(Integer(17)) [1, 2, 3, 5, 9, 17] >>> newton_method_sizes(Integer(16)) [1, 2, 4, 8, 16] >>> newton_method_sizes(Integer(1)) [1]
AUTHORS:
David Harvey (2006-09-09)
- sage.misc.misc.pad_zeros(s, size=3)[source]¶
EXAMPLES:
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'
>>> from sage.all import * >>> pad_zeros(Integer(100)) '100' >>> pad_zeros(Integer(10)) '010' >>> pad_zeros(Integer(10), Integer(5)) '00010' >>> pad_zeros(Integer(389), Integer(5)) '00389' >>> pad_zeros(Integer(389), Integer(10)) '0000000389'
- sage.misc.misc.random_sublist(X, s)[source]¶
Return a pseudo-random sublist of the list X where the probability of including a particular element is s.
INPUT:
X– lists– floating point number between 0 and 1
OUTPUT: list
EXAMPLES:
sage: from sage.misc.misc import is_sublist sage: S = [1,7,3,4,18] sage: sublist = random_sublist(S, 0.5); sublist # random [1, 3, 4] sage: is_sublist(sublist, S) True sage: sublist = random_sublist(S, 0.5); sublist # random [1, 3] sage: is_sublist(sublist, S) True
>>> from sage.all import * >>> from sage.misc.misc import is_sublist >>> S = [Integer(1),Integer(7),Integer(3),Integer(4),Integer(18)] >>> sublist = random_sublist(S, RealNumber('0.5')); sublist # random [1, 3, 4] >>> is_sublist(sublist, S) True >>> sublist = random_sublist(S, RealNumber('0.5')); sublist # random [1, 3] >>> is_sublist(sublist, S) True
- sage.misc.misc.run_once(func)[source]¶
Run a function (successfully) only once.
The running can be reset by setting the
has_runattribute to False
- sage.misc.misc.some_tuples(elements, repeat, bound, max_samples=None)[source]¶
Return an iterator over at most
boundnumber ofrepeat-tuples ofelements.INPUT:
elements– an iterablerepeat– integer (default:None); the length of the tuples to be returned. IfNone, just returns entries fromelements.bound– the maximum number of tuples returned (ignored ifmax_samplesgiven)max_samples– nonnegative integer (default:None); if given, then a sample of the possible tuples will be returned, instead of the first few in the standard order
OUTPUT:
If
max_samplesis not provided, an iterator over the firstboundtuples of lengthrepeat, in the standard nested-for-loop order.If
max_samplesis provided, a list of at mostmax_samplestuples, sampled uniformly from the possibilities. In this case,elementsmust be finite.
- sage.misc.misc.strunc(s, n=60)[source]¶
Truncate at first space after position n, adding ‘…’ if nontrivial truncation.
- sage.misc.misc.try_read(obj, splitlines=False)[source]¶
Determine if a given object is a readable file-like object and if so read and return its contents.
That is, the object has a callable method named
read()which takes no arguments (exceptself) then the method is executed and the contents are returned.Alternatively, if the
splitlines=Trueis given, firstsplitlines()is tried, then if that failsread().splitlines().If either method fails,
Noneis returned.INPUT:
obj– typically a \(file\) or \(io.BaseIO\) object, but any other object with aread()method is acceptedsplitlines– boolean (default:False); ifTrue, return a list of lines instead of a string
EXAMPLES:
sage: import io sage: filename = tmp_filename() sage: from sage.misc.misc import try_read sage: with open(filename, 'w') as fobj: ....: _ = fobj.write('a\nb\nc') sage: with open(filename) as fobj: ....: print(try_read(fobj)) a b c sage: with open(filename) as fobj: ....: try_read(fobj, splitlines=True) ['a\n', 'b\n', 'c']
>>> from sage.all import * >>> import io >>> filename = tmp_filename() >>> from sage.misc.misc import try_read >>> with open(filename, 'w') as fobj: ... _ = fobj.write('a\nb\nc') >>> with open(filename) as fobj: ... print(try_read(fobj)) a b c >>> with open(filename) as fobj: ... try_read(fobj, splitlines=True) ['a\n', 'b\n', 'c']
The following example is identical to the above example on Python 3, but different on Python 2 where
open != io.open:sage: with io.open(filename) as fobj: ....: print(try_read(fobj)) a b c
>>> from sage.all import * >>> with io.open(filename) as fobj: ... print(try_read(fobj)) a b c
I/O buffers:
sage: buf = io.StringIO('a\nb\nc') sage: print(try_read(buf)) a b c sage: _ = buf.seek(0); try_read(buf, splitlines=True) ['a\n', 'b\n', 'c'] sage: buf = io.BytesIO(b'a\nb\nc') sage: try_read(buf) == b'a\nb\nc' True sage: _ = buf.seek(0) sage: try_read(buf, splitlines=True) == [b'a\n', b'b\n', b'c'] True
>>> from sage.all import * >>> buf = io.StringIO('a\nb\nc') >>> print(try_read(buf)) a b c >>> _ = buf.seek(Integer(0)); try_read(buf, splitlines=True) ['a\n', 'b\n', 'c'] >>> buf = io.BytesIO(b'a\nb\nc') >>> try_read(buf) == b'a\nb\nc' True >>> _ = buf.seek(Integer(0)) >>> try_read(buf, splitlines=True) == [b'a\n', b'b\n', b'c'] True
Custom readable:
sage: class MyFile(): ....: def read(self): return 'Hello world!' sage: try_read(MyFile()) 'Hello world!' sage: try_read(MyFile(), splitlines=True) ['Hello world!']
>>> from sage.all import * >>> class MyFile(): ... def read(self): return 'Hello world!' >>> try_read(MyFile()) 'Hello world!' >>> try_read(MyFile(), splitlines=True) ['Hello world!']
Not readable:
sage: try_read(1) is None True
>>> from sage.all import * >>> try_read(Integer(1)) is None True