Maps between structures A and B may be specified either by providing
the full graph (as defined in the previous section) or by supplying
an expression rule for finding images.
map< A -> B | G > : Struct, Struct -> Map
Given a finite structure A, a structure B and a graph G of A x B, construct the mapping f : A -> B, as defined by G. Note that G must be a graph, i.e., the set formed by projecting the elements of G onto their first component must equal A.Obviously, this form of map definition is useful only when the set A is very small.
Given a set A, a set B, a variable x and an expression e(x), usually involving x, construct the mapping f : A -> B, as defined by e(x). It is the user's responsibility to ensure that a value is defined for every x in A. The scope of the free variable x is restricted to the map-constructor.
> Z4 := Integers(4); > F4<w> := FiniteField(4); > m := map< Z4 -> F4 | <0, 0>, <1, 1>, <2, w>, <3, w^2> >;The statements below define a bijection f between the elements of the 3-dimensional vector space over GF(2) and the integers 0--7:
> F := FiniteField(2);
> V := VectorSpace(F, 3);
> Z := Integers();
> f := map< V -> { 0..7 } | x :-> 4*Z!x[1] + 2*Z!x[2] + Z!x[3] >;
> print { <x, f(x)> : x in V };
{
<(0 0 0), 0>,
<(0 0 1), 1>,
<(0 1 0), 2>,
<(0 1 1), 3>,
<(1 0 0), 4>,
<(1 0 1), 5>,
<(1 1 0), 6>,
<(1 1 1), 7>
}
Note that if we do not coerce the coefficients x[i] of the vector
into the integers (using !), automatic coercion will force a product
such as 4*x[1] to be evaluated in GF(2) rather than Z.
The general image form of the mapping constructor permits the definition of mappings between structures of quite different types. As an illustration, the following statements define a homomorphism of the general linear group GL(3, 8) onto the multiplicative group of the field GF(8).
> F<w> := FiniteField(8); > V := VectorSpace(F, 3); > GL38 := sub< GeneralLinearGroup(V) | [0,1,0, 1,0,0, 0,0,1], > [1,0,0, 0,0,1, 0,1,0], [1,1,0, 0,1,0, 0,0,1], [w,0,0, 0,1,0, 0,0,1] >; > d := map< GL38 -> F | x :-> Determinant(x) >;
Probably the most useful form of the map-constructor is the version for homomorphisms. Most interesting mappings in algebra are homomorphisms, and if an algebraic structure A belongs to a family of algebraic structures which form a variety we have the fundamental result that a homomorphism is uniquely determined by the images of any generating set. This provides us with a particularly compact way of defining and representing homomorphisms. While the syntax of the homomorphism constructor is similar to that of the general mapping constructor, the semantics are sometimes different.
The kind of homomorphism built by the hom-constructor is determined entirely by the domain: thus, a group homomorphism results from applying hom to a domain A that is one of the types of group in Magma, a ring homomorphism results when A is a ring, etc. As a consequence, the requirements on the specification of homomorphisms are dependent on the category to which A belongs. Often, the codomain of a homomorphism is required to belong to the same variety. But even within a category the specification may depend on the type of structure; for details we refer the reader to the specific chapters.
Note that the onus is on the programmer to ensure that the mapping defined
by the hom-constructor is a homomorphism, as the
homomorphism property will be assumed when calculating images of elements
from A. If a homomorphism is specified
by generator images, the processor will
seek to express an element as a word in the generators
of A when asked to compute its image.
Thus, the domain A may be infinite only when
it is given as a finitely presented structure.
The codomain B may be finite or infinite.
hom< A -> B | G > : Struct, Struct -> Map
Given a finitely generated algebraic structure A possessing the universal mapping property, a set B and a subgraph G of A x B having the property that the set formed by projecting the elements of G onto their first component is equal to the defining generating set for A, construct the homomorphism f : A -> B defined by extending the map of the generators of A to all of A. The detailed requirements on the specification are module dependent, and can be found in the chapter describing the domain A.
This is a module dependent constructor for homomorphisms between structures A and B; see the chapter describing the functions for A. In general after the bar the images for all generators of the structure A must be specified.
Given a structure A, a structure B, a variable x and an expression e(x), construct the homomorphism f : A -> B, as defined by e(x). This form of the map constructor is a special case of the previous one whereby the image of x can be defined using a single expression. Again the scope of x is restricted to the map-constructor.
With respect to these generators, SL(2, Z) has presentation < a, b | a^2 = b^3, a^4 >. It is a simple matter to define the isomorphism between the finitely presented group and the matrix group:a = [ 0 -1 ] b = [ 0 -1 ] [ 1 0 ] [ 1 1 ]
> G<x, y> := Group<x, y | x^2 = y^3, x^4 = 1 >; > SL2Z<a, b> := sub< GeneralLinearGroup(2, Integers()) | > [0, -1, 1, 0], [0, -1, 1, 1] >; > f := hom< G -> SL2Z | x -> a, y -> b >;Note that this isomorphism could not have been given as a mapping from the matrix group onto the finitely presented group since then there would not have been any way of computing images.
Next we give an example of a homomorphism from an infinite group to a finite group. Let the group PSL(2, Z[i]), where Z[i] is the ring of Gaussian integers, be given by the presentation < a, b, c, d | a^3, b^2, c^3, d^2, (ac)^2, (ad)^2, (bd)^2, (bc)^2 >. The mapping
\ a -> (1, 2, 3)(4, 5, 6), \ b -> (1, 2)(4, 5)(3, 6), \ c -> (1, 2, 7)(4, 5, 8), \ d -> (1, 2)(4, 5)(7, 9)defines a homomorphism of PSL(2, Z[i]) onto the symmetric group of degree 9. This homomorphism can be specified in Magma as follows:
> PSL2Zi<a,b,c,d> := Group< a, b, c, d | a^3 = b^2 = c^3 = d^2 = > (a*c)^2 = (a*d)^2 = (b*d)^2 = (b*c)^2 = 1>; > S9<x,y,z,t> := sub< Sym(9) | (1,2,3)(4,5,6), (1,2)(4,5)(3,6), > (1,2,7)(4,5,8), (1,2)(4,5)(7,9) >; > f := hom< PSL2Zi -> S9 | x, y, z, t >;
> PGL27<a,b> := sub< Sym(8) |(2,6,8,7,4,5,3), (1,3,8,6,7,5,4,2) >; > f := hom< PGL27 -> PGL27 | x :-> x^-1 >;In the next example we construct a map that is a ring homomorphism only on a subring of the domain that is specified. This will not lead to problems as long as the map is not applied to elements outside the subring, in this case to elements having denominator divisible by 5.
> h := hom< RationalField() -> Integers(25) | >; > print h(1/2); 13No images need to be specified for a homomorphism on the rationals since, as is explained in the ring chapters, ring and field homomorphisms will always be assumed to be unitary, and the image 1 of 1 determines the whole map.
Partial mappings are quite different to both general mappings and
homomorphisms. Given structures A and B, a partial map is a subset G of
A x B, where it is no longer necessary for every element of A
to appear as a first element in some tuple of G.
PartialMap< A -> B | G > : Struct, Struct -> Map
Given a finite set A of cardinality n, a set B and a subgraph G of A x B, construct the partial map f : A -> B, as defined by G.
Given a set A, a set B, a variable x and an expression e(x), construct the partial map f : A -> B, as defined by e(x). This form of the map constructor is a special case of the previous one whereby the image of x can be defined using a single expression. Again the scope of x is restricted to the map-constructor.
> F<z> := FiniteField(9); > Zm := IntegerRing(8); > o := PartialMap< F -> Zm | x :-> Order(x) >; > print [ <x, o(x)> : x in F | x ne 0 ]; [ <1, 1>, <z, 0>, <z^2, 4>, <z^3, 0>, <2, 2>, <z^5, 0>, <z^6, 4>, <z^7, 0> ]