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 can easily construct the zero sign vector of a given length:

sage: zero_sign_vector(6)
(000000)

It is also possible to generate some random sign vector:

sage: random_sign_vector(7) # random
(+-+00+-)

To reverse signs, we apply the operator - as usual:

sage: X = sign_vector('+++000--')
sage: X
(+++000--)
sage: -X
(---000++)

There are different notions of support:

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

sage: X.compose(Y)
(-++-0)
sage: Y.compose(X)
(-+++0)

One can also use the operator & to compose sign vectors:

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
(-++-+)

We can apply it in the following way:

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

random_sign_vector(length)

Return a random sign vector of a given length.

sign_vector(iterable)

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

sign_vector_from_support(support, psupport, ...)

Return a sign vector that is given by lists representing support and positive support.

zero_sign_vector(length)

Return the zero sign vector of a given length.

Classes

Sign(value)

Auxiliary object for sign vectors.

SignVector(support, psupport, length)

A sign vector.

class sign_vectors.sign_vectors.Sign(value)

Auxiliary object for sign vectors.

compose(right)

Return the composition of two signs.

INPUT:

  • right – a sign vector

OUTPUT:

Composition of this sign vector with right.

Note

Alternatively, the operator & can be used.

EXAMPLES:

sage: from sign_vectors.sign_vectors import Sign
sage: Sign(1).compose(Sign(0))
+
sage: Sign(0).compose(Sign(-1))
-
sage: Sign(1).compose(Sign(-2))
+
sage: Sign(1) & Sign(2)
+
sage: Sign(-1) & Sign(2)
-
sage: Sign(0) & Sign(0)
0
is_negative() bool

Return whether this sign is -.

is_positive() bool

Return whether this sign is +.

is_zero() bool

Return whether this sign is 0.

static sign_sym(value) int

Return appropriate sign of symbolic expression.

OUTPUT: If the sign cannot be determined, a warning is shown and 0 is returned.

EXAMPLES:

sage: from sign_vectors.sign_vectors import Sign
sage: from sign_vectors import SignVector
sage: Sign.sign_sym(1)
1
sage: Sign.sign_sym(-2)
-1
sage: var('a')
a
sage: Sign.sign_sym(a)
...
UserWarning: Cannot determine sign of symbolic expression, using 0 for sign vector instead.
0
sage: assume(a > 0)
sage: Sign.sign_sym(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.sign_sym((a + b)*(c + d) - b*c)
1
to_integer()

Return the related integer.

class sign_vectors.sign_vectors.SignVector(support, psupport, length: int)

A sign vector.

compose(right)

Return the composition of two sign vectors.

INPUT:

  • right – a sign vector

OUTPUT:

Composition of this sign vector with right.

Note

Alternatively, the operator & can be used.

EXAMPLES:

sage: from sign_vectors import sign_vector
sage: X = sign_vector('+00')
sage: X
(+00)
sage: Y = sign_vector([-1, -1, 0])
sage: 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(right)

Return the composition of two harmonious sign vectors.

INPUT:

  • right – a sign vector

OUTPUT:

Composition of this sign vector with right.

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 sign_vector
sage: X = sign_vector('+00')
sage: X
(+00)
sage: Y = sign_vector([0, -1, 0])
sage: Y
(0-0)
sage: X.compose_harmonious(Y)
(+-0)
sage: Y.compose_harmonious(X)
(+-0)
conforms(right) 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 sign_vector
sage: X = sign_vector([-1, 1, 0, 0, 1]); X
(-+00+)
sage: Y = sign_vector([-1, 1, 1, 0, 1]); Y
(-++0+)
sage: Z = sign_vector([-1, 1, 1, -1, 1]); 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
disjoint_support(other) bool

Return whether these two sign vectors have disjoint support.

INPUT:

  • other – a sign vector or real vector

EXAMPLES:

sage: from sign_vectors import sign_vector
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
is_harmonious(other) 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 sign_vector
sage: X = sign_vector('++00-')
sage: X
(++00-)
sage: Y = sign_vector([1, -2, 1, 2, 5])
sage: Y
(+-+++)
sage: X.is_harmonious(Y)
False
sage: sign_vector('0+00').is_harmonious(sign_vector('-+0+'))
True
sage: v = vector([1, 2/3, 0, -1, -1])
sage: X.is_harmonious(v)
True
sage: Y.is_harmonious(v)
False
is_orthogonal_to(other) 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 sign_vector
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 sign_vector
sage: X = sign_vector('0+-'); X
(0+-)
sage: X.length()
3
list_from_positions(S) list[int]

Return a list of components that are in the list of indices S.

EXAMPLES:

sage: from sign_vectors import sign_vector
sage: X = sign_vector([-1, 1, 0, 0, 1])
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 sign_vector
sage: X = sign_vector([-1, 0, 1, -1, 0])
sage: X
(-0+-0)
sage: X.negative_support()
[0, 3]
positive_support() list[int]

Return a list of indices where the sign vector is positive.

EXAMPLES:

sage: from sign_vectors import sign_vector
sage: X = sign_vector([-1, 0, 1, -1, 0])
sage: X
(-0+-0)
sage: X.positive_support()
[2]
reverse_signs_in(indices)

Reverses sign of given entries.

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 sign_vector
sage: X = sign_vector([-1, 1, 1, 0, 1])
sage: X
(-++0+)
sage: X.reverse_signs_in([0, 2, 3])
(++-0+)
separating_elements(other) 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 sign_vector
sage: X = sign_vector('++00-')
sage: X
(++00-)
sage: Y = sign_vector([1, -2, 1, 2, 5])
sage: Y
(+-+++)
sage: X.separating_elements(Y)
[1, 4]
support() list[int]

Return a list of indices where the sign vector is nonzero.

EXAMPLES:

sage: from sign_vectors import sign_vector
sage: X = sign_vector([-1, 0, 1, -1, 0])
sage: X
(-0+-0)
sage: X.support()
[0, 2, 3]
zero_support() list[int]

Return a list of indices where the sign vector is zero.

EXAMPLES:

sage: from sign_vectors import sign_vector
sage: X = sign_vector([-1, 0, 1, -1, 0])
sage: X
(-0+-0)
sage: X.zero_support()
[1, 4]
sign_vectors.sign_vectors.random_sign_vector(length: int)

Return a random sign vector of a given length.

INPUT:

  • length – length

EXAMPLES:

sage: from sign_vectors import random_sign_vector
sage: random_sign_vector(5) # random
(++-0-)
sign_vectors.sign_vectors.sign_vector(iterable)

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. If variables occur and the signs of the corresponding entries cannot be determined, prints a warning and inserts "0" instead.

EXAMPLES:

sage: from sign_vectors import sign_vector
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) # not tested TODO fails for some reason
...
UserWarning: Cannot determine sign of symbolic expression, using 0 for sign vector instead.
(+0-)
sage: assume(a > 0)
sage: sign_vector(v)
(++-)
sign_vectors.sign_vectors.sign_vector_from_support(support, psupport, length: int)

Return a sign vector that is given by lists representing support and positive support.

INPUT:

  • support – a list

  • psupport – a list

  • length – a nonnegative integer

OUTPUT: a sign vector

Note

The list psupport should be a sublist of support. For efficiency, this is not checked.

EXAMPLES:

sage: from sign_vectors import *
sage: sign_vector_from_support([1, 2, 4], [1, 4], 6)
(0+-0+0)
sign_vectors.sign_vectors.zero_sign_vector(length: int)

Return the zero sign vector of a given length.

INPUT:

  • length – length

EXAMPLES:

sage: from sign_vectors import zero_sign_vector
sage: zero_sign_vector(4)
(0000)