1#############################################################################
2##
3#W  matunits.gi     Alnuth - ALgebraic NUmber THeory           Bettina Eick
4##
5
6#############################################################################
7##
8#F IntersectionOfUnitSubgroups( F, gen1, gen2 )
9##
10## Let <gen1> and <gen2> be two subgroups of U(F).
11## This function computes the intersection of <gen1> and <gen2> as exponents
12## in the generators of <gen1>.
13##
14InstallGlobalFunction( IntersectionOfUnitSubgroups, function(F,gen1,gen2)
15    local add, ad1, ad2, U, u, l, m, t, int, i;
16
17    # get an additive description of both unit groups
18    add := ExponentsOfUnits( F, Concatenation( gen1, gen2 ) );
19    ad1 := add{[1..Length(gen1)]};
20    ad2 := add{[Length(gen1)+1..Length(gen1)+Length(gen2)]};
21
22    # extract units
23    U := UnitGroupOfNumberField( F );
24    u := GeneratorsOfGroup(U);
25    l := Length(u)-1;
26    m := Order(u[1]);
27    t := List( [1..l+1], x -> 0 ); t[1] := m;
28
29    # compute intersection
30    int := NullspaceIntMat( Concatenation( ad1, ad2, [t] ) );
31    int := int{[1..Length(int)]}{[1..Length(ad1)]};
32
33    # reduce torsion
34    if int[1][1] <> 0 then
35        int[1][1] := int[1][1] mod m;
36    fi;
37    if int[1] = 0*int[1] then
38        int := int{[2..Length(int)]};
39    fi;
40
41    return int;
42end );
43
44#############################################################################
45##
46#F IntersectionOfTFUnitsByCosets( F, mats, C )
47##
48## <mats> is a torsion free subgroup of U(F) und C are some cosets in U(F).
49##
50InstallGlobalFunction( IntersectionOfTFUnitsByCosets, function( F, mats, C )
51    local a, b, c, d, all, add, rep, s, i, r, fr1, fr2, int;
52
53    # set up
54    a := Length( mats );
55    b := Length( C.units );
56    c := Length( C.reprs );
57
58    # determine additive description
59    all := Concatenation( mats, C.units, C.reprs );
60    add := ExponentsOfUnits( F, all );
61
62    # mod out torsion
63    d := Length( GeneratorsOfGroup(UnitGroup(F)) ) - 1;
64    add := add{[1..Length(add)]}{[2..d+1]};
65
66    # cut into pieces
67    rep := add{[ a+b+1..a+b+c ]};
68    add := add{[ 1..a+b ]};
69
70    # loop over reps
71    s := false;
72    i := 1;
73    while IsBool(s) and i <= Length(rep) do
74        r := SolutionIntMat( add, rep[i] );
75        i := i+1;
76        if not IsBool(r) then s := r{[1..a]}; fi;
77    od;
78
79    # if we cannot find a representative, then return
80    if IsBool(s) then return false; fi;
81
82    # otherwise add intersection of mats with C.units
83    fr1 := add{[1..a]};
84    fr2 := add{[a+1..a+b]};
85
86    # find linear combinations of mgrp in unit
87    int := NullspaceIntMat( Concatenation( fr1, fr2 ) );
88    int := int{[1..Length(int)]}{[1..a]};
89
90    return rec( repr := s, ints := int );
91end );
92
93