# Direct Sums

AbstractAlgebra allows the construction of the external direct sum of any nonempty vector of finitely presented modules.

Note that external direct sums are considered equal iff they are the same object.

## Generic direct sum type

AbstractAlgebra provides a generic direct sum type Generic.DirectSumModule{T} where T is the element type of the base ring. The implementation is in src/generic/DirectSum.jl

Elements of direct sum modules have type Generic.DirectSumModuleElem{T}.

## Abstract types

Direct sum module types belong to the abstract type FPModule{T} and their elements to FPModuleElem{T}.

## Constructors

direct_sumFunction
direct_sum(m::Vector{<:FPModule{T}}) where T <: RingElement
direct_sum(vals::FPModule{T}...) where T <: RingElement

Return a tuple $M, f, g$ consisting of $M$ the direct sum of the modules m (supplied as a vector of modules), a vector $f$ of the injections of the $m[i]$ into $M$ and a vector $g$ of the projections from $M$ onto the $m[i]$.

source
direct_sum(G::FinGenAbGroup...) -> FinGenAbGroup, Vector{FinGenAbGroupHom}

Return the direct sum $D$ of the (finitely many) abelian groups $G_i$, together with the injections $G_i \to D$.

For finite abelian groups, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain $D$ as a direct product together with the projections $D \to G_i$, one should call direct_product(G...). If one wants to obtain $D$ as a biproduct together with the projections and the injections, one should call biproduct(G...).

Otherwise, one could also call canonical_injections(D) or canonical_projections(D) later on.

source
direct_sum(x::Vararg{T}) where T <: AbstractSpace -> T, Vector{AbstractSpaceMor}
direct_sum(x::Vector{T}) where T <: AbstractSpace -> T, Vector{AbstractSpaceMor}

Given a collection of quadratic or hermitian spaces $V_1, \ldots, V_n$, return their direct sum $V := V_1 \oplus \ldots \oplus V_n$, together with the injections $V_i \to V$.

For objects of type AbstractSpace, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain V as a direct product with the projections $V \to V_i$, one should call direct_product(x). If one wants to obtain V as a biproduct with the injections $V_i \to V$ and the projections $V \to V_i$, one should call biproduct(x).

source
direct_sum(x::Vararg{T}) where T <: AbstractLat -> T, Vector{AbstractSpaceMor}
direct_sum(x::Vector{T}) where T <: AbstractLat -> T, Vector{AbstractSpaceMor}

Given a collection of quadratic or hermitian lattices $L_1, \ldots, L_n$, return their direct sum $L := L_1 \oplus \ldots \oplus L_n$, together with the injections $L_i \to L$ (seen as maps between the corresponding ambient spaces).

For objects of type AbstractLat, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain L as a direct product with the projections $L \to L_i$, one should call direct_product(x). If one wants to obtain L as a biproduct with the injections $L_i \to L$ and the projections $L \to L_i$, one should call biproduct(x).

source
direct_sum(x::Vararg{TorQuadModule}) -> TorQuadModule, Vector{TorQuadModuleMap}
direct_sum(x::Vector{TorQuadModule}) -> TorQuadModule, Vector{TorQuadModuleMap}

Given a collection of torsion quadratic modules $T_1, \ldots, T_n$, return their direct sum $T := T_1\oplus \ldots \oplus T_n$, together with the injections $T_i \to T$.

For objects of type TorQuadModule, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain T as a direct product with the projections $T \to T_i$, one should call direct_product(x). If one wants to obtain T as a biproduct with the injections $T_i \to T$ and the projections $T \to T_i$, one should call biproduct(x).

source
direct_sum(g1::QuadSpaceCls, g2::QuadSpaceCls) -> QuadSpaceCls

Return the isometry class of the direct sum of two representatives.

source
direct_sum(x::Vararg{ZZLat}) -> ZZLat, Vector{AbstractSpaceMor}
direct_sum(x::Vector{ZZLat}) -> ZZLat, Vector{AbstractSpaceMor}

Given a collection of $\mathbb Z$-lattices $L_1, \ldots, L_n$, return their direct sum $L := L_1 \oplus \ldots \oplus L_n$, together with the injections $L_i \to L$. (seen as maps between the corresponding ambient spaces).

For objects of type ZZLat, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain L as a direct product with the projections $L \to L_i$, one should call direct_product(x). If one wants to obtain L as a biproduct with the injections $L_i \to L$ and the projections $L \to L_i$, one should call biproduct(x).

source
direct_sum(S1::ZZLocalGenus, S2::ZZLocalGenus) -> ZZLocalGenus

Return the local genus of the direct sum of two representatives.

source
direct_sum(G1::ZZGenus, G2::ZZGenus) -> ZZGenus

Return the genus of the direct sum of G1 and G2.

The direct sum is defined via representatives.

source
direct_sum(g1::HermLocalGenus, g2::HermLocalGenus) -> HermLocalGenus

Given two local genus symbols g1 and g2 for hermitian lattices over $E/K$ at the same prime ideal $\mathfrak p$ of $\mathcal O_K$, return their direct sum. It corresponds to the local genus symbol of the $\mathfrak p$-adic completion of the direct sum of respective representatives of g1 and g2.

source
direct_sum(G1::HermGenus, G2::HermGenus) -> HermGenus

Given two global genus symbols G1 and G2 for hermitian lattices over $E/K$, return their direct sum. It corresponds to the global genus symbol of the direct sum of respective representatives of G1 and G2.

source
direct_sum(M::ModuleFP{T}...; task::Symbol = :sum) where T

Given modules $M_1\dots M_n$, say, return the direct sum $\bigoplus_{i=1}^n M_i$.

• a vector containing the canonical injections $M_i\to\bigoplus_{i=1}^n M_i$ if task = :sum (default),
• a vector containing the canonical projections $\bigoplus_{i=1}^n M_i\to M_i$ if task = :prod,
• two vectors containing the canonical injections and projections, respectively, if task = :both,
• none of the above maps if task = :none.
source
direct_sum(M::Matroid, N::Matroid)

The direct sum of the matroids M and N. Optionally one can also pass a vector of matroids.

See Section 4.2 of [Oxl11].

To obtain the direct sum of the Fano and a uniform matroid type:

Examples

julia> direct_sum(fano_matroid(), uniform_matroid(2,4))
Matroid of rank 5 on 11 elements

To take the sum of three uniform matroids use:

Examples

julia> matroids = Vector([uniform_matroid(2,4), uniform_matroid(1,3), uniform_matroid(3,4)]);

julia> M = direct_sum(matroids)
Matroid of rank 6 on 11 elements
source
direct_sum(x::Vector{QuadSpaceWithIsom}) -> QuadSpaceWithIsom, Vector{AbstractSpaceMor}
direct_sum(x::Vararg{QuadSpaceWithIsom}) -> QuadSpaceWithIsom, Vector{AbstractSpaceMor}

Given a collection of quadratic spaces with isometries $(V_1, f_1), \ldots, (V_n, f_n)$, return the quadratic space with isometry $(V, f)$ together with the injections $V_i \to V$, where $V$ is the direct sum $V := V_1 \oplus \ldots \oplus V_n$ and $f$ is the isometry of $V$ induced by the diagonal actions of the $f_i$'s.

For objects of type QuadSpaceWithIsom, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain $(V, f)$ as a direct product with the projections $V \to V_i$, one should call direct_product(x). If one wants to obtain $(V, f)$ as a biproduct with the injections $V_i \to V$ and the projections $V \to V_i$, one should call biproduct(x).

Examples

julia> V1 = quadratic_space(QQ, QQ[2 5;
5 6])
Quadratic space of dimension 2
over rational field
with gram matrix
[2   5]
[5   6]

julia> Vf1 = quadratic_space_with_isometry(V1, neg=true)
Quadratic space of dimension 2
with isometry of finite order 2
given by
[-1    0]
[ 0   -1]

julia> V2 = quadratic_space(QQ, QQ[ 2 -1;
-1  2])
Quadratic space of dimension 2
over rational field
with gram matrix
[ 2   -1]
[-1    2]

julia> f = matrix(QQ, 2, 2, [1  1;
0 -1])
[1    1]
[0   -1]

julia> Vf2 = quadratic_space_with_isometry(V2, f)
Quadratic space of dimension 2
with isometry of finite order 2
given by
[1    1]
[0   -1]

julia> Vf3, inj = direct_sum(Vf1, Vf2)
(Quadratic space with isometry of finite order 2, AbstractSpaceMor[Map: quadratic space -> quadratic space, Map: quadratic space -> quadratic space])

julia> Vf3
Quadratic space of dimension 4
with isometry of finite order 2
given by
[-1    0   0    0]
[ 0   -1   0    0]
[ 0    0   1    1]
[ 0    0   0   -1]

julia> space(Vf3)
Quadratic space of dimension 4
over rational field
with gram matrix
[2   5    0    0]
[5   6    0    0]
[0   0    2   -1]
[0   0   -1    2]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
direct_sum(x::Vector{ZZLatWithIsom}) -> ZZLatWithIsom,
Vector{AbstractSpaceMor}
direct_sum(x::Vararg{ZZLatWithIsom}) -> ZZLatWithIsom,
Vector{AbstractSpaceMor}

Given a collection of lattices with isometries $(L_1, f_1), \ldots, (L_n, f_n)$, return the lattice with isometry $(L, f)$ together with the injections $L_i \to L$, where $L$ is the direct sum $L := L_1 \oplus \ldots \oplus L_n$ and $f$ is the isometry of $L$ induced by the diagonal actions of the $f_i$'s.

For objects of type ZZLatWithIsom, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain $(L, f)$ as a direct product with the projections $L \to L_i$, one should call direct_product(x). If one wants to obtain $(L, f)$ as a biproduct with the injections $L_i \to L$ and the projections $L \to L_i$, one should call biproduct(x).

Examples

julia> L = root_lattice(:A,5);

julia> f = matrix(QQ, 5, 5, [ 1  0  0  0  0;
-1 -1 -1 -1 -1;
0  0  0  0  1;
0  0  0  1  0;
0  0  1  0  0]);

julia> g = matrix(QQ, 5, 5, [1  1  1  1  1;
0 -1 -1 -1 -1;
0  1  0  0  0;
0  0  1  0  0;
0  0  0  1  0]);

julia> Lf = integer_lattice_with_isometry(L, f)
Integer lattice of rank 5 and degree 5
with isometry of finite order 2
given by
[ 1    0    0    0    0]
[-1   -1   -1   -1   -1]
[ 0    0    0    0    1]
[ 0    0    0    1    0]
[ 0    0    1    0    0]

julia> Lg = integer_lattice_with_isometry(L, g)
Integer lattice of rank 5 and degree 5
with isometry of finite order 5
given by
[1    1    1    1    1]
[0   -1   -1   -1   -1]
[0    1    0    0    0]
[0    0    1    0    0]
[0    0    0    1    0]

julia> Lh, inj = direct_sum(Lf, Lg)
(Integer lattice with isometry of finite order 10, AbstractSpaceMor[Map: quadratic space -> quadratic space, Map: quadratic space -> quadratic space])

julia> Lh
Integer lattice of rank 10 and degree 10
with isometry of finite order 10
given by
[ 1    0    0    0    0   0    0    0    0    0]
[-1   -1   -1   -1   -1   0    0    0    0    0]
[ 0    0    0    0    1   0    0    0    0    0]
[ 0    0    0    1    0   0    0    0    0    0]
[ 0    0    1    0    0   0    0    0    0    0]
[ 0    0    0    0    0   1    1    1    1    1]
[ 0    0    0    0    0   0   -1   -1   -1   -1]
[ 0    0    0    0    0   0    1    0    0    0]
[ 0    0    0    0    0   0    0    1    0    0]
[ 0    0    0    0    0   0    0    0    1    0]
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

For a vector of maps fi : M -> Ni compute the map f : M -> prod Ni : m -> (fi(m))_i

Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source
direct_sum(V::LieAlgebraModule{C}...) -> LieAlgebraModule{C}
⊕(V::LieAlgebraModule{C}...) -> LieAlgebraModule{C}

Construct the direct sum of the modules V....

Examples

julia> L = special_linear_lie_algebra(QQ, 3);

julia> V1 = exterior_power(standard_module(L), 2)[1]; # some module

julia> V2 = symmetric_power(standard_module(L), 3)[1]; # some module

julia> direct_sum(V1, V2)
Direct sum module
of dimension 13
direct sum with direct summands
2nd exterior power of
standard module
3rd symmetric power of
standard module
over special linear Lie algebra of degree 3 over QQ
Experimental

This function is part of the experimental code in Oscar. Please read here for more details.

source

Examples

julia> F = free_module(ZZ, 5)
Free module of rank 5 over integers

julia> m1 = F(BigInt[4, 7, 8, 2, 6])
(4, 7, 8, 2, 6)

julia> m2 = F(BigInt[9, 7, -2, 2, -4])
(9, 7, -2, 2, -4)

julia> S1, f1 = sub(F, [m1, m2])
(Submodule over integers with 2 generators and no relations, Hom: submodule over integers with 2 generators and no relations -> free module of rank 5 over integers)

julia> m1 = F(BigInt[3, 1, 7, 7, -7])
(3, 1, 7, 7, -7)

julia> m2 = F(BigInt[-8, 6, 10, -1, 1])
(-8, 6, 10, -1, 1)

julia> S2, f2 = sub(F, [m1, m2])
(Submodule over integers with 2 generators and no relations, Hom: submodule over integers with 2 generators and no relations -> free module of rank 5 over integers)

julia> m1 = F(BigInt[2, 4, 2, -3, -10])
(2, 4, 2, -3, -10)

julia> m2 = F(BigInt[5, 7, -6, 9, -5])
(5, 7, -6, 9, -5)

julia> S3, f3 = sub(F, [m1, m2])
(Submodule over integers with 2 generators and no relations, Hom: submodule over integers with 2 generators and no relations -> free module of rank 5 over integers)

julia> D, f = direct_sum(S1, S2, S3)
(DirectSumModule over integers, AbstractAlgebra.Generic.ModuleHomomorphism{BigInt}[Hom: submodule over integers with 2 generators and no relations -> DirectSumModule, Hom: submodule over integers with 2 generators and no relations -> DirectSumModule, Hom: submodule over integers with 2 generators and no relations -> DirectSumModule], AbstractAlgebra.Generic.ModuleHomomorphism{BigInt}[Hom: DirectSumModule -> submodule over integers with 2 generators and no relations, Hom: DirectSumModule -> submodule over integers with 2 generators and no relations, Hom: DirectSumModule -> submodule over integers with 2 generators and no relations])

## Functionality for direct sums

In addition to the Module interface, AbstractAlgebra direct sums implement the following functionality.

### Basic manipulation

summandsMethod
summands(M::DirectSumModule{T}) where T <: RingElement

Return the modules that this module is a direct sum of.

source

Examples

julia> F = free_module(ZZ, 5)
Free module of rank 5 over integers

julia> m1 = F(BigInt[4, 7, 8, 2, 6])
(4, 7, 8, 2, 6)

julia> m2 = F(BigInt[9, 7, -2, 2, -4])
(9, 7, -2, 2, -4)

julia> S1, f1 = sub(F, [m1, m2])
(Submodule over integers with 2 generators and no relations, Hom: submodule over integers with 2 generators and no relations -> free module of rank 5 over integers)

julia> m1 = F(BigInt[3, 1, 7, 7, -7])
(3, 1, 7, 7, -7)

julia> m2 = F(BigInt[-8, 6, 10, -1, 1])
(-8, 6, 10, -1, 1)

julia> S2, f2 = sub(F, [m1, m2])
(Submodule over integers with 2 generators and no relations, Hom: submodule over integers with 2 generators and no relations -> free module of rank 5 over integers)

julia> m1 = F(BigInt[2, 4, 2, -3, -10])
(2, 4, 2, -3, -10)

julia> m2 = F(BigInt[5, 7, -6, 9, -5])
(5, 7, -6, 9, -5)

julia> S3, f3 = sub(F, [m1, m2])
(Submodule over integers with 2 generators and no relations, Hom: submodule over integers with 2 generators and no relations -> free module of rank 5 over integers)

julia> D, f = direct_sum(S1, S2, S3)
(DirectSumModule over integers, AbstractAlgebra.Generic.ModuleHomomorphism{BigInt}[Hom: submodule over integers with 2 generators and no relations -> DirectSumModule, Hom: submodule over integers with 2 generators and no relations -> DirectSumModule, Hom: submodule over integers with 2 generators and no relations -> DirectSumModule], AbstractAlgebra.Generic.ModuleHomomorphism{BigInt}[Hom: DirectSumModule -> submodule over integers with 2 generators and no relations, Hom: DirectSumModule -> submodule over integers with 2 generators and no relations, Hom: DirectSumModule -> submodule over integers with 2 generators and no relations])

julia> summands(D)
3-element Vector{AbstractAlgebra.Generic.Submodule{BigInt}}:
Submodule over integers with 2 generators and no relations
Submodule over integers with 2 generators and no relations
Submodule over integers with 2 generators and no relations
    (D::DirectSumModule{T}(::Vector{<:FPModuleElem{T}}) where T <: RingElement

Given a vector (or $1$-dim array) of module elements, where the $i$-th entry has to be an element of the $i$-summand of $D$, create the corresponding element in $D$.

Examples

julia> N = free_module(QQ, 1);

julia> M = free_module(QQ, 2);

julia> D, _ = direct_sum(M, N, M);

julia> D([gen(M, 1), gen(N, 1), gen(M, 2)])
(1//1, 0//1, 1//1, 0//1, 1//1)

### Special Homomorphisms

Due to the special structure as direct sums, homomorphisms can be created by specifying homomorphisms for all summands. In case of the codmain being a direct sum as well, any homomorphism may be thought of as a matrix containing maps from the $i$-th source summand to the $j$-th target module:

ModuleHomomorphism(D::DirectSumModule{T}, S::DirectSumModule{T}, m::Matrix{Any}) where T <: RingElement

Given a matrix $m$ such that the $(i,j)$-th entry is either $0$ (Int(0)) or a ModuleHomomorphism from the $i$-th summand of $D$ to the $j$-th summand of $S$, construct the corresponding homomorphism.

ModuleHomomorphism(D::DirectSumModule{T}, S::FPModuleElem{T}, m::Vector{ModuleHomomorphism})

Given an array $a$ of ModuleHomomorphism such that $a_i$, the $i$-th entry of $a$ is a ModuleHomomorphism from the $i$-th summand of D into S, construct the direct sum of the components.

Given a matrix $m$ such that the $(i,j)$-th entry is either $0$ (Int(0)) or a ModuleHomomorphism from the $i$-th summand of $D$ to the $j$-th summand of $S$, construct the corresponding homomorphism.

Examples

julia> N = free_module(QQ, 2);

julia> D, _ = direct_sum(N, N);

julia> p = ModuleHomomorphism(N, N, [3,4] .* basis(N));

julia> q = ModuleHomomorphism(N, N, [5,7] .* basis(N));

julia> phi = ModuleHomomorphism(D, D, [p 0; 0 q])
Module homomorphism
from DirectSumModule over rationals
to DirectSumModule over rationals

julia> r = ModuleHomomorphism(N, D, [2,3] .* gens(D)[1:2])
Module homomorphism
from vector space of dimension 2 over rationals
to DirectSumModule over rationals

julia> psi = ModuleHomomorphism(D, D, [r, r])
Module homomorphism
from DirectSumModule over rationals
to DirectSumModule over rationals