sign_vectors.sign_vectors

Sign vectors

There are several ways to define sign vectors:

sage: from sign_vectors import *
sage: sign_vector("+0-+-0")
(+0-+-0)
sage: sign_vector([1, 0, -1, 1])
(+0-+)
sage: v = vector([5, 2/5, -1, 0])
sage: sign_vector(v)
(++-0)

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 and compose them:

sage: X = sign_vector("-0+-0")
sage: Y = sign_vector("0+0+0")
sage: X.compose(Y)
(-++-0)
sage: Y.compose(X)
(-+++0)

The conformal relation is a partial order on a set of sign vectors:

sage: X = sign_vector("-+00+")
sage: Y = sign_vector("-++0+")
sage: Z = sign_vector("-+0+0")
sage: X.conforms(Y)
True
sage: Y.conforms(Z)
False
sage: X < Y
True
sage: X <= Z
False

Functions

random_sign_vector(length)

Return a random sign vector of a given length.

sign_symbolic(value)

Return the sign of an expression.

sign_vector(iterable)

Create a sign vector from a list, vector or string.

zero_sign_vector(length)

Return the zero sign vector of a given length.

Classes

SignVector(positive_support, negative_support)

A sign vector.

class sign_vectors.sign_vectors.SignVector(positive_support: FrozenBitset, negative_support: FrozenBitset)

A sign vector.

category(self)

File: sage/structure/sage_object.pyx (starting at line 484)

compose(other: SignVector) SignVector

Return the composition of two sign vectors.

INPUT:

  • other – a sign vector

OUTPUT:

Composition of this sign vector with other.

EXAMPLES:

sage: from sign_vectors import *
sage: X = sign_vector("+00")
sage: X
(+00)
sage: Y = sign_vector("--0")
sage: Y
(--0)
sage: X.compose(Y)
(+-0)
sage: Y.compose(X)
(--0)
sage: X = sign_vector("000+++---")
sage: Y = sign_vector("0+-0+-0+-")
sage: X.compose(Y)
(0+-+++---)
compose_harmonious(other: SignVector) SignVector

Return the composition of two harmonious sign vectors.

INPUT:

  • other – a sign vector

OUTPUT:

Composition of this sign vector with other. Two sign vectors are harmonious if there are no separating elements.

Note

This method is more efficient than compose() but requires the sign vectors to be 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: 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+")
sage: X
(-+00+)
sage: Y = sign_vector("-++0+")
sage: Y
(-++0+)
sage: Z = sign_vector("-++-+")
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
delete_components(indices: list[int]) 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: 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 string s, which can later be reconstituted as self using loads(s).

There is an optional boolean argument compress which defaults to True.

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]) 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) 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) 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) 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 and negative_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: 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: SignVector) bool

Return whether two sign vectors are orthogonal.

INPUT:

  • other – a sign vector.

OUTPUT:

  • Returns True if the sign vectors are orthogonal and False otherwise.

EXAMPLES:

sage: from sign_vectors import *
sage: X = sign_vector("-+00+")
sage: 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+-")
sage: 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+")
sage: 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")
sage: 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")
sage: 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: SignVector) list[int]

Compute the list of separating elements of two sign vectors.

INPUT:

  • other – sign vector

OUTPUT: List of elements e such that self[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_minus(indices: list[int]) SignVector

Set given entries to minus.

INPUT:

  • indices – list of indices

OUTPUT: Returns a new sign vector of same length. Components with indices in indices are set to -.

EXAMPLES:

sage: from sign_vectors import *
sage: X = sign_vector("-++0+")
sage: X
(-++0+)
sage: X.set_to_minus([0, 2, 3])
(-+--+)
sage: X = sign_vector("+-+0+0")
sage: X
(+-+0+0)
sage: X.set_to_minus([0, 1, 4])
(--+0-0)
set_to_plus(indices: list[int]) SignVector

Set given entries to plus.

INPUT:

  • indices – list of indices

OUTPUT: Returns a new sign vector of same length. Components with indices in indices are set to +.

EXAMPLES:

sage: from sign_vectors import *
sage: X = sign_vector("-++0+")
sage: X
(-++0+)
sage: X.set_to_plus([0, 2, 3])
(+++++)
sage: X = sign_vector("+-+0+0")
sage: X
(+-+0+0)
sage: X.set_to_plus([0, 1, 4])
(+++0+0)
set_to_zero(indices: list[int]) 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 set to 0.

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")
sage: 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) 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")
sage: X
(-0+-0)
sage: X.zero_support()
[1, 4]
sign_vectors.sign_vectors.random_sign_vector(length: int) 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 | SignVector) 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) 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)