# $$\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


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]


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


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


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


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


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


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


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

sage.modules.filtered_vector_space.FilteredVectorSpace(arg1, arg2=None, base_ring=Rational Field, check=True)#

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 (optional, 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


Dimension and degree:

sage: FilteredVectorSpace(2, 1)
QQ^2 >= 0


Dictionary of generators:

sage: FilteredVectorSpace({1:[(1,0), (0,1)], 3:[(1,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

class sage.modules.filtered_vector_space.FilteredVectorSpace_class(base_ring, dim, generators, filtration, check=True)#

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

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

change_ring(base_ring)#

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

direct_sum(other)#

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


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

dual()#

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)

exterior_power(n)#

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

get_degree(d)#

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]


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]})
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()#

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

is_exhaustive()#

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

is_separating()#

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

max_degree()#

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

min_degree()#

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

presentation()#

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: ()})

random_deformation(epsilon=None)#

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

shift(deg)#

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)

support()#

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)

symmetric_power(n)#

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

tensor_product(other)#

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


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

wedge(n)#

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

sage.modules.filtered_vector_space.construct_from_dim_degree(dim, max_degree, base_ring, check)#

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

sage.modules.filtered_vector_space.construct_from_generators(filtration, base_ring, check)#

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

sage.modules.filtered_vector_space.construct_from_generators_indices(generators, filtration, base_ring, check)#

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

sage.modules.filtered_vector_space.is_FilteredVectorSpace(X)#

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)
True
sage: is_FilteredVectorSpace('ceci n'est pas une pipe')
False

sage.modules.filtered_vector_space.normalize_degree(deg)#

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