sign_vectors.sign_vectors¶
Sign vectors¶
First, we load the functions from the package:
sage: from sign_vectors import *
There are several ways to define sign vectors:
sage: sign_vector([1, 0, -1, 1])
(+0-+)
sage: x = vector([5, 2/5, -1, 0])
sage: sign_vector(x)
(++-0)
sage: sign_vector('++-+-00-')
(++-+-00-)
We construct the zero sign vector of a given length:
sage: zero_sign_vector(6)
(000000)
It is also possible to generate random sign vectors:
sage: random_sign_vector(7) # random
(+-+00+-)
There are different notions of support:
sage: X = sign_vector('+++000--')
sage: X.support()
[0, 1, 2, 6, 7]
sage: X.zero_support()
[3, 4, 5]
sage: X.positive_support()
[0, 1, 2]
sage: X.negative_support()
[6, 7]
Next, we define two sign vectors:
sage: X = sign_vector([-1, 0, 1, -1, 0])
sage: X
(-0+-0)
sage: Y = sign_vector([0, 1, 0, 1, 0])
sage: Y
(0+0+0)
We compose them:
sage: X.compose(Y)
(-++-0)
sage: Y.compose(X)
(-+++0)
Use the operator &
as a shorthand for composition:
sage: X & Y
(-++-0)
sage: Y & X
(-+++0)
The conformal relation is a partial order on a set of sign vectors:
sage: X = sign_vector([-1, 1, 0, 0, 1])
sage: Y = sign_vector([-1, 1, 1, 0, 1])
sage: Z = sign_vector([-1, 1, 1, -1, 1])
sage: X
(-+00+)
sage: Y
(-++0+)
sage: Z
(-++-+)
sage: X.conforms(Y)
True
sage: X.conforms(X)
True
sage: Y.conforms(Z)
True
sage: Z.conforms(Y)
False
sage: X.conforms(Z)
True
sage: X < X
False
sage: X <= Y
True
sage: Y > Z
False
sage: Z >= X
True
Similar as for real vectors, we define orthogonality for sign vectors. First, we define some real vectors:
sage: x = vector([0, 0, 1])
sage: y = vector([1, -2, 0])
sage: z = vector([2, 1, 2])
We compute some scalar products to investigate orthogonality of those vectors:
sage: x.dot_product(y)
0
sage: y.dot_product(z)
0
sage: x.dot_product(z)
2
Next, we define the corresponding sign vectors:
sage: X = sign_vector(x)
sage: X
(00+)
sage: Y = sign_vector(y)
sage: Y
(+-0)
sage: Z = sign_vector(z)
sage: Z
(+++)
By definition, if two real vectors are orthogonal, then their corresponding sign vectors are also orthogonal:
sage: X.is_orthogonal_to(Y)
True
sage: Y.is_orthogonal_to(Z)
True
sage: X.is_orthogonal_to(Z)
False
Functions
|
Return a random sign vector of a given length. |
|
Return the sign of an expression. |
|
Create a sign vector from a list, vector or string. |
|
Return the zero sign vector of a given length. |
Classes
|
A sign vector. |
- class sign_vectors.sign_vectors.SignVector(positive_support: sage.data_structures.bitset.FrozenBitset, negative_support: sage.data_structures.bitset.FrozenBitset)¶
A sign vector.
- category(self)¶
File: sage/structure/sage_object.pyx (starting at line 484)
- compose(other: sign_vectors.sign_vectors.SignVector) sign_vectors.sign_vectors.SignVector ¶
Return the composition of two sign vectors.
INPUT:
other
– a sign vector
OUTPUT:
Composition of this sign vector with
other
.Note
Alternatively, the operator
&
can be used.EXAMPLES:
sage: from sign_vectors import * sage: X = sign_vector('+00'); X (+00) sage: Y = sign_vector('--0'); Y (--0) sage: X.compose(Y) (+-0) sage: Y.compose(X) (--0) sage: Y & X (--0) sage: X = sign_vector('000+++---') sage: Y = sign_vector('0+-0+-0+-') sage: X.compose(Y) (0+-+++---)
- compose_harmonious(other: sign_vectors.sign_vectors.SignVector) sign_vectors.sign_vectors.SignVector ¶
Return the composition of two harmonious sign vectors.
INPUT:
other
– a sign vector
OUTPUT:
Composition of this sign vector with
other
.Note
This method is more efficient than -
compose()
. However, it does not check whether the sign vectors are harmonious.EXAMPLES:
sage: from sign_vectors import * sage: X = sign_vector('+00') sage: X (+00) sage: Y = sign_vector('0-0') sage: Y (0-0) sage: X.compose_harmonious(Y) (+-0) sage: Y.compose_harmonious(X) (+-0)
- conforms(other: sign_vectors.sign_vectors.SignVector) bool ¶
Conformal relation of two sign vectors.
Note
Alternatively, the operator
<=
can be used. Use>=
,<
and>
for the other relations.EXAMPLES:
sage: from sign_vectors import * sage: X = sign_vector('-+00+'); X (-+00+) sage: Y = sign_vector('-++0+'); Y (-++0+) sage: Z = sign_vector('-++-+'); Z (-++-+) sage: X.conforms(Y) True sage: X.conforms(X) True sage: Y.conforms(Z) True sage: Z.conforms(Y) False sage: X.conforms(Z) True
- delete_components(indices: list[int]) sign_vectors.sign_vectors.SignVector ¶
Delete the given components from the sign vector.
INPUT:
indices
– list of indices to delete
OUTPUT:
Returns a new sign vector with the specified components removed.
EXAMPLES:
sage: from sign_vectors import * sage: X = sign_vector('+0-') sage: X (+0-) sage: X.delete_components([1]) (+-)
sage: X = sign_vector('-+0+0') sage: X (-+0+0) sage: X.delete_components([0, 2]) (++0) sage: X.delete_components([1]) (-0+0)
- disjoint_support(other: sign_vectors.sign_vectors.SignVector) bool ¶
Return whether these two sign vectors have disjoint support.
INPUT:
other
– a sign vector or real vector
EXAMPLES:
sage: from sign_vectors import * sage: X = sign_vector('++00') sage: Y = sign_vector('0+0-') sage: Z = sign_vector('00--') sage: X.disjoint_support(Y) False sage: Y.disjoint_support(X) False sage: X.disjoint_support(Z) True sage: Z.disjoint_support(X) True sage: Y.disjoint_support(Z) False
- dump(self, filename, compress=True)¶
File: sage/structure/sage_object.pyx (starting at line 445)
Same as self.save(filename, compress)
- dumps(self, compress=True)¶
File: sage/structure/sage_object.pyx (starting at line 451)
Dump
self
to a strings
, which can later be reconstituted asself
usingloads(s)
.There is an optional boolean argument
compress
which defaults toTrue
.EXAMPLES:
sage: from sage.misc.persist import comp sage: O = SageObject() sage: p_comp = O.dumps() sage: p_uncomp = O.dumps(compress=False) sage: comp.decompress(p_comp) == p_uncomp True sage: import pickletools sage: pickletools.dis(p_uncomp) 0: \x80 PROTO 2 2: c GLOBAL 'sage.structure.sage_object SageObject' 41: q BINPUT ... 43: ) EMPTY_TUPLE 44: \x81 NEWOBJ 45: q BINPUT ... 47: . STOP highest protocol among opcodes = 2
- flip_signs(indices: list[int]) sign_vectors.sign_vectors.SignVector ¶
Flips entries of given indices.
INPUT:
indices
– list of indices
OUTPUT: Returns a new sign vector. Components of
indices
are multiplied by-1
.EXAMPLES:
sage: from sign_vectors import * sage: X = sign_vector('-++0+') sage: X (-++0+) sage: X.flip_signs([0, 2, 3]) (++-0+)
sage: X = sign_vector('+-0+0') sage: X (+-0+0) sage: X.flip_signs([0, 3, 4]) (--0-0)
- classmethod from_iterable(iterable) sign_vectors.sign_vectors.SignVector ¶
Create a sign vector from an iterable.
EXAMPLES:
sage: from sign_vectors import * sage: SignVector.from_iterable([5, 0, -1, -2]) (+0--) sage: v = vector([5, 0, -1, 0, 8]) sage: SignVector.from_iterable(v) (+0-0+)
- classmethod from_string(s: str) sign_vectors.sign_vectors.SignVector ¶
Create a sign vector from a string.
EXAMPLES:
sage: from sign_vectors import * sage: SignVector.from_string("+-0+0") (+-0+0)
- classmethod from_support(positive_support: list[int], negative_support: list[int], length: int) sign_vectors.sign_vectors.SignVector ¶
Return a sign vector that is given by lists representing positive support and negative support.
INPUT:
positive_support
– a list of integers.negative_support
– a list of integers.length
– a nonnegative integer
OUTPUT: a sign vector
Note
The list
positive_support
andnegative_support
should be disjoint. For efficiency, this is not checked.EXAMPLES:
sage: from sign_vectors import * sage: SignVector.from_support([1, 4], [2], 6) (0+-0+0)
- is_harmonious_to(other: sign_vectors.sign_vectors.SignVector) bool ¶
Check whether these two sign vectors are harmonious.
INPUT:
other
– a sign vector or real vector
OUTPUT: Returns true if there are no separating elements. Otherwise, false is returned.
Note
Two sign vectors are harmonious if there is no component where one sign vector has
+
and the other has-
.EXAMPLES:
sage: from sign_vectors import * sage: X = sign_vector('++00-') sage: X (++00-) sage: Y = sign_vector('+-+++') sage: Y (+-+++) sage: X.is_harmonious_to(Y) False sage: sign_vector('0+00').is_harmonious_to(sign_vector('-+0+')) True sage: v = vector([1, 2/3, 0, -1, -1]) sage: X.is_harmonious_to(v) True sage: Y.is_harmonious_to(v) False
- is_orthogonal_to(other: sign_vectors.sign_vectors.SignVector) bool ¶
Return whether two sign vectors are orthogonal.
INPUT:
other
– a sign vector.
OUTPUT:
Returns
True
if the sign vectors are orthogonal andFalse
otherwise.
EXAMPLES:
sage: from sign_vectors import * sage: X = sign_vector('-+00+'); X (-+00+) sage: X.is_orthogonal_to(X) False sage: X.is_orthogonal_to(sign_vector('++000')) True sage: X.is_orthogonal_to(sign_vector('++00+')) True sage: X.is_orthogonal_to(sign_vector('00++0')) True
- is_vector() bool ¶
Return
False
since sign vectors are not vectors.
- length() int ¶
Return the length of the sign vector.
EXAMPLES:
sage: from sign_vectors import * sage: X = sign_vector('0+-'); X (0+-) sage: X.length() 3
- list_from_positions(positions: list[int]) list[int] ¶
Return a list of components that are in the list of indices
positions
.EXAMPLES:
sage: from sign_vectors import * sage: X = sign_vector('-+00+'); X (-+00+) sage: X.list_from_positions([0, 1, 4]) [-1, 1, 1]
- negative_support() list[int] ¶
Return a list of indices where the sign vector is negative.
EXAMPLES:
sage: from sign_vectors import * sage: X = sign_vector('-0+-0'); X (-0+-0) sage: X.negative_support() [0, 3]
- parent(self)¶
File: sage/structure/sage_object.pyx (starting at line 518)
Return the type of
self
to support the coercion framework.EXAMPLES:
sage: t = log(sqrt(2) - 1) + log(sqrt(2) + 1); t log(sqrt(2) + 1) + log(sqrt(2) - 1) sage: u = t.maxima_methods() sage: u.parent() <class 'sage.symbolic.maxima_wrapper.MaximaWrapper'>
- positive_support() list[int] ¶
Return a list of indices where the sign vector is positive.
EXAMPLES:
sage: from sign_vectors import * sage: X = sign_vector('-0+-0'); X (-0+-0) sage: X.positive_support() [2]
- rename(self, x=None)¶
File: sage/structure/sage_object.pyx (starting at line 68)
Change self so it prints as x, where x is a string.
Note
This is only supported for Python classes that derive from SageObject.
EXAMPLES:
sage: x = PolynomialRing(QQ, 'x', sparse=True).gen() sage: g = x^3 + x - 5 sage: g x^3 + x - 5 sage: g.rename('a polynomial') sage: g a polynomial sage: g + x x^3 + 2*x - 5 sage: h = g^100 sage: str(h)[:20] 'x^300 + 100*x^298 - ' sage: h.rename('x^300 + ...') sage: h x^300 + ...
Real numbers are not Python classes, so rename is not supported:
sage: a = 3.14 sage: type(a) <... 'sage.rings.real_mpfr.RealLiteral'> sage: a.rename('pi') Traceback (most recent call last): ... NotImplementedError: object does not support renaming: 3.14000000000000
Note
The reason C-extension types are not supported by default is if they were then every single one would have to carry around an extra attribute, which would be slower and waste a lot of memory.
To support them for a specific class, add a
cdef public __custom_name
attribute.
- reset_name(self)¶
File: sage/structure/sage_object.pyx (starting at line 125)
Remove the custom name of an object.
EXAMPLES:
sage: P.<x> = QQ[] sage: P Univariate Polynomial Ring in x over Rational Field sage: P.rename('A polynomial ring') sage: P A polynomial ring sage: P.reset_name() sage: P Univariate Polynomial Ring in x over Rational Field
- save(self, filename=None, compress=True)¶
File: sage/structure/sage_object.pyx (starting at line 420)
Save self to the given filename.
EXAMPLES:
sage: f = x^3 + 5 sage: f.save(os.path.join(SAGE_TMP, 'file')) sage: load(os.path.join(SAGE_TMP, 'file.sobj')) x^3 + 5
- separating_elements(other: sign_vectors.sign_vectors.SignVector) list[int] ¶
Compute the list of separating elements of two sign vectors.
INPUT:
other
– sign vector
OUTPUT: List of elements
e
such thatself[e] == -other[e] != 0
.EXAMPLES:
sage: from sign_vectors import * sage: X = sign_vector('++00-') sage: X (++00-) sage: Y = sign_vector('+-+++') sage: Y (+-+++) sage: X.separating_elements(Y) [1, 4]
- set_to_zero(indices: list[int]) sign_vectors.sign_vectors.SignVector ¶
Set given entries to zero.
INPUT:
indices
– list of indices
OUTPUT: Returns a new sign vector of same length. Components with indices in
indices
are multiplied by-1
.EXAMPLES:
sage: from sign_vectors import * sage: X = sign_vector('-++0+') sage: X (-++0+) sage: X.set_to_zero([0, 2, 3]) (0+00+)
sage: X = sign_vector('+-+0+0') sage: X (+-+0+0) sage: X.set_to_zero([0, 1, 4]) (00+000)
- support() list[int] ¶
Return a list of indices where the sign vector is nonzero.
EXAMPLES:
sage: from sign_vectors import * sage: X = sign_vector('-0+-0'); X (-0+-0) sage: X.support() [0, 2, 3]
- to_string() str ¶
Return a string representation of this sign vector (without parentheses).
EXAMPLES:
sage: from sign_vectors import * sage: X = sign_vector("0+-") sage: X (0+-) sage: X.to_string() '0+-'
Note that that str and to_string are different:
sage: str(X) '(0+-)'
- classmethod zero(length: int) sign_vectors.sign_vectors.SignVector ¶
Create a zero sign vector of a given length.
EXAMPLES:
sage: from sign_vectors import * sage: SignVector.zero(5) (00000)
- zero_support() list[int] ¶
Return a list of indices where the sign vector is zero.
EXAMPLES:
sage: from sign_vectors import * sage: X = sign_vector('-0+-0'); X (-0+-0) sage: X.zero_support() [1, 4]
- sign_vectors.sign_vectors.random_sign_vector(length: int) sign_vectors.sign_vectors.SignVector ¶
Return a random sign vector of a given length.
INPUT:
length
– length
EXAMPLES:
sage: from sign_vectors import * sage: random_sign_vector(5) # random (++-0-)
TEST:
sage: len(random_sign_vector(5)) 5
- sign_vectors.sign_vectors.sign_symbolic(value) int ¶
Return the sign of an expression. Supports symbolic expressions.
OUTPUT: If the sign cannot be determined, a warning is shown and
0
is returned.EXAMPLES:
For real numbers, the sign is determined:
sage: from sign_vectors.sign_vectors import sign_symbolic sage: sign_symbolic(1) 1 sage: sign_symbolic(-1/2) -1 sage: sign_symbolic(0) 0
For symbolic expressions, the sign is determined using assumptions:
sage: var('a') a sage: sign_symbolic(a) # not tested ... UserWarning: Cannot determine sign of symbolic expression, using ``0`` instead. 0 sage: assume(a > 0) sage: sign_symbolic(a) 1 sage: forget()
sage: var('a, b, c, d') (a, b, c, d) sage: assume(a > 0, b > 0, c > 0, d > 0) sage: sign_symbolic((a + b)*(c + d) - b*c) 1
- sign_vectors.sign_vectors.sign_vector(iterable: list[int] | str | sign_vectors.sign_vectors.SignVector) sign_vectors.sign_vectors.SignVector ¶
Create a sign vector from a list, vector or string.
INPUT:
iterable
– different inputs are accepted:an iterable (e.g. a list or vector) of real values. Variables can also occur.
a string consisting of
"-"
,"+"
,"0"
. Other characters are treated as"0"
.
OUTPUT:
Returns a sign vector.
EXAMPLES:
sage: from sign_vectors import * sage: sign_vector([5, 0, -1, -2]) (+0--) sage: v = vector([5, 0, -1, -2]) sage: sign_vector(v) (+0--)
We can also use a string to construct a sign vector:
sage: sign_vector("00--") (00--) sage: sign_vector('++-+-00-') (++-+-00-)
Variables are supported to some extent:
sage: var('a') a sage: v = vector([1, a, -1]) sage: sign_vector(v) ... UserWarning: Cannot determine sign of symbolic expression, using ``0`` instead. (+0-) sage: assume(a > 0) sage: sign_vector(v) (++-) sage: forget()
TESTS:
sage: sign_vector(sign_vector("+-+")) (+-+)
- sign_vectors.sign_vectors.zero_sign_vector(length: int) sign_vectors.sign_vectors.SignVector ¶
Return the zero sign vector of a given length.
INPUT:
length
– length
EXAMPLES:
sage: from sign_vectors import * sage: zero_sign_vector(4) (0000)