\(\ZZ\)-filtered vector spaces#

This module implements filtered vector spaces, that is, a descending sequence of vector spaces

\[\cdots \supset F_d \supset F_{d+1} \supset F_{d+2} \supset \cdots\]

with degrees \(d\in \ZZ\). It is not required that \(F_d\) is the entire ambient space for \(d\ll 0\) (see is_exhaustive()) nor that \(F_d=0\) for \(d\gg 0\) (see is_separating()). To construct a filtered vector space, use the FilteredVectorSpace() command. It supports easy creation of simple filtrations, for example the trivial one:

sage: FilteredVectorSpace(2, base_ring=RDF)
RDF^2
>>> from sage.all import *
>>> FilteredVectorSpace(Integer(2), base_ring=RDF)
RDF^2

The next-simplest filtration has a single non-trivial inclusion between \(V_d\) and \(V_{d+1}\):

sage: d = 1
sage: V = FilteredVectorSpace(2, d);  V
QQ^2 >= 0
sage: [V.get_degree(i).dimension() for i in range(0,4)]
[2, 2, 0, 0]
>>> from sage.all import *
>>> d = Integer(1)
>>> V = FilteredVectorSpace(Integer(2), d);  V
QQ^2 >= 0
>>> [V.get_degree(i).dimension() for i in range(Integer(0),Integer(4))]
[2, 2, 0, 0]

To construct general filtrations, you need to tell Sage about generating vectors for the nested subspaces. For example, a dictionary whose keys are the degrees and values are a list of generators:

sage: r1 = (1, 0, 5)
sage: r2 = (0, 1, 2)
sage: r3 = (1, 2, 1)
sage: V = FilteredVectorSpace({0:[r1, r2, r3], 1:[r1, r2], 3:[r1]});  V
QQ^3 >= QQ^2 >= QQ^1 >= QQ^1 >= 0
>>> from sage.all import *
>>> r1 = (Integer(1), Integer(0), Integer(5))
>>> r2 = (Integer(0), Integer(1), Integer(2))
>>> r3 = (Integer(1), Integer(2), Integer(1))
>>> V = FilteredVectorSpace({Integer(0):[r1, r2, r3], Integer(1):[r1, r2], Integer(3):[r1]});  V
QQ^3 >= QQ^2 >= QQ^1 >= QQ^1 >= 0

For degrees \(d\) that are not specified, the associated vector subspace is the same as the next-lower degree, that is, \(V_d \simeq V_{d-1}\). In the above example, this means that

  • \(V_d \simeq \QQ^3\) for \(d<0\)

  • \(V_0 = \mathop{span}(r_1, r_2) \simeq \QQ^2\)

  • \(V_1 = V_2 = \mathop{span}(r_3) \simeq \QQ\)

  • \(V_d = 0\) for \(d \geq 3\)

That is:

sage: V.get_degree(0) == V
True
sage: V.get_degree(1) == V.span([r1, r2])
True
sage: V.get_degree(2) == V.get_degree(3) == V.span([r1])
True
sage: V.get_degree(4) == V.get_degree(5) == V.span([])
True
>>> from sage.all import *
>>> V.get_degree(Integer(0)) == V
True
>>> V.get_degree(Integer(1)) == V.span([r1, r2])
True
>>> V.get_degree(Integer(2)) == V.get_degree(Integer(3)) == V.span([r1])
True
>>> V.get_degree(Integer(4)) == V.get_degree(Integer(5)) == V.span([])
True

If you have many generators you can just pass the generators once and then refer to them by index:

sage: FilteredVectorSpace([r1, r2, r3], {0:[0,1,2], 1:[1,2], 3:[1]})
QQ^3 >= QQ^2 >= QQ^1 >= QQ^1 >= 0
>>> from sage.all import *
>>> FilteredVectorSpace([r1, r2, r3], {Integer(0):[Integer(0),Integer(1),Integer(2)], Integer(1):[Integer(1),Integer(2)], Integer(3):[Integer(1)]})
QQ^3 >= QQ^2 >= QQ^1 >= QQ^1 >= 0

Note that generators for the degree-\(d\) subspace of the filtration are automatically generators for all lower degrees. For example, here we do not have to specify the ray \(r_2\) separately in degree 1:

sage: FilteredVectorSpace([r1, r2, r3], {0:[0   ], 1:[1]})
QQ^2 >= QQ^1 >= 0 in QQ^3
sage: FilteredVectorSpace([r1, r2, r3], {0:[0, 1], 1:[1]})
QQ^2 >= QQ^1 >= 0 in QQ^3
>>> from sage.all import *
>>> FilteredVectorSpace([r1, r2, r3], {Integer(0):[Integer(0)   ], Integer(1):[Integer(1)]})
QQ^2 >= QQ^1 >= 0 in QQ^3
>>> FilteredVectorSpace([r1, r2, r3], {Integer(0):[Integer(0), Integer(1)], Integer(1):[Integer(1)]})
QQ^2 >= QQ^1 >= 0 in QQ^3

The degree can be infinite (plus infinity), this allows construction of filtered vector spaces that are not eventually zero in high degree:

sage: FilteredVectorSpace([r1, r2, r3], {0:[0,1], oo:[1]})
QQ^2 >= QQ^1 in QQ^3
>>> from sage.all import *
>>> FilteredVectorSpace([r1, r2, r3], {Integer(0):[Integer(0),Integer(1)], oo:[Integer(1)]})
QQ^2 >= QQ^1 in QQ^3

Any field can be used as the vector space base. For example a finite field:

sage: F.<a> = GF(5^3)                                                               # needs sage.rings.finite_rings
sage: r1 = (a, 0, F(5));  r1                                                        # needs sage.rings.finite_rings
(a, 0, 0)
sage: FilteredVectorSpace([r1, r2, r3], {0:[0,1], oo:[1]}, base_ring=F)             # needs sage.rings.finite_rings
GF(125)^2 >= GF(125)^1 in GF(125)^3
>>> from sage.all import *
>>> F = GF(Integer(5)**Integer(3), names=('a',)); (a,) = F._first_ngens(1)# needs sage.rings.finite_rings
>>> r1 = (a, Integer(0), F(Integer(5)));  r1                                                        # needs sage.rings.finite_rings
(a, 0, 0)
>>> FilteredVectorSpace([r1, r2, r3], {Integer(0):[Integer(0),Integer(1)], oo:[Integer(1)]}, base_ring=F)             # needs sage.rings.finite_rings
GF(125)^2 >= GF(125)^1 in GF(125)^3

Or the algebraic field:

sage: r1 = (1, 0, 1+QQbar(I));  r1                                                  # needs sage.rings.number_field
(1, 0, I + 1)
sage: FilteredVectorSpace([r1, r2, r3], {0:[0,1], oo:[1]}, base_ring=QQbar)         # needs sage.rings.number_field
Vector space of dimension 2 over Algebraic Field
>= Vector space of dimension 1 over Algebraic Field
in Vector space of dimension 3 over Algebraic Field
>>> from sage.all import *
>>> r1 = (Integer(1), Integer(0), Integer(1)+QQbar(I));  r1                                                  # needs sage.rings.number_field
(1, 0, I + 1)
>>> FilteredVectorSpace([r1, r2, r3], {Integer(0):[Integer(0),Integer(1)], oo:[Integer(1)]}, base_ring=QQbar)         # needs sage.rings.number_field
Vector space of dimension 2 over Algebraic Field
>= Vector space of dimension 1 over Algebraic Field
in Vector space of dimension 3 over Algebraic Field
sage.modules.filtered_vector_space.FilteredVectorSpace(arg1, arg2=None, base_ring=Rational Field, check=True)[source]#

Construct a filtered vector space.

INPUT:

This function accepts various input that determines the vector space and filtration.

  • Just the dimensionFilteredVectorSpace(dimension): Return the trivial filtration (where all vector spaces are isomorphic).

  • Dimension and maximal degree, see constructor_from_dim_degree() for arguments. Construct a filtration with only one non-trivial step \(V\supset 0\) at the given cutoff degree.

  • A dictionary containing the degrees as keys and a list of vector space generators as values, see FilteredVectorSpace_from_generators()

  • Generators and a dictionary containing the degrees as keys and the indices of vector space generators as values, see FilteredVectorSpace_from_generators_indices()

In addition, the following keyword arguments are supported:

  • base_ring – a field (default: \(\QQ\)). The base field of the vector space. Must be a field.

EXAMPLES:

Just the dimension for the trivial filtration:

sage: FilteredVectorSpace(2)
QQ^2
>>> from sage.all import *
>>> FilteredVectorSpace(Integer(2))
QQ^2

Dimension and degree:

sage: FilteredVectorSpace(2, 1)
QQ^2 >= 0
>>> from sage.all import *
>>> FilteredVectorSpace(Integer(2), Integer(1))
QQ^2 >= 0

Dictionary of generators:

sage: FilteredVectorSpace({1:[(1,0), (0,1)], 3:[(1,0)]})
QQ^2 >= QQ^1 >= QQ^1 >= 0
>>> from sage.all import *
>>> FilteredVectorSpace({Integer(1):[(Integer(1),Integer(0)), (Integer(0),Integer(1))], Integer(3):[(Integer(1),Integer(0))]})
QQ^2 >= QQ^1 >= QQ^1 >= 0

Generators and a dictionary referring to them by index:

sage: FilteredVectorSpace([(1,0), (0,1)], {1:[0,1], 3:[0]})
QQ^2 >= QQ^1 >= QQ^1 >= 0
>>> from sage.all import *
>>> FilteredVectorSpace([(Integer(1),Integer(0)), (Integer(0),Integer(1))], {Integer(1):[Integer(0),Integer(1)], Integer(3):[Integer(0)]})
QQ^2 >= QQ^1 >= QQ^1 >= 0
class sage.modules.filtered_vector_space.FilteredVectorSpace_class(base_ring, dim, generators, filtration, check=True)[source]#

Bases: FreeModule_ambient_field

A descending filtration of a vector space

INPUT:

  • base_ring – a field. The base field of the ambient vector space.

  • dim – integer. The dimension of the ambient vector space.

  • generators – tuple of generators for the ambient vector space. These will be used to span the subspaces of the filtration.

  • filtration – a dictionary of filtration steps in ray index notation. See construct_from_generators_indices() for details.

  • check – boolean (optional; default: True). Whether to perform consistency checks.

ambient_vector_space()[source]#

Return the ambient (unfiltered) vector space.

OUTPUT:

A vector space.

EXAMPLES:

sage: V = FilteredVectorSpace(1, 0)
sage: V.ambient_vector_space()
Vector space of dimension 1 over Rational Field
>>> from sage.all import *
>>> V = FilteredVectorSpace(Integer(1), Integer(0))
>>> V.ambient_vector_space()
Vector space of dimension 1 over Rational Field
change_ring(base_ring)[source]#

Return the same filtration over a different base ring.

INPUT:

  • base_ring – a ring. The new base ring.

OUTPUT:

This method returns a new filtered vector space whose subspaces are defined by the same generators but over a different base ring.

EXAMPLES:

sage: V = FilteredVectorSpace(1, 0);  V
QQ^1 >= 0
sage: V.change_ring(RDF)
RDF^1 >= 0
>>> from sage.all import *
>>> V = FilteredVectorSpace(Integer(1), Integer(0));  V
QQ^1 >= 0
>>> V.change_ring(RDF)
RDF^1 >= 0
direct_sum(other)[source]#

Return the direct sum.

INPUT:

  • other – a filtered vector space.

OUTPUT:

The direct sum as a filtered vector space.

EXAMPLES:

sage: V = FilteredVectorSpace(2, 0)
sage: W = FilteredVectorSpace({0:[(1,-1),(2,1)], 1:[(1,1)]})
sage: V.direct_sum(W)
QQ^4 >= QQ^1 >= 0
sage: V + W    # syntactic sugar
QQ^4 >= QQ^1 >= 0
sage: V + V == FilteredVectorSpace(4, 0)
True

sage: W = FilteredVectorSpace([(1,-1),(2,1)], {1:[0,1], 2:[1]})
sage: V + W
QQ^4 >= QQ^2 >= QQ^1 >= 0
>>> from sage.all import *
>>> V = FilteredVectorSpace(Integer(2), Integer(0))
>>> W = FilteredVectorSpace({Integer(0):[(Integer(1),-Integer(1)),(Integer(2),Integer(1))], Integer(1):[(Integer(1),Integer(1))]})
>>> V.direct_sum(W)
QQ^4 >= QQ^1 >= 0
>>> V + W    # syntactic sugar
QQ^4 >= QQ^1 >= 0
>>> V + V == FilteredVectorSpace(Integer(4), Integer(0))
True

>>> W = FilteredVectorSpace([(Integer(1),-Integer(1)),(Integer(2),Integer(1))], {Integer(1):[Integer(0),Integer(1)], Integer(2):[Integer(1)]})
>>> V + W
QQ^4 >= QQ^2 >= QQ^1 >= 0

A suitable base ring is chosen if they do not match:

sage: v = [(1,0), (0,1)]
sage: F1 = FilteredVectorSpace(v, {0:[0], 1:[1]}, base_ring=QQ)
sage: F2 = FilteredVectorSpace(v, {0:[0], 1:[1]}, base_ring=RDF)
sage: F1 + F2                                                               # needs scipy
RDF^4 >= RDF^2 >= 0
>>> from sage.all import *
>>> v = [(Integer(1),Integer(0)), (Integer(0),Integer(1))]
>>> F1 = FilteredVectorSpace(v, {Integer(0):[Integer(0)], Integer(1):[Integer(1)]}, base_ring=QQ)
>>> F2 = FilteredVectorSpace(v, {Integer(0):[Integer(0)], Integer(1):[Integer(1)]}, base_ring=RDF)
>>> F1 + F2                                                               # needs scipy
RDF^4 >= RDF^2 >= 0
dual()[source]#

Return the dual filtered vector space.

OUTPUT:

The graded dual, that is, the dual of a degree-\(d\) subspace is a set of linear constraints in degree \(-d+1\). That is, the dual generators live in degree \(-d\).

EXAMPLES:

sage: gens = identity_matrix(3).rows()
sage: F = FilteredVectorSpace(gens, {0:[0,1,2], 2:[0]});  F
QQ^3 >= QQ^1 >= QQ^1 >= 0
sage: F.support()
(0, 2)

sage: F.dual()
QQ^3 >= QQ^2 >= QQ^2 >= 0
sage: F.dual().support()
(-2, 0)
>>> from sage.all import *
>>> gens = identity_matrix(Integer(3)).rows()
>>> F = FilteredVectorSpace(gens, {Integer(0):[Integer(0),Integer(1),Integer(2)], Integer(2):[Integer(0)]});  F
QQ^3 >= QQ^1 >= QQ^1 >= 0
>>> F.support()
(0, 2)

>>> F.dual()
QQ^3 >= QQ^2 >= QQ^2 >= 0
>>> F.dual().support()
(-2, 0)
exterior_power(n)[source]#

Return the \(n\)-th graded exterior power.

INPUT:

  • n – integer. Exterior product of how many copies of self.

OUTPUT:

The graded exterior product, that is, the wedge product of a generator of degree \(d_1\) with a generator in degree \(d_2\) has degree \(d_1 + d_2\).

EXAMPLES:

sage: # needs sage.groups
sage: F = FilteredVectorSpace(1, 1) + FilteredVectorSpace(1, 2);  F
QQ^2 >= QQ^1 >= 0
sage: F.exterior_power(1)
QQ^2 >= QQ^1 >= 0
sage: F.exterior_power(2)
QQ^1 >= 0
sage: F.exterior_power(3)
0
sage: F.wedge(2)
QQ^1 >= 0
>>> from sage.all import *
>>> # needs sage.groups
>>> F = FilteredVectorSpace(Integer(1), Integer(1)) + FilteredVectorSpace(Integer(1), Integer(2));  F
QQ^2 >= QQ^1 >= 0
>>> F.exterior_power(Integer(1))
QQ^2 >= QQ^1 >= 0
>>> F.exterior_power(Integer(2))
QQ^1 >= 0
>>> F.exterior_power(Integer(3))
0
>>> F.wedge(Integer(2))
QQ^1 >= 0
get_degree(d)[source]#

Return the degree-d entry of the filtration.

INPUT:

  • d – Integer. The desired degree of the filtration.

OUTPUT:

The degree-d vector space in the filtration as subspace of the ambient space.

EXAMPLES:

sage: rays = [(1,0), (1,1), (1,2), (-1,-1)]
sage: F = FilteredVectorSpace(rays, {3:[1], 1:[1,2]})
sage: F.get_degree(2)
Vector space of degree 2 and dimension 1 over Rational Field
Basis matrix:
[1 1]
sage: F.get_degree(oo)
Vector space of degree 2 and dimension 0 over Rational Field
Basis matrix:
[]
sage: F.get_degree(-oo)
Vector space of degree 2 and dimension 2 over Rational Field
Basis matrix:
[1 0]
[0 1]
>>> from sage.all import *
>>> rays = [(Integer(1),Integer(0)), (Integer(1),Integer(1)), (Integer(1),Integer(2)), (-Integer(1),-Integer(1))]
>>> F = FilteredVectorSpace(rays, {Integer(3):[Integer(1)], Integer(1):[Integer(1),Integer(2)]})
>>> F.get_degree(Integer(2))
Vector space of degree 2 and dimension 1 over Rational Field
Basis matrix:
[1 1]
>>> F.get_degree(oo)
Vector space of degree 2 and dimension 0 over Rational Field
Basis matrix:
[]
>>> F.get_degree(-oo)
Vector space of degree 2 and dimension 2 over Rational Field
Basis matrix:
[1 0]
[0 1]
graded(d)[source]#

Return the associated graded vectorspace.

INPUT:

  • d – integer. The degree.

OUTPUT:

The quotient \(G_d = F_d / F_{d+1}\).

EXAMPLES:

sage: rays = [(1,0), (1,1), (1,2)]
sage: F = FilteredVectorSpace(rays, {3:[1], 1:[1,2]})
sage: F.graded(1)
Vector space quotient V/W of dimension 1 over Rational Field where
V: Vector space of degree 2 and dimension 2 over Rational Field
Basis matrix:
[1 0]
[0 1]
W: Vector space of degree 2 and dimension 1 over Rational Field
Basis matrix:
[1 1]
>>> from sage.all import *
>>> rays = [(Integer(1),Integer(0)), (Integer(1),Integer(1)), (Integer(1),Integer(2))]
>>> F = FilteredVectorSpace(rays, {Integer(3):[Integer(1)], Integer(1):[Integer(1),Integer(2)]})
>>> F.graded(Integer(1))
Vector space quotient V/W of dimension 1 over Rational Field where
V: Vector space of degree 2 and dimension 2 over Rational Field
Basis matrix:
[1 0]
[0 1]
W: Vector space of degree 2 and dimension 1 over Rational Field
Basis matrix:
[1 1]
is_constant()[source]#

Return whether the filtration is constant.

OUTPUT:

Boolean. Whether the filtered vector spaces are identical in all degrees.

EXAMPLES:

sage: V = FilteredVectorSpace(2); V
QQ^2
sage: V.is_constant()
True

sage: V = FilteredVectorSpace(1, 0);  V
QQ^1 >= 0
sage: V.is_constant()
False

sage: V = FilteredVectorSpace({0:[(1,)]});  V
QQ^1 >= 0
sage: V.is_constant()
False
>>> from sage.all import *
>>> V = FilteredVectorSpace(Integer(2)); V
QQ^2
>>> V.is_constant()
True

>>> V = FilteredVectorSpace(Integer(1), Integer(0));  V
QQ^1 >= 0
>>> V.is_constant()
False

>>> V = FilteredVectorSpace({Integer(0):[(Integer(1),)]});  V
QQ^1 >= 0
>>> V.is_constant()
False
is_exhaustive()[source]#

Return whether the filtration is exhaustive.

A filtration \(\{F_d\}\) in an ambient vector space \(V\) is exhaustive if \(\cup F_d = V\). See also is_separating().

OUTPUT:

Boolean.

EXAMPLES:

sage: F = FilteredVectorSpace({0:[(1,1)]});  F
QQ^1 >= 0 in QQ^2
sage: F.is_exhaustive()
False
sage: G = FilteredVectorSpace(2, 0);  G
QQ^2 >= 0
sage: G.is_exhaustive()
True
>>> from sage.all import *
>>> F = FilteredVectorSpace({Integer(0):[(Integer(1),Integer(1))]});  F
QQ^1 >= 0 in QQ^2
>>> F.is_exhaustive()
False
>>> G = FilteredVectorSpace(Integer(2), Integer(0));  G
QQ^2 >= 0
>>> G.is_exhaustive()
True
is_separating()[source]#

Return whether the filtration is separating.

A filtration \(\{F_d\}\) in an ambient vector space \(V\) is exhaustive if \(\cap F_d = 0\). See also is_exhaustive().

OUTPUT:

Boolean.

EXAMPLES:

sage: F = FilteredVectorSpace({0:[(1,1)]});  F
QQ^1 >= 0 in QQ^2
sage: F.is_separating()
True
sage: G = FilteredVectorSpace({0:[(1,1,0)], oo:[(0,0,1)]});  G
QQ^2 >= QQ^1 in QQ^3
sage: G.is_separating()
False
>>> from sage.all import *
>>> F = FilteredVectorSpace({Integer(0):[(Integer(1),Integer(1))]});  F
QQ^1 >= 0 in QQ^2
>>> F.is_separating()
True
>>> G = FilteredVectorSpace({Integer(0):[(Integer(1),Integer(1),Integer(0))], oo:[(Integer(0),Integer(0),Integer(1))]});  G
QQ^2 >= QQ^1 in QQ^3
>>> G.is_separating()
False
max_degree()[source]#

Return the highest degree of the filtration.

OUTPUT:

Integer or minus infinity. The smallest degree of the filtration such that the filtration is constant to the right.

EXAMPLES:

sage: FilteredVectorSpace(1, 3).max_degree()
4
sage: FilteredVectorSpace({0:[[1]]}).max_degree()
1
sage: FilteredVectorSpace(3).max_degree()
-Infinity
>>> from sage.all import *
>>> FilteredVectorSpace(Integer(1), Integer(3)).max_degree()
4
>>> FilteredVectorSpace({Integer(0):[[Integer(1)]]}).max_degree()
1
>>> FilteredVectorSpace(Integer(3)).max_degree()
-Infinity
min_degree()[source]#

Return the lowest degree of the filtration.

OUTPUT:

Integer or plus infinity. The largest degree \(d\) of the (descending) filtration such that the filtered vector space \(F_d\) is still equal to \(F_{-\infty}\).

EXAMPLES:

sage: FilteredVectorSpace(1, 3).min_degree()
3
sage: FilteredVectorSpace(2).min_degree()
+Infinity
>>> from sage.all import *
>>> FilteredVectorSpace(Integer(1), Integer(3)).min_degree()
3
>>> FilteredVectorSpace(Integer(2)).min_degree()
+Infinity
presentation()[source]#

Return a presentation in term of generators of various degrees.

OUTPUT:

A pair consisting of generators and a filtration suitable as input to construct_from_generators_indices().

EXAMPLES:

sage: rays = [(1,0), (1,1), (1,2), (-1,-1)]
sage: F = FilteredVectorSpace(rays, {0:[1, 2], 2:[3]});  F
QQ^2 >= QQ^1 >= QQ^1 >= 0
sage: F.presentation()
(((0, 1), (1, 0), (1, 1)), {0: (1, 0), 2: (2,), +Infinity: ()})
>>> from sage.all import *
>>> rays = [(Integer(1),Integer(0)), (Integer(1),Integer(1)), (Integer(1),Integer(2)), (-Integer(1),-Integer(1))]
>>> F = FilteredVectorSpace(rays, {Integer(0):[Integer(1), Integer(2)], Integer(2):[Integer(3)]});  F
QQ^2 >= QQ^1 >= QQ^1 >= 0
>>> F.presentation()
(((0, 1), (1, 0), (1, 1)), {0: (1, 0), 2: (2,), +Infinity: ()})
random_deformation(epsilon=None)[source]#

Return a random deformation

INPUT:

  • epsilon – a number in the base ring.

OUTPUT:

A new filtered vector space where the generators of the subspaces are moved by epsilon times a random vector.

EXAMPLES:

sage: gens = identity_matrix(3).rows()
sage: F = FilteredVectorSpace(gens, {0:[0,1,2], 2:[0]});  F
QQ^3 >= QQ^1 >= QQ^1 >= 0
sage: F.get_degree(2)
Vector space of degree 3 and dimension 1 over Rational Field
Basis matrix:
[1 0 0]
sage: G = F.random_deformation(1/50);  G
QQ^3 >= QQ^1 >= QQ^1 >= 0
sage: D = G.get_degree(2)
sage: D.degree()
3
sage: v = D.basis_matrix()[0]
sage: v[0]
1

sage: while F.random_deformation(1/50).get_degree(2).matrix() == matrix([1, 0, 0]):
....:     pass
>>> from sage.all import *
>>> gens = identity_matrix(Integer(3)).rows()
>>> F = FilteredVectorSpace(gens, {Integer(0):[Integer(0),Integer(1),Integer(2)], Integer(2):[Integer(0)]});  F
QQ^3 >= QQ^1 >= QQ^1 >= 0
>>> F.get_degree(Integer(2))
Vector space of degree 3 and dimension 1 over Rational Field
Basis matrix:
[1 0 0]
>>> G = F.random_deformation(Integer(1)/Integer(50));  G
QQ^3 >= QQ^1 >= QQ^1 >= 0
>>> D = G.get_degree(Integer(2))
>>> D.degree()
3
>>> v = D.basis_matrix()[Integer(0)]
>>> v[Integer(0)]
1

>>> while F.random_deformation(Integer(1)/Integer(50)).get_degree(Integer(2)).matrix() == matrix([Integer(1), Integer(0), Integer(0)]):
...     pass
shift(deg)[source]#

Return a filtered vector space with degrees shifted by a constant.

EXAMPLES:

sage: gens = identity_matrix(3).rows()
sage: F = FilteredVectorSpace(gens, {0:[0,1,2], 2:[0]});  F
QQ^3 >= QQ^1 >= QQ^1 >= 0
sage: F.support()
(0, 2)
sage: F.shift(-5).support()
(-5, -3)
>>> from sage.all import *
>>> gens = identity_matrix(Integer(3)).rows()
>>> F = FilteredVectorSpace(gens, {Integer(0):[Integer(0),Integer(1),Integer(2)], Integer(2):[Integer(0)]});  F
QQ^3 >= QQ^1 >= QQ^1 >= 0
>>> F.support()
(0, 2)
>>> F.shift(-Integer(5)).support()
(-5, -3)
support()[source]#

Return the degrees in which there are non-trivial generators.

OUTPUT:

A tuple of integers (and plus infinity) in ascending order. The last entry is plus infinity if and only if the filtration is not separating (see is_separating()).

EXAMPLES:

sage: G = FilteredVectorSpace({0:[(1,1,0)], 3:[(0,1,0)]});  G
QQ^2 >= QQ^1 >= QQ^1 >= QQ^1 >= 0 in QQ^3
sage: G.support()
(0, 3)

sage: G = FilteredVectorSpace({0:[(1,1,0)], 3:[(0,1,0)], oo:[(0,0,1)]});  G
QQ^3 >= QQ^2 >= QQ^2 >= QQ^2 >= QQ^1
sage: G.support()
(0, 3, +Infinity)
>>> from sage.all import *
>>> G = FilteredVectorSpace({Integer(0):[(Integer(1),Integer(1),Integer(0))], Integer(3):[(Integer(0),Integer(1),Integer(0))]});  G
QQ^2 >= QQ^1 >= QQ^1 >= QQ^1 >= 0 in QQ^3
>>> G.support()
(0, 3)

>>> G = FilteredVectorSpace({Integer(0):[(Integer(1),Integer(1),Integer(0))], Integer(3):[(Integer(0),Integer(1),Integer(0))], oo:[(Integer(0),Integer(0),Integer(1))]});  G
QQ^3 >= QQ^2 >= QQ^2 >= QQ^2 >= QQ^1
>>> G.support()
(0, 3, +Infinity)
symmetric_power(n)[source]#

Return the \(n\)-th graded symmetric power.

INPUT:

  • n – integer. Symmetric product of how many copies of self.

OUTPUT:

The graded symmetric product, that is, the symmetrization of a generator of degree \(d_1\) with a generator in degree \(d_2\) has degree \(d_1 + d_2\).

EXAMPLES:

sage: F = FilteredVectorSpace(1, 1) + FilteredVectorSpace(1, 2);  F
QQ^2 >= QQ^1 >= 0
sage: F.symmetric_power(2)
QQ^3 >= QQ^2 >= QQ^1 >= 0
>>> from sage.all import *
>>> F = FilteredVectorSpace(Integer(1), Integer(1)) + FilteredVectorSpace(Integer(1), Integer(2));  F
QQ^2 >= QQ^1 >= 0
>>> F.symmetric_power(Integer(2))
QQ^3 >= QQ^2 >= QQ^1 >= 0
tensor_product(other)[source]#

Return the graded tensor product.

INPUT:

  • other – a filtered vector space.

OUTPUT:

The graded tensor product, that is, the tensor product of a generator of degree \(d_1\) with a generator in degree \(d_2\) has degree \(d_1 + d_2\).

EXAMPLES:

sage: F1 = FilteredVectorSpace(1, 1)
sage: F2 = FilteredVectorSpace(1, 2)
sage: F1.tensor_product(F2)
QQ^1 >= 0
sage: F1 * F2
QQ^1 >= 0

sage: F1.min_degree()
1
sage: F2.min_degree()
2
sage: (F1*F2).min_degree()
3
>>> from sage.all import *
>>> F1 = FilteredVectorSpace(Integer(1), Integer(1))
>>> F2 = FilteredVectorSpace(Integer(1), Integer(2))
>>> F1.tensor_product(F2)
QQ^1 >= 0
>>> F1 * F2
QQ^1 >= 0

>>> F1.min_degree()
1
>>> F2.min_degree()
2
>>> (F1*F2).min_degree()
3

A suitable base ring is chosen if they do not match:

sage: v = [(1,0), (0,1)]
sage: F1 = FilteredVectorSpace(v, {0:[0], 1:[1]}, base_ring=QQ)
sage: F2 = FilteredVectorSpace(v, {0:[0], 1:[1]}, base_ring=RDF)
sage: F1 * F2                                                               # needs scipy
RDF^4 >= RDF^3 >= RDF^1 >= 0
>>> from sage.all import *
>>> v = [(Integer(1),Integer(0)), (Integer(0),Integer(1))]
>>> F1 = FilteredVectorSpace(v, {Integer(0):[Integer(0)], Integer(1):[Integer(1)]}, base_ring=QQ)
>>> F2 = FilteredVectorSpace(v, {Integer(0):[Integer(0)], Integer(1):[Integer(1)]}, base_ring=RDF)
>>> F1 * F2                                                               # needs scipy
RDF^4 >= RDF^3 >= RDF^1 >= 0
wedge(n)[source]#

Return the \(n\)-th graded exterior power.

INPUT:

  • n – integer. Exterior product of how many copies of self.

OUTPUT:

The graded exterior product, that is, the wedge product of a generator of degree \(d_1\) with a generator in degree \(d_2\) has degree \(d_1 + d_2\).

EXAMPLES:

sage: # needs sage.groups
sage: F = FilteredVectorSpace(1, 1) + FilteredVectorSpace(1, 2);  F
QQ^2 >= QQ^1 >= 0
sage: F.exterior_power(1)
QQ^2 >= QQ^1 >= 0
sage: F.exterior_power(2)
QQ^1 >= 0
sage: F.exterior_power(3)
0
sage: F.wedge(2)
QQ^1 >= 0
>>> from sage.all import *
>>> # needs sage.groups
>>> F = FilteredVectorSpace(Integer(1), Integer(1)) + FilteredVectorSpace(Integer(1), Integer(2));  F
QQ^2 >= QQ^1 >= 0
>>> F.exterior_power(Integer(1))
QQ^2 >= QQ^1 >= 0
>>> F.exterior_power(Integer(2))
QQ^1 >= 0
>>> F.exterior_power(Integer(3))
0
>>> F.wedge(Integer(2))
QQ^1 >= 0
sage.modules.filtered_vector_space.construct_from_dim_degree(dim, max_degree, base_ring, check)[source]#

Construct a filtered vector space.

INPUT:

  • dim – integer. The dimension.

  • max_degree – integer or infinity. The maximal degree where the vector subspace of the filtration is still the entire space.

EXAMPLES:

sage: V = FilteredVectorSpace(2, 5);  V
QQ^2 >= 0
sage: V.get_degree(5)
Vector space of degree 2 and dimension 2 over Rational Field
Basis matrix:
[1 0]
[0 1]
sage: V.get_degree(6)
Vector space of degree 2 and dimension 0 over Rational Field
Basis matrix:
[]

sage: FilteredVectorSpace(2, oo)
QQ^2
sage: FilteredVectorSpace(2, -oo)
0 in QQ^2
>>> from sage.all import *
>>> V = FilteredVectorSpace(Integer(2), Integer(5));  V
QQ^2 >= 0
>>> V.get_degree(Integer(5))
Vector space of degree 2 and dimension 2 over Rational Field
Basis matrix:
[1 0]
[0 1]
>>> V.get_degree(Integer(6))
Vector space of degree 2 and dimension 0 over Rational Field
Basis matrix:
[]

>>> FilteredVectorSpace(Integer(2), oo)
QQ^2
>>> FilteredVectorSpace(Integer(2), -oo)
0 in QQ^2
sage.modules.filtered_vector_space.construct_from_generators(filtration, base_ring, check)[source]#

Construct a filtered vector space.

INPUT:

  • filtration – a dictionary of filtration steps. Each filtration step is a pair consisting of an integer degree and a list/tuple/iterable of vector space generators. The integer degree stipulates that all filtration steps of degree higher or equal than degree (up to the next filtration step) are said subspace.

EXAMPLES:

sage: from sage.modules.filtered_vector_space import construct_from_generators
sage: r = [1, 2]
sage: construct_from_generators({1:[r]}, QQ, True)
QQ^1 >= 0 in QQ^2
>>> from sage.all import *
>>> from sage.modules.filtered_vector_space import construct_from_generators
>>> r = [Integer(1), Integer(2)]
>>> construct_from_generators({Integer(1):[r]}, QQ, True)
QQ^1 >= 0 in QQ^2
sage.modules.filtered_vector_space.construct_from_generators_indices(generators, filtration, base_ring, check)[source]#

Construct a filtered vector space.

INPUT:

  • generators – a list/tuple/iterable of vectors, or something convertible to them. The generators spanning various subspaces.

  • filtration – a list or iterable of filtration steps. Each filtration step is a pair (degree, ray_indices). The ray_indices are a list or iterable of ray indices, which span a subspace of the vector space. The integer degree stipulates that all filtration steps of degree higher or equal than degree (up to the next filtration step) are said subspace.

EXAMPLES:

sage: from sage.modules.filtered_vector_space import construct_from_generators_indices
sage: gens = [(1,0), (0,1), (-1,-1)]
sage: V = construct_from_generators_indices(gens, {1:[0,1], 3:[1]}, QQ, True);  V
QQ^2 >= QQ^1 >= QQ^1 >= 0
>>> from sage.all import *
>>> from sage.modules.filtered_vector_space import construct_from_generators_indices
>>> gens = [(Integer(1),Integer(0)), (Integer(0),Integer(1)), (-Integer(1),-Integer(1))]
>>> V = construct_from_generators_indices(gens, {Integer(1):[Integer(0),Integer(1)], Integer(3):[Integer(1)]}, QQ, True);  V
QQ^2 >= QQ^1 >= QQ^1 >= 0
sage.modules.filtered_vector_space.is_FilteredVectorSpace(X)[source]#

Test whether X is a filtered vector space.

This function is for library use only.

INPUT:

  • X – anything.

OUTPUT:

Boolean.

EXAMPLES:

sage: from sage.modules.filtered_vector_space import is_FilteredVectorSpace
sage: V = FilteredVectorSpace(2, 1)
sage: is_FilteredVectorSpace(V)
doctest:warning...:
DeprecationWarning: the function is_FilteredVectorSpace is deprecated;
use 'isinstance(..., FilteredVectorSpace_class)' instead
See https://github.com/sagemath/sage/issues/37924 for details.
True
sage: is_FilteredVectorSpace('ceci n'est pas une pipe')
False
>>> from sage.all import *
>>> from sage.modules.filtered_vector_space import is_FilteredVectorSpace
>>> V = FilteredVectorSpace(Integer(2), Integer(1))
>>> is_FilteredVectorSpace(V)
doctest:warning...:
DeprecationWarning: the function is_FilteredVectorSpace is deprecated;
use 'isinstance(..., FilteredVectorSpace_class)' instead
See https://github.com/sagemath/sage/issues/37924 for details.
True
>>> is_FilteredVectorSpace('ceci n'est pas une pipe')
False
sage.modules.filtered_vector_space.normalize_degree(deg)[source]#

Normalized the degree

  • deg – something that defines the degree (either integer or infinity).

OUTPUT:

Plus/minus infinity or a Sage integer.

EXAMPLES:

sage: from sage.modules.filtered_vector_space import normalize_degree
sage: type(normalize_degree(int(1)))
<class 'sage.rings.integer.Integer'>
sage: normalize_degree(oo)
+Infinity
>>> from sage.all import *
>>> from sage.modules.filtered_vector_space import normalize_degree
>>> type(normalize_degree(int(Integer(1))))
<class 'sage.rings.integer.Integer'>
>>> normalize_degree(oo)
+Infinity