cryst/0000755001325400021140000000000014540074574011400 5ustar gaehlerusercryst/doc/0000755001325400021140000000000014540074574012145 5ustar gaehlerusercryst/doc/introduction.tex0000644001325400021140000000507313563603571015414 0ustar gaehleruser%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Chapter{Introduction} \index{cryst} The {\Cryst} package, previously known as \package{CrystGAP}, provides functions for the computation with affine crystallographic groups, in particular space groups. For the definition of the standard crystallographic notions we refer to the International Tables \cite{Hah95}, in particular the chapter by Wondratschek \cite{Won95}, and to the introductory chapter in \cite{BBNWZ78}. The principal algorithms used in this package are described in \cite{EGN97}. The present version for {\GAP}~4 has been considerably reworked from an earlier version for {\GAP}~3.4.4. Most of the porting to {\GAP}~4 has been done by Franz G{\accent127 a}hler. Besides affine crystallographic groups acting from the right, also affine crystallographic groups acting from the left are now fully supported. Many algorithms have been added, extended, or improved in other ways. Our warmest thanks go the Max Neunh{\accent127 o}ffer, whose extensive testing of the {\GAP} 4 version of {\Cryst} in connection with {\XGAP} uncovered several bugs and led to many performance improvements. {\Cryst} is implemented in the {\GAP}~4 language, and runs on any system supporting {\GAP}~4. However, certain commands may require that other GAP packages such as {\CaratInterface} or {\XGAP} are installed. In particular, the routines in Section~"Normalizers" are likely to require {\CaratInterface}, and the function WyckoffGraph (see~"WyckoffGraph") requires {\XGAP}. Both {\CaratInterface} and {\XGAP} may be available only under Unix. The {\Cryst} package is loaded with the command \beginexample gap> LoadPackage( "cryst" ); true \endexample {\Cryst} has been developed by \beginitems Bettina Eick & Fachbereich Mathematik und Informatik\hfil\break Technische Universit\accent127at Braunschweig\hfil\break Pockelsstr. 14, D-38106 Braunschweig, Germany\hfil\break e-mail: \Mailto{b.eick@tu-bs.de} Franz G{\accent127 a}hler & Fakult\accent127at f\accent127ur Mathematik, Universit\accent127at Bielefeld\hfil\break Postfach 10 01 31, D-33501 Bielefeld, Germany\hfil\break e-mail: \Mailto{gaehler@math.uni-bielefeld.de} Werner Nickel & Fachbereich Mathematik, AG2, Technische Universit{\accent127 a}t Darmstadt, \hfill\break Schlossgartenstra{\ss}e 7, D-64289 Darmstadt, Germany \hfil\break e-mail: \Mailto{nickel@mathematik.tu-darmstadt.de} \enditems For bug reports, suggestions and comments please please use the issue tracker on GitHub: \beginitems & \URL{https://github.com/gap-packages/Cryst/issues/} \enditems cryst/doc/cryst.tex0000644001325400021140000011151614540072334014030 0ustar gaehleruser%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %A cryst.tex GAP documentation Bettina Eick %A & Franz Gaehler %A & Werner Nickel %% %Y Copyright 1997-1999 by Bettina Eick, Franz G"ahler and Werner Nickel %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Chapter{Affine crystallographic groups} An affine crystallographic group is a subgroup of the group of all Euclidean motions of $d$-dimensional space, with the property that its subgroup of all pure translations is a discrete normal subgroup of finite index. If the rank of the translation subgroup is $d$, is called a space group. The quotient / is called the point group of . In this package, affine crystallographic groups are represented as groups of augmented matrices of dimension $d+1$. Most functions assume a group of rational matrices, but some may also work with cyclotomic matrix groups. In particular, it is possible to compute the translation basis of an affine crystallographic group given in a cyclotomic representation, and to pass to a rational representation by conjugating with that basis. Further functionality for cyclotomic crystallographic groups is currently not guaranteed. Augmented matrices can take one of two forms. Matrices of the form \begintt [ M 0 ] [ t 1 ] \endtt act from the right on row vectors $(x,1)$. Such a matrix is said to be an affine matrix acting on the right. Since in {\GAP} all groups act from the right, this is the preferred representation of an affine transformation. The second representation of affine transformations is by augmented matrices of the form \begintt [ M t ] [ 0 1 ] \endtt which act from the left on column vectors $(x,1)$. Such matrices are said to be affine matrices acting on the left. This is the representation usually adopted by crystallographers. {\Cryst} supports affine crystallographic groups in both representations. Every affine crystallographic group is constructed in one of these two representations. Affine crystallographic groups in different representations should never be mixed, however. It is recommended to adopt one of the two representations, and then to stick to that decision. In order to facilitate this, there is a global variable `CrystGroupDefaultAction', whose value is either `RightAction' or `LeftAction'. The initial value is `RightAction', but this can be changed with \> SetCrystGroupDefaultAction( ) F where must be either `RightAction' or `LeftAction'. Constructor functions without explicit representation qualifier then will construct an affine crystallographic group in the representation specified by `CrystGroupDefaultAction'. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Section{Construction} \atindex{construction!of an AffineCrystGroup}% {@construction!of an \noexpand`AffineCrystGroup'} \> AffineCrystGroupOnRight( ) F \> AffineCrystGroupOnRight( ) F \> AffineCrystGroupOnRight( , ) F returns the matrix group generated by or , which must be affine matrices acting on the right, as affine crystallographic group acting on the right. An already existing group of affine matrices acting on the right can be converted to an affine crystallographic group acting on the right with \>AsAffineCrystGroupOnRight( ) F The property \>IsAffineCrystGroupOnRight( ) P is `true' exactly for those groups which have been constructed in the above two ways. \>AffineCrystGroupOnLeft( ) F \>AffineCrystGroupOnLeft( ) F \>AffineCrystGroupOnLeft( , ) F returns the matrix group generated by or , which must be affine matrices acting on the left, as affine crystallographic group acting on the left. An already existing group of affine matrices acting on the left can be converted to an affine crystallographic group acting on the left with \>AsAffineCrystGroupOnLeft( ) F The property \>IsAffineCrystGroupOnLeft( ) P is `true' exactly for those groups which have been constructed in the above two ways. It is recommended to adopt one representation for affine crystallographic groups, and then to stick to it. To facilitate this, routines are provided which assume a default representation. \>AffineCrystGroup( ) F \>AffineCrystGroup( ) F \>AffineCrystGroup( , ) F calls `AffineCrystGroupOnRight' or `AffineCrystGroupOnLeft' with the same arguments, depending on the value of `CrystGroupDefaultAction'. \>AsAffineCrystGroup( ) F calls `AsAffineCrystGroupOnRight' or `AsAffineCrystGroupOnLeft' with the same argument, depending on the value of `CrystGroupDefaultAction'. \>IsAffineCrystGroup( ) F calls `IsAffineCrystGroupOnRight' or `IsAffineCrystGroupOnLeft' with the same argument, depending on the value of `CrystGroupDefaultAction'. \>TransposedMatrixGroup( ) A returns the transpose of the affine crystallographic group . If is acting on the right, its transpose is acting on the left, and vice versa. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Section{Point group} \atindex{point group!of an AffineCrystGroup}% {@point group!of an \noexpand`AffineCrystGroup'} The point group

of an affine crystallographic group is the quotient /, where is the normal subgroup of all pure translations.

is isomorphic to the group generated by the linear parts of all affine matrices contained in . In {\Cryst} this latter group is identified with the point group of . \>PointGroup( ) A returns the point group of . \>IsPointGroup(

) P returns `true' if and only if

has been constructed as the point group of an affine crystallographic group . \>AffineCrystGroupOfPointGroup(

) A returns the affine crystallographic group , from which

has been constructed. \>PointHomomorphism( ) A returns a homomorphism from the affine crystallographic group to its point group. \>IsPointHomomorphism( ) P returns `true' if and only if has been constructed as the `PointHomomorphism' of an affine crystallographic group. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Section{Translation lattice} \atindex{translation lattice!of an AffineCrystGroup}% {@translation lattice!of an \noexpand`AffineCrystGroup'} The vectors by which the pure translations in an affine crystallographic group translate form a discrete lattice, , called the translation lattice of . \>TranslationBasis( ) A returns a basis of the translation lattice of . The basis returned is unique for the translation lattice. \>InternalBasis( ) A returns a basis used internally for many computations. It consists of the translation basis of , extended by further standard basis vectors if has not full rank. If a generating set of the translation lattice of is known from somewhere, this knowledge can be added to with \>AddTranslationBasis( , ) F This function must do further work, so that `SetTranslationBasis' cannot be used for this purpose. If doubts arise about the correctness of the translation basis that has been added by hand, one can check the correctness of the stored value with \>CheckTranslationBasis( ) F An affine crystallographic group acting on $d$-dimensional Euclidean space is called a *space group* if its translation lattice has rank $d$. \>IsSpaceGroup( ) P tests if the affine crystallographic group is a space group. Since many computations are done internally in the `InternalBasis' of , we say that is in standard form if the `InternalBasis' is the standard basis of Euclidean row space or column space, respectively. This means that the translation lattice is generated by the first $k$ standard basis vectors, where $k$ is the rank of the translation lattice. \>IsStandardAffineCrystGroup( ) P checks if is in standard form. \>IsStandardSpaceGroup( ) P checks if is a space group in standard form. \>StandardAffineCrystGroup( ) F returns a conjugate of which is in standard form. If an space group is a semi-direct product of its point group with its translation subgroup, is said to be symmorphic. \>IsSymmorphicSpaceGroup( ) P checks if the space group is symmorphic. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Section{Special methods} \atindex{methods!for an AffineCrystGroup}% {@methods!for an \noexpand`AffineCrystGroup'} In the representation by augmented matrices, affine crystallographic groups are infinite matrix groups. Their infinity is relatively trivial in the sense that they have an abelian normal subgroup of finite index. Nevertheless, for many operations special methods have to be installed that avoid to attempt algorithms that never finish. These methods all make essential use of the exactness of the sequence of homomorphism `0 -> -> ->

-> 1', where is the translation subgroup of , and

its point group. All operations for general groups that make sense for affine crystallographic groups should work also in that case. In particular, there should be no restrictions for finite `AffineCrystGroups'. For infinite groups, some restrictions apply, however. For instance, algorithms from the orbit-stabilizer family can work only if the orbits generated are finite. Note, however, that `Normalizer', `Centralizer' and `RepresentativeAction' in an `AffineCrystGroup' work even if the corresponding orbit is infinite. Some methods installed for affine crystallographic groups have a special behavior. \indextt{\\\^{}!for an \noexpand`AffineCrystGroup'} \>`\\^( , )'{power!for an `AffineCrystGroup'}% @{power!for an `AffineCrystGroup'} If is an `AffineCrystGroupOnRight', the group is returned. must be an affine matrix acting on the right. If is an `AffineCrystGroupOnLeft', the group is returned. must be an affine matrix acting on the left. \>IsomorphismFpGroup(

)!{for a `PointGroup'} A returns an isomorphism from the `PointGroup'

to an isomorphic `FpGroup' . If

is solvable, is given in a power-commutator presentation. \>IsomorphismFpGroup( )!{for an `AffineCrystGroup'} A returns an isomorphism from the `AffineCrystGroup' to an isomorphic `FpGroup' . If is solvable, is given in a power-commutator presentation. The presentation of is an extension of the presentation of the point group

of used in `IsomorphismFpGroup(

)'. If the package polycyclic is installed, {\Cryst} automatically loads it, and then provides special methods for `IsomorphismPcpGroup'. \>IsomorphismPcpGroup(

)!{for a `PointGroup'} A with

a solvable `PointGroup', returns an isomorphism from

to an isomorphic `PcpGroup' . For details about `PcpGroups', we refer to the documentation of the package polycyclic. \>IsomorphismPcpGroup( )!{for an `AffineCrystGroup'} A with a solvable `AffineCrystGroup' (i.e., one with a solvable `PointGroup'), returns an isomorphism from to an isomorphic `PcpGroup' . The presentation of is an extension of the presentation of the point group

of used in `IsomorphismPcpGroup(

)'. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Section{Maximal subgroups} \atindex{subgroups!maximal!for an AffineCrystGroup}% {@subgroups!maximal!for an \noexpand`AffineCrystGroup'} \atindex{maximal subgroups!for an AffineCrystGroup}% {@maximal subgroups!for an \noexpand`AffineCrystGroups'} Since an `AffineCrystGroup' has infinitely many maximal subgroups in general, in the computation of maximal subgroups it must be further specified which maximal subgroups are desired. Recall that a maximal subgroup of an `AffineCrystGroup' is either latticeequal or classequal. A latticeequal subgroup has the same translation lattice as the parent, while a classequal subgroup has the same point group as the parent. In the classequal case a maximal subgroup always has prime-power index, whereas in the latticeequal case this is so only in dimensions up to 3. \>MaximalSubgroupClassReps( , )!{for an `AffineCrystGroup'} O returns a list of conjugacy class representatives of maximal subgroups of the `AffineCrystGroup' . \>ConjugacyClassesMaximalSubgroups( , )!{for an `AffineCrystGroup'} O returns a list of conjugacy classes of maximal subgroups of the `AffineCrystGroup' . In these two functions, the argument specifies which maximal subgroups are computed. is a record which may have the following components: \beginitems `flags.primes := [p1 .. pr]' & only maximal subgroups of p-power index for the given primes p are computed `flags.latticeequal := true' & only latticeequal maximal subgroups are computed `flags.classequal := true' & only classequal maximal subgroups are computed \enditems `flags.latticeequal' and `flags.classequal' must not both be bound and `true'. `flags.primes' may be omitted only if `flags.latticeequal' is bound and `true'. \beginexample gap> S := SpaceGroupIT(3,222); SpaceGroupOnRightIT(3,222,'2') gap> L := MaximalSubgroupClassReps( S, rec( primes := [3,5] ) );; gap> List( L, IndexInParent ); [ 3, 27, 125 ] gap> L := MaximalSubgroupClassReps( S, > rec( classequal := true, primes := [3,5] ) );; gap> List( L, IndexInParent ); [ 27, 125 ] gap> L := MaximalSubgroupClassReps( S, > rec( latticeequal := true, primes := [3,5] ) );; gap> List( L, IndexInParent ); [ 3 ] gap> L := MaximalSubgroupClassReps( S, rec( latticeequal := true ) );; gap> Length(L); 5 gap> List( L, IndexInParent ); [ 2, 2, 2, 3, 4 ] \endexample %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Section{Space groups with a given point group} \index{space groups!for given point group} \>SpaceGroupsByPointGroupOnRight(

) O \>SpaceGroupsByPointGroupOnRight(

, ) O \>SpaceGroupsByPointGroupOnRight(

, , ) O where

is any finite subgroup of $GL(d,\Z)$, returns a list of all space groups (acting on the right) with point group

, up to conjugacy in the full translation group of Euclidean space. All these space groups are returned as `AffineCrystGroupOnRight' in standard representation. If a second argument is present, which must be a list of elements of the normalizer of

in $GL(d,\Z)$, only space groups inequivalent under conjugation with these elements are returned. If these normalizer elements, together with

, generate the full normalizer of

in $GL(d,\Z)$, then exactly one representative of each space group type is obtained. If the third argument , which must be `false' or `true', is also present and `true', all space groups up to conjugacy in the full translation group are returned, but these space groups are collected into orbits under the conjugation action with elements from . \beginexample gap> P := Group([ [ [ -1, 0 ], [ 0, -1 ] ], [ [ -1, 0 ], [ 0, 1 ] ] ]); Group([ [ [ -1, 0 ], [ 0, -1 ] ], [ [ -1, 0 ], [ 0, 1 ] ] ]) gap> norm := GeneratorsOfGroup( NormalizerInGLnZ( P ) ); [ [ [ -1, 0 ], [ 0, -1 ] ], [ [ -1, 0 ], [ 0, 1 ] ], [ [ -1, 0 ], [ 0, -1 ] ], [ [ 1, 0 ], [ 0, -1 ] ], [ [ 0, 1 ], [ 1, 0 ] ] ] gap> SpaceGroupsByPointGroupOnRight( P ); [ , , , ] gap> SpaceGroupsByPointGroupOnRight( P, norm ); [ , , ] gap> SpaceGroupsByPointGroupOnRight( P, norm, true ); [ [ ], [ , ], [ ] ] \endexample \>SpaceGroupTypesByPointGroupOnRight(

) O \>SpaceGroupTypesByPointGroupOnRight(

, ) O returns a list of space group type representatives (acting on the right) of the point group

. As in the case of `SpaceGroupsByPointGroupOnRight', if the boolean argument is present and `true', not only space group type representatives, but all space groups up to conjugacy in the full translation group are returned. These are then collected into lists of space groups of the same space group type. \beginexample gap> SpaceGroupTypesByPointGroupOnRight( P ); [ , , ] gap> SpaceGroupTypesByPointGroupOnRight( P, true ); [ [ ], [ , ], [ ] ] \endexample \>SpaceGroupsByPointGroupOnLeft(

) O \>SpaceGroupsByPointGroupOnLeft(

, ) O \>SpaceGroupsByPointGroupOnLeft(

, , ) O works the same way as `SpaceGroupsByPointGroupOnRight', except that the space groups acting from the left are returned. \>SpaceGroupTypesByPointGroupOnLeft(

) O \>SpaceGroupTypesByPointGroupOnLeft(

, ) O works the same way as `SpaceGroupTypesByPointGroupOnRight', except that the space groups acting from the left are returned. \>SpaceGroupsByPointGroup(

) O \>SpaceGroupsByPointGroup(

, ) O \>SpaceGroupsByPointGroup(

, , ) O calls `SpaceGroupByPointGroupOnRight' or `SpaceGroupByPointGroupOnLeft' with the same arguments, depending on the value of `CrystGroupDefaultAction'. \>SpaceGroupTypesByPointGroupOnLeft(

) O \>SpaceGroupTypesByPointGroupOnLeft(

, ) O calls either `SpaceGroupTypesByPointGroupOnRight' or `SpaceGroupTypesByPointGroupOnLeft' with the same arguments, depending on the variable `CrystGroupDefaultAction'. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Section{Wyckoff positions} A Wyckoff position of a space group is an equivalence class of points in Euclidean space, having stabilizers which are conjugate subgroups of . Apart from a subset of lower dimension, which contains points with even bigger stabilizers, a Wyckoff position consists of an -orbit of some affine subspace . In {\Cryst}, a Wyckoff position is specified by such a representative affine subspace. \>WyckoffPositions( ) A returns the list of Wyckoff positions of the space group . \beginexample gap> S := SpaceGroupIT(2,14); SpaceGroupOnRightIT(2,14,'1') gap> W := WyckoffPositions(S); [ < Wyckoff position, point group 3, translation := [ 0, 0 ], basis := [ ] > , < Wyckoff position, point group 3, translation := [ 2/3, 1/3 ], basis := [ ] > , < Wyckoff position, point group 3, translation := [ 1/3, 2/3 ], basis := [ ] > , < Wyckoff position, point group 2, translation := [ 0, 0 ], basis := [ [ 1, -1 ] ] > , < Wyckoff position, point group 1, translation := [ 0, 0 ], basis := [ [ 1, 0 ], [ 0, 1 ] ] > ] \endexample In the previous example, has three kinds of special points (the basis is empty), whose representatives all have a stabilizer with the same point group (with label 1), one kind of special line (the basis has length 1), and the general position. \>WyckoffPositionsByStabilizer( , ) O where is a space group and a subgroup of the point group or a list of such subgroups, determines only the Wyckoff positions whose representatives have a stabilizer with a point group equal to the subgroup or contained in the list , respectively. \beginexample gap> sub := Group([ [ [ 0, -1 ], [ -1, 0 ] ] ]); Group([ [ [ 0, -1 ], [ -1, 0 ] ] ]) gap> IsSubgroup( PointGroup( S ), sub ); true gap> WyckoffPositionsByStabilizer( S, sub ); [ < Wyckoff position, point group 1, translation := [ 0, 0 ], basis := [ [ 1, -1 ] ] > ] \endexample \>IsWyckoffPosition( ) R checks whether is a Wyckoff position. \beginexample gap> ForAll( W, IsWyckoffPosition ); true \endexample \>WyckoffBasis( ) O returns a basis of the representative affine subspace of the Wyckoff position . \beginexample gap> WyckoffBasis( W[4] ); [ [ 1, -1 ] ] \endexample \>WyckoffTranslation( ) O returns a point of the representative affine subspace of the Wyckoff position . \beginexample gap> WyckoffTranslation( W[3] ); [ 1/3, 2/3 ] \endexample \>WyckoffSpaceGroup( ) O returns the space group of which is a Wyckoff position. \beginexample gap> WyckoffSpaceGroup( W[1] ); SpaceGroupOnRightIT(2,14,'1') \endexample \>WyckoffStabilizer( ) O returns the stabilizer of the (generic) points in the representative affine subspace of the Wyckoff position . This stabilizer is a subgroup of the space group of , and thus an `AffineCrystGroup'. \beginexample gap> stab := WyckoffStabilizer( W[4] ); Group([ [ [ 0, -1, 0 ], [ -1, 0, 0 ], [ 0, 0, 1 ] ] ]) gap> IsAffineCrystGroupOnRight( stab ); true \endexample \>WyckoffOrbit( ) O determines the orbit of the representative affine subspace of the Wyckoff position under the space group of (modulo lattice translations). The affine subspaces in this orbit are then converted into a list of Wyckoff positions, which is returned. The Wyckoff positions in this list are just different representations of . Their `WyckoffBasis' and `WyckoffTranslation' are chosen such that the induced parametrizations of their representative subspaces are mapped onto each other under the space group operation. \beginexample gap> orb := WyckoffOrbit( W[4] ); [ < Wyckoff position, point group 2, translation := [ 0, 0 ], basis := [ [ 1, -1 ] ] > , < Wyckoff position, point group 2, translation := [ 0, 0 ], basis := [ [ 1, 2 ] ] > , < Wyckoff position, point group 2, translation := [ 0, 0 ], basis := [ [ -2, -1 ] ] > ] gap> Set(orb); [ < Wyckoff position, point group 2, translation := [ 0, 0 ], basis := [ [ 1, -1 ] ] > ] \endexample \>WyckoffGraph( [, def ] ) O \>WyckoffGraph( [, def ] ) O displays the incidence relations of a set of Wyckoff positions graphically. This function is available only under {\XGAP}. In the first form, is a list of Wyckoff positions, which must belong to the same space group. In the second form, is a space group; in this case, the function is applied to the complete list of Wyckoff positions of . In both forms, a second argument, , is possible, which is a record with optional components `title', `width' and `height', specifying the title, width and height of the graphic sheet on which the graph will be displayed. Each vertex of the graph represents a Wyckoff position. Vertices are arranged in horizontal layers, determined by the dimension of the Wyckoff position and the size of its stabilizer. For each layer, the list <[ d, s ]> is displayed at the right border of the graphic sheet. The vertical positions of the layers are ordered according to the dimension of the Wyckoff position (primary criterion, smaller dimension above) and the size of the stabilizer (secondary criterion, bigger stabilizer above). Two Wyckoff positions are connected if the closure of the lower one contains the upper one. Two Wyckoff positions are connected by a line only if there is no Wyckoff position in between. The connection line is labelled with the number of affine subspaces contained in the lower Wyckoff position that contain a fixed representative affine subspace of the upper Wyckoff position. For instance, if the lower Wyckoff position consists of a space group orbit of lines (and thus the upper one of an orbit of points), the label of the connection line is the number of lines in the orbit which cross a fixed representative point of the upper Wyckoff position. The initial layout of the graph is not always optimal. In particular, several connection lines can be drawn on top of each other, so that it is not easy to see who is connected with whom. With the left mouse button, the graph can be rearranged, however. Just drag each vertex to a more suitable place. Note, however, that a vertex can not leave its layer. For more details, please consult the {\XGAP} manual. By right-clicking on a vertex, a popup menu with information on the Wyckoff position of that vertex appears. It informs on the size of the `WyckoffStabilizer', the dimension of the Wyckoff position, the length of the `WyckoffOrbit' (modulo lattice translations), the translation and basis of a representative affine subspace, the isomorphims type of the `WyckoffStabilizer', and the ConjugacyClassInfo of the point group

of the `WyckoffStabilizer'. The ConjugacyClassInfo lists for each conjugacy class of elements of

the number of that class, the order, trace and determinant of its elements, and the size of the class. This information is useful to identify the geometric operation of the stabilizer. The isomorphism type and ConjugacyClassInfo may not be displayed initially. It this case, they can be obtained by left-clicking on them, or by left-clicking on the button labelled . Unfortunately, the popup window cannot be resized automatically, and since the ConjugacyClassInfo needs several lines for the display, the information may be hidden behind the border of the window. You will have to use the slider of the popup window to make it visible, or resize the window with the help of your window manager. Alternatively, you can right-click again on the same vertex, in which case a new popup window of sufficient size appears. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Section{Normalizers} \atindex{normalizer!of an AffineCrystGroup}% {@normalizer!of an \noexpand`AffineCrystGroup'} At present, most of the functions in this section require that the {\GAP} package {\CaratInterface} is installed (and compiled). Otherwise, they are available only for space groups from the crystallographic groups catalogue or the International Tables (section "International Tables"). \>NormalizerPointGroupInGLnZ(

) A returns the normalizer of the `PointGroup'

in the group of all unimodular transformations of the lattice spanned by the `InternalBasis' of the `AffineCrystGroup' of

. If is in standard representation, this is the same as `Normalizer( GL(dim,Integers), P )', otherwise it is `Normalizer( GL(dim,Integers), P^(B^-1) )^B'. This notion probably makes sense only if is a space group. Note that

must have elements with integer entries (which is the case if is a space group). \>CentralizerPointGroupInGLnZ(

) A returns the centralizer of the `PointGroup'

in the group of all unimodular transformations of the lattice spanned by the `InternalBasis' of the `AffineCrystGroup' of

. If is in standard representation, this is the same as `Centralizer( GL(dim,Integers), P )', otherwise it is `Centralizer( GL(dim,Integers), P^(B^-1) )^B'. This notion probably makes sense only if is a space group. Note that

must have elements with integer entries (which is the case if is a space group). \index{normalizer!in translation group} \>TranslationNormalizer( ) F returns the normalizer of the space group in the full translation group. At present, this function is implemented only for space groups, not for general `AffineCrystGroups'. The translation normalizer of may contain a continuous subgroup . A basis of the space of such continuous translations is bound in `TN!.continuousTranslations'. Since this subgroup is not finitely generated, it is *not* contained in the group generated by `GeneratorsOfGroup( )'. Properly speaking, the translation normalizer is the span of and together. \index{normalizer!in affine group} \>AffineNormalizer( ) F returns the affine normalizer of the space group . The affine normalizer contains the translation normalizer as a subgroup. Similarly as with `TranslationNormalizer', the subgroup of continuous translations, which is not finitely generated, is not part of the group that is returned. However, a basis of the space of continuous translations is bound in the component `AF!.continuousTranslations'. \>AffineInequivalentSubgroups( , ) F takes as input a space group and list of subgroups of , and returns a sublist of affine inequivalent subgroups. Note that the affine normalizer of must be discrete in the current implementation. If it is not, `fail' is returned. For two space groups and of the same dimension (and acting from the same side), \>ConjugatorSpaceGroups( , ) F returns an affine matrix such that `S1\^{}m = S2', of `fail' if no such matrix exists, i.e., if the two space groups are not equivalent. This function requires that the {\GAP} package {\CaratInterface} is installed (and compiled). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Section{Color groups} A color group is a group whose elements are colored in the following way. The elements having the same color as the identity element `One(C)' form a subgroup of finite index . is called the `ColorSubgroup' of . Elements of have the same color if and only if they are in the same right coset of in . The labelling of the colors, which runs from 1 to , is determined by a fixed labelling of the right cosets of . The list of right cosets of is stored in the attribute `ColorCosetList'. The color of the elements of a coset corresponds to the position of the coset in that list. Elements of by definition have color 1, i.e., the coset with representative `One(C)' is always the first element of the `ColorCosetList' of . Color groups which have a parent inherit their coloring from that parent, including the labelling of the colors. As with other groups, color groups having no parent are their own parent. Right multiplication by a fixed element of induces a permutation of the colors of the parent of . This defines a natural homomorphism of into the symmetric group of degree . The image of this homomorphism is called the `ColorPermGroup' of , and the homomorphism to it is called the `ColorHomomorphism' of . \>ColorGroup( , ) F constructs a colored copy of , with color subgroup (which should have finite index in ). Color groups constructed in this way are always their own parent. It is not possible to set their parent attribute to a different value. Groups which may be colored include, in particular, `AffineCrystGroups', but coloring of any finite group should work as well. \>IsColorGroup( ) P checks whether is a color group. \>ColorSubgroup( ) A returns the color subgroup of . \>ColorCosetList( ) A returns the color labelling cosets of . \>ColorOfElement( , ) F returns the color of an element of . \>ColorPermGroup( ) A returns the ColorPermGroup of , which is the permutation group induced by acting on the colors of the parent of . \>ColorHomomorphism( ) A returns the homomomorphism from to its `ColorPermGroup'. \>Subgroup( , )!{for color groups} O where is a color group, returns the colored subgroup of generated by . The parent of is set to the parent of , from which the coloring of is inherited. \beginexample gap> G := Group( (1,2,3), (2,3,4) ); Group([ (1,2,3), (2,3,4) ]) gap> H := Group( (1,2,3) ); Group([ (1,2,3) ]) gap> C := ColorGroup( G, H ); Group([ (1,2,3), (2,3,4) ]) gap> ColorSubgroup( C ) = H; true gap> ColorCosetList( C ); [ RightCoset(Group( [ (1,2,3) ] ),()), RightCoset(Group( [ (1,2,3) ] ),(1,2) (3,4)), RightCoset(Group( [ (1,2,3) ] ),(1,3)(2,4)), RightCoset(Group( [ (1,2,3) ] ),(1,4)(2,3)) ] gap> List( last, x -> ColorOfElement( C, Representative(x) ) ); [ 1, 2, 3, 4 ] gap> U := Subgroup( C, [(1,3)(2,4)] ); Group([ (1,3)(2,4) ]) gap> IsColorGroup( U ); true gap> ColorSubgroup( U ); Group(()) gap> ColorCosetList( U ); [ RightCoset(Group( () ),()), RightCoset(Group( () ),(1,3)(2,4)) ] gap> List( last, x -> ColorOfElement( U, Representative(x) ) ); [ 1, 3 ] \endexample %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Section{Colored AffineCrystGroups} If is a colored `AffineCrystGroup' whose `ColorSubgroup' is lattice-equal (translationengleich) with , then the `PointGroup' of can consistently be colored. In that case, \>PointGroup( C )!{for a colored `AffineCrystGroup'} A returns a colored point group. Otherwise, the `PointGroup' of is an ordinary, uncolored group. \beginexample gap> S := SpaceGroupIT( 2, 10 ); SpaceGroupOnRightIT(2,10,'1') gap> m := MaximalSubgroupClassReps( S, rec( primes := [2] ) ); [ , , ] gap> List( last, x -> TranslationBasis(x) = TranslationBasis(S) ); [ false, true, false ] gap> C := ColorGroup( S, m[1] );; IsColorGroup( PointGroup( C ) ); false gap> C := ColorGroup( S, m[2] );; IsColorGroup( PointGroup( C ) ); true \endexample Two colorings of a *space group* are *equivalent* if the two `ColorSubgroups' are conjugate in the affine normalizer of . For instance, a list of inequivalent index-2 `ColorSubgroups' of can be obtained with the following code: \index{colorings!inequivalent!for space group} \beginexample gap> sub := MaximalSubgroupClassReps( S, rec( primes := [2] ) ); [ , , ] gap> List( sub, Size ); [ infinity, infinity, infinity ] gap> sub := Filtered( sub, s -> IndexInParent( s ) = 2 ); [ , , ] gap> Length( AffineInequivalentSubgroups( S, sub ) ); 2 \endexample Note that `AffineInequivalentSubgroups' requires the {\GAP} package {\CaratInterface} to be installed. Otherwise, this function is supported only for `AffineCrystGroups' constructed from the crystallographic groups catalog. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Section{International Tables} For the user's convenience, a table with the 17 plane groups and the 230 space groups is included in {\Cryst}. These groups are given in exactly the same settings (i.e., choices of basis and origin) as in the International Tables. Space groups with a centered lattice are therefore given in the non-primitive basis crystallographers are used to. This is in contrast to the crystallographic groups catalogue, where always a primitive basis is used. For some of the 3D space groups, two different settings are available. The possible settings are labelled with the characters `\pif{1}\pif', `\pif{2}\pif',`\pif{b}\pif',`\pif{c}\pif',`\pif{h}\pif' and `\pif{r}\pif'. If only one setting is available, it is labelled `\pif{1}\pif'. For some space groups there exists a point with higher symmetry than the origin of the `\pif{1}\pif' setting. In such cases, a second setting `\pif{2}\pif' is available, which has this high symmetry point as origin. This second setting `\pif{2}\pif' then is the default setting. Space groups which have a unique axis can have this axis in direction (setting`\pif{b}\pif') or direction (setting `\pif{c}\pif'). `\pif{b}\pif' is the default setting. Rhombohedral space groups are given in a hexagonal basis (setting `\pif{h}\pif') and in a rhombohedral basis (setting `\pif{r}\pif'). `\pif{h}\pif' is the default setting. \>SpaceGroupSettingsIT( , ) F returns a string, whose characters label the available settings of the space group with number and dimension . \> SpaceGroupOnRightIT( , ) F \> SpaceGroupOnRightIT( , , ) F returns space group number in dimension in the representation acting on the right. In the third argument, the desired setting can be specified. Otherwise, the space group is returned in the default setting for that space group. \> SpaceGroupOnLeftIT( , ) F \> SpaceGroupOnLeftIT( , , ) F returns space group number in dimension in the representation acting on the left. In the third argument, the desired setting can be specified. Otherwise, the space group is returned in the default setting for that space group. \> SpaceGroupIT( , ) F \> SpaceGroupIT( , , ) F returns either `SpaceGroupOnRightIT' or `SpaceGroupOnLeftIT' with the same arguments, depending on the value of `CrystGroupDefaultAction'. \beginexample gap> SpaceGroupSettingsIT( 3, 146 ); "hr" gap> SpaceGroupOnRightIT( 3, 146 ); SpaceGroupOnRightIT(3,146,'h') gap> SpaceGroupOnRightIT( 3, 146, 'r' ); SpaceGroupOnRightIT(3,146,'r') \endexample cryst/doc/manual.lab0000644001325400021140000001142114540074574014101 0ustar gaehleruser\makelabel{cryst:Introduction}{1} \makelabel{cryst:Affine crystallographic groups}{2} \makelabel{cryst:SetCrystGroupDefaultAction}{2} \makelabel{cryst:Construction}{2.1} \makelabel{cryst:AffineCrystGroupOnRight}{2.1.1} \makelabel{cryst:AffineCrystGroupOnRight}{2.1.1} \makelabel{cryst:AffineCrystGroupOnRight}{2.1.1} \makelabel{cryst:AsAffineCrystGroupOnRight}{2.1.2} \makelabel{cryst:IsAffineCrystGroupOnRight}{2.1.3} \makelabel{cryst:AffineCrystGroupOnLeft}{2.1.4} \makelabel{cryst:AffineCrystGroupOnLeft}{2.1.4} \makelabel{cryst:AffineCrystGroupOnLeft}{2.1.4} \makelabel{cryst:AsAffineCrystGroupOnLeft}{2.1.5} \makelabel{cryst:IsAffineCrystGroupOnLeft}{2.1.6} \makelabel{cryst:AffineCrystGroup}{2.1.7} \makelabel{cryst:AffineCrystGroup}{2.1.7} \makelabel{cryst:AffineCrystGroup}{2.1.7} \makelabel{cryst:AsAffineCrystGroup}{2.1.8} \makelabel{cryst:IsAffineCrystGroup}{2.1.9} \makelabel{cryst:TransposedMatrixGroup}{2.1.10} \makelabel{cryst:Point group}{2.2} \makelabel{cryst:PointGroup}{2.2.1} \makelabel{cryst:IsPointGroup}{2.2.2} \makelabel{cryst:AffineCrystGroupOfPointGroup}{2.2.3} \makelabel{cryst:PointHomomorphism}{2.2.4} \makelabel{cryst:IsPointHomomorphism}{2.2.5} \makelabel{cryst:Translation lattice}{2.3} \makelabel{cryst:TranslationBasis}{2.3.1} \makelabel{cryst:InternalBasis}{2.3.2} \makelabel{cryst:AddTranslationBasis}{2.3.3} \makelabel{cryst:CheckTranslationBasis}{2.3.4} \makelabel{cryst:IsSpaceGroup}{2.3.5} \makelabel{cryst:IsStandardAffineCrystGroup}{2.3.6} \makelabel{cryst:IsStandardSpaceGroup}{2.3.7} \makelabel{cryst:StandardAffineCrystGroup}{2.3.8} \makelabel{cryst:IsSymmorphicSpaceGroup}{2.3.9} \makelabel{cryst:Special methods}{2.4} \makelabel{cryst:power!for an `AffineCrystGroup'}{2.4.1} \makelabel{cryst:IsomorphismFpGroup!for a `PointGroup'}{2.4.2} \makelabel{cryst:IsomorphismFpGroup!for an `AffineCrystGroup'}{2.4.3} \makelabel{cryst:IsomorphismPcpGroup!for a `PointGroup'}{2.4.4} \makelabel{cryst:IsomorphismPcpGroup!for an `AffineCrystGroup'}{2.4.5} \makelabel{cryst:Maximal subgroups}{2.5} \makelabel{cryst:MaximalSubgroupClassReps!for an `AffineCrystGroup'}{2.5.1} \makelabel{cryst:ConjugacyClassesMaximalSubgroups!for an `AffineCrystGroup'}{2.5.2} \makelabel{cryst:Space groups with a given point group}{2.6} \makelabel{cryst:SpaceGroupsByPointGroupOnRight}{2.6.1} \makelabel{cryst:SpaceGroupsByPointGroupOnRight}{2.6.1} \makelabel{cryst:SpaceGroupsByPointGroupOnRight}{2.6.1} \makelabel{cryst:SpaceGroupTypesByPointGroupOnRight}{2.6.2} \makelabel{cryst:SpaceGroupTypesByPointGroupOnRight}{2.6.2} \makelabel{cryst:SpaceGroupsByPointGroupOnLeft}{2.6.3} \makelabel{cryst:SpaceGroupsByPointGroupOnLeft}{2.6.3} \makelabel{cryst:SpaceGroupsByPointGroupOnLeft}{2.6.3} \makelabel{cryst:SpaceGroupTypesByPointGroupOnLeft}{2.6.4} \makelabel{cryst:SpaceGroupTypesByPointGroupOnLeft}{2.6.4} \makelabel{cryst:SpaceGroupsByPointGroup}{2.6.5} \makelabel{cryst:SpaceGroupsByPointGroup}{2.6.5} \makelabel{cryst:SpaceGroupsByPointGroup}{2.6.5} \makelabel{cryst:SpaceGroupTypesByPointGroupOnLeft}{2.6.6} \makelabel{cryst:SpaceGroupTypesByPointGroupOnLeft}{2.6.6} \makelabel{cryst:Wyckoff positions}{2.7} \makelabel{cryst:WyckoffPositions}{2.7.1} \makelabel{cryst:WyckoffPositionsByStabilizer}{2.7.2} \makelabel{cryst:IsWyckoffPosition}{2.7.3} \makelabel{cryst:WyckoffBasis}{2.7.4} \makelabel{cryst:WyckoffTranslation}{2.7.5} \makelabel{cryst:WyckoffSpaceGroup}{2.7.6} \makelabel{cryst:WyckoffStabilizer}{2.7.7} \makelabel{cryst:WyckoffOrbit}{2.7.8} \makelabel{cryst:WyckoffGraph}{2.7.9} \makelabel{cryst:WyckoffGraph}{2.7.9} \makelabel{cryst:Normalizers}{2.8} \makelabel{cryst:NormalizerPointGroupInGLnZ}{2.8.1} \makelabel{cryst:CentralizerPointGroupInGLnZ}{2.8.2} \makelabel{cryst:TranslationNormalizer}{2.8.3} \makelabel{cryst:AffineNormalizer}{2.8.4} \makelabel{cryst:AffineInequivalentSubgroups}{2.8.5} \makelabel{cryst:ConjugatorSpaceGroups}{2.8.6} \makelabel{cryst:Color groups}{2.9} \makelabel{cryst:ColorGroup}{2.9.1} \makelabel{cryst:IsColorGroup}{2.9.2} \makelabel{cryst:ColorSubgroup}{2.9.3} \makelabel{cryst:ColorCosetList}{2.9.4} \makelabel{cryst:ColorOfElement}{2.9.5} \makelabel{cryst:ColorPermGroup}{2.9.6} \makelabel{cryst:ColorHomomorphism}{2.9.7} \makelabel{cryst:Subgroup!for color groups}{2.9.8} \makelabel{cryst:Colored AffineCrystGroups}{2.10} \makelabel{cryst:PointGroup!for a colored `AffineCrystGroup'}{2.10.1} \makelabel{cryst:International Tables}{2.11} \makelabel{cryst:SpaceGroupSettingsIT}{2.11.1} \makelabel{cryst:SpaceGroupOnRightIT}{2.11.2} \makelabel{cryst:SpaceGroupOnRightIT}{2.11.2} \makelabel{cryst:SpaceGroupOnLeftIT}{2.11.3} \makelabel{cryst:SpaceGroupOnLeftIT}{2.11.3} \makelabel{cryst:SpaceGroupIT}{2.11.4} \makelabel{cryst:SpaceGroupIT}{2.11.4} \makelabel{cryst:Bibliography}{} \setcitlab {BBNWZ78}{BBNWZ78} \setcitlab {EGN97}{EGN97} \setcitlab {Hah95}{Hah95} \setcitlab {Won95}{Won95} \makelabel{cryst:Index}{} cryst/doc/manual.toc0000644001325400021140000000116514540074574014134 0ustar gaehleruser\chapcontents {1}{Introduction}{3} \chapcontents {2}{Affine crystallographic groups}{4} \seccontents {2.1}{Construction} {5} \seccontents {2.2}{Point group} {6} \seccontents {2.3}{Translation lattice} {6} \seccontents {2.4}{Special methods} {7} \seccontents {2.5}{Maximal subgroups} {8} \seccontents {2.6}{Space groups with a given point group} {9} \seccontents {2.7}{Wyckoff positions} {10} \seccontents {2.8}{Normalizers} {13} \seccontents {2.9}{Color groups} {13} \seccontents {2.10}{Colored AffineCrystGroups} {15} \seccontents {2.11}{International Tables} {16} \chapcontents {}{Bibliography}{17} \chapcontents {}{Index}{18} cryst/doc/make_doc0000755001325400021140000000055614241201135013622 0ustar gaehleruser#!/bin/sh set -e echo "TeXing documentation" rm -f manual.aux manual.dvi manual.idx manual.ilg manual.ind manual.lab manual.log manual.six manual.toc tex manual ../../../doc/manualindex manual tex manual echo "Creating PDF version" pdftex manual; pdftex manual echo "Creating HTML documentation" mkdir -p ../htm ../../../etc/convert.pl -c -i -u -n cryst . ../htm cryst/doc/manual.tex0000644001325400021140000000226714540074211014137 0ustar gaehleruser\input ../../../doc/gapmacro.tex \Package{Cryst} \Package{CrystCat} \Package{CaratInterface} \Package{XGAP} \BeginningOfBook{cryst} \UseReferences{../../../doc/ref} \TitlePage{ \centerline{\titlefont Cryst} \medskip \centerline{\titlefont ---} \medskip \centerline{\subtitlefont Computing with Crystallographic Groups} \medskip \centerline{\titlefont ---} \medskip \centerline{\subtitlefont A GAP4 Package} \bigskip\medskip \centerline{\secfont Version 4.1.27} \bigskip\medskip \vfill \centerline{\secfont Bettina Eick} \bigskip \centerline{\secfont Franz G\accent127ahler} \bigskip \centerline{\secfont Werner Nickel} \bigskip \bigskip \centerline{\secfont{\Month} \Year} \vfill \centerline{Copyright {\copyright} 1999--2023 by Bettina Eick, Franz G{\accent127 a}hler, and Werner Nickel} \bigskip \centerline{This software is released under the GPL version 2 or later (at your preference).} \centerline{For the text of the GPL, please see https://www.gnu.org/licenses/.} } \OneColumnTableOfContents \FrontMatter \Chapters \Input{introduction} \Input{cryst} \Appendices \Bibliography \Index \EndOfBook cryst/doc/manual.mst0000644001325400021140000000046413232361435014143 0ustar gaehleruserpreamble "" postamble "\n" group_skip "\n" headings_flag 1 heading_prefix "\\letter " numhead_positive "{}" symhead_positive "{}" item_0 "\n " item_1 "\n \\sub " item_01 "\n \\sub " item_x1 ", " item_2 "\n \\subsub " item_12 "\n \\subsub " item_x2 ", " page_compositor "--" line_max 1000 cryst/doc/manual.six0000644001325400021140000000672714540074574014163 0ustar gaehleruserC introduction.tex 1. Introduction I 1.0. cryst C cryst.tex 2. Affine crystallographic groups F 2.0. SetCrystGroupDefaultAction S 2.1. Construction I 2.1. construction!of an AffineCrystGroup F 2.1. AffineCrystGroupOnRight F 2.1. AffineCrystGroupOnRight F 2.1. AffineCrystGroupOnRight F 2.1. AsAffineCrystGroupOnRight F 2.1. IsAffineCrystGroupOnRight F 2.1. AffineCrystGroupOnLeft F 2.1. AffineCrystGroupOnLeft F 2.1. AffineCrystGroupOnLeft F 2.1. AsAffineCrystGroupOnLeft F 2.1. IsAffineCrystGroupOnLeft F 2.1. AffineCrystGroup F 2.1. AffineCrystGroup F 2.1. AffineCrystGroup F 2.1. AsAffineCrystGroup F 2.1. IsAffineCrystGroup F 2.1. TransposedMatrixGroup S 2.2. Point group I 2.2. point group!of an AffineCrystGroup F 2.2. PointGroup F 2.2. IsPointGroup F 2.2. AffineCrystGroupOfPointGroup F 2.2. PointHomomorphism F 2.2. IsPointHomomorphism S 2.3. Translation lattice I 2.3. translation lattice!of an AffineCrystGroup F 2.3. TranslationBasis F 2.3. InternalBasis F 2.3. AddTranslationBasis F 2.3. CheckTranslationBasis F 2.3. IsSpaceGroup F 2.3. IsStandardAffineCrystGroup F 2.3. IsStandardSpaceGroup F 2.3. StandardAffineCrystGroup F 2.3. IsSymmorphicSpaceGroup S 2.4. Special methods I 2.4. methods!for an AffineCrystGroup I 2.4. \\{\accent 94 }!for an `AffineCrystGroup' F 2.4. power!for an `AffineCrystGroup' F 2.4. IsomorphismFpGroup!for a `PointGroup' F 2.4. IsomorphismFpGroup!for an `AffineCrystGroup' F 2.4. IsomorphismPcpGroup!for a `PointGroup' F 2.4. IsomorphismPcpGroup!for an `AffineCrystGroup' S 2.5. Maximal subgroups I 2.5. subgroups!maximal!for an AffineCrystGroup I 2.5. maximal subgroups!for an AffineCrystGroup F 2.5. MaximalSubgroupClassReps!for an `AffineCrystGroup' F 2.5. ConjugacyClassesMaximalSubgroups!for an `AffineCrystGroup' S 2.6. Space groups with a given point group I 2.6. space groups!for given point group F 2.6. SpaceGroupsByPointGroupOnRight F 2.6. SpaceGroupsByPointGroupOnRight F 2.6. SpaceGroupsByPointGroupOnRight F 2.6. SpaceGroupTypesByPointGroupOnRight F 2.6. SpaceGroupTypesByPointGroupOnRight F 2.6. SpaceGroupsByPointGroupOnLeft F 2.6. SpaceGroupsByPointGroupOnLeft F 2.6. SpaceGroupsByPointGroupOnLeft F 2.6. SpaceGroupTypesByPointGroupOnLeft F 2.6. SpaceGroupTypesByPointGroupOnLeft F 2.6. SpaceGroupsByPointGroup F 2.6. SpaceGroupsByPointGroup F 2.6. SpaceGroupsByPointGroup F 2.6. SpaceGroupTypesByPointGroupOnLeft F 2.6. SpaceGroupTypesByPointGroupOnLeft S 2.7. Wyckoff positions F 2.7. WyckoffPositions F 2.7. WyckoffPositionsByStabilizer F 2.7. IsWyckoffPosition F 2.7. WyckoffBasis F 2.7. WyckoffTranslation F 2.7. WyckoffSpaceGroup F 2.7. WyckoffStabilizer F 2.7. WyckoffOrbit F 2.7. WyckoffGraph F 2.7. WyckoffGraph S 2.8. Normalizers I 2.8. normalizer!of an AffineCrystGroup F 2.8. NormalizerPointGroupInGLnZ F 2.8. CentralizerPointGroupInGLnZ I 2.8. normalizer!in translation group F 2.8. TranslationNormalizer I 2.8. normalizer!in affine group F 2.8. AffineNormalizer F 2.8. AffineInequivalentSubgroups F 2.8. ConjugatorSpaceGroups S 2.9. Color groups F 2.9. ColorGroup F 2.9. IsColorGroup F 2.9. ColorSubgroup F 2.9. ColorCosetList F 2.9. ColorOfElement F 2.9. ColorPermGroup F 2.9. ColorHomomorphism F 2.9. Subgroup!for color groups S 2.10. Colored AffineCrystGroups F 2.10. PointGroup!for a colored `AffineCrystGroup' I 2.10. colorings!inequivalent!for space group S 2.11. International Tables F 2.11. SpaceGroupSettingsIT F 2.11. SpaceGroupOnRightIT F 2.11. SpaceGroupOnRightIT F 2.11. SpaceGroupOnLeftIT F 2.11. SpaceGroupOnLeftIT F 2.11. SpaceGroupIT F 2.11. SpaceGroupIT cryst/doc/manual.pdf0000644001325400021140000051304514540074574014125 0ustar gaehleruser%PDF-1.5 % 3 0 obj << /Length 615 /Filter /FlateDecode >> stream x}TMo0WR [&aƻ@vcMҪ'ϛyo.g"gRCaf-"2c}O> i<9Scx!X& ^'~h -} sjB#Ɔsvf"/C=U!:1M톲MH]IWO4?(\# M*yRn.-N.?y#/h]Nf]c@v:xx9pd׸rte>.S7_C/ҁ.V4s)nOmڍ> stream xMo0+|>&Q[RJE큰lJ`Mk^hV{a_;}o^ 1;4Ś+`NKpUmVM-~yo!HQ$) (J7`ۃ$h"4 l$݈C$˶CU8n^˞G%T<~aq){QD6V,4}L @, 6)Nwy:foFg>;1c3: kdFa.aF{bikGD39?)9d+IH2|q}B}ycsƾV9km`Җ pgs!AM >yjW9-Zc`z8<)Y{Wmm$`y$?2[[2}q>y=/Av,ʬFc"wq!4TfxwSC*!AJ C+o7s'׀$r?O@P:;ɻ+?B" 0Z Eagv&|j[v_Yf\ flecԖ;o~QB:O,*=lҘ+`A\pꎔo-Lb>{ҚZ4`;g>{}YPsI?O4BɗoN yQe~S I< W>0!md)q~$r'꣺.vAĺ* endstream endobj 58 0 obj << /Length 2396 /Filter /FlateDecode >> stream xڭYݏ۸_aܓ D\@qdI)zZ-aem}g8lɊ[9f8W7dH#23 |$j]jcWo_q/G!>_ݏ,0Xf t#N(oތ\`({ge‚4XKtE섕sK9lO4M6T Xqs0eGY%f Rɢ #"zꈝ\*pjCS3:ɺI\*E,xGse,O_sei. 02R1D fph*+*wukw +oviYSOM͟ U8#No>!{vVGsQ愑҈$"vBk "3Qr}\qpe{~jo/> PH Ꮨ~[ $#p',8kP5j!^s" p$>X Sr1ڻFU;/X}iFK% OVIB\aKJdHC#NW.S*a ۻBNd =RO--UƷaUxgwF >ɩbDT2NUaE c)@-T/ cS~2?~}oOn4sq9}v"#-,W~9Sτ1*!kp6Q8yM07.aͫd~on \gt\qr/9w^4z/c4Ź~qfDb^$=TծH0hzmE]%Lp"FСU!D3F2S:l(5M.Ma}֦=V !4􅉐"PѴ ;8D]Vd-}}ӮY, üRgZ s ∥`C~[cҧJ*A;8&\.AJm 4䴔On0*)TRT^%-wB9SzOт3@s,vZ[+"!H%eYPuGO(܄w5sShCDAՈͭ>!`mºòhj}VmLWM/7egM.t&8 X,/\9fD܏4sw7LkH$|Gֳ lzU^?e0LLgjt3s [㌷Kwч[l3wݽ l{Bk|d5Ri}>p2C_|fKmm@p+oNkp'@"n ].76N^\քaܧ_oDnvzNi4OHN3|2Oú\T8=X {- AD~2-<Ԫ"*,/ݭ@Q_ $Pi P֥1oփ()ӈ\^VA+tbԶV>n0ˢm{7(3,XE_ϡMㄓwݡfɹ_3P7Roƕk[ endstream endobj 74 0 obj << /Length 2126 /Filter /FlateDecode >> stream xXK۸W(UFX=9T\mwH-H=>ER;=~܈Dx_%Zd*]%&1׵OG%8_ũVY*ToQ W[\mu,8!n2Z?w}q:[\u%H4Y,`7*Zå#h&Ǝkzi릟XB`l(&;[sAHt{DLz8RH!ET\"z 3s(\(.ZW yBz.z[o h=R/p)g^I˿&#!Xz8lVД,\8A'Z4zGXfߵ-gqZu5O4^S۷g򿠅{L0zS.r8v5AKHŜ;]W?*[2IM.L<i0K #5n Kpg  t`E%']G#!9{=[c[ϴVƬa9DP? \jc8=ܷ D2nj5X &i} 8վvbɅ˂\ aym12~sIˌH*RdzWZDJNJu5/eɌP.{ʐt=hTև#Rk"![&6BfcU-2Q As{oDΪ6c9`U[jU]NtCr-Lδ_Hbo4E)"_wEc}|+ egf׾Ҙi#!hU@ D "YN;?Y/>j_ArdIag!7L7n<_;=ސ0SLZb=zu3~0YWHjl€Fyj֧jϋq-pAg<> =A?~Y=jI= {8 GJdp}M`>tHWv"QؽnRR Kk{} mY}pm~[j'도FD$-2{ۡX7/GP1"(jL'QHw3qSBܮv!--D]wlӎ@؜ZB0#NhHEgu%C rB@*s)1~ 8? h`7tp[xOq ]U֝+)v:qHԡ(khh+qz7ʵ<u> [[+Z 3?}1]U$T]_;* W4TԆoU6VHEXD(<>d| 1e2 rߋqYrVMο0{kҭ,&Φfpk ՋJ \ԹYx Ǣ9<!)l̳yf*B|'4VRh|vٕ엪L/l(b♙'o^^FO| eOkxʠC,$ E<ב8^{;W k0S:W~zO_w`Q Xr˚]tTv!j?.)wE+C,$+9>+?ƨ'{NM@]̋ܓ.?/Aؕw endstream endobj 85 0 obj << /Length 1644 /Filter /FlateDecode >> stream xYIo6ϯQbHiHѢŌom-Bɐq桼$qCOI-qO:hcO櫉RLN_їtQgE>Q#"rV 2pO rv(9!iA2{f!MFt&x>KbUR&mdbш2eZJ,ש1웛|0`4OˤNn~D(ĈJj(C|(YZu-<^&)!yiסnŔ13!bQikI<~sJ!.p-L%MP&[0 V1bua`#7ɦL!Q:%"f@"C 2/`!,V^:AwnH}>0qdKKԅM|efGz#N3n: f5 &~"'~muaY jJF`rN7pmb ?'}}g'obi-i1Ikn㶨^W>t] 4u2M4QhS]a:$yxՔdv+ $\̯J~KWOT2mu}brkGh:uw$:rB%%iGdG̰G-8Q.%㔋"UӔKX0.c\3.i0.x 3!m 0n* QI%tP^za _L|ˋPGɖ8ي!Nl 4zEۙ%G`%[VwAr--A]4 'K|LVô&3Fʞ<)d`14EKl>B,~oa3nޖi 1w蜇A@>̍ג7jrߡMfb>Ui\Y&\þrTיg^݊ԚLRvyc͖ 3Kj؜YNnktn+2ݑ޼r}z e*~+ ^1S000F;z@3PӔ'p[gKr$QzH_䗄Ux')A$8ɘ=|$V ѡQ{m*4BXb+x6yi~H?|x齎nKݙ#'n*hwxf3X@X!(NP P5rW.e)[ 3Ub1;}{ endstream endobj 101 0 obj << /Length 2286 /Filter /FlateDecode >> stream xZK6ϯ\e3|Աg*TeƷdjKږINg}^CsKK&!~% Jb?>HŐba=ŋ 4aؒ|ڥ6+*pD}>nDE`L܎lMՂ[ "Jbcga:DW\%Wu)88VRiVkVNz8+aӲ8:/J^;x+X 圖m]0['L!E:_Kp kX(Ed/_.')"w˯bS`izur1U)$zh+6gkUۘޒOVp2FQ :u[eOۢ*A^v FrJ Pnw['qKyk^u%y>ھӺm,e0rHۺMU)ʜeh[b'zУcDd"Ds.2٘&`N?pG~ F^vg߬#18A7HHLF<hWD0K((J"$A9,.fX?Z?!<:1WܤؐLϣ$.$@-S]67<1n3*ԙMB #":m} A=[Gi©*]MpDHc.u.+{AM8ENRC(p"I>scs3.6EБ=n㟴f ^uH"bԇYTW&*Gr %0u"i?Km[W`]ȅlUrͅ<#1,{'Pv£9qpqy^&|漐n t-Uۄ#3jSƌ!P{̙s?EJ^!YH}omF +DH`+u~M:(R9zMќG@ǔ7_/V) .ʍDt85}*?o~U_T5ݥmHh Q׼4XCM:! /e-a#jc lbhsznEZ;RB<:p /ʼbc&Dr[A Mz 2[uJ/ 7 Y Gu(kt+sQ_yI57t/K}Rv1f\i'P't(\^Xu%YS<,sUVrDlӟO}ƻ@昚3{;lTBٍp7-`;[ukn f+>X]:J])>|YlCd`LJ⎇OWm7Л$񜣛6oھ4Q+,슠7lF-u_R25;tTTfW ='xT֨ h=J.9Ѥ߽i^ .e ƶhQףi{H+$gJ$vm~S·9@;UغRWzhSOr0tm xF,tm`NH]xq:m@0m:& \TR/êmo>A%4;m `&PE r}ܙkzvW6wsȎ$sܔzm}(7cr?f+> endstream endobj 121 0 obj << /Length 2823 /Filter /FlateDecode >> stream xڵZK۸WQ!xq[N6IEqF%R!){g}h k"`h7z껔ǧ%F#?WEޕupEWé7Ǣ׻vǿZtԌJ@4RldbWnIY@Ba,"IbB!$lGfJ>tY˚)ˋ|D`"T>6uXB(">Z8$aK "ܢ˧OKn Qjke#=+94% c=jۧ*5/mwUK Ԥ7niIa+ZjThyVY%\gRBᠯ}vWinjLke/' rR C!RyXnvNM;㍴'yxNZvadU{<ؽ[7>fJ\Le`G;\qdܾusF \xc!h`6qE7o\rݾXT6AB-tIm^4<BND7NPb 9O`p:c mQui g#<)vHz̺̋?}Zs§*p$ȕsC4'i*|mCTM X鑕7# pp(Z+u;`icl* OE?؊Q'cCܗ)W~&v&s+s pn. ނ"60cyͨS +X/չNNYU0eJG﹨XN:nOsA?G kFxCP.q6rbqNr`NIʇSݣо H|R"yڥt|&]?.,D\\Cs5ާE.WF23ikXO,S&(,LugkXa/ x5}Fױw EfxxY~χ^gڡʥw/y/!^E5]Ypsf.mzǪ!0֋'h'SJlTjgk XP⽅~ =JaM=Z$[PFڪ4r|P9 x{|6?50ku- ږwޖj8;6%@>Q= UOruh}XO̟䗺+cF@o-R <  DP1b1Y^,%ɰր$!*gu})br]Ft-Vl4K&pE`pdndۓ95D:8שve1ż$Ww&?kLe"m/b,qv&m{_S Ŗ W3Y?D+-poTleiX}FhRqܢiX Hd~-]̳Mi GpɹTy'pNODjNgNM#(sD!m oN#C g :?;։t, Qh ^GuI.LuQN)_D:exܵGT,\=&N'{&9x~«7PUP81jpXw[ Q)Ӽ6`m1uU W!uhؓCtE!~R ̟з>Aħ:9oJr)y,1#J\ >>JT2R c_1[C˼cu_gk0 I_} _YgCq]5 dbs?VT|v` JyBtCv/HG중Cis슪|>F.2%1c(]L?8#7Q =.8IW݁6m_lBx9ojrWlWP.[Z[Grg ~*EMP<=)c~Z"djѐf$0%?`x=B򄀣p-wȫ[c +SEK}9_{^1_;o/Icy$ED(h%ŕ/Q5ґq Q7C/m}~D]ҳ(!4_}AOO]~1-vu~>N# dB3`}bZmuS}S~WKL+uڲOʋfyS2~dSIN M+ y䤴$ǭjתID e8p F+ =<]D8]X,[5pq+ ցb.lnI;LBm/f`%1DC}.2?m"+pه'(Bq^HgJIbY([_ٌK>m1SucTV2+H endstream endobj 136 0 obj << /Length 1480 /Filter /FlateDecode >> stream xWQo6~[eDJې!C$om5ؒ&K{Q%IE_L<xwO',!IĢz&L1Y>zO |VK}߯4>>cݮSTs=Ynwa!^q(k03Hio\W.Y@2K_!(W@]}c \gy (d+$㭩,Wڒ?*`B,H큭Qy.FqeݗA ~{ǍU%w ~l-ؗF6YawP7-)&ӹ%=P7rpe} R6KpܹŽ#誏=Y)\_:ԊJ!Z%077Q©ġG6Bl0Alz,sޯ)wyvק}֎ 2[|1 |UW˲3ݷ*WJ‡~߃U{B0="Rܨb5BY{̎uc'*\ZICaOKASiDX{ւ-( 6EkANgb]m̏AY/f%\J'U$C?bJO^RI Mu'{QN'.œO" MKkTsZH;os̡T6YUM N+UV#?-ꡖ>uX8Бx\~p&?.qDF^INze2B^1 2}41Q䝌8!1a_qp!pUCk%oUе!a42m$(" N=5)['?S]E'YrsLy6Ӿ 1UxUg,D^9ZVARiQ "DAhK^>O7ØFl]n\,ߴ/ߝh^&PǒvZ q4Uj.OjdIӹ]} ў`c :c&rc_|۽&nHΜ'9?ƙD$ e2dĢ9c⿂Nw , = htg+ 7O îʝ$alTz xh cm]r @}X@q|;l=Upb"b6A&t2%ѧ[RŨ| ÷q]Tyq`-ߔ^C~mshm{Ovp#~q2s ~S= Z^E(貙#(vB2%JM>`=e1fgC7Vpy}n| endstream endobj 141 0 obj << /Length 2037 /Filter /FlateDecode >> stream xr6}BR@ Hd+;孩O9h+^4 lkxf ՟a2]nfFL,1wouWb%k7MHռݷ8Pv >[pO HH`8`"33!U"u +YɄYJ:m$^NDtuz fz@8%gf)fL6,MR@d|T^2oA2nZwW.~-遜 R5sHbU9; `Åa8A 2$|lA{K\iXp [qU+9i4;njBDuT$Z &(>/Qy=Fk+?JXZM#h'^C%$>MQh{b0=ӤP`M_">0ݖ޺JRm"9_d{h{U GA 7||evDS4cF>Ktzygcc16s9%gsI u]Bj3D ynu#BVcf@u)WF0Xr74]LY!'7,"蕄^fCqX)߰Qrxڬ;e `z=T8# )0u#T46}鏉K_zvX!b2zQ} [,wnL)3zT'7k0{&'^).'u]]Z_,_@OLr";?2#رqkB4?i鋖Z|p sJYwېI9!#(o:ZģUD%L?]lH!-t[j)@b{}*I yļ1P)Ό&3/7R-̯zKnp$ \3pŬw I9+WfsV 1U풾rNR^]P7yr"~#9](6d2Fڼ`'iA^R>AH$vs.tb`d|x`}wE )rYW4cfw?P Œ'C1uZ(-6?K&sC뫟/;i)GT0>tڟ8¶8ۨnCڢ@W rGߵbjЂXh4bRg]ww$|xfCHazP$d9B0| Ӌ endstream endobj 7 0 obj << /Type /ObjStm /N 100 /First 820 /Length 1823 /Filter /FlateDecode >> stream xڵXo7 ~_E%Q?X.݀(qQǻ$vsr3 dERG#KL%R!NLYKc\$$PB)[ gb+9%.8KB$r82\!ܫR꠬"օUnI/<{wL: P6bp") 6J&O0MI |2gK@Xd+D-2Tfs)a\Ԥl L<>|P#c]<j#_>~7: vYXt!^'0!g @W~pHJPvC +`, C:t)V%;`[Jd)$upJ OYEp.&E&` E0xFH|@wL&pG)wcNұ ? ?\W4|7R ֳe5[.#E}1W DV:td EK&̱rCEa $Nha9Wֈʽ )q^')}g.$NF?& {qqDH %{#Fo9h\]AOg4/=%B&* C&0~9Z  !B&)|Vɿ kr+L~KOSeF*LrSjs_J +ƺ5s4%mM|ք?a9:V+s26b失;LN6_.8}%8AՏuȵ?%1f JkެlVܺ{X_^H,k$RH[H{iii,k]‚bbz'b<p,nHA;dh{hA}lWMm+A夵Q"r?"UX G^-i7I;q1d3f.!xwʾ,$=2YZIH=j罗w ZlOF)l&8k *A{0DJ7m)r QJCL,ޭ-lsM;gscuk;P\^1:h}C+i#^1c/ڀ-Rѧ>c|-+> 5ȯ ÏFɽ-o]=ٵa.mrFz1^L@M'DZ t˨x\O BoSGz#3~N#fFPE~t?_ ^aPw8ın"󃂑^:̟|uNGZh}t7m5Ara ZcZT܏+fSzK@^ې އx >c/nuk_M'q&'u/UY2N~ׄϡ~RvkF"?"q endstream endobj 152 0 obj << /Length 1992 /Filter /FlateDecode >> stream xYY6~ϯ[dfDR B CMj#ݺ3J\z"Z"\8C?y,d,EMǸZ}Չ5;һ" GatG eJ+HRؕ(=19Iz:4U*0q`qLp.\g@S*!@ (Bp\̅`t00/-~j 'i6!L슰vH`+wE/:V4ܪvxK$m- ~-ϵG!#' 4v9jהEfǭw"_U2htvVE%7qb+(?F1v)(bĈ8hvw}q y&CxXVW[]4te:t/1N5a`i.ssFsg#VSs%,_ؽX3%uzprC k*[%P{ɋ:41㦲:WX2xV&rI((2 1njռ5"E߲Fг? )XIƐytx-tADv>tS~VgG+]Ua_Κ[*eh%no>+)wF*[ZJ(\, lpݺJ2嚤Eip`ڔ J|ߎSw4*fC嫴F%+(/}B;GHژH|> stream xXKo8WVY>DJGv-&!ɻH93nSlOHj8 _xYBlE|ł"6BK.il/ sN/sFb;gq}Qej~ ӞP*dFQ8cF,ÐlIM/KePnؾ- ]`d^/K澩6 jtDJGo۳psۨc,.1#M.z0ƻ_>ϯ.&˾겷;:6 'mVi^ݥ>BF^S2F7iU^W-[V$\ ^$̢]FD0 C,Y(I3FB᤽i z˪P~' j"z+Ѭip:qUܬh %F\[KN;]z4S!aQH [2'3mJ]5TQѐ2"P(|uwrфg&!,£σ[|m>HdcKܐpN!bDF-wxQ̇shs;ޗy Aoͥџ(&ZO;͑SB^$5Om( zNaɧު 2ZnDW[E`M8Q\wa1z ѝ8˗N]NOEE1.]bGpEl#;z; PG]ne .S4́*<0A`5U7͞F܃+ T [*xf|\l W`(6 (Lf~Th;JWou'$B@pZ`SD䷤UP5qJ7' W`>>/d$i7Jo |`3ֈ3vkC߷aij 1I˟>N K',.|ѣDd܃/68Luf>z:aW;7?JUρ,pWV28\iݺ5x"'e78 `ShV9!gM0>Y``)Lbb1-zCsw$@Lt('Onzك`,]n4肧uPp'LY$_{/C(8RXjX `+*ӯwЫwiBnFft齮kkRdd%v'yn wB uڥ z:51f>IdLBٟg].] endstream endobj 172 0 obj << /Length 3167 /Filter /FlateDecode >> stream xˎh:$81^I6zDIS@R_zuZ&@SE~-Bi><!˵u}( PQ< P[>FIov0_QȘCY2 n&t0^8YS1UQ U1`Wv[ dC{0~ a `p~?Mf0mC w@6w#Y᧔ eWDL"^҄1\++?d0} &*Si1JUtj*0߃ʧC#0rw* $ǒdJ!*ı RMP,BkqSpZ &WG֛fZEs}xcp o݄oaYgJv8f@y4B&|x|aXO8BIAWi!vkS]^@0^ ;٘mlh]z,`ےο_fzRs@,X<2Mgg|sa!z{j,~Fu-$ `mf Œk?{WL-%Kpj?OHXԠ}1v3JBۀ66~iÂ/ wge]mFC}yS.:զmK@!L'y]eS/H#4"E_r4E^lʾZI1,c1Nl㩮=@=2)xM( 𪗄I8XA8++)R^] Dw=pQvǪ|E}謆p|\ #ꄪ3P{B5kh ՗GSB`pQ{(n_H`KN܍ NOPayPKn)}!g6UˮT$l{2T3@cdc-3h.֗+rkzt;FǪ,p:2>$NE+: lL&Z 9=/vmj- -r"%@X2PGL%d=,%]<38F`򥹹Aؚ}upβp@l! `"3Y/AmQ yHLHiXx8xvjLSneHYhBM5ES62'}qʵ=ʢͤS`6sG']ш{`E$tM3K-\qA/y(7c kR_fV;A%"/ġ7T=k1t/mmZK*x@S- EvԞc3Dqg,H51Klh^% ~zţweLR~ÄdϹYA'Uw|\ފsپ;|~~6Ch\&A%EK>M71Hz6?-.,-]ue6.3^S2;g̛ũs< R q5J3Wr۵}- n1-wlDvEK`]n)'"M ;"}# TpPysSKm5#B쾘f˹xtO2[Қ-*5}W?-jb VBW^ڱWAy#Tն N#tQifDFԸuyU:N'قٹjZ+HĩZsbJr {i xZ^q_ 3NВx,)/lg'?X@.X=H|)*c)Q}d;nqhf;`M $*Wc\ܡ zMx^Z J^߫6W- LESYƗ5*HgvmLe"rDku o7M endstream endobj 178 0 obj << /Length 3486 /Filter /FlateDecode >> stream xZo8~_{' ^őRN7䐢v"@LQ9$gofw7}ENrb]hІb}US̖9ߛfߴXܵ+![kw,u&"  :f2bV2˖Pi,H|c ?ۃtJ,۲+>|}Wca}UU a-s2)zlc{CH4&%EsB~"y,6Tg\ihwSdˢXe]q(oDJ.Mf~_ޣe2+{|i׶59J-)=^ >~ RV=SV,[brYTnA}oERwS/|68+l'7fG7cV.ptvӋ=ze`AO~c&[9Qra77knhw^ZsV9޿ywF(}6V$l\]s֕<(&Ψ3b(1{ǖ-+͍m)fA}F|26%,3Yll?7UK ^1QA?GTvj Ȓ- $` "el-pQ8Wz_X 201 皘!z6É5b@ jɜL;wǺ:4}ۢv*&W*鬒k`m݁smNˉRFk)q-%ˆ䧇·nU]X9FB&F706=dqT$3 '1ٕx4lWN?4[,PXۖD_aEQ.%n9`=/҃ˁ;˾@~peaW5+|N0Ռl-|CslaGVtbJB Kž|:!qG +:]5e=܀M=CuJ+kZv^=n 3q@C}ss ֢֫>xe(T rFmUvs܋މ|)Z]KMd\}?7ZLsD, ˗ѰovcWu< *0ys$+o.F)@".]bypXPB.„s.}{#.Of\,`Go5"cz-a`Rɘ 5!CF5dy=OƠҼai28 s6S=|J@=Cɤ8T΂ ))ea CW/.¿bY MEWf6gwS!0>DF4e'   oa};TA =Z:q GC,!2qHb}gZQ]. *i#jN|̘b"f C]Yz=QdJP?a%.fؿ^0S$xi s>é9ll nk jFRWq|MK2'<& zmb$1VG®aa)Ԣ6C,cu՗. Ϩ`5W~E㳄d}&Y_ܐ|ȀMDǻ p~~VL?3iφd_aI"J>cbJrWY^ջaN*&(XD`)ig0=Lž6$W&.M1]i]ɕ$'\)'Ɉ8F~6e ^Ɯ.n^+)jf>,f2|"_谳YG9Npn"0iM1@0_ VB,i]W1@9@塂H={ׁvo*K$ƈʎA$c&7bN~x۷֥(X)O@)H(8CPx,ZWʑ> d$wuE?'scUkicҮx<5݄7 8_ \n񶞇4ᱩmd1)>03̔dN-fSu3?$bJ۽( \}Q Vu %1O?SSy< kRAI2BcOr_o>":OUXp4]P9~rziMKgq>42\pISϯ`+~KfR媔('C"`t5B g.\ %%ذ% EΞT ƀ+?CQ \ aPi]PNaDtYL' .i3>&PkSӵjQ\JHlk O#鎯]k;k5c<,谭XyU;wv}+{|>NlϷUx+:H/Y[-V _/` h̠=:ðX7)w>.vtzX=5l9eGSμb+٢ۺnh; v'lW0)F˃E=} K`k^a)m'fu쓠BTn%քN!jy>KFyqUN9܇lͦ {l+fcUG!4$z7Drv`yi| nRN^\xo:V= yOζ Ez*K>L^[98~YdgK ntJkWkγт!j endstream endobj 188 0 obj << /Length 2020 /Filter /FlateDecode >> stream xYmo6_`sHm؀.Zl駶ڒ!Mw|[hM< BwϿ߽$$(I<[MIbr|bvOw&(BId\o}ʫ9є ۾]]a9E$WgQ>UuW8+̧~-(t0>--jWl7Nݩ#’Fb[E꿲H1"I3XQ!1q3QbW֏L3f0xc75٧k;)7j;gNBXOIݗVvgb{XC7(ABQ ndŴ#Hv\!7n>L,Sg~`h z3<6:dNFqE!NFƨ2gz:uf %a';FqҎi=q˜xCхH$ƃ+BW&>|yX1U;֢ebx8H֬bXN; meC(v"-nUv\Re®Ո1P[_ DSQ8㎈h=QVVv;UРxT:֥R! k0HEd]Vj vDL&օ<¨0D am#ލ3 OH&VG#i8=8$s9iu!Ϗۮ@\`@' P""lO@vC't39R؅Ny}L $AX;͘jI"`DLh H>Lh ,n"6AR430b-U(!8A#(.ZGm H0/{<ٷ#20>1r"n?xΞupkm%x"Pu6 c3$kh]Fko!+59 <9,;i f:/A0/c_TUvU}^vRk6lY#T0i)6Х{e&qN̿4aB]sξoW,W:YwZ8QqyQ~s 5Hlbrs 2$w JN #>8T?F-yd6Ng'M8둍Z~ä>~!d}zsǩ?[?'}K9h^nNT)XCco8A>lv,t>I!N;tşTctF xsAL~ig|X;9}G+p;Q1(Ou/TW$t* _HB3FcC 5., BȺNvSH! OB0E ̭\lK%iRm昄SB!9bұٽ $ATįO&ؖ S< >Z?;7jkU WV-ŰkAZ+/9"тS{ݻQˆFևd Hb X^*LI<fBxQ'6r)SBSO@V*kJN8d# Yyw97'muv1@ݭh 3e>KҝLή[:^,WhIY5s?% r1O@9'H4?^?ԛ̨ޅ3;GAό/MUp#sMCo*lc:3t<[>qSe 7(gmЧuyPg,ӿ  5ߙGJaABRaD(!o_,N`p~g ˮغ]׫=z8ئUyͼ9۬8}*~-ĵԵk}P`ӿyw_L;W\ endstream endobj 205 0 obj << /Length 1524 /Filter /FlateDecode >> stream xXIs6WqFB7q|˾aVZ z+=\&؋C8D8 S$9a$mH&)&\P B!:~2(6K.DRC y $јx=M0EcYI :$A+BA$([i( } &eSF`)XYT"^ /}.(Fa2_Pk^0r%3 TyhS< 5N{:-%yY5dBhfnxok&:4V/H\m6RKcdQ6?bݶR]f_rׅ)iksfvSD˝(k"X|lw3ԁi|-sek'qVɋNQjY_V6/x":bʁVCG 6^&zn~޾[Z٢s/RCB&؟Ư_FPCaES[.IjmnE|MnE>6~0)r Y顮Bz5^rd%cJ0CyE>NO]DOGEW?0(F{x]㍞BnқvO]c4+ CKrF)rHޫV]k^=h*(J-y,UQO3K014Vel^ u o]wk;Gܖ]Dr% ZDE(z;:1߁ Z&WS`ޚ}I1/D`=TTVhCO[.SGb/= Aa>򲖬\6pkc-kiw1]Ô,SracL܁E)~ҡ5Xu#hcЃ*\5-ohSBMZW43:8K%\r89yeI \$>z_-e@&ߚi09s{.z)m܇stݼ{O #T ?0M'a:|~p n{aN U iO_dI 3`+v/L@JȬ `t5FK>DH{c(]]}#ed[7 .} m3[Joy* ΂<$D wf!e1fᖊhZۮeZ7^ū endstream endobj 209 0 obj << /Length 2092 /Filter /FlateDecode >> stream xYKϯ02LA-ӖHrfߧE=-'39bJbOw߿O*aI(v*UVD L$sZ[dqq粴Mj-xp)/2 m|jh8Z #4xMy/K+{yPeUA_ũ:ZsR$RhOPmn87[4UZ(l–~dxc?m>S'"ziiiܡvkvHʼnhNiy~dQf7^3ZIAåBpѲeuƢ^EX !2$%PE=e`gkG &}(۶Ey̲ fyUd|LyWuq(J-fl&|*A1b.IÏTJ̢jL²0NQ}սμ%IQYx*ڑ0xGɻ;PtnfCiptJ(EhN!\w3=)|g,%|N Bg/ci dĵI5BW.ryO /^!d :+z{ik([?nHax@b-J@8-_^B#S4u-0̓~!E<0\ݫqk]߉l^f0)^4%Aӕ:aH$fZD bΥn5oeaOT%$r*gq]"6{;fVߒؾy 6˜ʼnIKկ{hZy=اp̋C=r'Ӳ, n@LW2~H X HCm:g,mCaEyAԅBSά02 E) [8S6p_.<~&jex$ Rˌ^CXG_[knn^I*dKq>IafF9w w҇sYܱt sYqv*wpPE=<.#b&vEm3cH9vNFV'o[XKcXdrgF;4pKuc1S<UZ kb1+IIG)෼zzri į3Ҿ=Co$v@o B01BqA"486S0R2o@]&]rqO;/۩rpGD@T)$h*A(6E>xXjs7̚}EW.%8{ZB.f-T g:\Jl%ϻB"!a Xj۞rzhV;q -{w,$~ Q}Nz@G*}Zey z[(ݓʹQSm}EgOz$Gh$WR ַw,"I ɼci P)J6+boU>Mws/BMZde_՝|.϶uЗ&l7V_d7Pj/UvgQџ` Kݷ\”y[H_>HsN0'Ǘst_9̀W`.f̕ys:(׉9Jq(ף" J|+(<5qMHokKi韃ǚx {8@Z܇L,hAk1nzyM?(e&(ugOQëƣy> stream xڍUKo0+rt#ciݮamb?B=oq48k3)M<r,YW KTjӤg4!^HE `xxBh( Q_\{Q# 13mW_Y(?ȡ=:Y/-ayd*^1A^5ifEi:{N6o#)9"J9JlfviUYfB7ߵvN}*~`+gJm^ vi_P PGUv Uf|[O/T41Aa&W'&DNj>!/gݛK+ xDJꠒFMݞab' 9Lrovwemjtp/7Ni ީwֶ~a.5E@%ByM֥V$vysAI!0ؠN0lhDP\NcXbCZ$i4ehV#N5b9CA.os=ZtY[qz:OYTos}seik#m5% &+#9G#a8 }GȽSͪɳ;L̦Ú{K<#zc̱6jgp)k㿮Cۣ@Db1$c4H;H;\ݦ[GBQh ?5#˶#p`pk6` "su9I) =K .iϠLZ'.`))(]!G endstream endobj 259 0 obj << /Length 1666 /Filter /FlateDecode >> stream xYmo6_ďv4lEmIr׏)ɢO& =Y'q=9COE/0~s7қH$Z~F}Z-q<͊6).fTiҬ^L|Y{0ߖͲ}2/W.)=oV#%HJ<9I'xmRd34FoE/LԼohk-+Ն#YO<ښɌ}1ܺu@$/ _5F%pR*7a2-'ϊ|o!$(i>SUsUWk݌?{9> & ޚNEchSmG4 9UsWt{ Hbc+V&UMLO#2A}\{q!74[;ҧ_z@PA1ꭨ>r؄|E\'6ǴqnJ?j9G GWvk ;uTwK`]2[Ң朦%MCeE:jʌl=W}$ SOy"QIy8TMik`L c#VY3ˋ@yv1l)l@V EA<iY<iq{ _bXE.j=!OTEݻ %6YaJ1oLvG#<00FouR+([!Ds{ib;؉>o̥Xt ~VNTXNq>Ն:cK|XSՏb-Q&Hө-"*88ɎI9e#B?>nC{( (^[NWA &݀9ߍo5xvU\fU Лr6ͨ bpQ͸0Ġi9^LtՍԿچғwRx|/b endstream endobj 146 0 obj << /Type /ObjStm /N 100 /First 868 /Length 1486 /Filter /FlateDecode >> stream xڭX[OH~d]B]J ^!5#~cv4H ̹qIB mᙄFhN4֝*? KzlqJ8m3JxjX'5=[;DJ*BS 5RT&XomA`%SfI"@ryc [G$+%a!)Ü u1 "x xa!8d+5 *Nc$t1 | -IA`$P<#݉uFSS"E#0&|.7h FиȻ0pN Mn$dib@[$<FYaOp,lbA@`6 `'m+p%VIeih ]k `5HA*wJL![^2 `T:ǚ2QGySED`_\icPX3rI1_1:WQ7KqK:QL~I YYL'bt?-U~.FB>w>Ox.re}<Ø|x@c9^P-7Q$.y%' C2+9.!%\+2uɽϿhPh!`:ͮűH8ۆ{j ,WndkԛFf4(ԽK퀅}W]Q<r)Ɉg֓D[6@w? L1ʔRoxVg<ˊXЮհodpn.)I1+JqWK77W6)wSt5p>/ H؄zQοguzLIAs#x ^&ܸvbST3_K gU 'BoÒ}xB6Vb pKvkm8i^?:T^7<;u=Y0m/[ 8vJpڠ ܇e0$.K|o9[7b|{;aj`VcfGwV85?_I|"+_Ykɟ=YD)qv[mq%Q|Ita'4[1 ;VVO~^Ϧ]9\QseC|I~ ;p=y< @3 s> stream xڥVˎ0WdHS;kI3b"pۤh*@Nۄ`U>>>;On^̓H2¼$8񸈐/}Jk` lL"Bzbi1%fցf$B[^-ӻxWcH`""E'q }BJv1^z?Y RPL!} ,ǚLk#rOi]|]'H#aY5n2 f[]oJM0oҾ8z"b#E4ŌdĖrb> stream xڍwT}? i7Fww ƀF ]Jw)""(")!tC繟=;g^}]2RqDh^, A@HLpsCxwz9CQᡆE@:Op4@^@,)  ߎh,Ptu(a.xB@^8,##%+"PwAx*¡@S4# zXgE>A4AXo#|d!g4a76>P,HP#rD`@S}Ar`a>OD h D90/84! ECa_C*@(a?X$!g9OCf #8D, A-9!QNc8zaDPHO/ o3IKIK@/Ee 3`a D A  O?% tD@;;Ap-EAϿN9Q~vb[zFQU  J`4Ppg[P>#V';pQg2C4 ￑n _3`~EwC=~<h`&߮5@8"<۪蠂r&@Z,. G4[H<7l~ D!nqG ! /ep7cGoG"eTCG;OTBb~ 0L#"(4$tBc狖(=Wj/#8$.ZvP#<,Oy`)*4\lG_H6˝{iay?n;`O|OSsՙ8ywa<%`$M3tU2l-8NJ%GSnjާ0kJFwV3ɘdoC%v*q?l1&&0|! ٧voE\\x: ~6uq*釗yod(o87552K/CMo8Aiҗ NĭU-i09=rϛti(N˄X҉Q{#3+.4|#/ ?}ޮ3YJ.~p yUϪWX ]@=o:^>o Lэ]bP+:A>!iUpz]wdi {m,"pLĸΤq^Ni_7ߟul"(RBABVpț&\>Unkcs>=P^28AeX'B vb?I!zݩQ{c\n{;\Y2BaܠwX3!onކ^aa@ܛל A9E~Z4 Ft'0`'8P:aNQ)R=}?O؂, #Ѳ ٢i]eg{wrPxa~eaX -O|QP'H*_uES14kzQ4#VZKZ#D +yAA09~paW%Q/0qME:Z+w4(Q`.!jCU{ZT};HFn<Ճ;?_Gٮ4<+ps+l ZR'a,z[L)_Jk$|p7a&8G8<6܈# {g 쯱Yϼ>VPh*JF CwDk7$mtVkA$D@ͫœ) m&GSI\mP{כ%M!90 n&0\]5<7%C=cdY;sug*9ΣQƏkj)yK? VSqa`Ԉdk<ּq?#KD_3Zw*#F(,f/{fD+y$v/-?lxOZ#4oe~1싸ekȕQQcܭ6eO~b{$꽜EAD5zӍ0=P8Vf-V򤱤jM"EdFt.O*m1{/GLIsPTsW[[#,-Umk ߢZ$6~ |kJwu98Yݠ֌CN5!tg ~"Z{ tMqƿ%G9i@8f<I3? ^8Ո'/vUu\0W 6 n[mo8s8.<Šaf - b%_\~Z+7#)( o*7w8 cg)I85 T4}ٽV<}>f}~D1>HlgfU];-a$ HI nMa/+]Z{"D%7ݭdaGG܌}_+:ouSr (=խI&t&`W~"NQ9P9c܍`&v\^ff5!)o uȿIv98,ʊP_#]w?ԬHvBTx. Ӑ5.||YYx<8YIwܪUkkDCK:!G@}al2^ER!}IK xu^Q4o5Loٚ>n>py~Bh4'kj'x]-#ϙ,#sܹ@ܾnOԲdCd> = r Q%B|nU9-HJiXҁ2ځ֙pR$~doU 鶷Ԃ\0G86!p70F`EŐQ8AJ.+:E9m>6ӱ ЊuQf*iBm*Yͣ =Lð~BNZKh(iBLոϼySn/uzwu4f\;KG<ځTuʩ[\[ː8Ϫհ`ѕJVEehe($Oƿ/frB#,)gاES|*e/c6pw4hHaE#I5UxSn[W"[ˮXX54S7.W݃ 5  *8,(1?IY>&BNcIY-؅=(tqvVؕ*m5Oμ;w]O2 UǚV$q}rڢk;k KDJw#(> ދ%#RO܎EFR9ÅW%YR"Mn{dCv,u n*qqr~+(-Ӕr%uʱr<ت?]d/[VpV0>tFpu?\mJ6𺧝R#Iյ*HJ^K+VYCU]}L\9MIG.Xa !=Z ̅aJYeRcI/:祤'Oi'1 /MND==* /k<ړ ݅ߥ,xy8Y= #m'v(P=M1A'cp5J`(c!9xT~rߛ*AVCn>fYOhȶ 0jR *tvbtJ3ݜM^K$r)IѪͼ^O o~¨[ri1y3D"coLYۈ][O(@D'U*ݰ% nwP649EM֊& n7g vM uvm.1 z) oK{=>)DMU8liFqꦎ ,ĤIx+nȇdô܂ h9꜋Z񗦕2bx"kbv^+/R4fA B__c9P<܁U}Ȣ׏e D[o7|LL7* .R-i!~_jңpB{"Q5j$4jώFP>3g;HQDN-J+E(^V'}@f}oO=CEdX,=ЇNai A07UyVe4vW,3-w?BK+0/ոX~ 3 i \6!h;J׾WfZ3XRS CPU7xN!>$9 E GN "54<`MH6sel<~ EVjũJzE@IEK(y2{[HtV_UJ~ w^Pe Ui/C.|#=c?b/y%ps@5f.c]g("D:NTҜW9k{77(d{p[gTdz GS@= 8yV>hN~a[B]%K9VjI9b~~FhbqA])O$LVBkfG #HF\ɾ~;lf.tb:/>4#hغWsr#g$vj}K?G*-+ AQ1>&XiעjO}2Et@ָ/*Qvi[l z`|h.ÏG}k?S$f2U)$^hSwN 9/[t:MHN%z4-I_7~͞\]1GH]ؘ 'i\miٔ<<ցJ8-v:ٲrfwɷer8@kF%QXDqtD| PߔGJl/d&AR_Z1Tل/zKal#Az_ 4)+"Џ1W2\L>@;bl"p˻ ^59Gqz^ 匾Y]ګ/t9p`Sy2S2ncmIԵᒍ>Ts_]HK{02X-rƆQeb1.kEw:C* ` R?knxXiL3s;s~q(עIU'ĺHת1Ub8꜒svaDr|2F.xꖦN{Lޅ2ގez,_ڟc&X/) #wV|vJj&9spN4G>Uƥkv_S endstream endobj 288 0 obj << /Length1 1411 /Length2 6173 /Length3 0 /Length 7132 /Filter /FlateDecode >> stream xڍtT6 E@:(RCo wDC!tz@AQHUAҋ{*/{=3g< MP0 z @DDLHDDC\P * A05C"mo8@ )Y@TDD_D$JP=!@zr"=Q0W74-^'>$##%Pv`NAAq':A E#!+,+qB\_ 0zAQ>Pgg>2!R. 7A}!((0'( pဉ.`E&& g 3 A  Bh?A8$B^H?Cq_C޼Uw,$̂JKAgAa?jseyzKShkLvE,-Hꐝbڄvf B ߢ~{4x-^,?Μ裣7^ LLwYUVRF ^ <&"V3CT6t-d="xn,$Vڣ8 JjhХb,+\T]>cxw [V5{Nw~jcrSwHNSo+{&H Z1ޚ &}nh^-yH&WhkV(kľ'ؽR֡"uHŎh 苩TD_C_6xj(]zu0?LxsTŇݽ2|wëS_O^7q1fJU]M6+}i}}gu&97G?s±6[9/vgo>=w1U.`.Mjήut]Vy^LVgM+I秽Iμ5 C-vM |dm+|Y5$}KO_id!ڋneZp?Kb8byaڎmcC1lAR*>e m!2UOFlK/8Ęn<0a(I'zGE#"V'Y@dY!''*d9!hwgaub&QnQ.'%]LzoD[fR$oBcObKz'>Ͻ_l\_܊z[~ LW}듗8mTz& Gz-DV=uo W/̅vV*q.h 8\?;hj~2Ei>Szdod+@c)ą&f0yA.BdǗPpumIFawiHpjι\o|A%I;:$y?D% s+Gy{,&ùrDts&07c&URebB;Y~_ eo,&㪇rxɘ~']ƬU6MʑzH_&׏ݴzqJ25K/[ByY+i7@SBǻ r[!\ڒ,?^F:-@`ލg ?s ۛi$`z?Z RQeU1J7 Gm> =ߍ}/7%M:~쭺XWO[i"h0^ d+4U"Ϳwp%-_C81bbu22kwdy汬k #Y'k^{O*ٔ\¯۱XLGrRȖ8D-6i|# d/r9 ^m| Lm;-Ш$Ӧ[))v>leeNFG*8udvaJn +cw0fmxo{pkP'aR!OY#J94WEJzuT ,DRoVEϡQB]q2fiav|_QYeRoG:4u]fqg#6qr+e=;!jWdSN$QuS H0a)5TMDb楚Ƿ@(cyaQ^k#W'd,$|=;e:Z/ }'M(&XKW7Np+h_/ZX]KL=A}{/E?{Sҧ亩_7'u]XVL_;h> 38k/{ѽ8ϛ*,oܹ7jhbPi/WƔ[9,(\t^[7WzVScIZfڡܱBxvyn`9X:=M*)6솒 Xɥ4}7lZkzI^=0pYMlͤKsבj} §ltLXj:/+lCG׬r xh`6FZ;C?Meו dWL,EJպYՋT*&ޙ^3!dD ѯRSQr@fEoLh!}?^??"oN`cTDi6rMR̆-5byj_TR+[Z"6ctěbfm۝ t=قO|1ҔNӏ}\ib?y9߽_]2Evų,? I.XDC!0ρ 2ꋾ9^xE>m.7͗ u ׽nRL2!mxsXv;zV,ceg􇻠4ey,]qC9SO[>NydStiFS3f̗LL*:s͕NHD7Ïdr4s]1V7`XhJL4[vxKp.a|>; l/̀z&쬥zA8&,T./`Cu#~Vw Eɢa\w2F'e]@XT#C ՂE` kWR';ޚs@hy[C"fxuc;5!/#PrrE1:$FG4m>Q Fj>gqմMn["n /<m0h4}j 6{te;|utطzE+L]MzmpcT^IMϗ,FrCGm"RN`^K[7 );ʹ$TCZGC#G^Ϩ'9<7Xvv\(=4[Ҥ&XL$q6T Z8u2Ɔ|Q#+Md4v/uQN#3t8 `m6{J endstream endobj 290 0 obj << /Length1 1387 /Length2 5972 /Length3 0 /Length 6922 /Filter /FlateDecode >> stream xڍxT6"H-  3 ) 4ҭtIH{y}k֚y}_w}]{f 2@!1B@Y( b$\\p ꎆPu0Xꡐ{8@TRVTJ2Q5'C!h.U; #Pv $@qb+A b|&+"% rE ^p{B!_#A? pL&( ` 8DcC<;[` 0p" Qn P0#!! yu@CNg>4A _3Jfu$D Eb$SC}s.H ~p1Cz@`&PFRRB}zD~0qv6cgsC`1pAyBwh:"@` G;; ƞ;` Oד ao#Pgj-g9UTP?!1$ *** 3!FP-{Ke.o?J73X+JH Ap PX- jKzPV HG,De5P!v5~ GB Qh+2 AcjuՑ`$$ ww + (Vo2D( 61C:XM&P3+T{[P7L27˅9 kVfZ&\ZNꍒpq?}*~T]%2{PR?#]bF4ęjijck"ɂ~qzG}5xԢ$sXֲLlJv~ʩU9L?Guӳk;~MKέtqbnݼ(*f*\E6 a1gw^-(|^ny+ym+ŹJ7`ٞ۳ب-qʜ_]S3ύ 47lД$3;o.NoJ5cJ6\9herB3&T ࣅkjF)kVou}%Mpp?#d_ss'ްpb5|(5,Ўу<ؓq'yʵQ)v߱cI='u[!àl?GX!!^Ec]uHؽ+ܝ`7ۭzeU<2/eIN@c!bHa'XBQg`ךqS U7Món4-5,"}x!= ?|4|료icY-D0RqDUUԻKCC+U;/KQZ~$ ;8%YdVxR?&I> `(XդHVz$a{(m^+ k0E6ՑU&7&ïid9fKZ_FƊJt}sh1J]d M:$'qNyJf(Nj .3ɥYϳ~>825b;~|dC%H_kD7sIXYd7] .Wύ.po^zD(KeHS-x"2LW_f׌q؈ E (M 94󞷨%cIQǽ5׷;#~3w͌3TД -LOkS/̐:6Ew|RfIB*DlAg']ÏPfwjMȇچ9 ajQ|]507tܿYAUvqIy-M;Q3uoc+` 7{:p\#o]hI9upYgוw+;}7z;  ?}L3wכo<]f|XQu18`uK5_u(@̣b+S>)(*=3o낄ӯvkg!t7 !Q'mGc$"B'J[L W}`)0):qX^@̌2iV.z *0 yU .q0^/XCnIrs//9YL Visz'S%q<`%܍wFz_<=`gګ3W&&p7g `7vb5",ͺetrޒ6ucqK{sj{AdO28X*pIo=v)@\|Gkvūy4_ؼ"mgNۅutqᴹ[E5lUŷHS::.s¨YFF4r g,;4ƥ~L)S%u"wi,pՉ;ՙKzj z7J_ ?C k#]X#bR1WFܡQIs^Jm*{y2fb6#l 7zɻR.P1@}3>h97WLBfw J`>J24)).~-n\9UtwvjQZ< *&(p8s ō%l[T|5S߲ o鵐׆=nyYoiƩم!GHD@yۄUTFXΛzF 03g9ɼJEWOmn(kU>[buM_ik 7d$$yƩQ>MKmȜIgi3"|kHWJ$YάS#:&|A UCSz w'Rb/~+NiZi`|"h>AIՊ t'%HSw乼y`ᗭ7(8T櫬-筄pt90[Iף-i M_Do4?㝙٬U&ɏ[q$Q:&=H#_젊Ȗˬ^i-J<|6oE7w740[ =q3 < JP TP6V|}*Skɬ.\I&2͋Utw\1#졔x4ۿ:3QGͲYܧ;dUzK %ٗ䗽,^#w7 f\Ʌcǽ]=PN&8ꑖ.nt`T w (HEq#dN, Ɛ'׵56e0) &f#>rg1UWOR .\ Jq,xB_gSu5+~5 8/g)#H3n33}IXBdԥj3 ~6G9"7PB<[FZr9`P1̑PDq6Y9zɑ1Y%&'vwp?DN(ޠ4Yk' Pd+gv<;B$9_/هBrgLT_c촆gSpyjunGpZ>g KWYhvMJ/C0ESEVǻ5?G\,d`iʱqLdCϖ|粈n⺍ikI<8+jZY ҏ\DZIp+GOUhBܻ:Tk{N7K q\w2OO7r&Oc|/ZL6@bp-̫n,Zî(=6a>` LW΍C <#墉ޛR ^nˮ= q[R_R$jΕ*Wu+-QAFUuO ӽ(b hZ"&{0 gOK|x áԌR9aO!{JbHqǎ)#칃YD'IUIWj:lDo"aYJ^6".G_l)=+dyNT4]$%nڴm8Y5,_Ѥ)N|hł˔Sg{p%y è5oU>J?͖K[KvxGArHT Xkw#=cП]aA; Cws۩ʔ|SB~(K(nߊ2%>RqK\i2j)Cd95פkL=P!x3^GڨD~L<5=19b q3X{]qSރ$]$q!3W.DL[\|i!a :Ϲ KɈCKF>m~L9*\lJ^EG+|oٜx€hdN#gWw |)VܗKfgGi?JQX̨;x{#,^҈IV|LfB o2m$nP7e`ı`p̽Qӳ$EeWҵI2f9^`{B *diy[mBUsqbmyR4)~AW# 5IDcMF5Q٤|ٺdܢH%>iT`&;S-V8"AM;URJqb𸄒`~a[($t_Y\x> stream xڌt| G4ضmĶjhl7hƶ6Iws=9g2 e5sGS #3/@LA] OAnfBj D7q *8:d,lN^.^ff+33]x&FB ?_f4.D.f&7+=ȣ@?&ܜx<==M]],inVU+h2@Oju+k3-w:R S18b4] NFooURcpB7[ӓ.uT,B93>+xqRLXvl9B}Qe9%]@Y4ԼnnI`[kA-f4npqqaP 86deA ;}4\+'[(E lѱZ/Br&CPKn+w&RV 2&tuǼFjc"kQ%͝eS7t,t+I5]a4z+X&np83<}LSho[>9!xrQd,)\ugpTc7=P*9Z'7icwgN՗^rƏ*ܦ^ՅQDI.alu.u'%ehFX1:<>5H 1~̽RcC AbyWTZ+\_fs:BpBq;gpWUH)GYMnq' b1[iAdNtw[o>baiLUS9ES5oEB8gիڡ0[j|uzП^&Htq.#*?ni>4Ědp%YɌ&;Z#O|9"#tKc>cͰ#q Ց=)V'ܫfWAr݈\ }=#?ZJs*[FEuH *:$U<^q[: %L65pJ4sEg ڬ1Xǚ9*hGB9*9$*|meEz^ch56)VUdaNm!Cl8@IlFgw:Ov!&+5&ˌkjnvx0e-z#NtK4 r&1.L1~;.:bmeQ]=AAn{2:~}nq/8#ni@UNL-U~xW@w\:<19o5/عOQǮ<QABJst M^3}#@){hNQ^wP$QET~˧ys&HFNj4^ x3<G 9s"g\hyx~9`V˨VYz=ElI4~rSf[x)͍QIBoƝK(U ~$HI$͘.}t4s RP!k` I# D(F7+礥("ZfAAGaX_5؆GPxZ.9\!; />-sl} p]0nL1L[ C}aj9%0UW0:^ ϵ[+ﴉ6pICsl;vX,.ت2Rӯ#Q8/y=gUpϹg)x'k7-A-/ǂxZO}DBTS)<ӑDTVį ?.ˆ yd-\f'-0U`Tm(3S,YGZU0+ot n !-l vo*x$H:mF/E'꥖MvP+q</BzN_Vߍ9MY.L%_Eh@pM/mG5=B<}},zN "_1qk44"ZUcP`'ɉ3Rh~DSR!H R' %ާjQ& J|=C0(g:Bᦜb5AKK!`jtCmUff"$j b9!IJ:"|g*?=5&5CCaxڌ5j֋X{ Dwk=ۍh`[}eXZ/P'+8 ۲I?Gax z]fXI2R!`H(vr4<_5L43pt~[8Y&.27lӻU4Q)W 0O{J6ܵ;[ \Ǭ3)C*`2pK[pC8o^Eg`C;{0m%T)ȎKQ% K~X"]ӊІ13\_qs I;[Ts8EYט̗w=J6?o5h/̸V(,hT>d߆Ѽn:c6'gPh 6-PG&na:3]oi#=CVnZ X^88cAu;vkz#fV`r?00f;?Ǚ_FJ2[\xLP> .^Hď\[WaKs}Mj{T}|LKlMa 6uT!6ܗ_q"c>%aQD̀^V/T7ɘ ʯʞ/.5sKe)dYD*gTWTUL2^z`NK|dx`a3Y n4TKVbk? trunq[E%UԹ+4lSyI?5@R(upƥhRz&UgKO_ײ.-UR_jO v7puuSHR1,ZWړ؞svÁ~\^<=ɋc)?2R`yyB:ݭ]'ejAuƞ7FdFI"t +5d85ޠX ނ-RV=DXL4:GƲFDVeW'܈$|_{i{86M-UK75u˖9tsl\$fK_KRq&Bz@9W{\tYY3^T3m6: 5JE!N#>z4 mGENI6ߴbq=}00Ǐ RSmkgAcl_b3%ˎOX]s_oͯՏj weyl*JC,XyPWg{߯maO,D?"L]|pm&1 qk >\,<h~Y6/ic26XX4UPWlt8;Z)T-8$h$#dj@-c=?ׇalZ6 ,#"[C0\`;dscv%Xql(7QyAB?Go!x0ej^~!BsD(lK^E eJrW[ :nVYq5xzo? Qpj֠H㳷ʳydZϬ>߬Y OZ69onBN,-k% ][K!M͖=eք<Ҟ˫PcZ*zߥ:`j[d9lh+ž+ x|Q2&H>!,X@=a%r.5cI"5蓼!83`lShteJ)b4y:{]|Bb!_Vk<ʱ-jL7u@&USUpGKD T._&C*(]x,F| >ە?{A{~H G}`ҧDf̜_(f[wF?y &X87<`_6{%]ސMiC!6d/#@cxٖ@3BY5pXX :n%H\|]Y-װS|)~0ɔ_2@/{mPRR-`k&ԡW/8̬$Y n7GH H+ +3:á@l< Q@'raPY]-%+μM8%RzѼFV[ qmXسCq߲ )e[PbN]Ȃ"tOk~]o(&bb_( 0 әXҴ%QAu.f#JzOj8TEd<ci#7'?Nw,RZ}õ]lz:o S)0n=,8p8\=Vr[x &!ûOz,)_na7[k`9Ȣ rTST ?Lfw+W~o<-ym#ģ6( ǀdVхc/)ʐ` 但\bw@M΍C%ڐllNiJ8Yd~9Hwd9f 6B[YdɚΙ H|s(=+)ήom[@:l*oH,@kTHT`vJyKnJ|)t UAʷ\z3|6+?*3^ts;Zmfmo@<ƗKqrYu]_n Fife1ٵÒD.Gɶ֌2Ӏgbt29Wg-L(H+BpGrqT6oH:a}4o[|3iIZDC +ދr7b a6%Kn^,M~.__|;?Ҫޞly-*Lf!dqfohQv:wNE;} ZH@Zpͩ s}]Hŗ^ zseoe5eX?xzhz@ďJUñoYlb/;w\i+ N5sI2?08>ܣ|&!!8|[ Bе=WsৎT[mc0Fzcs~!쫵l1<8g@ 豞Ĥ۰1yG?K JC(oHK/eMJe ӻo1ׇG:.:s W bl];&}%%]&]bg9*}icso(p!`=l9Fr,- 9{ђb?Rz{`";'G5ylRf#֨N3na;E1jk;\?Cҷk95k weD`aϋnhtI"&fڏٮŁ ejs(Ȥʧ\AYMKsc+?:K^J֔*q JQ7>x,eUm{ݽG q?In݄9}yW9wU6z!؟))YsUXkמuJ"$Fnͣ2!7={+,GZ7㹇l.D HyLTVNns )=zb.@Q -+3bz[*(5#'ˇPg4hߥ(U4QīptplKrЌ /ۄL~ $+Ab, ]$b/fm#"j?u0MPo^38 =,;wE ¥ddOav`,M2XJTFڹsNjL%e0!~Nh,1r^ܛ [s;[sbOq+sXB'q1zI`s}`dzv3) k#NR'f6xh9@$zEȆNIPI%ip=+N$T/pGNbۈJXR~}dC UZ(FTUD?-ʣ痎@Ο9S?‚g,ranZVr%/ Q!ђ*йı˿h|O7G̽CEK0%˪@7<)iWJ]0[8ߺxF:bz\P~/T]Hr[$[+VQ%6[)ee\c$cbЕdid_ZV3:Ţ N㍅RxxLQ?HSm!|EI =ށkgx~qNjޛ(7=@}MzwM}cClPjT 9"ER{"\zDae>V`3ib^B=77pJR^[h]7qym]\O8FG0#XFD#:|g~X&,s64qZ죏ЉE#6ݎyK~{* C`R.san<~[:9f[L M CM"H}Y?7$(Xb`|Z &9a$s}mg`'CҵbAX+y350n0"%l_ːNOKry ]b"q Qu"\~`'rPMRqRE v{xp&a,P%Ŋ헰Cn/HOPvz( V!VfnH%ponO@24ZQN| 3B),kELZ:ˡyp]&Ι6^I;ѾɁ\:08eH ΀ K4>- A.6 ߖ) K{+;ԗ* >T R۬uF 8*PݼA`kjLU&nYķFEh̍V02{qz7fEd,b,ߔ;<$%Qwu~FH iDHxWSdV*\c>>U\L)5 }Tl% YiəO01@ANBKh7:Bhq҇2~Xwƿܠt07ZԗQl[V`ȏو{қeN)ΰLsH7C+Hr(YQ ¡S.,ؐ;6 5 jpC/BPRp D.-Y1K=n:+,Coq'e-wwhhh`k.ꢾj&rc }Fj}S$b'3=񩺄5f,0!UlZ#UI_=~_FԳH -֙YǚeH3Wav6/S=, H>+m?0`n gF:qū X=~Owl"Y?iJ-Rʢi̍ 8?K~{{C]Zkoy|qU2د g}rHXx'=3IpbVdJv\;;픬c㚏]7!Jڎ(_}$ {m`oOf1h$5]Dc,_jQw0)ƜJwqE|':u9]ajT"Vر9K#7 A)Șa{~L;7a,!?CV9=UivLBt0jCʇzDО/πVfV 1rN3x]*M QYDz_byؼ|S[Cz*mΩ`_?GSn+iZJ{M1Cs +u*)|~ ]aE.TƠoQ#G7_O|8?{R>0,Lwfg[5y"oEm77YET7#cڎv> ʾ 5iI{N`]8jfdmh'(76gH7U+]u =YirJzZ9E.W)zfų6eK0,n`Cs>+~AOK`-wTw88>suUU{glN#6~5PIA2k3Rl G %?su`|gw ,OOnXC]ZG$J'=Jƭ3DW 6Sw6K3 >c\w/>SKFJ"S6~Ԝ{,ڛ$MMde)#JN.mcV6鶽z/i0gPQY;mTXyBvѣ[JvMж6j#ċ;y7}{2|%=qk=m Np~U,J)4yh5[ZtGm̈́WHdӿ8 f+'DQolXdb"eH#+;S6z+wzOwԤ|JT 䓊ߧraI0Gy~~WcY۝c-ŋܢ׎kVvV&mbB3"t!<G^.!%fo~hVڏ9 gʺZ{j'rɻoKBv))1RX{p+\Vra (\+"e*Z2? R Q!YW7lm /iɔhY4!jG>jQv5zq,cJ*J:#K`-8, PxL@OOf])si $nvAF>*tA&"%ԍvsQ*|jdmn^7|hb6Hu:5|58PdȧDT\jj-UΐbLt~Wy ,5y֕4>}F3wA]w?8ͥsf,w3dEa/?# di%$uev\>ruت@6@S̘Z=yF'CL)O{p꼇_J~*3{-WouT=#s2/5hhH;Qndy@IG'~;ނ>?" F.0kgo)Ch%R:eśjR;%^ֆev"̣>e=%|2AZd6 F{X11,i}1j]-Bϥ!$e9݄Xw]yE龄UajB+NAԓm4w-Գn}Tb"OU'VL9Ä bdG.r̴֐`{4{4g"TX~rߤ=m:hCrkh`L!80y<UgcbR_~1%͂10aw 33 ^%Al8=틹50 r$0 Ü)=Prv;O< *nsi|] bMQ)EG|̓ZiL3ܯd]2ʬMNO:pMQ֖u͌lU4#}]@F#CvaWYS鱐w/&+F>0o1>037K  ϷB_ g驋g×m1MgL=]aTз9g#߷j 7{eDd~G4|/Τ"1H%=.2T>P4wk&PA/k/QCl'E*R4$kWKk[^O.nt@~=)y[G]E5gUhYno$ Ri8 l+dd%ժe\MP XDŽׄKe0QƠrWH!/ a76?ON1؛I$A5a7V>(lUNNa-MY#sADd/dze[iJrr zcHFiT?o^hd#e")">\O3+G yI|OܧGLP [TU2-Fb|+ÉNx;̼䇦Ak>rj̠xs8ړiuR2J? /oZY\If|ʟa6C3.JhLI'{KVDȵ&ue V%hz DI!m9_ LSxd>,Q9(,+oڿ'Md`16ҋC?Dq蟫}\jτ=̛6#,n\YF+{>Ufs#hv 3w?sĩ{$$d5x'jW{\aϴveI񩧼?VqM:; bN؆a$~UX% u Dyw 8 Ƙ%\g[T H5ףUD~_?E 9.s?j阑XVC5!_; h8Ӻ|EEiDkzNv*Bk& > WJ4EwA֜`]!WB}n J)TLDqW)[GqhE7''hr>A;[oUN IGGD~GTpküKB}[Ÿ.AӪ*l325lcQZ1b I9x%uz\R{ݒsm>Yt Sra_؝18 7Yq9`68}oc{W?c e8{v=?(V&2ľ.>O׮ގN_T`܇~s䓥m!=3oY\ ]G=R$Ñf!a)]y7ѫ'iaKNTTITR#U͋ nOi#c 7fɨ]eL|!g0XzjqICrqgd2;QJ#h|^.a/+}"ڬ馹ɐ=e>> 笽j&Kh,:s\}_.ިD<*NcQR%*`sRM[i: )ֽj \yiRchUĶa[?^&k7"r?@&0kөCͶC^'C :BgVw$?ؘW2sd{29T? 2tAz)g( (MI4!qo[fp#n>wLNJ8 d=N#V8U{I3o{2kӘ71,0}>2]T ;~ucsui?x IUA5 nѓXXu8U2}6HԐ.z2{_jS(ϙlΚ b k.QG*ݳ:D8(T9tZxPj* ZQeoرm7;Ⳟ҆Yw13U)s%XT0}cwt5Ib2-.uބ;{o.f=DJJ-{#t?.-p:v>$Gq)9K(~  ˒<֙؀ TbBJ=MUi@ժ_,eP;G cB\]yݓx4E|ks6*(81g[bۖٮcZ&^r4SN:`#%@ MR]-+zDS9&?b:}r?LG:}쿵㚼!Wm"`?4^QtS-GP!5|vAe郖=M1},QWY;L<(" iHp!q ΉT8 ғ 0zZ$Ckj7O礈P<$Q:EWb#J;ټj4S;)A'A}iB{e)݅Q2ڡ_};7o609r!|7NilrvU<)iY, V0~xila볕 f=B:JҼs .:=dd lh屉ٚҁ[<3B| !)3-twy-^zVEFfgn9_6?wߒ߇c ;ϢdՓǗ6 Ui@sQeD?vwy@!]@ sb?}- ͥ6[')4بo50d n{h Ś+j*V\ǹzac3 *+6~C/曯wFJOC}o3&W ":t=ʡDAִ$v"]en_V5a8 9M;#{^ȃٓQvC{ljkBRQZ:7Թ}S>Ҷiቍ T;ǹ8e7޽@ͻVR4Jt~[m)ԟ"mԵ}"lpMQ:!*jD^aFAJ endstream endobj 294 0 obj << /Length1 1313 /Length2 6528 /Length3 0 /Length 7434 /Filter /FlateDecode >> stream xڍwTT{6%- 000t7"ҡ t7 *H#Hw}k}:ks޿>k]y!yx%ZZb~~!^~~A\C Kb FA0PD; 4ܡ!$??@_?@8BZ 8 ˢwF@_ 1yg0b H݉@(n #]t:2Ov#< @gxqY?zP-v0XWoW 3yC`; QEz!@u=(;s @E^+lD_a )0 ]۽L %A` _E]`Ww_;?:{0 /$/ ^|z~*uCw\_7D}El?`?/9,àϗOQW^WŐO^_A @@X /w] 4Ubk2-߱w!M]o ENH mfm?@g@ F7gU [Ց;7t!H[?߾0[8׆n>wWn@`;;`G)_g Sl==ƻ#^J0 l;5 sk:/Y~e$w ~y+UT>eik߭*ȆDƟ~WV/Vq'GɻGr+hqhx V]Q[5X޸}Kz٩UU831Z*3 ,96)1<؜$^_ONdk~!`Ÿ\[3%- z7߂ݓ^unMSwSCR=lGbb֪GCQ dCnE;, Ws͋c]R-NA gľ 6fx=5߶ׅGnp^ 57qR^>b_dY<2)U 8yk콺'|>oy@SĠ=LB* @dz; uyo2$(r]II_\yg'[9 KQqf% cߣ5izkrQeaam:Z|k=JޙLUԬ!DfhPjFS2ag0yQ^G>4-H}ښֱ# |9"#7^펳O+ F =ꁨoV":.^dd;|s;*Cr|Y Ϋj`ޤw O.ԪJZOxu0|ﻗd1-U4&1txG \=[G_uxi ߳WETs>x/K;7p8 P_%aY_oj| H%{"~%]t.V*Lecw22f '{Jcsk !E3 ߇YTf*M>ɉQcoZ5}hզNCΫ|Ŝ roƽV[bOifӽ:hauݻ\\imy[C' &rpwk0~eAon*OfK}2+0LxI#8+rPڟ mc`^F޻9j8>y-Z3aDa(:C)Sb34=h c߂pFg^%홨e,$ ̙qL1 ~Srw?&e< aJ$멏L܄;DاG+[ҾIǘͽ79syS!9BVV}HE.r_EE|7F|! })1<&(nA0](2MMj:Ll#ij.IO?V,H5n3lg<{y!om. aa +CFi~&t8pQ)h۵|,1M]]PíI޿IjVq?Fxǖ',ɔt^ݢU,|ʼvt攍yICբe+^;K(۩KΦDNדSnh-Nj: hd["fkFϾ涱jC~I8l }y9\f7?q37W?zVim{d!flPZkL/ͷPes_,Əy,*(oozKL^nd?ph!B84WMsqd#Y*'A?i|?AͲ ڨQ|Ka%{Jã}<-gMzK2m?iqQĿ}rN/LjQķXSGj/]j^x%}AGJfE%a*#.1GLhd7k!&_y~uk9)ZۙWװԇKx؇γyB]=f+3 5q#Ih_nt ^Lpw̾:hW\0%N1 2Qf0,v\ O'8'/FZ6+Uŕ3 :$̮ra1Ir EEuȚrR'qg5z9.JeC^O?5V!ÖS+灷PGͧ9urdsb}]4wZ0o{INlՉ.]VcO^"|#Y 6^|Ѐ39݀:O8(k(}LJGlµFH5:hen~m lD]ucjP ;Ȃ]=X Ba刨U# XY9a?O:lq1+lʪF~O|i@]eq+N;݇xc"Eb DrfT1qr)wDClAHĭz9ƙ77quAcgV_~!ikyܡ|BS\?vO^ ~$ӹi  ^ΕMuWH%΃ CeG|[zBODd6߬WpaIG:gхE+(S5&kf$ Ikbyn-(.LD79IM-i/ 9;  )E(imMcXеøTꒉ&w9zC} ub/n2_>+Z©Ȟ֫T"U=AM ZKla!TSO&!C.e/qi1]]e^PgdjF~16v 8]&ڥv;1SeU+򀫝X\_9L VFayصx,֦W-ͻ0'5d!/FTȭp2d+\o0h`%db>RW<%~Fg)h:Ì>)z{(86^JsLQq,%Svz[}~=\Ū"Z|9uگbPkϗ X11NcjRD\⓺uFS +-ݬ8޳E/WI>Qʈ0T<xr;O,'zFfwQ|Dv-'qvUp.QU(9]e LUDAfElνeS/%wIyvɈԄbʽAw {tG.^'9<ɩ/V&URRk)lRh>./b8B۲ {y!Oao~Zmn\bR`.l\⦆n'r+zGB H/4Æ v>wёs.x|=3Ytuf0i/[-4ģL Au/<Ԟa0Q@gfAua|]3ζN8SΫ Aåay(D$ |&T"ʤ;y1+{)gǨ2rdWU pF޸+{k;@,M2NЊR'kyBʄnK4 *yn-SqSx=z{e7ȣ54 SR;<w$kx]4s=N}oqVʛ^LHF>_`fxI\A~"s=fez2\ ӛKP,,V9;_(-mg1z< pvQ~hk[;hu؂aĸdW,N#+n򄾤.E*; 57ӏ_!u>fZYd#ؚl{q;#m$T]3`&SbGiʔȕMLm34iٞaAfit3B2*[@7|NQIdž5lc CcQwOh4iUkO0qSM0g[MoVi,D*3_BbKa?gj_ZXnbՎaM$$={4iQ{H9Lk<B@/eJUozE PůVF-㗋FPlj?XG}F-e{ -@m7`E!{%Vq-_ +圗SRm[M-jk JBWG80ccUK Cmn GkDXdmQd==)7ȁ᳠@כEDIRS3Dtg V*b))ags`Fm7nLCo!=qYSAX Pr2AN`| S+t5vnD-8Mٿ]F|q,1s4U!q]wdO"Z :ܦ:*8Uȶd d>` QQƃ85RdH֧2?"16ךD19P;^ʣr&2Y Xt@B\aM b _>Uf@h ~UThѳK2"OX_RUs:ӡ3e۷\{Q)KlVPYc:,?>~BADOS\3-[蛮/#sھ!~;e%dg$" B?2H=殙0)@yrJFG{| YKTT8@AsBSf8 7VGNƍK{mo\!ǭI3n o/9*ۻoGUj-c yԫi U! M'¿9,^~1ieMF8cvSkbK[.ɩl'| ,n*D1A x=uF:ڷ5 TGyEؓҙo/+QH~.T3wƖ'qMo-vԲUr&tJ߬(e3'st.|H,=iJ`ywA dwmc`bd3KxDLR:8-W+/ )˲PĆ5=e٭;qG`ȂW͠W3c?OC}2u˨I!QdqJ}-' OmXKQ endstream endobj 296 0 obj << /Length1 1306 /Length2 1243 /Length3 0 /Length 2081 /Filter /FlateDecode >> stream xڍS TSga,LuZŐ KDv"*S y$y/KB rTePEA, "*(XAD ([E¼\p朙s^]kMh#G\  Ƥh M8KvXD0p z ЙF_F)܀7F 0Vl0Vĉp7꺌lV |.ċ|H0>)!"QILaOjX%H OF!ـppaB\)`@$FE ` ^aA` F'A2lSM@|L*P-!"*nOBz $QbRC%!Qd}JJkmA^T Q|Zp(AuoBeT2jU$0>`hL r'ETZlpfD !Qa⏤SBj 1FӁ CPN܉+Fȏh߇S40JS9^ȥ%pzzb @bG'SĩqB!d2O&%>e&LʅGoh|Cn7OW%vCRD@$s@$<QI?4N}$P&dbÄr}P>&Я ҒhttbpAJA1 OBLAҏĕ&Ҕ|BAlarěUOj㻧ƗV ı8>g84~:ŋny{sop2;7&K`f /,"~E/>\xX;EyRlJ:4e-`lo5,>GJᓱƴ׬Ib-;*O_rVb[nݝT]>=2_ސ)Hv<\򘼖ty1WZ6qfgz# N8ݕdivyD38Cpᆨ +/;KW[XPF-ι^'&i2`_>aDeP870|~CEKq/"+c[eȓuR A4͹֝[ h[O<8=ܖ%:[y3.imZF5ٕvK6h}=苏Ƹx~6iwI(VY(Kf' Pi .MYw۵#:v!/&B\yfne{ƔݕGVX'+.mx̫ VT^\]z}uMe!9W%֏}aWdY{]^:vXl,]j^oelu]!IloI=Oo昭_oi9eXW$aG=d_*U8~|;}BTAQl% endstream endobj 298 0 obj << /Length1 1608 /Length2 10176 /Length3 0 /Length 11000 /Filter /FlateDecode >> stream xڭteTݒ5N@pi݂4@#$ Bp$}Y_3dzSrv]0hrH¬ 0([qpA8d`ζg&r 8Xhʁm@aaaL, b2W ?#'!P 'Ÿ!u`  8Z@fE }" v9 ;8@`g;NL6(&_ ypϘ'13,$@0lɥ?2To"E  |~a܁jޘ/q52<iܜpB `[-hr~~}-?k<s8A!0_?7o.Cu##c}MzVL?P #zl|@a~@l w;3uOr)XzWۄvB,p2 cNPL v6Ƶu, ('^^{KHh6U#+3Ԟmx QI`!M RSrM0M=V7=ʎ4@<]o-ڦq9p^v@w#1c~e+CV6Wl"Dy"Yorg)^˼u1l49%б7n^ߨR,ˣ_0siI,r@vnD[ۘ\WFFg&ʉ~~b AEݡy94I kI WU xOY Y{lر-*ޔ!H($Vi˜ϒG=Yb*)NKJ4 E朗IRB&9<`<I.ݨMD_݊10c]4PcP"HmP%9VnyIB]#fXPk4j?'DRb^+%3W~cQLZ2dYp+ I^D۔>ydyN"i)E貇;1.CJ3A?f7~X7ܔZ~+8t JlL(%8Ph((BLuLѬ=UN(IEM9{#tn 9p=?EٽQBk"$ K 7&2[7B3=H~^H(USYύA6T⮃mCM{mk=1աZ7Ʀr9fkIGTپ>Ht%l E2B7NO]B.J8Mx@; ݰvicg+Ae#( lgWU$ʪ ,[.n|Ae 속P BqXW#SF<}StzAD82G^ 8B~!?m7c6K&2fV~e窕`q&Xpo `Td1`cqn^&JgD^et$םukv|bi8b:U V ܤ^xNh0C;扟yw8(.s#&KZ@Kf6%OK϶a?#-R\I! al34G|Jp#\Uhu|H2ӕ4XCDvq1uCnֵ >Om4+8J&d.OV.9Vn--:sےad;|o2~lpD3@ur8AJ/g}M5Y^3@;g+{cV(vHvRkSAyy8kgvO$d|[ДJpVWCuݟ~/~Z<0'aJp bө1{*7w6Va#Št!@ vuTFiP)KT莓=7d s .ȡI0J6w^KvF½d&ʊxxa~#׽I"'a[s sƵ>@[bS7[U\u^Οql?V[q^qtH,jڶjGb(Xn DТȰ5sGX F>/P:I ۭ^J=٦ i.ғ|z|Pay\-IKl)V8xy.#qЭ2' _8Z4 s.ִ~7UYs:?.|VQj(cjYY4@.gPaDgt )G?DQ",Mr/ 9yԘтWa&lX%1"2gX4DRr;Ѫda[#d"xJAgə"jnN陒H:n)|t?_$Rkݕʴ'c&MT>#ZP $vs6ro@@#ni&JQ`Fq¢3p>T">h837eM3do0'-1]kc4|5?C{nP.2Դ;1eH9y5y0g -/OXXhSvu+Y*8>iNܙ"sAE%WOf 7*&uSOxes`rXWGPt޻{Y9),$Ҡ&I<~MߦS/.~aӴ,8Lv:pJ]\}kTG\8Lz&~)DHym%V=Up,K0FGw Г`lh?X2*Lu" BTLmi|ʬ(HY) HfE4&l9P3{)_ W1֬Q?~=p FPӮoZ-II5E`NoM/\QO>~% 1֧#,$&qaت]UwZLVC2.ŔHxPbVk:#~(zυ-]HK֧# O&썅W|H=f>lTe+ƢBYɝK]!;ͷ?"bt nkٔLsj`K-Ħ6:> ߇eQt?1U#Rg%q0gçY=MFRP,Lek6OBs@E: 3Dfg'R_~[Vj~:ԉF.IG@òPibSjoG;5$y@lG$ d=Fw!՘lihFxz"S|awO7Ǡe~ iI=`Sbc7ŦHaSl"Kif?,]/C^%s9;M~T~炣_Ir*7'A{DC-Gx58SBd`6vf\ȲIu޷|Oq례1Ս' ZFBh0j1Cn|ԸH+IwEoT'e,CZS)8:Ÿ]V? wleyz-,M[g#[a)Km2NG q{Ući=oJ{1|%c*\[U_5J*ㆸjGg2_g{O3$& *Bx"g^j$ 8mT1Mڮّy#/&g EީK9k,` neg@]3>=v'û|uE(Œ&gt 6΁2` Hp9"Җz қȹ7%',*ooH%-{pzeR8!;(I=`6,fϜ<јƢs4xVvo @6(&BI1ރl<A+u!韽_H~ߔ<"T "|CIj-,qwhڑ)Tj2 `}<8V;i$|$bh1ڬaB&JLkȂE!,W04;Xk^Sy%5nV 4O:#IԾ'Le ]򇛵ql4 -g`L;Dhh.|cyg w=u&:y ;bx#ZO"p0mu" +{1D6Ҭd^"(QZW"Ջ$ GɎ8G2$#ʁ})=)EΎ] V1P'5]j1KP,SZ/$\D}]I/t;u(0Eh@i4|)[pw~ ^q,hQp]v.9G`ڷ8nzۛ]GTG| w0Z!0*ŅhdOjuUFPI;ü)^jmzܴԔuG*75Fs|?GQf#U\JF2"l OE&;=-yZQ@B'AGo9ȇ4jѡ$J/[fsyK T+ګrO=JYf]Hͥ~il`ߟlvaOcRVղg7u+}*ɄdRҎ#Ve<\|=+ByLeoR:|Z|0>x+I^q2EC>)y}U6?0fO&ʚ4_secO P U`@uhPك?[#BL>=[ޖ kg[VRg{>w%aҷ]62g܃6kTB)V &mM{ӧ?FAI6Sk3~;ؾۮI VuRjCKtyá7y_#h F 0uYXM4pX"r,PMp!dh u$ޚ,>6E'֣QG+U{Wͳ*U!o] Zo::H=Wbx4v Ʀ"3e FD }26UH? [blDqnGhg)(W]*ʮR0r/*D8dJHëmGZ{5ɉ#alK>l%w ivbD\"(-$,M"NKnML621[:Ʉ.۶T+#wjѻjv޶F~]tSdHxkc>ZM LGxQ$rtr /NWFUP~Jm-yJ,6#*'B+8xhv,Yr9flRxӥX#w[X CgZ' @!=Tg3jO;kt }@=W؈'  ]2>1(45Lq6ׇkQ[}6ySRb}|HGSwTqV qxI?*o #n`P4W $sܫ~mR%, k}Y$m*6D}!ݳ]@P&V6)$F[Mo>4nxiheSY[£ WҠ$jC z7El)225P oE_P:{` npO'N!5V+ŧ+K}cE<ށp E=&OԒ>]׻<[e;T#/(3E-`}"R>f^rlϕ"X8M|t`4➞ZpSyV4c:l]sC%R(Dcs"N^Bԝ" f߁u:pC1dܘ}*[By{@zՄ!)0{Րgq_X]ӥt,r |w; zqNޠ^j+,ʼ(:ܻ|-[_`]*2IN!G*N5^ȗQ֐IóM9e3gm|>xS~|wC8Y9REdeBXFQ7j*JN( >bbg,l5[F>kdH[[4+2x{(:8{؄'Ghm92 [iAޑ^ ۊ4qh? ?xm 8DͪmwjȽoCgOO#KdՅ*YSytled?%V˯0L-8ܺT MiT,J1}4QF!k /_,4~-cD_#?XiRSZ[Gg8zĻ oeLm~z+Dn&8@S\گOy$f-ty"6mo/UEłӤ|JyXp w~dEV-^NY2@&wfVA 2~gLmH~Nzr d^YtO{fe.}_ge]F鱸̄meE2?oM|`HXH>bO9aI"\L2m{ec5Q*N8)L.;vw i_<+S 7 z VWűͭoԿɇPmC,= ݖe@Hچy4߻Bؖq8*xJjrT?=%EF_ bUH7WIzege40m*izB׃:L}E⫢&?fC%fBXk?wM,H70V+>}3$Pߋ@|`S9\$j\4 *+ &*(p qϳ+UʢعՏ"KN&Tsh]p8~Dt0,n^Ky2PظG\O?y9?%@e!9cm 6 ܂!Dw!q /,akq+vqF?bOvmmq]F:K!Riڊ)rw4E YMg &t_a(60lzZ%ܕ#qfAs"d^C51n!)QZ@s$?өDiBJVqgCc wmޗVoVQ4\g;~X8K_5 >D T[,f׺\ H1ԋ_gRFhG( )U#=6i"c]hD|Ұלڽ]zB %KxOux"1De A4$,1]⎊1/oDT #M %|+{VXqcFb jymv7}liS|'j6cM Z ¶lo7aVKgecufY7~6?p,3 \D|0N@y3[%K;bac"FXmg]DfãR3BYĄeُoK2 wk5k1884kx)o;wV| @FbR"sPLœ#Z>:~+gQZcYjM0 jP 2aEݟt~9/5vIեO_N>TRM 8(Hc:޺+3MF,V"]}ߜ<"p'!!*"Pwz^rruMDO/KYe]k :x,#|I>'Š8凔kǂ TUc- =͌$bJF\wӬ,zcOșAR'L  W-o?lE] J% a[ݔIDٍ H7o}X„YMuR+LČSf! t=nIڂ`h~ڢZjJDG Tl\5 $خ yҶPψF&>\= ό񃽢rJtxXoP*jn-^֏ &x}ROA&3rF^OkXTP# ѺЃ+$&V RʓԵٍ_2yN!兊I<1;VvV`ް<+jrkφPj5h%&<DAXpA1!뀆CtIh/G :kDʘhW?[T^/JHFjTxWXٯMO_nn# t+Ԗ}$OsS_/CB"Sln k@E5 *RvOie\/R q\\,uT B3yt]O\Jewrr)2Q?,_p4ט)-_a}P2Sd`ZOGMqWeJ`<2F0(kjAW/4~aq鄲+lGl؃>p|!昐T'|4NiNMs;tc$?YqZXe{{iۄRm6I"o'6 .8W.'iسy# !dE'/FMhВzX>Cѣ+s,2XA ӶWyß)@+jأo[F=51O:S(y*Pn/NŘE,mUwYR5vH6}Q5_AmWޅ endstream endobj 300 0 obj << /Length1 1144 /Length2 3680 /Length3 0 /Length 4427 /Filter /FlateDecode >> stream xuVy8m&YBe+"/c2dɾ/Ì1f(cM5Y5{ )UN>O~}]rq"B2Z0\ˀ UǍMd *BEDlx_4¡x$ SyOȁ`*HYUL] `UX&`ñ($Jb >p4ޚBaVpuT%bO<@NBJJ7VQQbpRpG&> R^!?{񾪲P8|ceINa=3h6ė2x/uխڥ~:DԨॢNvD%d&1 _\޼,J/mQw[)DcZ<@\ycM[F4N؀r"(bUQm„"ѵ՝z"EaRg^~ͤ!p:ݸO7cr>n kBm _ a97ӱ扙'(,}/; AإwDi|L2?G";fft*g[w|JϰvYJ"=BP<&}.GfnGs%6p!4žZ-;v,x9/ hڴTJd+N3d.p]z_2+cRyqCk:bPu@Z%P̊I[\n6]D<>eU= tbU:WL ΫFj}]bQюd0ޗb~fwQpFG eة!"ҡru?Y!{ ާ}R7,"n.ю˪s;3ȋ>3}3Xˀ M`fQ_߲= VX& .3OW2M< 76i8I=M&&H^Yrx|p 5gN:<Τk&x d5&<V/t._IH{Z}ǐ5^1PAtlJÓ2F9ǂAgkwO@IWD9_9l:.#>q볳1zcqCLɕT,12?GV6N_ Vsud7fG&c:ud/nfk=t.IRfZ&[C[L-.~=/k(ۛCyE!mwRҤހgb4Yf}"=ZkhjG8`|K *A{$2OV;Gz噬׹hߏ`}i48l/T30bkzfZY *屎üѧ8QX#t(U劯O]砀X=277tW m-4GI_7r?+6bAb;u$=~S3 d}HD)lj2& gsy6\\Hgx.@; @Vn}yZ05o@7S{䭚B-IgoadwLl>UiJ\=CO>84!n;ѓ6NkaFDmSGG)d$-DVA ou J0@{ֱ#"kBt&.mx C L*era }߹ =RTy*;=wX Z6ln1myp9G317ϴmzqe73fj,ͫW8Dqi3#B~|"oCns_5,ΩzMHwd" K!L䚑$tl<$ 6)=?TȍaJSiRgH#u0іSnBR%zLVSX4݃]^m&aBM8Mfu [uثaˆL!M~)vQѼ 1=/)aȴ{.yOfv]6 S̸ɶ+GyZ[2b5i"ܐqolz# b29*gc1o^8s{(/w*C<}{Lʛs[Cke閷"sQ\\*ݺj3*]3AmZųü&2vM('y7^yQ ;&.;3<V|r93't f{TSͿxA%϶Ib*dއ'gDmkhj}R'øHkN'ٍy#؟DN 7 gX_av:$Lv9'|hI1 D& (#NO:C*nWBZB|8@5Z`G^U?:858 \}2 }=h> stream xڭxUT.w'4%] ==k97sE?UOuj"@I{;03; @dkjoh+Ϭ4Ŝ&` āf;///5@ diij322S ?- K;+h~OT`+ d))(J5R@; @d휁 {'?9֜Ys8L@3{ t9;@K'; _rp}'Sw;9 2Un[{ۛ߶4V e lL{/ 3Ƃ㽦%]Co6WkgAx́H,> [Gr{Ԓ.66& x?2&v;uh\l[+_@+joc6HD,iaca, r+fV yװ3:ـ=R3;ۿԭ@f_"?L@;NYE%de4d=ޱG+ %FT~bJ {O_Hؙٛ6j`;M/_f3'w~]@3{3 ij1qnv`:\J.԰-2` / {Cݸ6]boJ\u6nƽV"cH9MOl{c*p$mN~~Tw>f)18yihw]1f R$&O{;ԙ>r;@h 8.ę7~WXgXͲ=_Uywm`)j{W(Ru8S#< D]wG0L7GjXYfoXߎ `ܹb=8>&Mט|T|49 =t?f R],Jm745O>wœbct0:N?.~X;b˔o"y#rp o}cYμ&@H2x`ZUM X`t$!@Rj0kǃ`(7Ѓ׷ LI>MI="ce?)p)0V<]~t+f6ꕜHO 7+L}S_nЕMX{zB7QxFU $ixhj36m :?zN\?LSXQ#'p'b]טnM\تM n)dѭ2V~GV F]C)# onU.8GZi쟸*Ù֡1jeMᴺe.$s[ 1T;ݯR 7w9g:vߊzqA!m!@ۭHq=B/$27c6lb(ڳG._p8¼ -6]&VޭihrhTࣴlda걪k8f:pVPr85e1_,Z"%=DԼ&ZaM'^N9dT; .]ȨǎuoFc}=߬6('JjKD]CZ*ţwriugPu2fإa1I2\yMUJ7"sST|&aR^6G+`N(ZrfcsK0>uݳ@q1k췈J"daCsu"zMx` y "ف.?,SsUT#_Zs\!LRZG98N7_sCngwCqdbN%zjʰ>Ԧw|+.*񈌀=8Pkh2uuK,*O,>eo=bxBȮQUS?P*adc:( +2=ό>Ecq+b}ʰ[*UѝdxtF6U!9KUr*!])/KE@ҹkR%} OQby`\0c) w,";e@k}־%KFa{'G@Dk$ɫۏ2ݦD UtL h5{܏"S?[U qrD9I7NkR_ xAUe~u)~zd>^P@V[ OZG&wUL4k𛛬E[+j۞i%ff>pOeˢ~.PP(\!Sц~}\^}}a˅2ڗ oF߽_~>!j.JU}֮p̅Db]όEح] Yo (.l?s\rŗ{{Pwym2;&VvZ/ag_JuQ4(8U՝gx2,dz Pc ?Pղ qKc8DOי\ċ :Qh4z)-@4Ў)JZǐ ֩`➷XXl!;vH"/͒iOG`ͼqQB1/6zV1:*%npT4Vu%3'`xޥCRVoPp O e9&=EBЀMwn&<Ɠ"-Ts)ne&\kE }#I-m߁43-lE|bS_.%Zy1XX+Z0Q ug5[Pi`ԹE d\?@Xxm9} jɡ0fh0v#MC~DMx Ҹ._.϶fB9F44nx{T&Y1uSHR'4)<#~(44f BƼݮ LD͠bB7m=CRwC BVosZt>׭a*EvWTﵮi/ qoW8=QMB2OXE{sCZ,$̌!ȳ53'&ump >D(H_sd_:vTSyStLrîCزA+aoar8=_sSQ'0~<*<. tp#YNBq`Jkɼk.ZwGلҾ)J@[Q@vGwlq:> 7sr!luYd&LdHFG|F0zיʘJen}.tc`Va7]\mZށygCzKe>osߺ6'K>|!&9WG#~ !cя\#24)) 7M`Mg/A܃\KۀoHއ;BPO~FX.bk)id+V2]C P4jQ'Vl8 KM0 )ɟéTV:},i_S5&Xތ4zHn,O7+npS?kIʿ.۔3՞?4*lLSG;nZA.)Zrp3<') %nj{.WV 6 v-f3LF?@ `3تxALq@ZIC+p&Ӯg VEݻ2efDhЫ?hq3HR{dZcL{ջ J@(nXi!y:7*omF"3xL8}au iq.y;|T<moIa~"i`T?.]0tvQBjJVX_0{S ljp%Fz'.*d8QZ n܄REY|=؎<3[#ll"E~"f#Z*:dBI?\߈x:-bu˧f[7B SA!;JV# z.'W-pU S"tj+L{H{3+mi`]y sm/Z5~*5+Y88>T4Al϶/z5KRx]x-y\%dvexj0!DiW1=q?5=5%6EW+ФR<0(U.W>T:G} QB\`>e(ˈ1~KX,U~=!3jj_l4lGnOhT φm ոTWrWD Z"mLI0J=l.9.7ϊ6y /^|R]hR8:oOkpAc:zeFT{c%=%ƼhWEuO9q}?dqyK0{{4?ԙS,u'-۴;XLm^0#P( k*7quk$^eɤj8"8gs_O9*kyeF55fb_Qh$R)Al,'emsLjҊ_h"\Ox9${;U[ ~8 ~L/wt,װ5sa:&ʛ?~H)n*8{hXvZI)'=&3| v*c0ՅO&+;DyE}BZ\[ }E2^\Z|_m?clx#>yXz#$3˞ES8G-FYV9a* tCT6ɩEWn=?mlVEk@۸guD?tPF2?'cO&;g 32/,/w#xzbtCu7r_!zgfu̜G 3*dWmH UD ǰ9 WTR6|wq9ΰ: 8BJh2ݖ;fao0Dq6"ROkFF:1탊Ӿ&A)z$W͝ C&>_Qr ?fe/2k6gwe:+gy|Zr&4;UʍKR,~m^~{[( vL`<˨4"gm3`ܮ01e *]Z,HIfj귙F]1Fy[?{,7[:CFQ A+ ?~J[O) pճiyo^FεI l|bD 焵(|UU䗤s+:(rh_p=Pm3'Ub]Ԑ \"NYAgo+KOS}[y2XŴ2Ht3ɗ_"T2J$ў$hE%uQIҌGɽxUp74g6K'52NR$ q\:^"̀ T"S,B/<|d )n- Y>Tmq-)sM G+҂νA^9C8T۔N8!R%l7#bXUcI/u;)uևXs+;R\F<X,@?awZviD}]\xKb-8lW?G˯z٬B;x6zs;T3yr_Pfi)^-Ve"&L}]42=f^IUoʼnf|> i, >kv(Nҿ϶4nٹjnGK BۤamFs=18%{Lr#u9[w);_d9|)xoEB2ƼCvHYcaZyk9B8K8& yiJ.{nC{juy?q<l>.AqAJMK}q^6~+*? czhJ=H].Lؚ`(4vSah9'o8EX>E 'Ď4BGUurBB1sLZ XxfLMx,YA|CnR Zb&g/bLT1iK~B}j6܁X裏el(Q鄢Ęɀ1Y/@)(~T/RD~\1{9g[KOa$ j`@>WN$KB-=_gܚ{g Nq9r&ůxQ!haW,t,?mFIrvDP} ('BBvp#W7GڃoB|P6W6D?P =&a[]ǮxGZԃ}X zYv MhRŲw͌DAEG*]NdA7,BdG?7~jg\oX'aMdQOqEUy{AU*&|`n7Ƅ~hW ۪w wPs%b@9Lu OU[R YUnQ#up&]lEz@bEMoԲɧS GžQ]8hg7% J|qlj&O(g)m)il/Oj-Yfq77g-.w\]d_u- o~&Kp aUHӻ{D«'֝;zx3֩#S6U|j+n2n &) ?{ " yDBOSуD "b8Ҽu*.Ay+A&?7tW=%/<\Xȋ yTbqhe C6 j̓ +!Uu 2DEFbVοd̶faV¾CVS>_Lց~dO1nTL&(0k7aGT wR)]3wyPup=F;gyV§ʵ-=o?>9yʲj@|H+,b4)ث &K1\f(0 P,//R8:FGiLv6lZ {R^h,ϡu/X{Rm4~9n2uy̍2X: RXJK2"Ӗ'iҧw4x~5D+4E$Cݬ~ NAP"yT\@d6G%!rqĪ?}m W2"=.9E\bgD_FhшQ8MHt _ϊaF㥎8HUFxjz]tHmnz`(mgW!ALK#X}E,4A@@?ЄB _F5a4pl p{,;[(5lVu,6I'"yQl~ 4_Y8Ȧoѥ2+rr9b3KgN.1m5#7kDwt}1z`p^ QkaWir.a}a/rEcVgNyțd љт۰g7;8zj(W؂JRc/韽"*b]&8Z8l8ygn%?6{}=r +S7z%fz< ] I3Xڕ@PU)yB1gCrAjb }܈R7,vqyY#cz"FfrϲkUvf'F&n/{,U|?xᓟ ҝ3Ŝkj|+tY>2uW=OBoK˴㺶o0CBH̆W{ ę߄ur2%Lą k7ZJ"k. $4g{"y߶2'RP*JƘ;w(HjNM%1P6:*ǬPn%NUqX͑yh m=S3G>-AO|#SXRhގ̒-ߩ_qdNmPE!9?8bRjX\ IqO"(. JNb(;GӎefL %mZsfh{+=G׽USS*Ou?Fw}79fP4 SyFѿdL.M1_?O 8kuȆ?Mo=ݻ4"Q1¢F]ޫ_H#&cd7E#&3(SY|Q2"v/F*RkR'MmԹC Ű.e{qY~J5?sŨZO;SGǤp?*!SBL^, ؏1b:a'\~- _-`@W7i8![8+MMsN̴Ԁ#)N> stream xڬceݶ%a۶mffm۶m۶;SU?vkk>֘{I'dlgh"ngLD 1tqR㒥S21s88[ي8pL&Fff @@FECC_Ldaf jbmgocb `jamQ!%/WHؚ8X~Z[d-LlLvFvDK `p71fndb`ohc`0s4ug;? +!{G6u~99;9Z;F!*< dW 3kilgOIu6u8;`ldom7_0{Gdak_M M;U'_v,LMa4rY501[nb:W5򟙡AoHH@Gzo-bm-o`wc-Y4? kV3w0)gm5K #=㿅N&?,{/_nV#)[YCۿU&t+E%)1Ił᏿a7Qsx1s9bf_ -ZfdW_'#fkdgt65;m)Gm-U_sobnbdgl\=4!:b_\\_eUQB0xfy M}8҃aMѝdrCB՛IAsȠ[ zu Ψz;[?uLOFdk\ށRvND10:<4} {KMcxFPoTѬVBHʔzB`-(d'v \pLdZYZcI|};*}+!jI"m YRPr`!]3*#'Rj4k-?B`hY®`an_PrJm!> P#^FAA P'7RX=^ IˊUpHNj7}270dMBhl{Dnή1@y](! ɮKhX_DOZr܌6Ht5+Jn|{|` (t:t]3 K˴%7R$peOcrRD$m#>~5}WNv%:~'gKOW"0l}}ƴ+Dz/C*|$0`TINFiRlWwe' q;Y2hoJ crA?ɺBLJ6$Z'U'W {4Ǽ,B@?M\HBj/Ĩ,JXzY{ 9k`-՗Or*_EXmYl-0Xw<{-i/ wzsl+qGuNeCq[EJWB5[DzRt91lyNH7WN6E?Yjd &/{2U5Q*?b‰JA~L}hz:=rҫWan}K !G,{,tTM9EUa]c6Y_ɬΓw)&qވ? LĂδqS' 2aG;2SFfjٯ5*g}F#Sq8['"1(уq )ugLEd:zCqC7{\QMF22Xj; $Տ YmK.Wq\2_<ȡW9#XW6;4~x~$FO+7"x䠳/eh90<"6Փԣ1~'<ĕMH6JCx{>ېhc䄿7qVy 4=X蘇 ( o?wSЅ?y tWrw0;+WCyxc?yJl{M>|QńzaWN4F,n\2utN{_?eO J0o̹rPUy ?U]i\ndp)(AJ*1&"ew6B:8VBlWwj)v9M`$ku_w} ii 犧Pv^ʩ )czBe0jEpq%i^ bP+-`3KF?_Q5q=7fb ]0\wF&`Ӓ 8C33S[+md= jfzA_Xt?VhuKȿ#xQ`WgoO'?%-NNWJ־I AM#l`\[1z8}.#޳y~$GMUL*HJJ W܊WWjPGBo߁yR܊7*kO O;{(y o{^I"9cwDdX% D}|"d޹֮Us5xOO2~ NESxf<LWoOgj^FᲡ(VxRSTo{fE.Gʩ8 \f&[Z9ZS8T[ $02&0c7Nj EirD‹9 9\ilq򨚇kL2?d$V.9Fɝ҈nXivk ;_V+qzX/Q%\*GոqtTC$fq= ^Pn\d$"-9 5'=%vҞ[g¤K3v(dF]g R("o_f55,x_7 b,Rr#F {o0|A4RmFrd2?XG՟9EԶRÕ_A :+|5N5\A10u*6qՈbϦKeNa7K.![srV0r}8shRX?}N[fTNfb| 1%Y >P|ޮ&h_]ŨDt;YNݸqs-DC>5-S^ !&]\ }(!WB-$<=%HE|]yY޼S"EF3'_Ffh(}6+K!<{zֽzNo^hHF֎y ~Rݜcv8lDj3Pf7p&W$NJ%x.oTeٓ_a{C}nu^gTc"k#Q >"j8_t[8Ų+=CM&Kcm0>bJ=ջ8_$j;65d~آڣmA[sg+vr<貛lz6B&KbA `"t7=-YGt17zHDϻtj#~'LL{e t@N唑EPC7#~IjT>t̞[zާ%pU%vUO˕VPx˲m0 zh ̓'<8ZѢ*?X'zثHg,H=iKN̖J(V^OE'Ne=,I/0|+Am'ЇZu]D}GFɵlBr)]JTB~cg0ۋ?Q'jcF')<G/'.C^J˰h}pad$AJ).#O)J+p&U~M CNkެ'fmNKv|i6;@Ȳ)N>u,<*|ܕ &ASOoPpoWX3vZwܫ ŠLG]oN2thZ_X[s'Þhl\2mwu3 m9h <]HW&ePh iELsMKD 6v;RCo=7t[+۟#Ʀ| 8q~("4-OcZUޮwVu}qgP5Yh]s#@[$.=0zaj$A?`G cRɈ2RS05+0IJ+& ŇѨb;2xTEњGRNA?jh#zwNVH𛻒r JBkTj0zXiz)bQAJ;$`}zPIa h',[X'to_ Q0Fu;M&wRz]. A>mVQE*|l(AFE]ڗGquIp:hXn4|2աtOMM;+ߎX)4HD+ (_IODNz_k#Y v,1Ի473p»,WW @D!G;6'وC 0XbD~8Ou.m4M4kv0s{urht"W6>{Se\g Q*a[ |6PZnQ[uiq0v֏a1ej?*{f]^b~14/WˑUw AޞCDgzNvXU8PKͤfωRbU)͖uH ZdJ3mVI>+07_k#R؈zޥ:%lsчw6X)G R1]8 j͐0|vQä~Ǡ\;#|O:2u$ j<oy++J҂svasN(+ZBvF,g77C yj=G@~Z)"k@qXB+*F)ºS'6,>Fp  ?qk7:~D^|Ʋcb{ƛڻv`=S}F,ZvM6 䙂*pԐ da$\FK|;W|Sz[gcxڹܥ$ QȭX"D(?֗&6Жl 651K69BJD؋5V߽bH W: $ĸCEN.Bؐ 8eNKyeX^ŭmRX\*hn<8:1OI9~ ɰl I3{ԝ0s41-^wB8C*s#:[ز]?O%Sgm4]~dr[RynIP SA#Ba۰xn@19ߏ]HBm^!w:JeN*|{mѮ v WT!ip*`%9I[ Oƥc&tLj3$^\W3R/>- M+Nθ[81E<j*iDʣXZQ^{:r:tL% 4O)Cp}y=Po. 1 WlHs*"w`O1@C~E^Qmх|d$^1LXѮ_9ɒ/Jz_ƬLX!f7^7YG`{š瘌mJ^ClWb?jTWȽs\;u{@#˔͙t"SB$S;m_ Y?G;,6.~C~v6˭`YdHsHYZT_  o{HuCk5Ra3EM&ԪSrL<̄6X, jfSE5&_7F lc_&g R "\+U aL- ;/Y$\y jyPuW63r׵-G5G@DuR8݌uBV[ă E| .|tG1tr::0 ʃ,iYFL#%3hgqҮ^3TďSD ^]0JK,zocmt}rb.{H\:R IMmiG,"& l: ^22)_:gnKS;~=yLq=v _>o&2`%ޞ8ЮPRVٯD}*TX5޾]#X5_>br/%sc6tKz2 fJβ;Ş޽Fdݲ:ZrJÈ_xiYQ Z֎J2nQn݉J>DgU{Nȝ~p_WX' [+d]r~%-{yZQO o.~ꜫ\">8e:ӭhv5Z Su&8 &e Bb){p8[xy<+u- QҔs<.uF8&e`Nr̫gdxX&>T ~k~߀`i+exv ĸNąZRvy]c 2VuŒke@ynz6E!Y=*JFLRҷN iЃ558<^I<0g-7^ >1pn y  - W;ӓ}wd60|ᆤ)l@i${FwDLqYv;81WhBc; p8 ~)Sq0AwGҥD?*C2 B[F`G[=HmA{G"ۨHrnžlyˀZbW_i9rz93kE+(/fsKAwBZ&/%%uS~mI,z]!l%P|xWtqX҅pcxEޙiluFևeu<-x:__25Vh35 Q9tA|@QɒAM^ #SJ"Q'S0抌%a%1"+ <^ 4i1$1r7Y ?/ujXWvGִ3?1%O;)6b\k{Lǝ]sEp!;GmM!USXgĠԔw[{Nxe ׂYȉQ .#b/G V4qS5d}jf6rjyx:!dڒXkVv: Kms1tćقI)>OY45hzFFQ3O7JF>H2cCmkO0dh}m|(G q'Yx7kGC(u_0'0ifZe+GKi5(J.O=50M/;cn*ot*a(현0$ y.7LݗsΒh},?N9+NuK`rg/B;d4!rӄ?]Xc2@]kN=cqz̮RM}Fw(8AĀ2mLs/@zg/0۠$`0W: 럖"&VzwUe:bs( =Ana*zLX,`n06$mw՚wkoAGgkX|^cqENA&0dˌr=fcԪ~~m9)eaeC#+qP't\ Yb5o `[% od?5>|m{'bq((sJa$٦a->#v_?}^׍ [D\eGFq(~BOK O~=##ræ XZ1T8j݉/:f[}&C: Ӿ`%-ސ]=-^N,@a}?*+ٹw_\ub$f@䳔wv`k|yWy15=U.OـVZO;;uz \e7'\yɽ^1x".F:>q3؎_-P@8xTtgײbz3֍n,<''kXhI9ֳ" w?x#[M9qG&&8C |bz;$\:U3^3~m`a(+3>PSd)H0&`nb +hmbfn!GJэN-,՘'@/,Ri(!}3X&_/ڻOBq-˒Ŝ 9uNB$ʽ.r|ȦTN9pMmw*].A: IeVJ[YWΙbxO݂a' zXZ ۱ؘqt,>YH]6x~keG]t]Wsoq+U@ /$QC% &31F$Iú7G_k r囉ɗʙNTǵ$/!vk+-nƵ03 PGYGH1aCC?/k|~:Jv lrXuvWvŲW z7N֍]`"e1  vݛUl53Xpuq  Z4{k,x*3UZ(f]^en= _Dt. 'tQi3iNǏAr< sYh'd~bu@`9d#ゥXZChph 9P!r1qڧȷZ˅Cּ#IU5ܻ%50&WG'Lp"$ ,#xa׮=ݎQx9J_nZSdtpƔ [{c9iWýHFǯ:8vz&XT7_b3L[mVv19|MAqno(C8;Pe21O\)[s$[#(|V_ @P"l*0sk雎]\l: V?e(9l*1.a*S*y8p-|㖋{|7eB+x\G'0R3GmKQ[b L_fI]d6Kg&KXsqZ0!cկi%goR"r@rZ2{p7ji&kXl&L6{C4[$kP*/>nLo࣒+GoPّTU.} kS@%lՒ: 3ѝ4'MaR~A%zb5rDHYvBٲPےt_p?9l%\|"G0HM z B2>$9+.Ptt!I@p ,N4ńCt:O 9h4fbA jLs.-X9lL^E X)V]QpJpVG좳~, g5mA,Bn:LFM# bKs`>#_Ӭ bez1ECO75_P;$7#[$ E= ScܶMJ8`M]h^'f]I6$0Xnb0"1vL-_w}ަ5yZCE¡ N37DTzrǶ\[PKgkOa!B]WҠnV'dwmNP.ƪ@jfW~Rr<>Rg VobPQ=CQԻjX^%1ר7G#FfE:6 J70Fv _=47K!>#;9 8L1Ӯ:̌h mf\mߘyj5f Dxd-лQ!Ow)9mJYKހvF`SxrDLmN*Pg/?ޘC@NKdIAG0N" 5P/A3{ѵzle1-an)=}`\}n8N00(ީE=p,jN|~=1,\@Aa%Pt< H\\n1 0Ƴ}=Ţ:aQiu_Xs,ngb/lӜi/X_nF⪙ CAc'*zco].D!pBvz55̨Enmx|L*2[:`"4nVVjt@+RƉ!c%@*7_6v.҄=!?c;͛8Fc.j bbZK̐fkx5y1 I3~&q,$|@䛺g  0bM`J~ʬV%6IW׌əѧ&j]g/YVmD͜Hb{7^ ]%J&%gWG0$D[}h/qSCGG״&Y9sf9}Ǟ;|yq S|Ӻ8uSF}~AgKռ3D|e=ڒkc[9,Tf+WsT5mY"@ {Fשׂq(qr\Ej//Ў^&3$^\! <5-zeh'dcl'Ey6Ê(70;Uȗ _ت,P` qCPj5HOt +zTP0)R.B=$I&vSjߘDi L#j@zvNFR#)8YxCL>L>+鰈4|1vM3eÂNt:{o{׏CҼ*p9;+`ox )-Fr ;?]G;h?>/I\ endstream endobj 306 0 obj << /Length1 1644 /Length2 11116 /Length3 0 /Length 11972 /Filter /FlateDecode >> stream xڭyeTܲ%NBp % 4H7Nwwܝew7̟>KvZV|Rg0d'VN6A2Q j PbUY8^%@@'0"t Af)) ) Fڹ;-,o5մY ?WOGdA^)A %`$U>+*kdAl P &9` 1-͑K8ځLn 7S_`r;:~@k0ovs? 9@_oؾbdN`;'kOR27#@_oAMJ:Go, hgtJf' gG02`8,f6 GWW:K@;;N s64NטN-4"189e7sO$fP; dƮ uz x2 "S8(m__;d(.۸߼6__䝀mXJ*!/(v};Ź6}Ǯ 19؀!W}i-0 K5 f^ūd%%/YVua/OcnxfyK `|} pxC_@'@'i4jwԝO_Ukq@n SYdJ̾)NN lrhouNJ 1& :l;@'YtL]ٸ+ -|Fɇx97FTՌ(ZP0ѹd1M"lũ98dݻf8CMΜJ/$?sr7v1}Fws,Ik.Ǎt u~sϙ|Me"!>kzɕ#B=$KCuVpwZT0:u^ S6+D~W뭸\t^w39-~dU]0_|^'{W:QX&NGnBΥjxoV,da&,rsx/)2qdWBȺU7v><[$T+L+uf' ?0;'wwtqH+.? X8/$?(ʙD oh[#ܟYJgIn6Vx:aO,~x&C~*ī~L!h5eMeu%nKY'63P ea$ٙ}3G;GZCn܅r[Iw1*sdYyAmXb&7lP7&z7 yF e;*F8ךL#w>;Gav!tKuߞ1y".e߃?72o%|Q*ih=_sK!_9_fY'U,Z4phr__95+ ع]XUIh*cۇ?Ev9pSK)2;#U``k])Qw N]>?9G9KtJ$veItWCqcݍ< FΈr"HԿ&),v7ldNLDrqn/+&LlG/`逕'XUzJQZ?xst?۩5T;U}g }Լ,i*Z-+i3¡8xfR GϙL/)^VMm~a#H3&G#H] 5.ZaƓ o4IJFřBLC}i 3F[Jh; ә|Nt7/2 -%hї/uVKG 5s?A ֺ qBr&dhҧ WaU/,KE4W׉w7gz4hysw]h.)ȼOͼ$D| 'ߗ^h֠iIݝe]V$$Ac51!tk2%2H^;SJs ?8R8@ojaBӞIםZ^їS%@Jɽ1N'p2XYxh4 @qp۷iLL)jgO &m3C m6`u.>M2Ò2رU:~k?ǐC}QP6}> 0352Xe\פ p/?c¤.qF4vIfx Am1!˕-cZ;166:AVD]3Fbӷw_'rK1gz Clok$h8+hP u v]"xᗕyy¼͡n &+0246dm&j/c#H~G! )%qxHirїl.4{Ox/ F*tYaF1ejZ($LN)KVx$,g%X4чqNoӺj4"4LG쾓cd"(#ؗN[IzY{!B5z=_%0(W`ܣRmt:9&˰Nzl>ߒMǷ!N4S :#xsO8a'L߯3%4Z( =!&լN!F=Eq b>$J[s"du}!=B[` Ќ\6,If9ɝ+w:0f|pEQ+] ot^4P!-k=[uNax4p62 l>=  s<#:sIl5j[L08zuj{ޒ%CMb SˋL e0Hؘety鉠٭oP lŘI\HUd޲c^ᭅk: ?^ղ:=Ɉ}^g}thI⨬1 oM?R+'"G ]><brSC ~,3'ZTmaR<@c1(P9 %g UAʟ^n+̟G7*GS.?˛hm6OgyV ~=E/Ͱ~|;J!:TV̏`{%+ ^%]0-Dx|Q*^;AOTܸ y5[{BFǪxiovck-!_n:|˭-P{Z'.,{o[:Xƽ?'0-잃KQUk[ɉע%;he.sn6)aI?rA_4٩vž8 3Lm45bU%[5bI;rAן~NC$3fDL3(r\YD4L DK"g&j_>Dt_c1>Duw5M 0NeK jgq{̷"4RTm|%lb"被jB0kT(P>+e+݄%t9SU]ȧxK-l) .}PA#`qJ"\횘Z.}vXaLy:-KSiuF,ZEIRr) 皤:g+] LQe;o߈i#Y \a}wRqx:Sk:6۩̖=ך8o\EЕ  n>1% 8B3' 0GũmߕgY a(` Ӊ’ i0%v}܍+F_7a~W}8a.tMO7>vljDP{J҈TNxZdn ?N|3JAb@l(A7e{}t^VsXM Oki>:7r֯P}j`U^r{(])@\6 X74_ /QYG3ށ=aT#O߮[[$CmF ϳuņv+# uş\ѣ5~L{p6GX0f nh@.W6.&_JEoU9\M 7j~T*KWv *[G7ܦͩpl+0/R<53WXWb : Uz#C7#' P6~Dq$ə(gv;,iWIRk[yiGZTL>+9^ugf^!~?ཻAgcnЖIT[ ߱g1oKUB,H/yXxw|Pa6FR>.Np)a蕚+Uψ[G$s,֋SZ/'r0KSE6tLG8TMqLw۞e 0}I@(ѐތF4p}!qC@x[Ž)$ 2HPI`~?FI[aM>TNչ 1}zT>@ї4?mOێ^v/YN k4.if8Hڬ(1*ʯ=_nPߐDO>,t/mAlܙrm5\^03C!Mهo . IQ72 )ݟdϲbi`>]V3 &tOaR8W+^O~Bc0"k%UlwU[jq j&Nt!I8jqhtݳG'3ATj*.eWk*l &*?O(`5vz66 \cf\.^dZլG˄ME5nE.c|ք'O<pWF>.G 7 nҬ8Q;>3dS\"koꃸ.ŸNN+uբ 7L6g/VʕaԵ6g?>;,]UJNTV,'7|X46;v~V_-śXr#7}ZT:>Ud]j"X x eT[`X7{kz _3w-60k_?t2xჟ7 T͘@N#\eiDd}e,E_UBYJM2.lTY;)nx?=WJmP'7+ лʒ,Ẃգ͡l/ &{"Q' *!8όUJm_KIQާN(Yk+i ͧ[[tBv?GYIM[NKA (F}\vegɻ8G;ꪸTI䴨y26tҒ^- bf}fN d^ F.XpƒXLͷ qqw\2>" zm1(הڳ~t8/GG{FH,2|%YcL9L\J>gRߓt,~ƅUd11Fw1*ɞq9#f oAt.C.ơ# ~J>웣D A E9{V4kB`Y3JL:˟ EUb6O 3~Ȱ|eB[$X^G75qb*jzEL1;FƟ ]5cF`B 2>e.)-| =orC>%fdt̶E|͐ڮ(.Ql>T*M{ÎXʿ%v8(<-6ZbVR"v' @ _B/r7Bs97cH7p<:}؅Qw⸬1T.FȻXk~h 92c[P9MVct2P?N#hT~F3B;3%]l#`*nV]gD u/⃳Z%O=Q/dM@F C`~'"UWFICW E )j,v?Y3yUy/|2H]9sʾK_C(MdY%ɖG֌o!+s=c2Gl1rd!(nPtGw{X͔JF]-,{"B?!] /]s :ho]7 'yVٮB(X:`"i7=7뾘J _ƵI=ߪZs(=JE3:# k"=JugNpSI9qXs9e yLbj*t8V ,RT4PG" LS7:O9܄GvXڙr%yVh5a@ G!R99SkL=H Aa;܍~{ex ]42 s\%P%K?DPFF)RV]r ?,ɶ"b=R!Y5RB>j81vAv{a4eTJ-hKL-l> ?$9ţ "Dxg Z,:Š>.^e!]eȓS"1](DW.YJ۶bV;/<.jTܴZ03V\nD-8,l&,}^KSP#>/% ,` F=l'Nٍ#̷11{Y]a6:ٴ +MIPǰW12sbQ~ nJp$JxGe.<%-\0IgAKJOD4wn;dbt~b|Bb*Yz~)0DUsEFe cY8 Gb,>w5^#]'wL G̯V,PSN?$Aۅ]J+]i4Pwg-R9aT4c`9,V"݌QN0d/I(2f~-ݴįEtW;D°4x2%z=lZc^_hj?IQ6Gf뮣9LR6Zp7'~Uu!qs7˳k>==3qI轶Ls!^hsR:ED] }"..tDyqBk/4 %7}o ]ТaTGK^eێ*>F^g_wR;:.50n!ԧ&r{M2Fq+bu}a=iwcXy@LN*=(Anö>#g JiaS IBkW?e D0(cp$mJ* Ù.=ں5Z >}vw%>z:Ʌ}/m-Z,-,7@<)XD bO̰Іf1dΑ)L*MUcP%\jI;@1=ͱ?\,W:<JI 2'x']MfgfyS|݀m;w 8Qß5Ì©e$3 4>"1!7Z8.# %}kB>9frVM:a3L. 曗9DTڦ9`*Ddm=<p7ҭi+(v价nW[f561/?l~X$۝ыK\u+)`6gkuJ$#' r0bb*/ԆjW_w][{KݢN#!Z3{"(0z~ߜ#A̴ endstream endobj 308 0 obj << /Length1 1647 /Length2 14510 /Length3 0 /Length 15366 /Filter /FlateDecode >> stream xڭcx]%WlsǶmbWTl۶**m;w=ۧO_Ou9cII(jfo12lM\UmyU. c_R h 0Z@3`內;x8YYX4Z i ?Vv@{[/YV6@4FZI :-B`e s6>L̬)͙/34t7:1NVV 'c;Vv6.f$nnް%Sw9:Y9HH;O1Vaߛf.//_dle A2̬l=Kd4\,3/?:[6׭hc7)ol +;xEo`@5柙 hϬd@2 "UJ-bcdlwg(Y66N_okCYUf+g)+w`nlykؙlEW:L58 k uW̪Jr:m*HZf;1}l>?aEgEc;@?~y2/4vf̑/?_ V= h ho=5# T34. 9PҠ^ھ/5l&q©H uw22Ї7m ٰ)L+j^a JE`ga d;rȾ)1X`gT OC7н1p8I #Wn7$/wr;T{:g4%wb) +,WCPtnoZhӐk>¤Mz9NW HR4ƹZ-R4kDjb._1@CyQ$5 Evqǯ0[n2ފh6Aq9/'dNbjBuk,W"o=-e|'U100f} d+oZX%L7;q˲W .D^@iEG]W.$kӄߘpN[L*ppgC` Sb-~E5iC5A6p3[c ^k9fQ].YV,H@Kos' I!<42eYN:7[˰],DWo~X<\$bvXbaIq/>krRqI'◜o r.ui mUcx;I"E\wt\o6ß+h]`GNK-C]"A r\``{y`,| ;XB%y0cv~6K"+aJdרΟH_sd:h vc-#wjCXOg^cDRlETЕ]X-H %Ƽ͞ZuV6r]dzf GgY^hꆚ(%ZG$m)ZIt N-UZ൜\'kKsĞ- 4Z^Qed}zK2'<+B%)]&h[ ֊G|: U eO>~;P9dlj%fl0y_=wTR&#? OóNM۳EWir%",m>x(,/o3 "sMGhց6{")+y_+F[rhWbycLZ4b3#Nu$cw*m\eӆMd84jG䉉<^h41u-UۏҦ6-xkɯp:'}_*Q 1w*sR]- ȹni2)5ZJڮU0?9`>$_DzU{`^e=FpyF\ZV![X4LwjŌOH1dqAM g#gq+2zpw `c .{}Oj9rs׫ӱ,b=I׉f*gՇ+;2Ov@@FU"Ս/T}{;_u+Myȁ q>b~@Ȭ<|͜ w̸$*^[z6@?<Ln`-t+چ:Z׹*|)6ŦTHRCKͿI(n$w~U7CR,"vG<`I Y\ӿ\"㰊9ɱ4̋]͆15zWybr7 ~|2Z% R@)Z*,dDfIV c3)T(~#Z R|pq~+d) kRQ(oF`$Q|Ee}TrFÅy`EAE;yR !~?&Cw7<,yVSՉ[vGS˽}@]c@A:$g,)Li|oRgq9u΂Oԅ+RP*kxZdA${N2wsg(m7ltH"/()+ׁ8k1KҖilKTa$ɜ9 VYŁeQM Ѡ;r"~Q3~47(~ ^L\)I/v՜&iS.?Yه`9ط]NyXGB gWc mXbÆƴV})E&yߓ`+>Rpx 1OPSt~-^&L)CP㭾f`S9%ͬNI9ӷߌ]R\/@1_Su PTbq,;.V+^ ..,5s,y-f6D5j3ƇPpK-( Kf{:!aN` _LfbS4|ZE7E*^@[ꦊIktʐSsi#v2wTBĺjY`;щhV}ב4_ 5FǴQt5JfڎP]yȉ֞dgH*iS rPB^.Um,-Ri]-&ZXOC/)Xi+ٱoz~:T6Qe܇mb-NXϨCZ1BۖgԬ`JkjYP@kvgc|+S1 ^V+8%%$)[2oCT,U +cO@juGjmYV-fH:Y_G!Vx/ȧ??{5f9ğ(AA$ZxЂ9\Q>2.Q%DRg@MIHh45Z 6ɇHgꉧeCė=2w3+Vܩ?QXsHJķțLK6].V̹N6[zPTǪJH)湊173 `!y^lRϲr +ȀL-LcYu=RP;Oa#[Xs"$B;u$ե|21hʶ%`4weP׀+om&=¹igE8[u2'֨m q~^f+^Y@Ar!!JrӫLTA|Lp˿}QHo@DZ.mOUHO"֧l-MZq -놗_#|bZ}Kazl5e ŝL;ZHѫĺY ɽ`Yg_~G.8_/T9mV ēCgתM0-䱇4)Yqˤze+I1{e&AIHNF1&AME|j:LorLؙ .`58:Mv^yPv_dבȤ-Ņ~.2]݁UsBL<⯋8HEś.Q<9 M0~A-x;*$j :W&r|_5"Sj2lDŖ|4)mb( D]="IZ8azP^9(/8 _>ʐh`& P00nԩ`4uJނD Rki1S'%QlZcYoE,+q<R_R:}[x |!O->k}.UHSTAC +@h7a Y݋@u;LM-( -TJN!·͓yc7?%$@I"]W5 %yC"^R~@j{W`MױX.魪n$#nM!_5iNnnxЬRؽ6v"/LoEd'XUuB칯I;7\u&y䨡-)I &j5I 4ޅCB0RiCPqg[z*2W~l˪ {t&<ʑnv^\$9+~:b<(_2Gl^`WB s S']a|ᭈCW=jJm%xb3Xo 0#5~i#zWDL~\~Ha|jsimhA6XYpFޓ>³]hTI*T"l[I?ðma`gW39R{?w ]ͳr<^C+dSIrJ4uoD|h ߎNq6ٔ4v0|CJ|@f⁜fz![U ҝ A^6@TNh>zo%x6`I 1 =/Y7tn:ħE '{<'ۊ[h-y5DJ_f ifaO_ZJDnzU^t,$R"8WyOWJxF5U+y`b{(h:BmdrqKV0LnH~ܯ/';3g?D>?oDE J/aV|HCRg~¿U.C: ܐ2%ޒ?'(V=ZQoh3$aJ*u0bj:%X"J?.&r$t(jR!~+Cu3 om?RN]qӁǦl{63zeRgmTz`qᤞ*auߣ{;y-aWlj_=mDdp!En+AA k1U1 &fcc43"sTyJI繙eiGsdB?z{ު$=.SNYʆDɖ!|ly썜Dr΍9AZrtZ@3͢gDρDm^b{/Ҽfjۇv}O@XƅmJNsr@2HSaha_ط9p_Z%Y'zU_'T9x=Zn@~.OX K>ځ:>V&/}1 q4esL#h>6>id%~Lڐji1+(%~ZǝTc$M}< yEY%.wޫ?Kmf4΄HKb,UܴˉXRmr΍I`Gin%]i5ѹ5[Hڇ?_a@VgR^˕oǵJ^K5߮[IvM6]^|`:nȸoT^$$[޵'v8pDl7^#aԱ)qdSy12f5YBEd3L;l9h1evS}-{Q_HBJ~YтO_ٌȤKBZ6@=(AvRY}3(?#^C#J̽3 c"56;مj* {Pl*W{T/Z ',=K%ai=ayPxgȝ$ӂC`&Y?Tȧ9Ш4&7i6Km>;P9mM}"^+l/como7ot qZ0$)d-"ٱMו U*Nȱ^6jd׹cRO M!>$/ֱ{-  c]F^(~;vH3 s܀-+)9<3\|ua{b7R6bJt>r-vhw(IqNhIzrGټ4ۯ}өCNjȭ7`2 ܓP wxvy)%uHI%Iy{#ln;6dysz>rcȾpK;(Zʰ\b1j@ G\>NJ.)/:ѼDJ@Gr)EF7^E ε@|j`|3[J6 $dHu5]1=Ѧ[Ly(O7"*TC/aS|Zsow%5s7P=1:#Zf/H'o~Eon?ߥ1Ddf63>}./DaAo~U?X`}9-K|FW-Hd\Yl ɸlJc쇝4~+>sۈe2T(2b'`.R롺PjCZ9Gr79\fvxa kX$ *eiѡ`>~ր x.Ypg%ºQ PvDzbyr ?]|ܞ*=:*EP|}hVss.R`rtf"C)M\s*$ =*nT  =Ԫk}eB@:&)koǾ/2 %ñ@ݯ3\_xTl8>0.,M-0c{bd mS7dA%;a{_>:8 T,|.,3ۗmJ$=)ʯYzMlk ،*{Y;^K>ύƤBsb h1iOKYwY$!5g %8]lS 3-0&8$LE\o2b{ąSJ PJKM:{u\T241`rjPJ w(h,_<9usl\ ƒ]~5e*56^; ,$:T>$s ʞrc]Ų:jࠔS}-]V}%x[miE3ߗa^bi;kYw.ײڳWQ9FwAw @x~e=:}mԤrm(lkp7Ȗև&h*j]n7ITU@)#3fEGZB?JǂIc7=гL {+ &5ViAaFBF'H̨Tݫw{˵XZ=l{ ?:a˗mbv $5`R{>5?(R7ȇ| EH/ !)Z?WHuxxGX\|Ҟ{n̿ 8DJlxT1ݙ\w廐rT "E\c;ބcJkocysxFP|%%w:gBsշɍeqrg]9&@028@Ppݵbg N|7Bxl 1Ty[^Ft_D5 c+ݘ|;j佴 |[ߺ?(vs؟FXS[.`3C A,qIؒ,7W#GBĒi|=9oQ?kԒW.^Ј&o˵>Xnxɟi2y'5©| j<@כW}u*17z2u0.:ҁ=ǭ nxuĕ8ZR98ɹt|NݭoI1g7X $I3FOnڸ cۼU\GXpexn1\9lDڥݾ`B;F NMi$0QC2;ک l0@,(]Wn{1h ğLۧ?ǃ]htDy^KXGrڬE~F~;٥R<a[;26Yj$Jc|WyT>E0.*}-ϊa89O+Rk݅,E`=H~E K)B(JdF)і֤aS68¶`ד!(ǯ5N%xz_%בrs gNfglةt[^g[ {~znb@( '=sG9 ?@TBCz0$l,+~/O]#1/g"Z-/X^嵳pzm.'i:OL=ź,';ؑծ_ 27] ۾PcErƄm]ˏyd EjS,ŧ,?uo0lW Oevծ͞,]oѲT苰Pn!F`+Z¶Y!f1{;;{c)h=o"{vK +;5a)h^@le7N= Bg2Oe”3JW/;MX(iƷL=$= mI/C-ۉDž@֊\Cw2[AПA{!g4[A8>wc$)Tn&o`q:I)Ҩw7nOqÇ!EFat6Zw \y^&rYP̳DҊy׌G[>YK.̎kɿ-lD]`PaxYj9b96,K{ĮiM07HInC}k'E= ޑ=ubڙ`eRbà%XK|7U@ULmo6PO䪽BkƩ]ćQKg_bȨSsƶ:ǤP^+ GQޣ kh0T%Y+7D3iOABb1Nz0B>4P\J۶NȌtD%.ФAz]yd|)WH5x2`{w$QSDuͻcQl2l>v|Kk`鉲Kyb ެ0Bۆ,PaF짺'oxN h M_"oJP3hp }nN?"G.P*z"먤61Taw`:"xx|j|薋*qʐD"09TmTCF(wkzx`OJety$>%ՂH*R'`p/NLZjMiXӛR?x:2ݠ5XH}ڌgnIzQIW4Y3^AORyaޅg&Ĕ[ɽG4(pжn&K`õi r, QHyYLX-2\ZH&j( A F(79#3\z+_*i!hQq,GlKaÿt^R_4eQ˝lyFыist}J&+N|9z{7.#cb'YZV`4:/rpcMC-@>牽W] DTnp_E%-q&I(:/F KZ 3= d6oR4ä}[zJN7Q GC4NՁ,B-ӈMNXRf cZEa)oi84ec̓)70X,3e+IEW1d0,g =:GET!( 9-g|V+CvNZM>xuaCyQK.%tnnDq`; k]y+~NG-zފeZ|n-%fRsb l #}_-Ryӛ.nlp|c-/GKCZ4 /&NSbh?)8jhp\c-eOa\`3u$P/, ~Jln$xMFzcU"$j\9J$E dXl!0/'ҝhpO(Dӡf*m^5Uڡ*z9pd*ΉPė*+AFt߿$;K2RCO7D)$Hg0*2jv^̌E:ƔCt{D  b#3=6=TO=MA"]D= ^3i2/>)REwIHSap: oyoXK1i̜$;!+Q:=Ы/0/'T)W ( P+[69hq Eo-kW)U-e Jzϰ@ k-ֲִd8 Յ|f#55~C 0o+_Ep|4y|,BŎ-N.x{\TORug t!CWxi#)/$l'Aƞ&BZe*=eU4Ys{Ok{w}2P%#@^h{w%MsqP;7T(l/֊j6ZDn-M6lWhïa7n9hYSvačO**o"I{gsZDmba/d51[A(p;0Q$LJw!Xi[*w=cBj9n##3{I$3,#6=CH[7 *c/կ9''XgB'6֗|ĮwS1YRiiڌ<ԙT !9-9cfqwέv~1τ _֛gK+ endstream endobj 334 0 obj << /Producer (pdfTeX-1.40.22) /Subject (GAP Manual) /Author (The GAP Group) /Creator (TeX) /CreationDate (D:20231218175524+01'00') /ModDate (D:20231218175524+01'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.141592653-2.6-1.40.22 (TeX Live 2022/dev/Debian) kpathsea version 6.3.4/dev) >> endobj 261 0 obj << /Type /ObjStm /N 99 /First 898 /Length 4507 /Filter /FlateDecode >> stream x;RJ|EӘ\DG6؆l|pL*jW~ڊeoXVVɳoR( $<[H[B`Ep+" ,$0%A86zOb"b-QD(0"ءs\$ +W^0  ,D| 4@4$!'uD_DbT"0up)a$gRDHDo$qDq%HQJ [&".HhG`F@C А1hMp,hBap wz@]GuIЦ='[g^$/e|[/η'/oی:ۢŪVu oYUYVS~\;<]8.ZD_}98">l)AzzYrzz[ݗY{lC{Vw]{ԸB}%,8G4_~lNлŝe}/԰؃> ce=;o/}Y_pQތyxOl&/K;Aq. W\Q%! Ƌ2 L7 d"FfokҘ1gn]B<J3amؔ CTIx2Ոыq5j挋9@q =Ϭa{I r_Pk5GmlaʃyQ$cŲp> 5SW]ȫ/huNϩnݬ(;U;=UɊh٧c0n}XK?{a7p] ͮ&:jp%3hӶw!Swģˬm]v.aet뷿٘.H;pbb N{ Oȃu_D13k; tV׋ f`Ζ[%$7i'tV,a0md26Y^٬/\*xN>>:?4X^@Pg8:RF*hcn=OKkzDczB==iJj稂5[HzY0x |Q9h}.hv7[KzE*%eYIoM9'FtU]-h턷ee^w}]rafenةῦMeY5A;zOee54NN;>;GOܳt|KQZ:063#E`j1J%"H m6j[Lh; =esUV)6@OIY~՛oIC  /P~čr:[,&-hՊZQ1jpamDGutLFX+/W(Rz%LD; ) vI4?rAW/w~qw?2A' 䡿>˪Fw'!D˻pJ]2қN}Ok}C\ xtwb}w5ԙG=w;]&&Mp4{b050SV 7GܜḡRrV$aE5i̽]CǺ^@[UY;,^? a5!Jd3o{|qZf?+wݲlZ'™c+\؈upTp#d!QCRtp1\$ۄK(ӗ \"ވ{9/^lԽro=^鞷Ǵ[ms-\N_}Zgڢ. T| ANnzO>f暢=6oFlbUGq/OrQfPrlthPP (dlW㱇U;۠vaȧ3d;ƁG^#Ew&#zOyq^4;L03k]a]zܨ5Shή?5(emQvbfl7`gpF3Gof$gNp&2]}/'}gt[;Ù0Ŷ)ILW"buVy?WWɐYy_A(&X !C{x A>Jqu[+lo8жIS#|}HgjUtj 37@5GON@E/161ysKSW8,VmW M66*,>" fy{sl*YyI${<_+=o qKvVThIw lN@#{GD\s}gjMh;]q6~qMgYr.3T?$vVLSWtuVEՒ羇~< R .bވd0rjleātN wUW(M(hoWB'܄ǃmt6LRn_t/0A~:F趍 Li9z c<4.~z[S% *+"j;g n/u\Cy:H[\G Y@VX>탭]'IkT<8CxO":P6"1a!ȵ *]/Ԧ/Zml[[ϼNيt#ALM3z<"ց:| ~'^]wu.3VMٔ\fu Z2>Q)kF44f921%ܐ3.)[8g.6?˴8/S=Iy@˴.;W˭oشJ\^LtӺwf(/ѼLN8KYeXNޭ\7o <27DBAD2DC2B30D34AF1B31189D6A2C7C>] /Length 776 /Filter /FlateDecode >> stream x%KoNQN/G/ЫjRjQRU-mID Td01C&&b@"1$t~kf/1K2hrn1nI`/kT9.(B(b { %P eP -W1p Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. cryst/README0000644001325400021140000000421514540074574012262 0ustar gaehleruser The GAP 4 package Cryst, previously known as CrystGap, is the successor of the CrystGap package for GAP 3. During the porting process to GAP 4, large parts of the code have been rewritten, and the functionality has been extended considerably. Cryst provides a rich set of methods to compute with affine crystallographic groups, in particular space groups. In constrast to the GAP 3 version, affine crystallographic groups are now fully supported both in the representation acting from the right and in the representation acting from the left. The latter representation is the one preferred by crystallographers. There are also functions to determine representatives of all space group types of a given dimension. Cryst is implemented in the GAP 4 language, and runs on any system supporting GAP 4. This version requires at least GAP version 4.5. It is recommended, however, to use the most recent version of GAP. Certain commands may need other GAP packages such as CARAT or XGAP. Both CARAT and XGAP are available only under Unix. CARAT may be required by functions that need to know normalizers or conjugators of finite unimodular groups in GL(n,Z) (see the section on normalizers of the Cryst manual). The function WyckoffGraph needs the package XGAP. Cryst is distributed with GAP, and does not require any installation. It is loaded with the GAP command gap> LoadPackage( "cryst" ); Cryst has been developed by Bettina Eick, Institut Computational Mathematics, Fachbereich Mathematik und Informatik, Technische Universität Braunschweig, Pockelsstr. 14, D-38106 Braunschweig, Germany e-mail: beick@tu-bs.de Franz Gähler, Fakultät für Mathematik, Universität Bielefeld, Postfach 10 01 31, D-33501 Bielefeld, Germany e-mail: gaehler@math.uni-bielefeld.de Werner Nickel, Fachbereich Mathematik, AG2, Technische Universität Darmstadt, Schlossgartenstrasse 7, D-64289 Darmstadt, Germany e-mail: nickel@mathematik.tu-darmstadt.de For bug reports, suggestions and other comments please use the issue tracker on the GitHub page of the package: https://github.com/gap-packages/cryst/issues cryst/init.g0000644001325400021140000000276514372461414012521 0ustar gaehleruser############################################################################# ## #A init.g Cryst library Bettina Eick #A Franz Gaehler #A Werner Nickel ## #Y Copyright 1997-1999 by Bettina Eick, Franz G"ahler and Werner Nickel ## ## Cryst - the crystallographic groups package ## ## GAP 4 Version ## ## introducing globally the NC version of PreImagesRepresentative if not IsBound( PreImagesRepresentativeNC ) then BindGlobal( "PreImagesRepresentativeNC", PreImagesRepresentative ); fi; ############################################################################# ## #R read the declaration files ## ReadPackage( "cryst", "gap/common.gd" ); # declarations for integral matrices ReadPackage( "cryst", "gap/cryst.gd" ); # declarations for AffineCrystGroups ReadPackage( "cryst", "gap/hom.gd" ); # declarations for homomorphism ReadPackage( "cryst", "gap/wyckoff.gd" ); # declarations for Wyckoff position ReadPackage( "cryst", "gap/zass.gd" ); # declarations for Zassenhaus alg. ReadPackage( "cryst", "gap/max.gd" ); # declarations for maximal subgroups ReadPackage( "cryst", "gap/color.gd" ); # declarations for color groups ReadPackage( "cryst", "gap/equiv.gd" ); # isomorphism test for space groups ReadPackage( "cryst", "grp/spacegrp.gd" ); # the IT space group catalogue cryst/htm/0000755001325400021140000000000014540074574012170 5ustar gaehlerusercryst/htm/theindex.htm0000644001325400021140000001626714540074574014526 0ustar gaehlerusercryst : a GAP 4 package - Index

cryst : a GAP 4 package - Index

_ A C I M N P S T W

_

\^, for an noexpand`AffineCrystGroup' 2.4

A

AddTranslationBasis 2.3.3
Affine crystallographic groups 2.0
AffineCrystGroup 2.1.7
AffineCrystGroupOfPointGroup 2.2.3
AffineCrystGroupOnLeft 2.1.4
AffineCrystGroupOnRight 2.1.1
AffineInequivalentSubgroups 2.8.5
AffineNormalizer 2.8.4
AsAffineCrystGroup 2.1.8
AsAffineCrystGroupOnLeft 2.1.5
AsAffineCrystGroupOnRight 2.1.2

C

CentralizerPointGroupInGLnZ 2.8.2
CheckTranslationBasis 2.3.4
Color groups 2.9
ColorCosetList 2.9.4
Colored AffineCrystGroups 2.10
ColorGroup 2.9.1
ColorHomomorphism 2.9.7
colorings, inequivalent, for space group 2.10
ColorOfElement 2.9.5
ColorPermGroup 2.9.6
ColorSubgroup 2.9.3
ConjugacyClassesMaximalSubgroups, for an `AffineCrystGroup' 2.5.2
ConjugatorSpaceGroups 2.8.6
Construction 2.1
construction, of an AffineCrystGroup 2.1
cryst 1.0

I

InternalBasis 2.3.2
International Tables 2.11
Introduction 1.0
IsAffineCrystGroup 2.1.9
IsAffineCrystGroupOnLeft 2.1.6
IsAffineCrystGroupOnRight 2.1.3
IsColorGroup 2.9.2
IsomorphismFpGroup, for a `PointGroup' 2.4.2
IsomorphismFpGroup, for an `AffineCrystGroup' 2.4.3
IsomorphismPcpGroup, for a `PointGroup' 2.4.4
IsomorphismPcpGroup, for an `AffineCrystGroup' 2.4.5
IsPointGroup 2.2.2
IsPointHomomorphism 2.2.5
IsSpaceGroup 2.3.5
IsStandardAffineCrystGroup 2.3.6
IsStandardSpaceGroup 2.3.7
IsSymmorphicSpaceGroup 2.3.9
IsWyckoffPosition 2.7.3

M

Maximal subgroups 2.5
maximal subgroups, for an AffineCrystGroups 2.5
MaximalSubgroupClassReps, for an `AffineCrystGroup' 2.5.1
methods, for an AffineCrystGroup 2.4

N

normalizer, in affine group 2.8
normalizer, in translation group 2.8
normalizer, of an AffineCrystGroup 2.8
NormalizerPointGroupInGLnZ 2.8.1
Normalizers 2.8

P

Point group 2.2
point group, of an AffineCrystGroup 2.2
PointGroup 2.2.1
PointGroup, for a colored `AffineCrystGroup' 2.10.1
PointHomomorphism 2.2.4
power, for an `AffineCrystGroup' 2.4.1

S

SetCrystGroupDefaultAction 2.0
Space groups with a given point group 2.6
space groups, for given point group 2.6
SpaceGroupIT 2.11.4
SpaceGroupOnLeftIT 2.11.3
SpaceGroupOnRightIT 2.11.2
SpaceGroupsByPointGroup 2.6.5
SpaceGroupsByPointGroupOnLeft 2.6.3
SpaceGroupsByPointGroupOnRight 2.6.1
SpaceGroupSettingsIT 2.11.1
SpaceGroupTypesByPointGroupOnLeft 2.6.6
SpaceGroupTypesByPointGroupOnRight 2.6.2
Special methods 2.4
StandardAffineCrystGroup 2.3.8
Subgroup, for color groups 2.9.8
subgroups, maximal, for an AffineCrystGroup 2.5

T

Translation lattice 2.3
translation lattice, of an AffineCrystGroup 2.3
TranslationBasis 2.3.1
TranslationNormalizer 2.8.3
TransposedMatrixGroup 2.1.10

W

Wyckoff positions 2.7
WyckoffBasis 2.7.4
WyckoffGraph 2.7.9
WyckoffOrbit 2.7.8
WyckoffPositions 2.7.1
WyckoffPositionsByStabilizer 2.7.2
WyckoffSpaceGroup 2.7.6
WyckoffStabilizer 2.7.7
WyckoffTranslation 2.7.5

[Up]

cryst manual
Dezember 2023
cryst/htm/CHAP002.htm0000644001325400021140000013464714540074574013656 0ustar gaehleruser[cryst] 2 Affine crystallographic groups [Up] [Previous] [Index]

2 Affine crystallographic groups

Sections

  1. Construction
  2. Point group
  3. Translation lattice
  4. Special methods
  5. Maximal subgroups
  6. Space groups with a given point group
  7. Wyckoff positions
  8. Normalizers
  9. Color groups
  10. Colored AffineCrystGroups
  11. International Tables

An affine crystallographic group G is a subgroup of the group of all Euclidean motions of d-dimensional space, with the property that its subgroup T of all pure translations is a discrete normal subgroup of finite index. If the rank of the translation subgroup T is d, G is called a space group. The quotient G/T is called the point group of G.

In this package, affine crystallographic groups are represented as groups of augmented matrices of dimension d+1. Most functions assume a group of rational matrices, but some may also work with cyclotomic matrix groups. In particular, it is possible to compute the translation basis of an affine crystallographic group given in a cyclotomic representation, and to pass to a rational representation by conjugating with that basis. Further functionality for cyclotomic crystallographic groups is currently not guaranteed.

Augmented matrices can take one of two forms. Matrices of the form

                     [ M 0 ]
                     [ t 1 ]
act from the right on row vectors (x,1). Such a matrix is said to be an affine matrix acting on the right. Since in GAP all groups act from the right, this is the preferred representation of an affine transformation.

The second representation of affine transformations is by augmented matrices of the form

                     [ M t ]
                     [ 0 1 ]
which act from the left on column vectors (x,1). Such matrices are said to be affine matrices acting on the left. This is the representation usually adopted by crystallographers.

Cryst supports affine crystallographic groups in both representations. Every affine crystallographic group is constructed in one of these two representations.

Affine crystallographic groups in different representations should never be mixed, however. It is recommended to adopt one of the two representations, and then to stick to that decision. In order to facilitate this, there is a global variable CrystGroupDefaultAction, whose value is either RightAction or LeftAction. The initial value is RightAction, but this can be changed with

  • SetCrystGroupDefaultAction( action ) F

    where action must be either RightAction or LeftAction. Constructor functions without explicit representation qualifier then will construct an affine crystallographic group in the representation specified by CrystGroupDefaultAction.

    2.1 Construction

  • AffineCrystGroupOnRight( gens ) F
  • AffineCrystGroupOnRight( genlist ) F
  • AffineCrystGroupOnRight( genlist, identity ) F

    returns the matrix group generated by gens or genlist, which must be affine matrices acting on the right, as affine crystallographic group acting on the right. An already existing group S of affine matrices acting on the right can be converted to an affine crystallographic group acting on the right with

  • AsAffineCrystGroupOnRight( S ) F

    The property

  • IsAffineCrystGroupOnRight( S ) P

    is true exactly for those groups which have been constructed in the above two ways.

  • AffineCrystGroupOnLeft( gens ) F
  • AffineCrystGroupOnLeft( genlist ) F
  • AffineCrystGroupOnLeft( genlist, identity ) F

    returns the matrix group generated by gens or genlist, which must be affine matrices acting on the left, as affine crystallographic group acting on the left. An already existing group S of affine matrices acting on the left can be converted to an affine crystallographic group acting on the left with

  • AsAffineCrystGroupOnLeft( S ) F

    The property

  • IsAffineCrystGroupOnLeft( S ) P

    is true exactly for those groups which have been constructed in the above two ways.

    It is recommended to adopt one representation for affine crystallographic groups, and then to stick to it. To facilitate this, routines are provided which assume a default representation.

  • AffineCrystGroup( gens ) F
  • AffineCrystGroup( genlist ) F
  • AffineCrystGroup( genlist, identity ) F

    calls AffineCrystGroupOnRight or AffineCrystGroupOnLeft with the same arguments, depending on the value of CrystGroupDefaultAction.

  • AsAffineCrystGroup( S ) F

    calls AsAffineCrystGroupOnRight or AsAffineCrystGroupOnLeft with the same argument, depending on the value of CrystGroupDefaultAction.

  • IsAffineCrystGroup( S ) F

    calls IsAffineCrystGroupOnRight or IsAffineCrystGroupOnLeft with the same argument, depending on the value of CrystGroupDefaultAction.

  • TransposedMatrixGroup( S ) A

    returns the transpose of the affine crystallographic group S. If S is acting on the right, its transpose is acting on the left, and vice versa.

    2.2 Point group

    The point group P of an affine crystallographic group S is the quotient S/T, where T is the normal subgroup of all pure translations. P is isomorphic to the group generated by the linear parts of all affine matrices contained in S. In Cryst this latter group is identified with the point group of S.

  • PointGroup( S ) A

    returns the point group of S.

  • IsPointGroup( P ) P

    returns true if and only if P has been constructed as the point group of an affine crystallographic group S.

  • AffineCrystGroupOfPointGroup( P ) A

    returns the affine crystallographic group S, from which P has been constructed.

  • PointHomomorphism( S ) A

    returns a homomorphism from the affine crystallographic group to its point group.

  • IsPointHomomorphism( H ) P

    returns true if and only if H has been constructed as the PointHomomorphism of an affine crystallographic group.

    2.3 Translation lattice

    The vectors by which the pure translations in an affine crystallographic group translate form a discrete lattice, L, called the translation lattice of S.

  • TranslationBasis( S ) A

    returns a basis of the translation lattice of S. The basis returned is unique for the translation lattice.

  • InternalBasis( S ) A

    returns a basis used internally for many computations. It consists of the translation basis B of S, extended by further standard basis vectors if B has not full rank.

    If a generating set B of the translation lattice of S is known from somewhere, this knowledge can be added to S with

  • AddTranslationBasis( S, B ) F

    This function must do further work, so that SetTranslationBasis cannot be used for this purpose. If doubts arise about the correctness of the translation basis that has been added by hand, one can check the correctness of the stored value with

  • CheckTranslationBasis( S ) F

    An affine crystallographic group S acting on d-dimensional Euclidean space is called a space group if its translation lattice has rank d.

  • IsSpaceGroup( S ) P

    tests if the affine crystallographic group S is a space group.

    Since many computations are done internally in the InternalBasis of S, we say that S is in standard form if the InternalBasis is the standard basis of Euclidean row space or column space, respectively. This means that the translation lattice is generated by the first k standard basis vectors, where k is the rank of the translation lattice.

  • IsStandardAffineCrystGroup( S ) P

    checks if S is in standard form.

  • IsStandardSpaceGroup( S ) P

    checks if S is a space group in standard form.

  • StandardAffineCrystGroup( S ) F

    returns a conjugate of S which is in standard form.

    If an space group is a semi-direct product of its point group with its translation subgroup, S is said to be symmorphic.

  • IsSymmorphicSpaceGroup( S ) P

    checks if the space group S is symmorphic.

    2.4 Special methods

    In the representation by augmented matrices, affine crystallographic groups are infinite matrix groups. Their infinity is relatively trivial in the sense that they have an abelian normal subgroup of finite index. Nevertheless, for many operations special methods have to be installed that avoid to attempt algorithms that never finish. These methods all make essential use of the exactness of the sequence of homomorphism 0 -> T -> S -> P -> 1, where T is the translation subgroup of S, and P its point group.

    All operations for general groups that make sense for affine crystallographic groups should work also in that case. In particular, there should be no restrictions for finite AffineCrystGroups. For infinite groups, some restrictions apply, however. For instance, algorithms from the orbit-stabilizer family can work only if the orbits generated are finite. Note, however, that Normalizer, Centralizer and RepresentativeAction in an AffineCrystGroup work even if the corresponding orbit is infinite.

    Some methods installed for affine crystallographic groups have a special behavior.

  • \^( S, conj )

    If S is an AffineCrystGroupOnRight, the group conj^-1 S conj is returned. conj must be an affine matrix acting on the right. If S is an AffineCrystGroupOnLeft, the group conj S conj^-1 is returned. conj must be an affine matrix acting on the left.

  • IsomorphismFpGroup( P ) A

    returns an isomorphism from the PointGroup P to an isomorphic FpGroup F. If P is solvable, F is given in a power-commutator presentation.

  • IsomorphismFpGroup( S ) A

    returns an isomorphism from the AffineCrystGroup S to an isomorphic FpGroup F. If S is solvable, F is given in a power-commutator presentation. The presentation of F is an extension of the presentation of the point group P of S used in IsomorphismFpGroup( P ).

    If the package polycyclic is installed, Cryst automatically loads it, and then provides special methods for IsomorphismPcpGroup.

  • IsomorphismPcpGroup( P ) A

    with P a solvable PointGroup, returns an isomorphism from P to an isomorphic PcpGroup pcp. For details about PcpGroups, we refer to the documentation of the package polycyclic.

  • IsomorphismPcpGroup( S ) A

    with S a solvable AffineCrystGroup (i.e., one with a solvable PointGroup), returns an isomorphism from S to an isomorphic PcpGroup pcp. The presentation of pcp is an extension of the presentation of the point group P of S used in IsomorphismPcpGroup( P ).

    2.5 Maximal subgroups

    Since an AffineCrystGroup has infinitely many maximal subgroups in general, in the computation of maximal subgroups it must be further specified which maximal subgroups are desired. Recall that a maximal subgroup of an AffineCrystGroup is either latticeequal or classequal. A latticeequal subgroup has the same translation lattice as the parent, while a classequal subgroup has the same point group as the parent. In the classequal case a maximal subgroup always has prime-power index, whereas in the latticeequal case this is so only in dimensions up to 3.

  • MaximalSubgroupClassReps( S, flags ) O

    returns a list of conjugacy class representatives of maximal subgroups of the AffineCrystGroup S.

  • ConjugacyClassesMaximalSubgroups( S, flags ) O

    returns a list of conjugacy classes of maximal subgroups of the AffineCrystGroup S.

    In these two functions, the argument flags specifies which maximal subgroups are computed. flags is a record which may have the following components:

    flags.primes := [p1 .. pr]
    only maximal subgroups of p-power index for the given primes p are computed

    flags.latticeequal := true
    only latticeequal maximal subgroups are computed

    flags.classequal := true
    only classequal maximal subgroups are computed

    flags.latticeequal and flags.classequal must not both be bound and true. flags.primes may be omitted only if flags.latticeequal is bound and true.

    gap> S := SpaceGroupIT(3,222);
    SpaceGroupOnRightIT(3,222,'2')
    gap> L := MaximalSubgroupClassReps( S, rec( primes := [3,5] ) );;
    gap> List( L, IndexInParent );
    [ 3, 27, 125 ]
    gap> L := MaximalSubgroupClassReps( S,             
    >                  rec( classequal := true, primes := [3,5] ) );;
    gap> List( L, IndexInParent );                                                 
    [ 27, 125 ]
    gap> L := MaximalSubgroupClassReps( S,
    >                  rec( latticeequal := true, primes := [3,5] ) );;
    gap> List( L, IndexInParent );                                       
    [ 3 ]
    gap> L := MaximalSubgroupClassReps( S, rec( latticeequal := true ) );;
    gap> Length(L);
    5
    gap> List( L, IndexInParent );                                       
    [ 2, 2, 2, 3, 4 ]
    

    2.6 Space groups with a given point group

  • SpaceGroupsByPointGroupOnRight( P ) O
  • SpaceGroupsByPointGroupOnRight( P, norm ) O
  • SpaceGroupsByPointGroupOnRight( P, norm, orbsflag ) O

    where P is any finite subgroup of GL(d,Z), returns a list of all space groups (acting on the right) with point group P, up to conjugacy in the full translation group of Euclidean space. All these space groups are returned as AffineCrystGroupOnRight in standard representation. If a second argument is present, which must be a list of elements of the normalizer of P in GL(d,Z), only space groups inequivalent under conjugation with these elements are returned. If these normalizer elements, together with P, generate the full normalizer of P in GL(d,Z), then exactly one representative of each space group type is obtained. If the third argument orbsflag, which must be false or true, is also present and true, all space groups up to conjugacy in the full translation group are returned, but these space groups are collected into orbits under the conjugation action with elements from norm.

    gap> P := Group([ [ [ -1, 0 ], [ 0, -1 ] ], [ [ -1, 0 ], [ 0, 1 ] ] ]);
    Group([ [ [ -1, 0 ], [ 0, -1 ] ], [ [ -1, 0 ], [ 0, 1 ] ] ])
    gap> norm := GeneratorsOfGroup( NormalizerInGLnZ( P ) );
    [ [ [ -1, 0 ], [ 0, -1 ] ], [ [ -1, 0 ], [ 0, 1 ] ], [ [ -1, 0 ], [ 0, -1 ] ],
      [ [ 1, 0 ], [ 0, -1 ] ], [ [ 0, 1 ], [ 1, 0 ] ] ]
    gap> SpaceGroupsByPointGroupOnRight( P );
    [ <matrix group with 4 generators>, <matrix group with 4 generators>, 
      <matrix group with 4 generators>, <matrix group with 4 generators> ]
    gap> SpaceGroupsByPointGroupOnRight( P, norm );
    [ <matrix group with 4 generators>, <matrix group with 4 generators>, 
      <matrix group with 4 generators> ]
    gap> SpaceGroupsByPointGroupOnRight( P, norm, true );
    [ [ <matrix group with 4 generators> ], 
      [ <matrix group with 4 generators>, <matrix group with 4 generators> ], 
      [ <matrix group with 4 generators> ] ]
    

  • SpaceGroupTypesByPointGroupOnRight( P ) O
  • SpaceGroupTypesByPointGroupOnRight( P, orbsflag ) O

    returns a list of space group type representatives (acting on the right) of the point group P. As in the case of SpaceGroupsByPointGroupOnRight, if the boolean argument orbsflag is present and true, not only space group type representatives, but all space groups up to conjugacy in the full translation group are returned. These are then collected into lists of space groups of the same space group type.

    gap> SpaceGroupTypesByPointGroupOnRight( P );
    [ <matrix group with 4 generators>, <matrix group with 4 generators>, 
      <matrix group with 4 generators> ]
    gap> SpaceGroupTypesByPointGroupOnRight( P, true );
    [ [ <matrix group with 4 generators> ], 
      [ <matrix group with 4 generators>, <matrix group with 4 generators> ], 
      [ <matrix group with 4 generators> ] ]
    

  • SpaceGroupsByPointGroupOnLeft( P ) O
  • SpaceGroupsByPointGroupOnLeft( P, norm ) O
  • SpaceGroupsByPointGroupOnLeft( P, norm, orbsflag ) O

    works the same way as SpaceGroupsByPointGroupOnRight, except that the space groups acting from the left are returned.

  • SpaceGroupTypesByPointGroupOnLeft( P ) O
  • SpaceGroupTypesByPointGroupOnLeft( P, orbsflag ) O

    works the same way as SpaceGroupTypesByPointGroupOnRight, except that the space groups acting from the left are returned.

  • SpaceGroupsByPointGroup( P ) O
  • SpaceGroupsByPointGroup( P, norm ) O
  • SpaceGroupsByPointGroup( P, norm, orbsflag ) O

    calls SpaceGroupByPointGroupOnRight or SpaceGroupByPointGroupOnLeft with the same arguments, depending on the value of CrystGroupDefaultAction.

  • SpaceGroupTypesByPointGroupOnLeft( P ) O
  • SpaceGroupTypesByPointGroupOnLeft( P, orbsflag ) O

    calls either SpaceGroupTypesByPointGroupOnRight or SpaceGroupTypesByPointGroupOnLeft with the same arguments, depending on the variable CrystGroupDefaultAction.

    2.7 Wyckoff positions

    A Wyckoff position of a space group S is an equivalence class of points in Euclidean space, having stabilizers which are conjugate subgroups of S. Apart from a subset of lower dimension, which contains points with even bigger stabilizers, a Wyckoff position consists of an S-orbit of some affine subspace A. In Cryst, a Wyckoff position W is specified by such a representative affine subspace.

  • WyckoffPositions( S ) A

    returns the list of Wyckoff positions of the space group S.

    gap> S := SpaceGroupIT(2,14);
    SpaceGroupOnRightIT(2,14,'1')
    gap> W := WyckoffPositions(S);
    [ < Wyckoff position, point group 3, translation := [ 0, 0 ], 
        basis := [  ] >
        , < Wyckoff position, point group 3, translation := [ 2/3, 1/3 ], 
        basis := [  ] >
        , < Wyckoff position, point group 3, translation := [ 1/3, 2/3 ], 
        basis := [  ] >
        , < Wyckoff position, point group 2, translation := [ 0, 0 ], 
        basis := [ [ 1, -1 ] ] >
        , < Wyckoff position, point group 1, translation := [ 0, 0 ], 
        basis := [ [ 1, 0 ], [ 0, 1 ] ] >
         ]
    

    In the previous example, S has three kinds of special points (the basis is empty), whose representatives all have a stabilizer with the same point group (with label 1), one kind of special line (the basis has length 1), and the general position.

  • WyckoffPositionsByStabilizer( S, sub ) O

    where S is a space group and sub a subgroup of the point group or a list of such subgroups, determines only the Wyckoff positions whose representatives have a stabilizer with a point group equal to the subgroup sub or contained in the list sub, respectively.

    gap> sub := Group([ [ [ 0, -1 ], [ -1, 0 ] ] ]);
    Group([ [ [ 0, -1 ], [ -1, 0 ] ] ])
    gap> IsSubgroup( PointGroup( S ), sub );
    true
    gap> WyckoffPositionsByStabilizer( S, sub );
    [ < Wyckoff position, point group 1, translation := [ 0, 0 ], 
        basis := [ [ 1, -1 ] ] >
         ]
    

  • IsWyckoffPosition( obj ) R

    checks whether obj is a Wyckoff position.

    gap> ForAll( W, IsWyckoffPosition );
    true
    

  • WyckoffBasis( W ) O

    returns a basis of the representative affine subspace of the Wyckoff position W.

    gap> WyckoffBasis( W[4] );
    [ [ 1, -1 ] ]
    

  • WyckoffTranslation( W ) O

    returns a point of the representative affine subspace of the Wyckoff position W.

    gap> WyckoffTranslation( W[3] );
    [ 1/3, 2/3 ]
    

  • WyckoffSpaceGroup( W ) O

    returns the space group of which W is a Wyckoff position.

    gap> WyckoffSpaceGroup( W[1] );
    SpaceGroupOnRightIT(2,14,'1')
    

  • WyckoffStabilizer( W ) O

    returns the stabilizer of the (generic) points in the representative affine subspace of the Wyckoff position W. This stabilizer is a subgroup of the space group of W, and thus an AffineCrystGroup.

    gap> stab := WyckoffStabilizer( W[4] );
    Group([ [ [ 0, -1, 0 ], [ -1, 0, 0 ], [ 0, 0, 1 ] ] ])
    gap> IsAffineCrystGroupOnRight( stab );
    true
    

  • WyckoffOrbit( W ) O

    determines the orbit of the representative affine subspace A of the Wyckoff position W under the space group S of W (modulo lattice translations). The affine subspaces in this orbit are then converted into a list of Wyckoff positions, which is returned. The Wyckoff positions in this list are just different representations of W. Their WyckoffBasis and WyckoffTranslation are chosen such that the induced parametrizations of their representative subspaces are mapped onto each other under the space group operation.

    gap> orb := WyckoffOrbit( W[4] );
    [ < Wyckoff position, point group 2, translation := [ 0, 0 ], 
        basis := [ [ 1, -1 ] ] >
        , < Wyckoff position, point group 2, translation := [ 0, 0 ], 
        basis := [ [ 1, 2 ] ] >
        , < Wyckoff position, point group 2, translation := [ 0, 0 ], 
        basis := [ [ -2, -1 ] ] >
         ]
    gap> Set(orb);
    [ < Wyckoff position, point group 2, translation := [ 0, 0 ], 
        basis := [ [ 1, -1 ] ] >
         ]
    

  • WyckoffGraph( W [, def ] ) O
  • WyckoffGraph( S [, def ] ) O

    displays the incidence relations of a set of Wyckoff positions graphically. This function is available only under XGAP. In the first form, W is a list of Wyckoff positions, which must belong to the same space group. In the second form, S is a space group; in this case, the function is applied to the complete list of Wyckoff positions of S. In both forms, a second argument, def, is possible, which is a record with optional components title, width and height, specifying the title, width and height of the graphic sheet on which the graph will be displayed.

    Each vertex of the graph represents a Wyckoff position. Vertices are arranged in horizontal layers, determined by the dimension s of the Wyckoff position and the size s of its stabilizer. For each layer, the list [ d, s ] is displayed at the right border of the graphic sheet. The vertical positions of the layers are ordered according to the dimension of the Wyckoff position (primary criterion, smaller dimension above) and the size of the stabilizer (secondary criterion, bigger stabilizer above). Two Wyckoff positions are connected if the closure of the lower one contains the upper one. Two Wyckoff positions are connected by a line only if there is no Wyckoff position in between. The connection line is labelled with the number of affine subspaces contained in the lower Wyckoff position that contain a fixed representative affine subspace of the upper Wyckoff position. For instance, if the lower Wyckoff position consists of a space group orbit of lines (and thus the upper one of an orbit of points), the label of the connection line is the number of lines in the orbit which cross a fixed representative point of the upper Wyckoff position.

    The initial layout of the graph is not always optimal. In particular, several connection lines can be drawn on top of each other, so that it is not easy to see who is connected with whom. With the left mouse button, the graph can be rearranged, however. Just drag each vertex to a more suitable place. Note, however, that a vertex can not leave its layer. For more details, please consult the XGAP manual.

    By right-clicking on a vertex, a popup menu with information on the Wyckoff position of that vertex appears. It informs on the size of the WyckoffStabilizer, the dimension of the Wyckoff position, the length of the WyckoffOrbit (modulo lattice translations), the translation and basis of a representative affine subspace, the isomorphims type of the WyckoffStabilizer, and the ConjugacyClassInfo of the point group P of the WyckoffStabilizer. The ConjugacyClassInfo lists for each conjugacy class of elements of P the number of that class, the order, trace and determinant of its elements, and the size of the class. This information is useful to identify the geometric operation of the stabilizer. The isomorphism type and ConjugacyClassInfo may not be displayed initially. It this case, they can be obtained by left-clicking on them, or by left-clicking on the button labelled all. Unfortunately, the popup window cannot be resized automatically, and since the ConjugacyClassInfo needs several lines for the display, the information may be hidden behind the border of the window. You will have to use the slider of the popup window to make it visible, or resize the window with the help of your window manager. Alternatively, you can right-click again on the same vertex, in which case a new popup window of sufficient size appears.

    2.8 Normalizers

    At present, most of the functions in this section require that the GAP package CaratInterface is installed (and compiled). Otherwise, they are available only for space groups from the crystallographic groups catalogue or the International Tables (section International Tables).

  • NormalizerPointGroupInGLnZ( P ) A

    returns the normalizer of the PointGroup P in the group of all unimodular transformations of the lattice spanned by the InternalBasis B of the AffineCrystGroup S of P. If S is in standard representation, this is the same as Normalizer( GL(dim,Integers), P ), otherwise it is Normalizer( GL(dim,Integers), P^(B^-1) )^B. This notion probably makes sense only if S is a space group. Note that P must have elements with integer entries (which is the case if S is a space group).

  • CentralizerPointGroupInGLnZ( P ) A

    returns the centralizer of the PointGroup P in the group of all unimodular transformations of the lattice spanned by the InternalBasis B of the AffineCrystGroup S of P. If S is in standard representation, this is the same as Centralizer( GL(dim,Integers), P ), otherwise it is Centralizer( GL(dim,Integers), P^(B^-1) )^B. This notion probably makes sense only if S is a space group. Note that P must have elements with integer entries (which is the case if S is a space group).

  • TranslationNormalizer( S ) F

    returns the normalizer of the space group S in the full translation group. At present, this function is implemented only for space groups, not for general AffineCrystGroups. The translation normalizer TN of S may contain a continuous subgroup C. A basis of the space of such continuous translations is bound in TN!.continuousTranslations. Since this subgroup is not finitely generated, it is not contained in the group generated by GeneratorsOfGroup( TN ). Properly speaking, the translation normalizer is the span of TN and C together.

  • AffineNormalizer( S ) F

    returns the affine normalizer of the space group S. The affine normalizer AF contains the translation normalizer as a subgroup. Similarly as with TranslationNormalizer, the subgroup C of continuous translations, which is not finitely generated, is not part of the group that is returned. However, a basis of the space of continuous translations is bound in the component AF!.continuousTranslations.

  • AffineInequivalentSubgroups( S, sub ) F

    takes as input a space group S and list of subgroups of S, and returns a sublist of affine inequivalent subgroups. Note that the affine normalizer of S must be discrete in the current implementation. If it is not, fail is returned.

    For two space groups S1 and S2 of the same dimension (and acting from the same side),

  • ConjugatorSpaceGroups( S1, S2 ) F

    returns an affine matrix m such that S1^m = S2, of fail if no such matrix exists, i.e., if the two space groups are not equivalent. This function requires that the GAP package CaratInterface is installed (and compiled).

    2.9 Color groups

    A color group C is a group whose elements are colored in the following way. The elements having the same color as the identity element One(C) form a subgroup H of finite index n. H is called the ColorSubgroup of C. Elements of C have the same color if and only if they are in the same right coset of H in C. The labelling of the colors, which runs from 1 to n, is determined by a fixed labelling of the right cosets of H. The list of right cosets of H is stored in the attribute ColorCosetList. The color of the elements of a coset corresponds to the position of the coset in that list. Elements of H by definition have color 1, i.e., the coset with representative One(C) is always the first element of the ColorCosetList of C. Color groups which have a parent inherit their coloring from that parent, including the labelling of the colors. As with other groups, color groups having no parent are their own parent.

    Right multiplication by a fixed element g of C induces a permutation p(g) of the colors of the parent of C. This defines a natural homomorphism of C into the symmetric group of degree n. The image of this homomorphism is called the ColorPermGroup of C, and the homomorphism to it is called the ColorHomomorphism of C.

  • ColorGroup( G, H ) F

    constructs a colored copy of G, with color subgroup H (which should have finite index in G). Color groups constructed in this way are always their own parent. It is not possible to set their parent attribute to a different value.

    Groups which may be colored include, in particular, AffineCrystGroups, but coloring of any finite group should work as well.

  • IsColorGroup( G ) P

    checks whether G is a color group.

  • ColorSubgroup( G ) A

    returns the color subgroup of G.

  • ColorCosetList( G ) A

    returns the color labelling cosets of G.

  • ColorOfElement( G, elem ) F

    returns the color of an element of G.

  • ColorPermGroup( G ) A

    returns the ColorPermGroup of G, which is the permutation group induced by G acting on the colors of the parent of G.

  • ColorHomomorphism( G ) A

    returns the homomomorphism from G to its ColorPermGroup.

  • Subgroup( C, elems ) O

    where C is a color group, returns the colored subgroup U of C generated by elems. The parent of U is set to the parent of C, from which the coloring of U is inherited.

    gap> G := Group(  (1,2,3), (2,3,4) );
    Group([ (1,2,3), (2,3,4) ])
    gap> H := Group( (1,2,3) ); 
    Group([ (1,2,3) ])
    gap> C := ColorGroup( G, H );
    Group([ (1,2,3), (2,3,4) ])
    gap> ColorSubgroup( C ) = H;
    true
    gap> ColorCosetList( C );
    [ RightCoset(Group( [ (1,2,3) ] ),()), RightCoset(Group( [ (1,2,3) ] ),(1,2)
        (3,4)), RightCoset(Group( [ (1,2,3) ] ),(1,3)(2,4)), 
      RightCoset(Group( [ (1,2,3) ] ),(1,4)(2,3)) ]
    gap> List( last, x -> ColorOfElement( C, Representative(x) ) );
    [ 1, 2, 3, 4 ]
    gap> U := Subgroup( C, [(1,3)(2,4)] );
    Group([ (1,3)(2,4) ])
    gap> IsColorGroup( U );
    true
    gap> ColorSubgroup( U );
    Group(())
    gap> ColorCosetList( U );
    [ RightCoset(Group( () ),()), RightCoset(Group( () ),(1,3)(2,4)) ]
    gap> List( last, x -> ColorOfElement( U, Representative(x) ) );
    [ 1, 3 ]
    

    2.10 Colored AffineCrystGroups

    If C is a colored AffineCrystGroup whose ColorSubgroup is lattice-equal (translationengleich) with C, then the PointGroup of C can consistently be colored. In that case,

  • PointGroup( C ) A

    returns a colored point group. Otherwise, the PointGroup of C is an ordinary, uncolored group.

    gap> S := SpaceGroupIT( 2, 10 );                                  
    SpaceGroupOnRightIT(2,10,'1')
    gap> m := MaximalSubgroupClassReps( S, rec( primes := [2] ) );    
    [ <matrix group with 4 generators>, <matrix group with 3 generators>, 
      <matrix group with 4 generators> ]
    gap> List( last, x -> TranslationBasis(x) = TranslationBasis(S) );
    [ false, true, false ]
    gap> C := ColorGroup( S, m[1] );; IsColorGroup( PointGroup( C ) );
    false
    gap> C := ColorGroup( S, m[2] );; IsColorGroup( PointGroup( C ) );
    true
    

    Two colorings of a space group S are equivalent if the two ColorSubgroups are conjugate in the affine normalizer of S. For instance, a list of inequivalent index-2 ColorSubgroups of S can be obtained with the following code:

    gap> sub := MaximalSubgroupClassReps( S, rec( primes := [2] ) );
    [ <matrix group with 4 generators>, <matrix group with 3 generators>, 
      <matrix group with 4 generators> ]
    gap> List( sub, Size );
    [ infinity, infinity, infinity ]
    gap> sub := Filtered( sub, s -> IndexInParent( s ) = 2 );
    [ <matrix group of size infinity with 4 generators>, 
      <matrix group of size infinity with 3 generators>, 
      <matrix group of size infinity with 4 generators> ]
    gap> Length( AffineInequivalentSubgroups( S, sub ) );
    2
    

    Note that AffineInequivalentSubgroups requires the GAP package CaratInterface to be installed. Otherwise, this function is supported only for AffineCrystGroups constructed from the crystallographic groups catalog.

    2.11 International Tables

    For the user's convenience, a table with the 17 plane groups and the 230 space groups is included in Cryst. These groups are given in exactly the same settings (i.e., choices of basis and origin) as in the International Tables. Space groups with a centered lattice are therefore given in the non-primitive basis crystallographers are used to. This is in contrast to the crystallographic groups catalogue, where always a primitive basis is used.

    For some of the 3D space groups, two different settings are available. The possible settings are labelled with the characters '1', '2','b','c','h' and 'r'. If only one setting is available, it is labelled '1'. For some space groups there exists a point with higher symmetry than the origin of the '1' setting. In such cases, a second setting '2' is available, which has this high symmetry point as origin. This second setting '2' then is the default setting. Space groups which have a unique axis can have this axis in b direction (setting'b') or c direction (setting 'c'). 'b' is the default setting. Rhombohedral space groups are given in a hexagonal basis (setting 'h') and in a rhombohedral basis (setting 'r'). 'h' is the default setting.

  • SpaceGroupSettingsIT( dim, nr ) F

    returns a string, whose characters label the available settings of the space group with number nr and dimension dim.

  • SpaceGroupOnRightIT( dim, nr ) F
  • SpaceGroupOnRightIT( dim, nr, setting ) F

    returns space group number nr in dimension dim in the representation acting on the right. In the third argument, the desired setting can be specified. Otherwise, the space group is returned in the default setting for that space group.

  • SpaceGroupOnLeftIT( dim, nr ) F
  • SpaceGroupOnLeftIT( dim, nr, setting ) F

    returns space group number nr in dimension dim in the representation acting on the left. In the third argument, the desired setting can be specified. Otherwise, the space group is returned in the default setting for that space group.

  • SpaceGroupIT( dim, nr ) F
  • SpaceGroupIT( dim, nr, setting ) F

    returns either SpaceGroupOnRightIT or SpaceGroupOnLeftIT with the same arguments, depending on the value of CrystGroupDefaultAction.

    gap> SpaceGroupSettingsIT( 3, 146 );
    "hr"
    gap> SpaceGroupOnRightIT( 3, 146 );        
    SpaceGroupOnRightIT(3,146,'h')
    gap> SpaceGroupOnRightIT( 3, 146, 'r' );
    SpaceGroupOnRightIT(3,146,'r')
    

    [Up] [Previous] [Index]

    cryst manual
    Dezember 2023
    cryst/htm/CHAP001.htm0000644001325400021140000001003314540074574013633 0ustar gaehleruser[cryst] 1 Introduction [Up] [Next] [Index]

    1 Introduction

    The Cryst package, previously known as CrystGAP, provides functions for the computation with affine crystallographic groups, in particular space groups. For the definition of the standard crystallographic notions we refer to the International Tables Hah95, in particular the chapter by Wondratschek Won95, and to the introductory chapter in BBNWZ78. The principal algorithms used in this package are described in EGN97.

    The present version for GAP 4 has been considerably reworked from an earlier version for GAP 3.4.4. Most of the porting to GAP 4 has been done by Franz Gähler. Besides affine crystallographic groups acting from the right, also affine crystallographic groups acting from the left are now fully supported. Many algorithms have been added, extended, or improved in other ways.

    Our warmest thanks go the Max Neunhöffer, whose extensive testing of the GAP 4 version of Cryst in connection with XGAP uncovered several bugs and led to many performance improvements.

    Cryst is implemented in the GAP 4 language, and runs on any system supporting GAP 4. However, certain commands may require that other GAP packages such as CaratInterface or XGAP are installed. In particular, the routines in Section Normalizers are likely to require CaratInterface, and the function WyckoffGraph (see WyckoffGraph) requires XGAP. Both CaratInterface and XGAP may be available only under Unix.

    The Cryst package is loaded with the command

    gap> LoadPackage( "cryst" ); 
    true
    

    Cryst has been developed by

    Bettina Eick
    Fachbereich Mathematik und Informatik
    Technische Universität Braunschweig
    Pockelsstr. 14, D-38106 Braunschweig, Germany
    e-mail: b.eick@tu-bs.de

    Franz Gähler
    Fakultät für Mathematik, Universität Bielefeld
    Postfach 10 01 31, D-33501 Bielefeld, Germany
    e-mail: gaehler@math.uni-bielefeld.de

    Werner Nickel
    Fachbereich Mathematik, AG2, Technische Universität Darmstadt,
    Schlossgartenstraße 7, D-64289 Darmstadt, Germany
    e-mail: nickel@mathematik.tu-darmstadt.de

    For bug reports, suggestions and comments please please use the issue tracker on GitHub:

    https://github.com/gap-packages/Cryst/issues/

    [Up] [Next] [Index]

    cryst manual
    Dezember 2023
    cryst/htm/chapters.htm0000644001325400021140000000106614540074574014516 0ustar gaehlerusercryst : a GAP 4 package - Chapters

    cryst : a GAP 4 package - Chapters

    1. Introduction
    2. Affine crystallographic groups

    cryst manual
    Dezember 2023
    cryst/htm/biblio.htm0000644001325400021140000000234414540074574014145 0ustar gaehlerusercryst : a GAP 4 package - References

    cryst : a GAP 4 package - References

    [BBNWZ78]
    H. Brown, R. Bülow, J. Neubüser, H. Wondratschek, and H. Zassenhaus.
    Crystallographic Groups of Four-Dimensional Space.
    John Wiley, New York, 1978.
    [EGN97]
    F. G"ahler, B. Eick and W. Nickel.
    Computing maximal subgroups and wyckoff positions of space groups.
    Acta Cryst A 53, 467--474 (1997).
    [Hah95]
    T. Hahn, editor.
    International Tables for Crystallography, Volume A, Space-group Symmetry, 4th Edition.
    Kluwer, Dordrecht, 1995.
    [Won95]
    H. Wondratschek.
    Introduction to space-group symmetry.
    In Internation Tables for Crystallography, Vol. A Hah95, pages 711--735.

    [Up]

    cryst manual
    Dezember 2023
    cryst/read.g0000644001325400021140000000461413232361435012460 0ustar gaehleruser############################################################################# ## #A read.g Cryst library Bettina Eick #A Franz Gaehler #A Werner Nickel ## #Y Copyright 1997-1999 by Bettina Eick, Franz G"ahler and Werner Nickel ## ## Cryst - the crystallographic groups package ## ## GAP 4 Version ## ############################################################################# ## #R read the general stuff for integer matrix groups ## ReadPackage( "cryst", "gap/common.gi" ); # routines for integral matrices ############################################################################# ## #R read the crystallographic groups specific functions ## ReadPackage( "cryst", "gap/hom.gi" ); # methods for PointHomomorphisms ReadPackage( "cryst", "gap/cryst.gi" ); # methods for CrystGroups ReadPackage( "cryst", "gap/cryst2.gi" ); # more methods for CrystGroups ReadPackage( "cryst", "gap/fpgrp.gi" ); # FpGroup for CrystGroups # and PointGroups ReadPackage( "cryst", "gap/zass.gi" ); # methods for Zassenhaus algorithm ReadPackage( "cryst", "gap/max.gi" ); # methods for maximal subgroups ReadPackage( "cryst", "gap/wyckoff.gi" ); # methods for Wyckoff positions ReadPackage( "cryst", "gap/color.gi" ); # methods for color groups if IsBound( GAPInfo.PackagesLoaded.xgap ) then ReadPackage( "cryst", "gap/wypopup.gi" ); # popup menu for Wyckoff graph ReadPackage( "cryst", "gap/wygraph.gi" ); # Wyckoff graph methods; needs XGAP else ReadPackage( "cryst", "gap/noxgap.gi" ); # dummy for WyckoffGraph fi; if IsBound( GAPInfo.PackagesLoaded.polycyclic ) then # PcpGroup for CrystGroups and PointGroups ReadPackage( "cryst", "gap/pcpgrp.gi" ); fi; ############################################################################# ## #R read the orbit stabilizer methods ## ReadPackage( "cryst", "gap/orbstab.gi" ); # Orbit, Stabilizer & Co. ReadPackage( "cryst", "gap/equiv.gi" ); # conjugator between space groups ############################################################################# ## #R load the IT space group catalogue ## ReadPackage( "cryst", "grp/spacegrp.grp" ); # the catalogue ReadPackage( "cryst", "grp/spacegrp.gi" ); # access functions cryst/gap/0000755001325400021140000000000014540074574012147 5ustar gaehlerusercryst/gap/common.gd0000644001325400021140000000032214053147612013741 0ustar gaehleruser############################################################################# ## #A RowEchelonForm . . . . . . . . . . row echelon form of an integer matrix ## DeclareAttribute( "RowEchelonForm", IsMatrix ); cryst/gap/equiv.gi0000644001325400021140000001345414404635412013621 0ustar gaehleruser############################################################################# ## #A equiv.gi Cryst library Bettina Eick #A Franz G"ahler #A Werner Nickel ## #Y Copyright 1997-1999 by Bettina Eick, Franz G"ahler and Werner Nickel ## ############################################################################# ## #F ConjugatorSpaceGroupsStdSamePG( S1, S2 ) . . . . returns C with S1^C = S2 ## ## S1 and S2 act on the right, are in standard form, ## and have the same point group ## ConjugatorSpaceGroupsStdSamePG := function( S1, S2 ) local P, d, M, I, g, i, gen1, t1, gen2, t2, sol, Ngen, orb, img, S, rep, nn, n1; P := PointGroup( S1 ); # catch trivial case if IsTrivial( P ) then return One( S1 ); fi; d := DimensionOfMatrixGroup( P ); # determine space in which translational parts of generators can # be shifted by conjugating the space group with pure translations M := List( [1..d], i->[] ); i := 0; I := IdentityMat(d); for g in GeneratorsOfGroup( P ) do g := g - I; M{[1..d]}{[1..d]+i*d} := g{[1..d]}{[1..d]}; i := i+1; od; gen1 := List( GeneratorsOfGroup( P ), x -> PreImagesRepresentativeNC( PointHomomorphism( S1 ), x ) ); t1 := Concatenation( List( gen1, x -> x[d+1]{[1..d]} ) ); gen2 := List( GeneratorsOfGroup( P ), x -> PreImagesRepresentativeNC( PointHomomorphism( S2 ), x ) ); t2 := Concatenation( List( gen2, x -> x[d+1]{[1..d]} ) ); sol := SolveInhomEquationsModZ( M, t1-t2, true )[1]; if sol <> [] then return AugmentedMatrix( IdentityMat( d ), sol[1] ); fi; # if we arrive here, we need the normalizer Ngen := GeneratorsOfGroup( NormalizerPointGroupInGLnZ( P ) ); Ngen := List( Filtered( Ngen, x -> not x in P ), y -> AugmentedMatrix( y, 0*[1..d] ) ); orb := [ S1 ]; rep := [ One( S1 ) ]; for S in orb do for g in Ngen do img := S^g; if not img in orb then nn := rep[Position(orb,S)]*g; Add( orb, img ); Add( rep, nn ); gen1 := List( GeneratorsOfGroup( P ), x -> PreImagesRepresentativeNC( PointHomomorphism( img ), x ) ); n1 := nn{[1..d]}{[1..d]}; t1 := Concatenation( List( gen1, x -> x[d+1]{[1..d]})); sol := SolveInhomEquationsModZ( M, t1-t2, true )[1]; if sol <> [] then return AugmentedMatrix( n1, sol[1] ); fi; fi; od; od; return fail; end; ############################################################################# ## #M ConjugatorSpaceGroups( S1, S2 ) . . . . . . . . .returns C with S1^C = S2 ## InstallMethod( ConjugatorSpaceGroups, IsIdenticalObj, [ IsAffineCrystGroupOnRight and IsSpaceGroup, IsAffineCrystGroupOnRight and IsSpaceGroup ], 0, function( S1, S2 ) local d, P1, P2, ls1, ls2, C1, C2, C3, C4, c, S1std, S2std, P1std, P2std, S3; d := DimensionOfMatrixGroup( S1 ) - 1; # some short cuts P1 := PointGroup( S1 ); P2 := PointGroup( S2 ); if Size( P1 ) <> Size( P2 ) then return fail; fi; ls1 := AsSortedList( List( ConjugacyClasses( P1 ), x -> [ Size(x), TraceMat( Representative(x) ), DeterminantMat( Representative(x) ) ] ) ); ls2 := AsSortedList( List( ConjugacyClasses( P2 ), x -> [ Size(x), TraceMat( Representative(x) ), DeterminantMat( Representative(x) ) ] ) ); if ls1 <> ls2 then return fail; fi; # go to standard representation # S1 = S1std^C1 if IsStandardSpaceGroup( S1 ) then S1std := S1; C1 := IdentityMat( d+1 ); else S1std := StandardAffineCrystGroup( S1 ); C1 := AugmentedMatrix( InternalBasis( S1 ), 0*[1..d] ); fi; # S2 = S2std^C2 if IsStandardSpaceGroup( S2 ) then S2std := S2; C2 := IdentityMat( d+1 ); else S2std := StandardAffineCrystGroup( S2 ); C2 := AugmentedMatrix( InternalBasis( S2 ), 0*[1..d] ); fi; P1std := PointGroup( S1std ); P2std := PointGroup( S2std ); if P1std = P2std then C3 := IdentityMat( d+1 ); S3 := S2std; else c := RepresentativeAction( GL(d,Integers), P2std, P1std ); if c = fail then return fail; fi; C3 := AugmentedMatrix( c, 0*[1..d] ); S3 := S2std^C3; fi; C4 := ConjugatorSpaceGroupsStdSamePG( S1std, S3 ); if C4 = fail then return fail; else return C1^-1 * C4 * C3^-1 * C2; fi; end ); ############################################################################# ## #M ConjugatorSpaceGroups( S1, S2 ) . . . . . . . . .returns C with S1^C = S2 ## InstallMethod( ConjugatorSpaceGroups, IsIdenticalObj, [ IsAffineCrystGroupOnLeft and IsSpaceGroup, IsAffineCrystGroupOnLeft and IsSpaceGroup ], 0, function( S1, S2 ) local S1tr, S2tr, C; S1tr := TransposedMatrixGroup( S1 ); S2tr := TransposedMatrixGroup( S2 ); C := ConjugatorSpaceGroups( S1tr, S2tr ); if C = fail then return fail; else return TransposedMat( C ); fi; end ); RedispatchOnCondition( ConjugatorSpaceGroups, IsIdenticalObj, [IsAffineCrystGroupOnRight,IsAffineCrystGroupOnRight], [IsAffineCrystGroupOnRight and IsSpaceGroup, IsAffineCrystGroupOnRight and IsSpaceGroup],0); RedispatchOnCondition( ConjugatorSpaceGroups, IsIdenticalObj, [IsAffineCrystGroupOnLeft,IsAffineCrystGroupOnLeft], [IsAffineCrystGroupOnLeft and IsSpaceGroup, IsAffineCrystGroupOnLeft and IsSpaceGroup],0); cryst/gap/max.gd0000644001325400021140000000116513232361435013243 0ustar gaehleruser############################################################################# ## #A max.gd Cryst library Bettina Eick #A Franz G"ahler #A Werner Nickel ## #Y Copyright 1997-1999 by Bettina Eick, Franz G"ahler and Werner Nickel ## ############################################################################# ## #A CocVecs( ) . . Cocycles of extension of point group with translations ## DeclareAttribute( "CocVecs", IsAffineCrystGroupOnLeftOrRight ); cryst/gap/cryst2.gi0000644001325400021140000006732214372461414013724 0ustar gaehleruser############################################################################# ## #A cryst2.gi Cryst library Bettina Eick #A Franz G"ahler #A Werner Nickel ## #Y Copyright 1997-2012 by Bettina Eick, Franz G"ahler and Werner Nickel ## ## More methods for affine crystallographic groups ## ############################################################################# ## #M IsSolvableGroup( S ) . . . . . . . . . . . . . . . . . . .IsSolvableGroup ## InstallMethod( IsSolvableGroup, "for AffineCrystGroup, via PointGroup", true, [ IsAffineCrystGroupOnLeftOrRight ], 0, S -> IsSolvableGroup( PointGroup( S ) ) ); ############################################################################# ## #M IsCyclic( S ) . . . . . . . . . . . . . . . . . . . . . . . . . .IsCyclic ## InstallMethod( IsCyclic, "for AffineCrystGroup", true, [ IsAffineCrystGroupOnLeftOrRight ], 0, function( S ) local P, T; P := PointGroup(S); T := TranslationBasis(S); if Length(T) = 0 then return IsCyclic(P); elif Length(T) > 1 then return false; elif IsTrivial(P) then return true; else return IsCyclic(P) and T=CocVecs(S); fi; end ); ############################################################################# ## #M Index( G, H ) . . . . . . . . . . . . . . . . . . . . . . . . . . . Index ## InstallMethod( IndexOp, "AffineCrystGroupOnRight", IsIdenticalObj, [ IsAffineCrystGroupOnRight, IsAffineCrystGroupOnRight ], 0, function( G, H ) if not IsSubgroup( G, H ) then Error( "H must be a subgroup of G" ); fi; return IndexNC( G, H ); end ); InstallMethod( IndexOp, "AffineCrystGroupOnLeft", IsIdenticalObj, [ IsAffineCrystGroupOnLeft, IsAffineCrystGroupOnLeft ], 0, function( G, H ) if not IsSubgroup( G, H ) then Error( "H must be a subgroup of G" ); fi; return IndexNC( G, H ); end ); InstallMethod( IndexNC, "AffineCrystGroupOnRight", IsIdenticalObj, [ IsAffineCrystGroupOnRight, IsAffineCrystGroupOnRight ], 0, function( G, H ) local TG, TH, IP, M; TG := TranslationBasis( G ); TH := TranslationBasis( H ); if Length( TG ) > Length( TH ) then return infinity; fi; IP := Index( PointGroup( G ), PointGroup( H ) ); if IsFinite( G ) then return IP; else M := List( TH, x -> SolutionMat( TG, x ) ); return IP * DeterminantMat( M ); fi; end ); InstallMethod( IndexNC, "AffineCrystGroupOnLeft", IsIdenticalObj, [ IsAffineCrystGroupOnLeft, IsAffineCrystGroupOnLeft ], 0, function( G, H ) local TG, TH, IP, M; TG := TranslationBasis( G ); TH := TranslationBasis( H ); if Length( TG ) > Length( TH ) then return infinity; fi; IP := Index( PointGroup( G ), PointGroup( H ) ); if IsFinite( G ) then return IP; else M := List( TH, x -> SolutionMat( TG, x ) ); return IP * DeterminantMat( M ); fi; end ); ############################################################################# ## #M ClosureGroup( G, elm ) . . . . . . . . .closure of a group and an element ## InstallMethod( ClosureGroup, "AffineCrystGroupOnRight method for group and element", IsCollsElms, [ IsAffineCrystGroupOnRight, IsMultiplicativeElementWithInverse ], 0, function( G, elm ) local gens, C; if not IsAffineMatrixOnRight( elm ) then Error( "elm must be an affine matrix acting OnRight" ); fi; gens:= GeneratorsOfGroup( G ); # try to avoid adding an element to a group that already contains it if elm in gens or elm^-1 in gens or elm = One( G ) then return G; fi; # make the closure group C := AffineCrystGroupOnRightNC( Concatenation( gens, [ elm ] ) ); # if is infinite then so is if HasIsFinite( G ) and not IsFinite( G ) then SetIsFinite( C, false ); SetSize( C, infinity ); fi; return C; end ); InstallMethod( ClosureGroup, "AffineCrystGroupOnLeft method for group and element", IsCollsElms, [ IsAffineCrystGroupOnLeft, IsMultiplicativeElementWithInverse ], 0, function( G, elm ) local gens, C; if not IsAffineMatrixOnLeft( elm ) then Error( "elm must be an affine matrix acting OnLeft" ); fi; gens:= GeneratorsOfGroup( G ); # try to avoid adding an element to a group that already contains it if elm in gens or elm^-1 in gens or elm = One( G ) then return G; fi; # make the closure group C := AffineCrystGroupOnLeftNC( Concatenation( gens, [ elm ] ) ); # if is infinite then so is if HasIsFinite( G ) and not IsFinite( G ) then SetIsFinite( C, false ); SetSize( C, infinity ); fi; return C; end ); ############################################################################# ## #M ConjugateGroup( , ) . . . . . . . . . . . . . . . . ConjugateGroup ## ## InstallMethod( ConjugateGroup, "method for AffineCrystGroupOnRight and element", IsCollsElms, [ IsAffineCrystGroupOnRight, IsMultiplicativeElementWithInverse ], 0, function( G, g ) local gen, H, d, T; if not IsAffineMatrixOnRight( g ) then Error( "g must be an affine matrix action OnRight" ); fi; # if is trivial conjugating is trivial if IsTrivial(G) then return G; fi; # create the domain gen := List( GeneratorsOfGroup( G ), x -> g^-1 * x * g ); H := AffineCrystGroupOnRightNC( gen ); if HasTranslationBasis( G ) then d := DimensionOfMatrixGroup( G ) - 1; T := TranslationBasis( G ); AddTranslationBasis( H, T*g{[1..d]}{[1..d]} ); fi; # maintain useful information UseIsomorphismRelation( G, H ); return H; end ); InstallMethod( ConjugateGroup, "method for AffineCrystGroupOnLeft and element", IsCollsElms, [ IsAffineCrystGroupOnLeft, IsMultiplicativeElementWithInverse ], 0, function( G, g ) local gen, H, d, T; if not IsAffineMatrixOnLeft( g ) then Error( "g must be an affine matrix action OnLeft" ); fi; # if is trivial conjugating is trivial if IsTrivial(G) then return G; fi; # create the domain gen := List( GeneratorsOfGroup( G ), x -> g * x * g^-1 ); H := AffineCrystGroupOnLeftNC( gen ); if HasTranslationBasis( G ) then d := DimensionOfMatrixGroup( G ) - 1; T := TranslationBasis( G ); AddTranslationBasis( H, T*g{[1..d]}{[1..d]} ); fi; # maintain useful information UseIsomorphismRelation( G, H ); return H; end ); ############################################################################# ## #M RightCosets( G, H ) . . . . . . . . . . . . . . . . . . . . . RightCosets ## InstallMethod( RightCosetsNC, "AffineCrystGroupOnRight", true, [ IsAffineCrystGroupOnRight, IsAffineCrystGroupOnRight ], 0, function( G, H ) local orb, pnt, img, gen, rep; # first some simple checks if Length( TranslationBasis(G) ) <> Length( TranslationBasis(H) ) then Error("sorry, there are infinitely many cosets"); fi; orb := [ RightCoset( H, One( H ) ) ]; for pnt in orb do rep := Representative( pnt ); for gen in GeneratorsOfGroup( G ) do img := RightCoset( H, rep*gen ); if not img in orb then Add( orb, img ); fi; od; od; return orb; end ); InstallMethod( RightCosetsNC, "AffineCrystGroupOnLeft", true, [ IsAffineCrystGroupOnLeft, IsAffineCrystGroupOnLeft ], 0, function( G, H ) local orb, pnt, img, gen, rep; # first some simple checks if Length( TranslationBasis(G) ) <> Length( TranslationBasis(H) ) then Error("sorry, there are infinitely many cosets"); fi; orb := [ RightCoset( H, One( H ) ) ]; for pnt in orb do rep := Representative( pnt ); for gen in GeneratorsOfGroup( G ) do img := RightCoset( H, rep*gen ); if not img in orb then Add( orb, img ); fi; od; od; return orb; end ); ############################################################################# ## #M CanonicalRightCosetElement( S, rep ) . . . . . CanonicalRightCosetElement ## InstallMethod( CanonicalRightCosetElement, "for AffineCrystGroupOnRight", IsCollsElms, [ IsAffineCrystGroupOnRight, IsObject ], 0, function( S, rep ) local P, d, m, T, mm, res; P := PointGroup( S ); d := DimensionOfMatrixGroup( P ); m := rep{[1..d]}{[1..d]}; T := ReducedLatticeBasis( TranslationBasis( S )*m ); mm := CanonicalRightCosetElement( P, m ); res := PreImagesRepresentativeNC( PointHomomorphism( S ), mm*m^-1 ) * rep; res := MutableCopyMat( res ); res[d+1]{[1..d]} := VectorModL( res[d+1]{[1..d]}, T ); return res; end ); InstallMethod( CanonicalRightCosetElement, "for AffineCrystGroupOnLeft", IsCollsElms, [ IsAffineCrystGroupOnLeft, IsObject ], 0, function( S, rep ) local P, d, m, T, mm, res; P := PointGroup( S ); d := DimensionOfMatrixGroup( P ); m := rep{[1..d]}{[1..d]}; T := ReducedLatticeBasis( TranslationBasis( S )*m ); mm := CanonicalRightCosetElement( P, m ); res := PreImagesRepresentativeNC( PointHomomorphism( S ), mm*m^-1 ) * rep; res := MutableCopyMat( res ); res{[1..d]}[d+1] := VectorModL( res{[1..d]}[d+1], T ); return res; end ); ############################################################################# ## #M Intersection2( G1, G2 ) . . . . . . . . . intersection of two CrystGroups ## InstallMethod( Intersection2, "two AffineCrystGroupsOnRight", IsIdenticalObj, [ IsAffineCrystGroupOnRight, IsAffineCrystGroupOnRight ], 0, function( G1, G2 ) local d, P1, P2, P, T1, T2, T, L, gen, gen1, gen2, orb, set, rep, stb, pnt, i, img, sch, new, g, g1, g2, t1, t2, s, t, R; # get the intersections of the point groups and the translation groups d := DimensionOfMatrixGroup( G1 ) - 1; P1 := PointGroup(G1); P2 := PointGroup(G2); P := Intersection( P1, P2 ); T1 := TranslationBasis( G1 ); T2 := TranslationBasis( G2 ); T := IntersectionModule( T1, T2 ); L := UnionModule( T1, T2 ); gen := GeneratorsOfGroup( P ); gen1 := List( gen, x -> PreImagesRepresentativeNC( PointHomomorphism( G1 ), x) ); gen2 := List( gen, x -> PreImagesRepresentativeNC( PointHomomorphism( G2 ), x)^-1 ); orb := [ MutableMatrix( One( G1 ) ) ]; set := [ One( G1 ) ]; rep := [ One( P ) ]; stb := TrivialSubgroup( P ); # get the subgroup of P that can be lifted to the intersection for pnt in orb do for i in [1..Length( gen )] do img := gen2[i]*pnt*gen1[i]; img[d+1]{[1..d]} := VectorModL( img[d+1]{[1..d]}, L ); if not img in set then Add( orb, img ); AddSet( set, img ); Add( rep, rep[Position(orb,pnt)]*gen[i] ); else sch := rep[Position(orb,pnt)]*gen[i] / rep[Position(orb,img)]; if not sch in stb then stb := ClosureGroup( stb, sch ); fi; fi; od; od; # determine the lift of stb new := []; for g in GeneratorsOfGroup( stb ) do g1 := PreImagesRepresentativeNC( PointHomomorphism( G1 ), g ); g1 := AffMatMutableTrans( g1 ); if Length(T1) > 0 then g2 := PreImagesRepresentativeNC( PointHomomorphism( G2 ), g ); t1 := g1[d+1]{[1..d]}; t2 := g2[d+1]{[1..d]}; s := IntSolutionMat( Concatenation( T1, -T2 ), t2-t1 ); g1[d+1]{[1..d]} := t1+s{[1..Length(T1)]}*T1; fi; Add( new, g1 ); od; # add the translations for t in T do g1 := IdentityMat( d+1 ); g1[d+1]{[1..d]} := t; Add( new, g1 ); od; R := AffineCrystGroupOnRightNC( new, One( G1 ) ); AddTranslationBasis( R, T ); return R; end ); InstallMethod( Intersection2, "two AffineCrystGroupsOnLeft", IsIdenticalObj, [ IsAffineCrystGroupOnLeft, IsAffineCrystGroupOnLeft ], 0, function( G1, G2 ) local T1, T2, I; T1 := TransposedMatrixGroup( G1 ); T2 := TransposedMatrixGroup( G2 ); I := Intersection2( T1, T2 ); return TransposedMatrixGroup( I ); end ); ############################################################################# ## #M NormalizerPointGroupInGLnZ(

    ) . . . . . . .Normalizer of a PointGroup ## InstallMethod( NormalizerPointGroupInGLnZ, true, [ IsPointGroup ], 0, function( P ) local S, T; S := AffineCrystGroupOfPointGroup( P ); T := InternalBasis( S ); if T <> One(P) then return NormalizerInGLnZ( P^(T^-1) )^T; else return NormalizerInGLnZ( P ); fi; end ); ############################################################################# ## #M CentralizerPointGroupInGLnZ( G ) . . . . . . .Centralizer of a PointGroup ## InstallMethod( CentralizerPointGroupInGLnZ, "via NormalizerPointGroupInGLnZ", true, [ IsPointGroup ], 0, function( G ) return Centralizer( NormalizerPointGroupInGLnZ( G ), G ); end ); ############################################################################# ## #F CentralizerElement ## CentralizerElement := function( G, u, TT ) local d, I, U, L, orb, set, rep, stb, pnt, gen, img, sch, v; d := DimensionOfMatrixGroup( G ) - 1; I := IdentityMat( d ); U := List( TT, t -> t * (u{[1..d]}{[1..d]} - I) ); L := ReducedLatticeBasis( U ); orb := [ MutableMatrix( u ) ]; set := [ u ]; rep := [ MutableMatrix( One( G ) ) ]; stb := TrivialSubgroup( G ); for pnt in orb do for gen in GeneratorsOfGroup( G ) do img := pnt^gen; # reduce image mod L img[d+1]{[1..d]} := VectorModL( img[d+1]{[1..d]}, L ); if not img in set then Add( orb, img ); AddSet( set, img ); Add( rep, rep[Position(orb,pnt)]*gen ); else sch := rep[Position(orb,pnt)]*gen / rep[Position(orb,img)]; # check if a translation conjugate of sch is in stabilizer v := u^sch - u; v := v[d+1]{[1..d]}; if v <> 0 * v then Assert(0, U <> [] ); v := IntSolutionMat( U, v ); Assert( 0, v <> fail ); sch[d+1]{[1..d]} := sch[d+1]{[1..d]} + v*TT; fi; stb := ClosureGroup( stb, sch ); fi; od; od; return stb; end; ############################################################################# ## #F CentralizerAffineCrystGroup( G, obj ) . . centralizer of subgroup/element ## CentralizerAffineCrystGroup := function ( G, obj ) local d, P, T, e, I, M, m, L, i, U, o, gen, Q, C, u; d := DimensionOfMatrixGroup( G ) - 1; P := PointGroup( G ); T := TranslationBasis( G ); e := Length( T ); I := IdentityMat( d ); # we first determine the subgroup of G that centralizes the # point group and the translation group of obj or its span if IsGroup( obj ) then M := PointGroup( obj ); L := List( [1..e], x -> [] ); gen := GeneratorsOfGroup( M ); for i in [ 1..Length( gen ) ] do L{[1..e]}{[1..d]+(i-1)*d} := T*(gen[i]-I); od; P := Centralizer( P, M ); if not IsEmpty( TranslationBasis( obj ) ) then P := Stabilizer( P, TranslationBasis( obj ), OnRight ); fi; U := Filtered( GeneratorsOfGroup(obj), x -> x{[1..d]}{[1..d]} <> I ); else if not IsAffineMatrixOnRight( obj ) then Error( "obj must be an affine matrix acting OnRight" ); fi; M := obj{[1..d]}{[1..d]}; L := T*(M - I); P := Centralizer( P, M ); o := Order( M ); m := obj^o; P := Stabilizer( P, m[d+1]{[1..d]} ); if o > 1 then U := [ obj ]; else U := []; fi; fi; gen := List( GeneratorsOfGroup( P ), x -> PreImagesRepresentativeNC( PointHomomorphism( G ), x ) ); # if G is finite if e = 0 then return SubgroupNC( G, gen ); fi; # we keep only translation generators which centralize obj Q := IdentityMat( e ); if L <> [] then L := RowEchelonFormT( L, Q ); fi; for i in [ Length( L )+1..e ] do Add( gen, AugmentedMatrix( I, Q[i]*T ) ); od; # C centralizes the point group and the translation group of obj C := SubgroupNC( G, gen ); # now find the centralizer for each u in U for u in U do C := CentralizerElement( C, u, T ); T := TranslationBasis( C ); od; return C; end; ############################################################################# ## #M Centralizer( G, obj ) . . . . . . . . . . centralizer of subgroup/element ## InstallMethod( CentralizerOp, "AffineCrystGroupOnRight and element", IsCollsElms, [ IsAffineCrystGroupOnRight, IsMatrix ], 0, function( G, m ) if not IsAffineMatrixOnRight( m ) then Error( "m must be an affine matrix acting OnRight" ); fi; return CentralizerAffineCrystGroup( G, m ); end ); InstallMethod( CentralizerOp, "AffineCrystGroupOnLeft and element", IsCollsElms, [ IsAffineCrystGroupOnLeft, IsMatrix ], 0, function( G, m ) local T, C; if not IsAffineMatrixOnLeft( m ) then Error( "m must be an affine matrix acting OnLeft" ); fi; T := TransposedMatrixGroup( G ); C := CentralizerAffineCrystGroup( T, TransposedMat( m ) ); return TransposedMatrixGroup( C ); end ); InstallMethod( CentralizerOp, "two AffineCrystGroupsOnRight", IsIdenticalObj, [ IsAffineCrystGroupOnRight, IsAffineCrystGroupOnRight ], 0, function( G1, G2 ) return CentralizerAffineCrystGroup( G1, G2 ); end ); InstallMethod( CentralizerOp, "two AffineCrystGroupsOnLeft", IsIdenticalObj, [ IsAffineCrystGroupOnLeft, IsAffineCrystGroupOnLeft ], 0, function( G1, G2 ) local G, U, C; G := TransposedMatrixGroup( G1 ); U := TransposedMatrixGroup( G2 ); C := CentralizerAffineCrystGroup( G, U ); return TransposedMatrixGroup( C ); end ); ############################################################################# ## #M TranslationNormalizer( S ) . . . . . . . . . . . . translation normalizer ## InstallMethod( TranslationNormalizer, "for SpaceGroup acting OnRight", true, [ IsAffineCrystGroupOnRight and IsSpaceGroup ], 0, function( S ) local P, T, d, N, M, I, Pgens, B, invB, g, i, Q, L, K, k, l, j, gen; P := PointGroup( S ); T := TranslationBasis( S ); d := DimensionOfMatrixGroup( S ) - 1; if Size( P ) = 1 then N := GroupByGenerators( [], IdentityMat( d+1 ) ); N!.continuousTranslations := IdentityMat( d ); return N; fi; M := List( [1..d], i->[] ); i := 0; I := IdentityMat( d ); Pgens := GeneratorsOfGroup( P ); if not IsStandardAffineCrystGroup( S ) then B := InternalBasis( S ); invB := B^-1; Pgens := List( Pgens, x -> B * x * invB ); fi; for g in Pgens do g := g - I; M{[1..d]}{[1..d]+i*d} := g; i := i+1; od; # first diagonalize M Q := IdentityMat( Length(M) ); M := TransposedMat(M); M := RowEchelonForm( M ); while Length(M) > 0 and not IsDiagonalMat(M) do M := TransposedMat(M); M := RowEchelonFormT(M,Q); if not IsDiagonalMat(M) then M := TransposedMat(M); M := RowEchelonForm(M); fi; od; # and then determine the solutions of x*M=0 mod Z if Length(M)>0 then L := List( [1..Length(M)], i -> [ 0 .. M[i][i]-1 ] / M[i][i] ); L := List( Cartesian( L ), l -> l * Q{[1..Length(M)]} ); else L := NullMat( 1, Length(Q) ); fi; # get the kernel if Length(M) < Length(Q) then K := Q{[Length(M)+1..Length(Q)]}; TriangulizeMat( K ); else K := []; fi; # reduce to basis modulo kernel Append( L, IdentityMat( d ) ); for k in K do j := PositionProperty( k, x -> x=1 ); for l in L do l := l-l[j]*k; od; od; L := ReducedLatticeBasis( L ); # conjugate if not standard if not IsStandardAffineCrystGroup( S ) then L := L*T; fi; # get generators gen := List( L, x -> IdentityMat( d+1 ) ); for i in [1..Length(L)] do gen[i][d+1]{[1..d]} := L[i]; od; N := GroupByGenerators( gen, IdentityMat( d+1 ) ); N!.continuousTranslations := K; return N; end ); InstallMethod( TranslationNormalizer, "for SpaceGroup acting OnLeft", true, [ IsAffineCrystGroupOnLeft and IsSpaceGroup ], 0, function( S ) local N1, gen, N; N1 := TranslationNormalizer( TransposedMatrixGroup( S ) ); gen := List( GeneratorsOfGroup( N1 ), TransposedMat ); N := GroupByGenerators( gen, One( N1 ) ); N!.continuousTranslations := N1!.continuousTranslations; return N; end ); RedispatchOnCondition( TranslationNormalizer, true, [IsAffineCrystGroupOnRight], [IsAffineCrystGroupOnRight and IsSpaceGroup], 0); RedispatchOnCondition( TranslationNormalizer, true, [IsAffineCrystGroupOnLeft], [IsAffineCrystGroupOnLeft and IsSpaceGroup], 0); ############################################################################# ## #F AffineLift( pnt, d ) ## AffineLift := function( pnt, d ) local M, b, i, I, p, m, Q, j, s; M := List( [1..d], i->[] ); b := []; i := 0; I := IdentityMat( d ); for p in pnt do m := p[1]{[1..d]}{[1..d]} - I; M{[1..d]}{[1..d]+i*d} := m; Append( b, p[2] - p[1][d+1]{[1..d]} ); i := i+1; od; Q := IdentityMat( d ); M := TransposedMat(M); M := RowEchelonFormVector( M,b ); while Length(M) > 0 and not IsDiagonalMat(M) do M := TransposedMat(M); M := RowEchelonFormT(M,Q); if not IsDiagonalMat(M) then M := TransposedMat(M); M := RowEchelonFormVector(M,b); fi; od; ## Check if we have any solutions modulo Z. for j in [Length(M)+1..Length(b)] do if not IsInt( b[j] ) then return []; fi; od; s := List( [1..Length(M)], i -> b[i]/M[i][i] ); for i in [Length(M)+1..d] do Add( s, 0); od; return s*Q; end; ############################################################################# ## #M AffineNormalizer( S ) . . . . . . . . . . . . . . . . . affine normalizer ## InstallMethod( AffineNormalizer, "for SpaceGroup acting OnRight", true, [ IsAffineCrystGroupOnRight and IsSpaceGroup ], 0, function( S ) local d, P, H, T, N, Pgens, Sgens, invT, gens, Pi, Si, hom, opr, orb, g, m, set, rep, lst, pnt, img, t, sch, n, nn, normgens, TN, AN; d := DimensionOfMatrixGroup( S ) - 1; P := PointGroup( S ); H := PointHomomorphism( S ); T := TranslationBasis( S ); N := NormalizerPointGroupInGLnZ( P ); Pgens := GeneratorsOfGroup( P ); Sgens := List( Pgens, x -> PreImagesRepresentativeNC( H, x ) ); # we work in a standard representation if not IsStandardAffineCrystGroup( S ) then invT := T^-1; gens := List( GeneratorsOfGroup( N ), x -> T * x * invT ); Pgens := List( Pgens, x -> T * x * invT ); Sgens := List( Sgens, x -> S!.lconj * x * S!.rconj ); else gens := GeneratorsOfGroup( N ); fi; Pi := Group( Pgens, One( P ) ); Si := Group( Sgens, One( S ) ); hom := GroupHomomorphismByImagesNC( Si, Pi, Sgens, Pgens ); # the operation we shall need in the stabilizer algorithm opr := function( data, g ) local m, mm, res; m := data[1]{[1..d]}{[1..d]}; mm := m^g; if m = mm then res := [ data[1], List( data[2]*g, FractionModOne ) ]; else m := AffMatMutableTrans( PreImagesRepresentativeNC( hom, mm ) ); m[d+1]{[1..d]} := List( m[d+1]{[1..d]}, FractionModOne ); res := [ m, List( data[2]*g, FractionModOne ) ]; fi; return res; end; orb := []; for g in Sgens do m := AffMatMutableTrans( g ); m[d+1]{[1..d]} := List( m[d+1]{[1..d]}, FractionModOne ); Add( orb, [ m, m[d+1]{[1..d]} ] ); od; orb := [ orb ]; set := ShallowCopy( orb ); rep := [ One( N ) ]; lst := []; for pnt in orb do for g in gens do img := List( pnt, x -> opr( x, g ) ); if not img in set then Add( orb, img ); AddSet( set, img ); Add( rep, rep[Position(orb,pnt)]*g ); else t := AffineLift( img, d ); if t<>[] then sch := rep[Position(orb,pnt)]*g; n := IdentityMat( d+1 ); n{[1..d]}{[1..d]} := sch; n[d+1]{[1..d]} := t; AddSet( lst, n ); fi; fi; od; od; if IsFinite( N ) then nn := Subgroup( N, [] ); normgens := []; for g in lst do m := g{[1..d]}{[1..d]}; if not m in nn then Add( normgens, g ); nn := ClosureGroup( nn, m ); fi; od; else normgens := lst; fi; m := IdentityMat( d+1 ); m{[1..d]}{[1..d]} := T; if not IsStandardAffineCrystGroup( S ) then normgens := List( normgens, x -> x^m ); fi; TN := TranslationNormalizer( S ); Append( normgens, GeneratorsOfGroup( TN ) ); AN := Group( normgens, One( S ) ); AN!.continuousTranslations := TN!.continuousTranslations; # can AN be made an AffineCrystGroup? if IsFinite( N ) and AN!.continuousTranslations = [] then SetIsAffineCrystGroupOnRight( AN, true ); lst := List( GeneratorsOfGroup( TN ), x -> x[d+1]{[1..d]} ); lst := ReducedLatticeBasis( lst ); AddTranslationBasis( AN, lst ); fi; return AN; end ); InstallMethod( AffineNormalizer, "for SpaceGroup acting OnLeft", true, [ IsAffineCrystGroupOnLeft and IsSpaceGroup ], 0, function( S ) local A1, A, gen; A1 := AffineNormalizer( TransposedMatrixGroup( S ) ); if IsAffineCrystGroupOnRight( A1 ) then A := TransposedMatrixGroup( A1 ); else gen := List( GeneratorsOfGroup( A1 ), TransposedMat ); A := Group( gen, One( A1 ) ); fi; A!.continuousTranslations := A1!.continuousTranslations; return A; end ); RedispatchOnCondition( AffineNormalizer, true, [IsAffineCrystGroupOnRight], [IsAffineCrystGroupOnRight and IsSpaceGroup], 0); RedispatchOnCondition( AffineNormalizer, true, [IsAffineCrystGroupOnLeft], [IsAffineCrystGroupOnLeft and IsSpaceGroup], 0); ############################################################################# ## #M AffineInequivalentSubgroups( S, subs ) . . reps of affine ineq. subgroups ## InstallGlobalFunction( AffineInequivalentSubgroups, function( S, subs ) local C, A, opr, reps, orb, grp, gen, img; if subs = [] then return subs; fi; C := ShallowCopy( subs ); A := AffineNormalizer( S ); if A!.continuousTranslations <> [] then return fail; fi; reps := []; while C <> [] do if not IsSubgroup( S, C[1] ) then Error( "subs must be a list of subgroups of S" ); fi; orb := [ C[1] ]; for grp in orb do for gen in GeneratorsOfGroup( A ) do img := List( GeneratorsOfGroup( grp ), x -> x^gen ); if not ForAny( orb, g -> ForAll( img, x -> x in g ) ) then Add( orb, ConjugateGroup( grp, gen ) ); fi; od; od; Add( reps, orb[1] ); C := Filtered( C, x -> not x in orb ); od; return reps; end ); cryst/gap/zass.gi0000644001325400021140000003302314372461414013445 0ustar gaehleruser############################################################################# ## #A zass.gi Cryst library Bettina Eick #A Franz G"ahler #A Werner Nickel ## #Y Copyright 1997-1999 by Bettina Eick, Franz G"ahler and Werner Nickel ## ## Routines for the determination of space groups for a given a point group ## ############################################################################# ## #F NullBlockMat( , , ). . . . . . d1xd2-matrix of d-NullMatrices ## NullBlockMat := function( d, d1, d2 ) # return d1 x d2 matrix, whose entries are d x d NullMatrices return List( [1..d1], i -> List( [1..d2], j -> NullMat( d, d ) ) ); end; ############################################################################# ## #F FlattenedBlockMat( < BlockMat > ). . . . . . . . . flattened block matrix ## FlattenedBlockMat := function( mat ) # flatten a matrix whose entries are matrices to a normal matrix local m; m := mat; m := List( [1..Length(m[1])], j -> Concatenation( List([1..Length(m)], i -> m[i][j] ) ) ); m := TransposedMat( Concatenation( List( [1..Length(m)], i -> TransposedMat(m[i]) ) ) ); return m; end; ############################################################################# ## #F MakeSpaceGroup( , , , ) construct space group ## MakeSpaceGroup := function( d, Pgens, transl, transp ) # construct space group from point group and translation vector local Sgens, i, m, S; # first the non-translational generators Sgens := List( [1..Length( Pgens )], i -> AugmentedMatrix( Pgens[i], transl{[(i-1)*d+1..i*d]} ) ); # the pure translation generators for i in [1..d] do m := IdentityMat( d+1 ); m[d+1][i] := 1; Add( Sgens, m ); od; # make the space group and return it if transp then Sgens := List( Sgens, TransposedMat ); S := AffineCrystGroupOnLeftNC( Sgens, IdentityMat(d+1) ); else S := AffineCrystGroupOnRightNC( Sgens, IdentityMat(d+1) ); fi; AddTranslationBasis( S, IdentityMat( d ) ); return S; end; ############################################################################# ## #F GroupExtEquations( , , ) . equations for group extensions ## GroupExtEquations := function( d, gens, rels ) # construct equations which determine the non-primitive translations local mat, i, j, k, r, r0, max, prod; mat := NullBlockMat( d, Length(gens), Length(rels) ); for i in [1..Length(rels)] do # interface to GAP-3 format r0 := rels[i]; r := []; for k in [1..Length(r0)/2] do max := r0[2*k]; if max > 0 then for j in [1..max] do Add( r, r0[2*k-1] ); od; else for j in [1..-max] do Add( r, -r0[2*k-1] ); od; fi; od; prod := IdentityMat(d); for j in Reversed([1..Length(r)]) do if r[j]>0 then mat[ r[j] ][i] := mat[ r[j] ][i]+prod; prod := gens[ r[j] ]*prod; else prod := gens[-r[j] ]^-1*prod; mat[-r[j] ][i] := mat[-r[j] ][i]-prod; fi; od; od; return FlattenedBlockMat( mat ); end; ############################################################################# ## #F StandardTranslation( , ) . .reduce to std. translation ## StandardTranslation := function( L, NN ) # reduce non-primitive translations to "standard" form local N, j, k; # first apply "continuous" translations for N in NN[1] do j := PositionProperty( N, x -> x=1 ); L := L-L[j]*N; od; L := List( L, FractionModOne ); # and then "discrete" translations for N in NN[2] do j := PositionProperty( N, x -> x<>0 ); k := Int( L[j] / N[j] ); if k > 0 then L := List( L-k*N, FractionModOne ); fi; od; return L; end; ############################################################################# ## #F SolveHomEquationsModZ( ) . . . . . . . . . . . solve x*mat=0 mod Z ## SolveHomEquationsModZ := function( M ) local Q, L, N, N2; Q := IdentityMat( Length(M) ); # first diagonalize M M := TransposedMat(M); M := RowEchelonForm( M ); while Length(M) > 0 and not IsDiagonalMat(M) do M := TransposedMat(M); M := RowEchelonFormT(M,Q); if not IsDiagonalMat(M) then M := TransposedMat(M); M := RowEchelonForm(M); fi; od; # and then determine the solutions of x*M=0 mod Z if Length(M)>0 then L := List( [1..Length(M)], i -> [ 0 .. M[i][i]-1 ] / M[i][i] ); L := List( Cartesian( L ), l -> l * Q{[1..Length(M)]} ); else L := NullMat( 1, Length(Q) ); fi; # we later need the space in which one can freely shift # non-primitive translations; first the translations which # can be applied with rational coefficients if Length(M)[] then N2 := List( N, n -> List( n, FractionModOne ) ); N2 := ReducedLatticeBasis( N2 ); N2 := List( N2, n -> List( n, FractionModOne ) ); N2 := Filtered( N2, n -> n<>0*N[1] ); else N2 := []; fi; # reduce non-primitive translations to standard form L := Set( List( L, x -> StandardTranslation( x, [ N, N2 ] ) ) ); return [ L, [ N, N2 ] ]; end; ############################################################################# ## #F CollectEquivExtensions( , , , ) . . . . . . #F . . . . collect extensions equivalent by conjugation with elems from norm ## CollectEquivExtensions := function( ll, nn, norm, grp ) # check for conjugacy with generators of the normalizer of grp in GL(n,Z) local cent, d, gens, sgens, res, orb, x, y, c, n, i, j, sg, h, m; norm := Set( Filtered( norm, x -> not x in grp ) ); cent := Filtered( norm, x -> ForAll( GeneratorsOfGroup( grp ), g -> x*g=g*x ) ); SubtractSet( norm, cent ); d := DimensionOfMatrixGroup( grp ); gens := GeneratorsOfGroup( grp ); sgens := List( gens, g -> AugmentedMatrix( g, List( [1..d], x -> 0 ) ) ); res := [ ]; while ll<>[] do orb := [ ll[1] ]; for x in orb do # first the generators which are in the centralizer for c in cent do y := List([1..Length(gens)], i -> x{ [(i-1)*d+1..i*d] }*c ); y := StandardTranslation( Concatenation(y), nn ); if not y in orb then Add( orb, y ); fi; od; # then the remaining ones; this is more complicated for n in norm do for i in [1..Length(gens)] do for j in [1..d] do sgens[i][d+1][j]:=x[(i-1)*d+j]; od; od; sg := Group( sgens, IdentityMat( d+1 ) ); SetIsFinite( sg, false ); h :=GroupHomomorphismByImagesNC( sg, grp, sgens, gens ); y :=[]; for i in [1..Length(gens)] do m := PreImagesRepresentativeNC( h, n*gens[i]*n^-1 ); Append( y, m[d+1]{[1..d]}*n ); od; y := StandardTranslation( y, nn ); if not y in orb then Add( orb, y ); fi; od; od; Add( res, orb ); SubtractSet( ll, orb ); od; return res; end; ############################################################################# ## #F ZassFunc( , , , ) . Zassenhaus algorithm ## ZassFunc := function( grp, norm, orbsflag, transpose ) local d, S, N, F, Fam, rels, gens, mat, ext, lst, res; d := DimensionOfMatrixGroup( grp ); if transpose then grp := TransposedMatrixGroup( grp ); norm := List( norm, TransposedMat ); fi; if not IsIntegerMatrixGroup( grp ) then Error( "the point group must be an integer matrix group" ); fi; if not IsFinite( grp ) then Error("the point group must be finite" ); fi; # catch the trivial case if IsTrivial( grp ) then S := MakeSpaceGroup( d, [], [], transpose ); if orbsflag then return [[S]]; else return [ S ]; fi; fi; # first get group relators for grp N := NiceObject( grp ); F := Image( IsomorphismFpGroupByGenerators( N, GeneratorsOfGroup( N ) ) ); rels := List( RelatorsOfFpGroup( F ), ExtRepOfObj ); gens := GeneratorsOfGroup( grp ); # construct equations which determine the non-primitive translations # an alternative would be # mat := MatJacobianMatrix( F, gens ); mat := GroupExtEquations( d, gens, rels ); # now solve them modulo integers ext := SolveHomEquationsModZ( mat ); # collect group extensions which are equivalent as space groups lst := CollectEquivExtensions( ext[1], ext[2], norm, grp ); # make the space groups if orbsflag then res := List( lst, x -> List( x, y -> MakeSpaceGroup( d, gens, y, transpose ) ) ); else res := List( lst, x -> MakeSpaceGroup( d, gens, x[1], transpose ) ); fi; return res; end; ############################################################################# ## #M SpaceGroupsByPointGroupOnRight( [, [, ] ] ) ## InstallMethod( SpaceGroupsByPointGroupOnRight, true, [ IsCyclotomicMatrixGroup ], 0, function( grp ) return ZassFunc( grp, [], false, false ); end ); InstallOtherMethod( SpaceGroupsByPointGroupOnRight, IsIdenticalObj, [ IsCyclotomicMatrixGroup, IsList ], 0, function( grp, norm ) return ZassFunc( grp, norm, false, false ); end ); InstallOtherMethod( SpaceGroupsByPointGroupOnRight, function(a,b,c) return IsIdenticalObj(a,b); end, [ IsCyclotomicMatrixGroup, IsList, IsBool ], 0, function( grp, norm, orbsflag ) return ZassFunc( grp, norm, orbsflag, false ); end ); ############################################################################# ## #M SpaceGroupsByPointGroupOnLeft( [, , [ ] ] ) ## InstallMethod( SpaceGroupsByPointGroupOnLeft, true, [ IsCyclotomicMatrixGroup ], 0, function( grp ) return ZassFunc( grp, [], false, true ); end ); InstallOtherMethod( SpaceGroupsByPointGroupOnLeft, IsIdenticalObj, [ IsCyclotomicMatrixGroup, IsList ], 0, function( grp, norm ) return ZassFunc( grp, norm, false, true ); end ); InstallOtherMethod( SpaceGroupsByPointGroupOnLeft, function(a,b,c) return IsIdenticalObj(a,b); end, [ IsCyclotomicMatrixGroup, IsList, IsBool ], 0, function( grp, norm, orbsflag ) return ZassFunc( grp, norm, orbsflag, true ); end ); ############################################################################# ## #M SpaceGroupsByPointGroup( [, [, ] ] ) ## InstallMethod( SpaceGroupsByPointGroup, true, [ IsCyclotomicMatrixGroup ], 0, function( grp ) return ZassFunc( grp, [], false, CrystGroupDefaultAction=LeftAction ); end ); InstallOtherMethod( SpaceGroupsByPointGroup, IsIdenticalObj, [ IsCyclotomicMatrixGroup, IsList ], 0, function( grp, norm ) return ZassFunc( grp, norm, false, CrystGroupDefaultAction=LeftAction ); end ); InstallOtherMethod( SpaceGroupsByPointGroup, function(a,b,c) return IsIdenticalObj(a,b); end, [ IsCyclotomicMatrixGroup, IsList, IsBool ], 0, function( grp, norm, orbsflag ) return ZassFunc( grp, norm, orbsflag, CrystGroupDefaultAction=LeftAction ); end ); ############################################################################# ## #M SpaceGroupTypesByPointGroupOnRight( [, ] ) ## InstallMethod( SpaceGroupTypesByPointGroupOnRight, true, [ IsCyclotomicMatrixGroup ], 0, function( grp ) local norm; norm := GeneratorsOfGroup( NormalizerInGLnZ( grp ) ); return ZassFunc( grp, norm, false, false ); end ); InstallOtherMethod( SpaceGroupTypesByPointGroupOnRight, true, [ IsCyclotomicMatrixGroup, IsBool ], 0, function( grp, orbsflag ) local norm; norm := GeneratorsOfGroup( NormalizerInGLnZ( grp ) ); return ZassFunc( grp, norm, orbsflag, false ); end ); ############################################################################# ## #M SpaceGroupTypesByPointGroupOnLeft( [, ] ) ## InstallMethod( SpaceGroupTypesByPointGroupOnLeft, true, [ IsCyclotomicMatrixGroup ], 0, function( grp ) local norm; norm := GeneratorsOfGroup( NormalizerInGLnZ( grp ) ); return ZassFunc( grp, norm, false, true ); end ); InstallOtherMethod( SpaceGroupTypesByPointGroupOnLeft, true, [ IsCyclotomicMatrixGroup, IsBool ], 0, function( grp, orbsflag ) local norm; norm := GeneratorsOfGroup( NormalizerInGLnZ( grp ) ); return ZassFunc( grp, norm, orbsflag, true ); end ); ############################################################################# ## #M SpaceGroupTypesByPointGroup( [, ] ) ## InstallMethod( SpaceGroupTypesByPointGroup, true, [ IsCyclotomicMatrixGroup ], 0, function( grp ) local norm; norm := GeneratorsOfGroup( NormalizerInGLnZ( grp ) ); return ZassFunc( grp, norm, false, CrystGroupDefaultAction=LeftAction ); end ); InstallOtherMethod( SpaceGroupTypesByPointGroup, true, [ IsCyclotomicMatrixGroup, IsBool ], 0, function( grp, orbsflag ) local norm; norm := GeneratorsOfGroup( NormalizerInGLnZ( grp ) ); return ZassFunc( grp, norm, orbsflag, CrystGroupDefaultAction=LeftAction ); end ); cryst/gap/wyckoff.gd0000644001325400021140000000750513232361435014132 0ustar gaehleruser############################################################################# ## #A wyckoff.gd Cryst library Bettina Eick #A Franz G"ahler #A Werner Nickel ## #Y Copyright 1997-1999 by Bettina Eick, Franz G"ahler and Werner Nickel ## ############################################################################# ## #R IsWyckoffPosition . . . . . . . . . . . . . . . . . . . IsWyckoffPosition ## DeclareRepresentation( "IsWyckoffPosition", IsComponentObjectRep and IsAttributeStoringRep, [ "basis", "translation", "spaceGroup", "class" ] ); ############################################################################# ## #F WyckoffPositionObject . . . . . . . . . . .make a Wyckoff position object ## DeclareGlobalFunction( "WyckoffPositionObject" ); ############################################################################# ## #F WyckoffSpaceGroup . . . . . . . . . . . . .space group of WyckoffPosition ## DeclareOperation( "WyckoffSpaceGroup", [ IsWyckoffPosition ] ); ############################################################################# ## #F WyckoffTranslation . . . . . . . . . .translation of representative space ## DeclareOperation( "WyckoffTranslation", [ IsWyckoffPosition ] ); ############################################################################# ## #F WyckoffBasis . . . . . . . . . . . . . . . .basis of representative space ## DeclareOperation( "WyckoffBasis", [ IsWyckoffPosition ] ); ############################################################################# ## #F ReduceAffineSubspaceLattice . . . . reduce affine subspace modulo lattice ## DeclareGlobalFunction( "ReduceAffineSubspaceLattice" ); ############################################################################# ## #F ImageAffineSubspaceLattice . . . .image of affine subspace modulo lattice ## DeclareGlobalFunction( "ImageAffineSubspaceLattice" ); ############################################################################# ## #F ImageAffineSubspaceLatticePointwise . . . . . . image of pointwise affine #F subspace modulo lattice ## DeclareGlobalFunction( "ImageAffineSubspaceLatticePointwise" ); ############################################################################# ## #A WyckoffStabilizer . . . . . . . . . stabilizer of representative subspace ## DeclareAttribute( "WyckoffStabilizer", IsWyckoffPosition ); ############################################################################# ## #F WyckoffOrbit . . . . . . . . . . . . orbit of pointwise subspace lattices ## DeclareAttribute( "WyckoffOrbit", IsWyckoffPosition ); ############################################################################# ## #A WyckoffPositions( ) . . . . . . . . . . . . . . . . Wyckoff positions ## DeclareAttribute( "WyckoffPositions", IsAffineCrystGroupOnLeftOrRight ); ############################################################################# ## #F WyckoffPositionsByStabilizer( S, stabs ) . . Wyckoff pos. for given stabs ## DeclareGlobalFunction( "WyckoffPositionsByStabilizer" ); ############################################################################# ## #F IsWyckoffGraph( G ) . . . . . . . . . . . . . . . . . . . .IsWyckoffGraph ## DeclareFilter( "IsWyckoffGraph" ); ############################################################################# ## #F WyckoffGraphFun( W, def ) . . . . . . . . . . . . display a Wyckoff graph ## DeclareGlobalFunction( "WyckoffGraphFun" ); ############################################################################# ## #O WyckoffGraph( S, def ) . . . . . . . . . . . . . .display a Wyckoff graph ## DeclareOperation( "WyckoffGraph", [ IsAffineCrystGroupOnLeftOrRight, IsRecord ] ); cryst/gap/wyckoff.gi0000644001325400021140000005545214540072334014143 0ustar gaehleruser############################################################################# ## #A wyckoff.gi Cryst library Bettina Eick #A Franz G"ahler #A Werner Nickel ## #Y Copyright 1997-2012 by Bettina Eick, Franz G"ahler and Werner Nickel ## ## Routines for the determination of Wyckoff positions ## ############################################################################# ## #M WyckoffPositionObject . . . . . . . . . . .make a Wyckoff position object ## InstallGlobalFunction( WyckoffPositionObject, function( w ) return Objectify( NewType( FamilyObj( w ), IsWyckoffPosition ), w ); end ); ############################################################################# ## #M PrintObj . . . . . . . . . . . . . . . . . . . . . Print Wyckoff position ## InstallMethod( PrintObj, "Wyckoff position", true, [ IsWyckoffPosition ], 0, function( w ) Print( "< Wyckoff position, point group ", w!.class, ", translation := ", w!.translation, ", \nbasis := ", w!.basis, " >\n" ); end ); ############################################################################# ## #M ViewObj . . . . . . . . . . . . . . . . . . . . . View a Wyckoff position ## InstallMethod( ViewObj, "Wyckoff position", true, [ IsWyckoffPosition ], 0, function( w ) Print( "< Wyckoff position, point group ", w!.class, ", translation := ", w!.translation, ", \nbasis := ", w!.basis, " >\n" ); end ); ############################################################################# ## #M WyckoffSpaceGroup . . . . . . . . . . . . .space group of WyckoffPosition ## InstallMethod( WyckoffSpaceGroup, true, [ IsWyckoffPosition ], 0, w -> w!.spaceGroup ); ############################################################################# ## #M WyckoffTranslation . . . . . . . . . .translation of representative space ## InstallMethod( WyckoffTranslation, true, [ IsWyckoffPosition ], 0, w -> w!.translation ); ############################################################################# ## #M WyckoffBasis . . . . . . . . . . . . . . . .basis of representative space ## InstallMethod( WyckoffBasis, true, [ IsWyckoffPosition ], 0, w -> w!.basis ); ############################################################################# ## #M ReduceAffineSubspaceLattice . . . . reduce affine subspace modulo lattice ## InstallGlobalFunction( ReduceAffineSubspaceLattice, function( r ) local rk, d, T, Ti, M, R, Q, Qi, P, v, j; r.basis := ReducedLatticeBasis( r.basis ); rk := Length( r.basis ); d := Length( r.translation ); T := TranslationBasis( r.spaceGroup ); Ti := T^-1; if rk = d then v := 0 * r.translation; elif rk > 0 then M := r.basis; v := r.translation; if not IsStandardAffineCrystGroup( r.spaceGroup ) then M := M * Ti; v := v * Ti; fi; # these three lines are faster than the other four Q := IdentityMat(d); RowEchelonFormT(TransposedMat(M),Q); Q := TransposedMat(Q); # R := NormalFormIntMat( TransposedMat( M ), 4 ); # Q := TransposedMat( R.rowtrans ); # R := NormalFormIntMat( M, 9 ); # Q := R.coltrans; Qi := Q^-1; P := Q{[1..d]}{[rk+1..d]} * Qi{[rk+1..d]}; v := List( v * P, FractionModOne ); if not IsStandardAffineCrystGroup( r.spaceGroup ) then v := v * T; fi; v := VectorModL( v, T ); else v := VectorModL( r.translation, T ); fi; r.translation := v; end ); ############################################################################# ## #F ImageAffineSubspaceLattice . . . .image of affine subspace modulo lattice ## InstallGlobalFunction( ImageAffineSubspaceLattice, function( s, g ) local d, m, t, b, r; d := Length( s.translation ); m := g{[1..d]}{[1..d]}; t := g[d+1]{[1..d]}; b := s.basis; if not IsEmpty(b) then b := b * m; fi; r := rec( translation := s.translation * m + t, basis := b, spaceGroup := s.spaceGroup ); ReduceAffineSubspaceLattice( r ); return r; end ); ############################################################################# ## #F ImageAffineSubspaceLatticePointwise . . . . . . image of pointwise affine #F subspace modulo lattice ## InstallGlobalFunction( ImageAffineSubspaceLatticePointwise, function( s, g ) local d, m, t, b, L, r; d := Length( s.translation ); m := g{[1..d]}{[1..d]}; t := g[d+1]{[1..d]}; b := s.basis; if not IsEmpty(b) then b := b * m; fi; L := TranslationBasis( s.spaceGroup ); r := rec( translation := VectorModL( s.translation * m + t, L ), basis := b, spaceGroup := s.spaceGroup ); return r; end ); ############################################################################# ## #M \= . . . . . . . . . . . . . . . . . . . . . . .for two Wyckoff positions ## InstallMethod( \=, IsIdenticalObj, [ IsWyckoffPosition, IsWyckoffPosition ], 0, function( w1, w2 ) local S, r1, r2, d, gens, U, rep; S := WyckoffSpaceGroup( w1 ); if S <> WyckoffSpaceGroup( w2 ) then return false; fi; r1 := rec( translation := WyckoffTranslation( w1 ), basis := WyckoffBasis( w1 ), spaceGroup := WyckoffSpaceGroup( w1 ) ); r2 := rec( translation := WyckoffTranslation( w2 ), basis := WyckoffBasis( w2 ), spaceGroup := WyckoffSpaceGroup( w2 ) ); r1 := ImageAffineSubspaceLattice( r1, One(S) ); r2 := ImageAffineSubspaceLattice( r2, One(S) ); d := DimensionOfMatrixGroup( S ) - 1; gens := Filtered( GeneratorsOfGroup( S ), x -> x{[1..d]}{[1..d]} <> One( PointGroup( S ) ) ); U := SubgroupNC( S, gens ); if IsAffineCrystGroupOnLeft( U ) then U := TransposedMatrixGroup( U ); fi; rep := RepresentativeAction( U, r1, r2, ImageAffineSubspaceLattice ); return rep <> fail; end ); ############################################################################# ## #M \< . . . . . . . . . . . . . . . . . . . . . . .for two Wyckoff positions ## InstallMethod( \<, IsIdenticalObj, [ IsWyckoffPosition, IsWyckoffPosition ], 0, function( w1, w2 ) local S, r1, r2, d, gens, U, o1, o2; S := WyckoffSpaceGroup( w1 ); if S <> WyckoffSpaceGroup( w2 ) then return S < WyckoffSpaceGroup( w2 ); fi; r1 := rec( translation := WyckoffTranslation( w1 ), basis := WyckoffBasis( w1 ), spaceGroup := WyckoffSpaceGroup( w1 ) ); r2 := rec( translation := WyckoffTranslation( w2 ), basis := WyckoffBasis( w2 ), spaceGroup := WyckoffSpaceGroup( w2 ) ); r1 := ImageAffineSubspaceLattice( r1, One(S) ); r2 := ImageAffineSubspaceLattice( r2, One(S) ); d := DimensionOfMatrixGroup( S ) - 1; gens := Filtered( GeneratorsOfGroup( S ), x -> x{[1..d]}{[1..d]} <> One( PointGroup( S ) ) ); U := SubgroupNC( S, gens ); if IsAffineCrystGroupOnLeft( U ) then U := TransposedMatrixGroup( U ); fi; o1 := Orbit( U, r1, ImageAffineSubspaceLattice ); o2 := Orbit( U, r2, ImageAffineSubspaceLattice ); o1 := Set( List( o1, x -> rec( t := x.translation, b := x.basis ) ) ); o2 := Set( List( o2, x -> rec( t := x.translation, b := x.basis ) ) ); return o1[1] < o2[1]; end ); ############################################################################# ## #M WyckoffStabilizer . . . . . . . . . . .stabilizer of representative space ## InstallMethod( WyckoffStabilizer, true, [ IsWyckoffPosition ], 0, function( w ) local S, t, B, d, I, gen, U, r, new, n, g, v; S := WyckoffSpaceGroup( w ); t := WyckoffTranslation( w ); B := WyckoffBasis( w ); d := Length( t ); I := IdentityMat( d ); gen := GeneratorsOfGroup( S ); gen := Filtered( gen, g -> g{[1..d]}{[1..d]} <> I ); if IsAffineCrystGroupOnLeft( S ) then gen := List( gen, TransposedMat ); fi; U := AffineCrystGroupOnRight( gen, One( S ) ); r := rec( translation := t, basis := B, spaceGroup := S ); U := Stabilizer( U, r, ImageAffineSubspaceLatticePointwise ); t := ShallowCopy( t ); Add( t, 1 ); gen := GeneratorsOfGroup( U ); new := []; for g in gen do v := t * g - t; n := List( g, ShallowCopy ); n[d+1] := g[d+1] - v; if n <> One( S ) then AddSet( new, n ); fi; od; if IsAffineCrystGroupOnLeft( S ) then new := List( new, TransposedMat ); fi; return SubgroupNC( S, new ); end ); ############################################################################# ## #M WyckoffOrbit( w ) . . . . . . . . . orbit of pointwise subspace lattices ## InstallMethod( WyckoffOrbit, true, [ IsWyckoffPosition ], 0, function( w ) local S, t, B, d, I, gen, U, r, o, s; S := WyckoffSpaceGroup( w ); t := WyckoffTranslation( w ); B := WyckoffBasis( w ); d := Length( t ); I := IdentityMat( d ); gen := GeneratorsOfGroup( S ); gen := Filtered( gen, g -> g{[1..d]}{[1..d]} <> I ); if IsAffineCrystGroupOnLeft( S ) then gen := List( gen, TransposedMat ); fi; U := AffineCrystGroupOnRight( gen, One( S ) ); r := rec( translation := t, basis := B, spaceGroup := S ); o := Orbit( U, r, ImageAffineSubspaceLatticePointwise ); s := List( o, x -> WyckoffPositionObject( rec( translation := x.translation, basis := x.basis, spaceGroup := w!.spaceGroup, class := w!.class ) ) ); return s; end ); ############################################################################# ## #F SolveOneInhomEquationModZ . . . . . . . . solve one inhom equation mod Z ## ## Solve the inhomogeneous equation ## ## a x = b (mod Z). ## ## The set of solutions is ## {0, 1/a, ..., (a-1)/a} + b/a. ## Note that 0 < b < 1, so 0 < b/a and (a-1)/a + b/a < 1. ## SolveOneInhomEquationModZ := function( a, b ) return [0..a-1] / a + b/a; end; ############################################################################# ## #F SolveInhomEquationsModZ . . . . .solve an inhom system of equations mod Z ## ## If onRight = true, compute the set of solutions of the equation ## ## x * M = b (mod Z). ## ## If onRight = false, compute the set of solutions of the equation ## ## M * x = b (mod Z). ## ## RowEchelonFormT() returns a matrix Q such that Q * M is in row echelon ## form. This means that (modulo column operations) we have the equation ## x * Q^-1 * D = b with D a diagonal matrix. ## Solving y * D = b we get x = y * Q. ## SolveInhomEquationsModZ := function( M, b, onRight ) local Q, j, L, space, i, v; b := ShallowCopy(b); if onRight then M := TransposedMat(M); fi; Q := IdentityMat( Length(M[1]) ); M := RowEchelonFormVector( M,b ); while Length(M) > 0 and not IsDiagonalMat(M) do M := TransposedMat(M); M := RowEchelonFormT(M,Q); if Length(M) > 0 and not IsDiagonalMat(M) then M := TransposedMat(M); M := RowEchelonFormVector(M,b); fi; od; ## Now we have D * y = b with y = Q * x ## Check if we have any solutions modulo Z. for j in [Length(M)+1..Length(b)] do if not IsInt( b[j] ) then return [ [], [] ]; fi; od; ## Solve each line in D * y = b separately. L := List( [1..Length(M)], i->SolveOneInhomEquationModZ( M[i][i],b[i] ) ); L := Cartesian( L ); L := List( L, l->Concatenation( l, 0 * [Length(M)+1..Length(Q)] ) ); L := List( L, l-> l * Q ); L := List( L, l->List( l, q->FractionModOne(q) ) ); return [ L, Q{[Length(M)+1..Length(Q)]} ]; end; ############################################################################# ## #F FixedPointsModZ . . . . . . fixed points up to translational equivalence ## ## This function takes a space group and computes the fixpoint spaces of ## this group modulo the translation subgroup. It is assumed that the ## translation subgroup has full rank. ## FixedPointsModZ := function( gens, d ) local I, M, b, i, g, f, F; # Solve x * M + t = x modulo Z for all pairs (M,t) in the generators. # This leads to the system # x * [ M_1 M_2 ... ] = [ b_1 b_2 ... ] (mod Z) M := List( [1..d], i->[] ); b := []; i := 0; I := IdentityMat(d+1); for g in gens do g := g - I; M{[1..d]}{[1..d]+i*d} := g{[1..d]}{[1..d]}; Append( b, -g[d+1]{[1..d]} ); i := i+1; od; # Catch trivial case if Length(M[1]) = 0 then M := List( [1..d], x->[0] ); b := [0]; fi; ## Compute the spaces of points fixed modulo translations. F := SolveInhomEquationsModZ( M, b, true ); return List( F[1], f -> rec( translation := f, basis := F[2] ) ); end; ############################################################################# ## #F IntersectionsAffineSubspaceLattice( , ) ## IntersectionsAffineSubspaceLattice := function( U, V ) local T, m, t, Ti, s, b, lst, x, len, tt; T := TranslationBasis( U.spaceGroup ); m := Concatenation( U.basis, -V.basis ); t := V.translation - U.translation; Ti := T^-1; s := SolveInhomEquationsModZ( m*Ti, t*Ti, true ); if s[1] = [] then return fail; fi; b := IntersectionModule( U.basis, -V.basis ); lst := []; for x in s[1] do tt := x{[1..Length(U.basis)]} * U.basis + U.translation; Add( lst, rec( translation := tt, basis := b, spaceGroup := U.spaceGroup ) ); od; for x in lst do ReduceAffineSubspaceLattice( x ); od; return lst; end; ############################################################################# ## #F IsSubspaceAffineSubspaceLattice( , ) repres. of V contained in U? ## IsSubspaceAffineSubspaceLattice := function( U, V ) local s; s := IntersectionsAffineSubspaceLattice( U, V ); if s = fail then return false; else return V in s; fi; end; ############################################################################# ## #F WyPos( S, stabs, lift ) . . . . . . . . . . . . . . . . Wyckoff positions ## WyPos := function( S, stabs, lift ) local d, W, T, i, lst, w, dim, a, s, r, new, orb, I, gen, U, c; # get representative affine subspace lattices d := DimensionOfMatrixGroup( S ) - 1; W := List( [0..d], i -> [] ); T := TranslationBasis( S ); for i in [1..Length(stabs)] do lst := List( GeneratorsOfGroup( stabs[i] ), lift ); if IsAffineCrystGroupOnLeft( S ) then lst := List( lst, TransposedMat ); fi; lst := FixedPointsModZ( lst, d ); for w in lst do dim := Length( w.basis ) + 1; w.translation := w.translation * T; if not IsEmpty( w.basis ) then w.basis := w.basis * T; fi; w.spaceGroup := S; w.class := i; ReduceAffineSubspaceLattice( w ); Add( W[dim], w ); od; od; # eliminate multiple copies I := IdentityMat( d ); gen := Filtered( GeneratorsOfGroup( S ), g -> g{[1..d]}{[1..d]} <> I ); if IsAffineCrystGroupOnLeft( S ) then gen := List( gen, TransposedMat ); fi; U := AffineCrystGroupOnRight( gen, One( S ) ); for i in [1..d+1] do lst := ShallowCopy( W[i] ); new := []; while lst <> [] do s := lst[1]; c := s.class; Unbind( s.class ); orb := Orbit( U, Immutable(s), ImageAffineSubspaceLattice ); lst := Filtered( lst, x -> not rec( translation := x.translation, basis := x.basis, spaceGroup := x.spaceGroup ) in orb ); s.class := c; Add( new, WyckoffPositionObject( s ) ); od; W[i] := new; od; return Flat( W ); end; ############################################################################# ## #F WyPosSGL( S ) . . . Wyckoff positions via subgroup lattice of point group ## WyPosSGL := function( S ) local P, N, lift, stabs, W; # get point group P, and its nice representation N P := PointGroup( S ); N := NiceObject( P ); # set up lift from nice rep to std rep lift := x -> NiceToCrystStdRep( P, x ); stabs := List( ConjugacyClassesSubgroups( N ), Representative ); Sort( stabs, function(x,y) return Size(x) > Size(y); end ); # now get the Wyckoff positions return WyPos( S, stabs, lift ); end; ############################################################################# ## #F WyPosStep . . . . . . . . . . . . . . . . . . .induction step for WyPosAT ## WyPosStep := function( idx, G, M, b, lst ) local g, G2, M2, b2, F, c, added, stop, f, d, w, O; g := lst.z[idx]; if not g in G then G2 := ClosureGroup( G, g ); M2 := Concatenation( M, lst.mat[idx] ); b2 := Concatenation( b, lst.vec[idx] ); if M <> [] then M2 := RowEchelonFormVector( M2, b2 ); fi; if ForAll( b2{[Length(M2)+1..Length(b2)]}, IsInt ) then b2 := b2{[1..Length(M2)]}; F := SolveInhomEquationsModZ( M2, b2, false ); F := List( F[1], f -> rec( translation := f, basis := F[2] ) ); else F := []; fi; c := lst.c + 1; added := false; for f in F do d := Length( f.basis ) + 1; stop := d=lst.dim+1; f.translation := f.translation * lst.T; if not IsEmpty( f.basis ) then f.basis := f.basis * lst.T; fi; f.spaceGroup := lst.S; ReduceAffineSubspaceLattice( f ); if not f in lst.sp[d] then O := Orbit( lst.S2, Immutable(f), ImageAffineSubspaceLattice ); w := ShallowCopy( f ); w.class := c; UniteSet( lst.sp[d], O ); Add( lst.W[d], WyckoffPositionObject(w) ); added := true; fi; od; if added and not stop then lst.c := lst.c+1; if idx < Length(lst.z) then WyPosStep( idx+1, G2, M2, b2, lst ); fi; fi; fi; if idx < Length(lst.z) then WyPosStep( idx+1, G, M, b, lst ); fi; end; ############################################################################# ## #F WyPosAT( S ) . . . . Wyckoff positions with recursive method by Ad Thiers ## WyPosAT := function( S ) local d, P, gen, S2, lst, zz, mat, vec, g, m, M, b, s, w; d := DimensionOfMatrixGroup(S)-1; P := PointGroup( S ); gen := Filtered( GeneratorsOfGroup(S), x -> x{[1..d]}{[1..d]} <> One(P) ); S2 := Subgroup( S, gen ); if IsAffineCrystGroupOnLeft( S ) then S2 := TransposedMatrixGroup( S2 ); fi; lst := rec( dim := d, T := TranslationBasis(S), S := S, c := 1, S2 := S2 ); zz := []; mat := []; vec := []; for g in Zuppos( NiceObject( P ) ) do if g <> () then m := NiceToCrystStdRep(P,g); if IsAffineCrystGroupOnRight( S ) then m := TransposedMat(m); fi; M := m{[1..d]}{[1..d]}-IdentityMat(d); b := m{[1..d]}[d+1]; M := RowEchelonFormVector(M,b); if ForAll( b{[Length(M)+1..Length(b)]}, IsInt ) then Add( zz, g ); Add( mat, M ); Add( vec, -b{[1..Length(M)]} ); fi; fi; od; lst.z := zz; lst.mat := mat; lst.vec := vec; s := rec( translation := ListWithIdenticalEntries(d,0), basis := TranslationBasis(S), spaceGroup := S ); ReduceAffineSubspaceLattice(s); lst.sp := List( [1..d+1], x-> [] ); Add( lst.sp[d+1], s ); w := ShallowCopy( s ); w.class := 1; w := WyckoffPositionObject( w ); lst.W := List( [1..d+1], x -> [] ); Add( lst.W[d+1], w ); if 1 <= Length(lst.z) then WyPosStep(1,TrivialGroup(IsPermGroup),[],[],lst); fi; return Flat(lst.W); end; ############################################################################# ## #M WyckoffPositions( S ) . . . . . . . . . . . . . . . . . Wyckoff positions ## InstallMethod( WyckoffPositions, "for AffineCrystGroupOnLeftOrRight", true, [ IsAffineCrystGroupOnLeftOrRight ], 0, function( S ) # check if we indeed have a space group if not IsSpaceGroup( S ) then Error("S must be a space group"); fi; # for small dimensions, the recursive method is faster if DimensionOfMatrixGroup( S ) < 6 then return WyPosAT( S ); else return WyPosSGL( S ); fi; end ); ############################################################################# ## #M WyckoffPositionsByStabilizer( S, stabs ) . . Wyckoff pos. for given stabs ## InstallGlobalFunction( WyckoffPositionsByStabilizer, function( S, stb ) local stabs, P, lift; # check the arguments if not IsSpaceGroup( S ) then Error( "S must be a space group" ); fi; if IsGroup( stb ) then stabs := [ stb ]; else stabs := stb; fi; # get point group P P := PointGroup( S ); # set up lift from nice rep to std rep lift := x -> NiceToCrystStdRep( P, x ); stabs := List( stabs, x -> Image( NiceMonomorphism( P ), x ) ); Sort( stabs, function(x,y) return Size(x) > Size(y); end ); # now get the Wyckoff positions return WyPos( S, stabs, lift ); end ); ############################################################################# ## #M WyckoffGraphFun( S, def ) . . . . . . . . . . . . display a Wyckoff graph ## InstallMethod( WyckoffGraph, true, [ IsAffineCrystGroupOnLeftOrRight, IsRecord ], 0, function( S, def ) return WyckoffGraphFun( WyckoffPositions( S ), def ); end ); InstallOtherMethod( WyckoffGraph, true, [ IsAffineCrystGroupOnLeftOrRight ], 0, function( S ) return WyckoffGraphFun( WyckoffPositions( S ), rec() ); end ); InstallOtherMethod( WyckoffGraph, true, [ IsList, IsRecord ], 0, function( L, def ) if not ForAll( L, IsWyckoffPosition ) then Error("L must be a list of Wyckoff positions of the same space group"); fi; return WyckoffGraphFun( L, def ); end ); InstallOtherMethod( WyckoffGraph, true, [ IsList ], 0, function( L ) if not ForAll( L, IsWyckoffPosition ) then Error("L must be a list of Wyckoff positions of the same space group"); fi; return WyckoffGraphFun( L, rec() ); end ); cryst/gap/hom.gd0000644001325400021140000000275513236025737013255 0ustar gaehleruser############################################################################# ## #A hom.gd Cryst library Bettina Eick #A Franz G"ahler #A Werner Nickel ## #Y Copyright 1997-1999 by Bettina Eick, Franz G"ahler and Werner Nickel ## ############################################################################# ## #P IsPointHomomorphism . . . . . . . . . . . . . . . . . IsPointHomomorphism ## DeclareProperty( "IsPointHomomorphism", IsGroupGeneralMappingByImages ); ############################################################################# ## #A NiceToCryst . . . . . . .Lift from NiceObject of PointGroup to CrystGroup ## DeclareAttribute( "NiceToCryst", IsPointGroup ); ############################################################################# ## #F NiceToCrystStdRep( P, perm ) ## DeclareGlobalFunction( "NiceToCrystStdRep" ); ############################################################################# ## #P IsFromAffineCrystGroupToFpGroup ## DeclareProperty( "IsFromAffineCrystGroupToFpGroup", IsGroupGeneralMappingByImages ); ############################################################################# ## #P IsFromAffineCrystGroupToPcpGroup ## DeclareProperty( "IsFromAffineCrystGroupToPcpGroup", IsGroupGeneralMappingByImages ); cryst/gap/zass.gd0000644001325400021140000000364713232361435013445 0ustar gaehleruser############################################################################# ## #A zass.gd Cryst library Bettina Eick #A Franz G"ahler #A Werner Nickel ## #Y Copyright 1997-1999 by Bettina Eick, Franz G"ahler and Werner Nickel ## ## Routines for the determination of space groups for a given a point group ## ############################################################################# ## #O SpaceGroupsByPointGroupOnRight( [, [, ] ] ) ## DeclareOperation("SpaceGroupsByPointGroupOnRight",[IsCyclotomicMatrixGroup]); ############################################################################# ## #O SpaceGroupsByPointGroupOnLeft( [, [, ] ] ) ## DeclareOperation("SpaceGroupsByPointGroupOnLeft", [IsCyclotomicMatrixGroup]); ############################################################################# ## #O SpaceGroupsByPointGroup( [, [, ] ] ) ## DeclareOperation( "SpaceGroupsByPointGroup", [ IsCyclotomicMatrixGroup ] ); ############################################################################# ## #O SpaceGroupTypesByPointGroupOnRight( [, ] ) ## DeclareOperation("SpaceGroupTypesByPointGroupOnRight", [ IsCyclotomicMatrixGroup ] ); ############################################################################# ## #O SpaceGroupTypesByPointGroupOnLeft( [, ] ) ## DeclareOperation("SpaceGroupTypesByPointGroupOnLeft", [ IsCyclotomicMatrixGroup ] ); ############################################################################# ## #O SpaceGroupTypesByPointGroup( [, ] ) ## DeclareOperation( "SpaceGroupTypesByPointGroup", [IsCyclotomicMatrixGroup] ); cryst/gap/hom.gi0000644001325400021140000000734514372461414013260 0ustar gaehleruser############################################################################# ## #A hom.gi Cryst library Bettina Eick #A Franz G"ahler #A Werner Nickel ## #Y Copyright 1997-1999 by Bettina Eick, Franz G"ahler and Werner Nickel ## ############################################################################# ## #M ImagesRepresentative( , ) . . . . . . . for PointHomomorphism ## InstallMethod( ImagesRepresentative, FamSourceEqFamElm, [ IsGroupGeneralMappingByImages and IsPointHomomorphism, IsMultiplicativeElementWithInverse ], 0, function( hom, elm ) local d; d := Length( elm ) - 1; return elm{[1..d]}{[1..d]}; end ); ############################################################################# ## #M PreImagesRepresentativeNC( , ) . . . . . for PointHomomorphism ## InstallMethod( PreImagesRepresentativeNC, FamRangeEqFamElm, [ IsGroupGeneralMappingByImages and IsPointHomomorphism, IsMultiplicativeElementWithInverse ], 0, function( hom, elm ) local P, perm; P := PointGroup( Source( hom ) ); perm := ImagesRepresentative( NiceMonomorphism( P ), elm ); return ImagesRepresentative( NiceToCryst( P ), perm ); end ); ############################################################################# ## #M CoKernelOfMultiplicativeGeneralMapping( ) . . for PointHomomorphism ## InstallMethod( CoKernelOfMultiplicativeGeneralMapping, true, [ IsGroupGeneralMappingByImages and IsPointHomomorphism ], 0, hom -> TrivialSubgroup( Range( hom ) ) ); ############################################################################# ## #M KernelOfMultiplicativeGeneralMapping( ) . . . for PointHomomorphism ## InstallMethod( KernelOfMultiplicativeGeneralMapping, true, [ IsGroupGeneralMappingByImages and IsPointHomomorphism ], 0, function( hom ) local S, d, T, gens, t, m; S := Source( hom ); d := DimensionOfMatrixGroup( S ) - 1; T := TranslationBasis( S ); gens := []; for t in T do m := IdentityMat( d+1 ); m[d+1]{[1..d]} := t; Add( gens, m ); od; if IsAffineCrystGroupOnLeft( S ) then gens := List( gens, TransposedMat ); fi; return SubgroupNC( S, gens ); end ); ############################################################################# ## #F NiceToCrystStdRep( P, perm ) ## InstallGlobalFunction( NiceToCrystStdRep, function( P, perm ) local S, m, d, c; S := AffineCrystGroupOfPointGroup( P ); m := ImagesRepresentative( NiceToCryst( P ), perm ); if IsStandardAffineCrystGroup( S ) then return m; else return S!.lconj * m * S!.rconj; fi; end ); ############################################################################# ## #M NaturalHomomorphismByNormalSubgroup( , ) . . for AffineCrystGroup ## InstallMethod( NaturalHomomorphismByNormalSubgroupOp, "for AffineCrystGroup", IsIdenticalObj, [ IsAffineCrystGroupOnRight, IsAffineCrystGroupOnRight ], 0, function( G, N ) if IsFinite(G) or Length( TranslationBasis(G) ) <> Length( TranslationBasis(N) ) then TryNextMethod(); fi; return SparseActionHomomorphism( G, [ RightCoset(N,()) ], OnRight ); end ); InstallMethod( NaturalHomomorphismByNormalSubgroupOp, "for AffineCrystGroup", IsIdenticalObj, [ IsAffineCrystGroupOnLeft, IsAffineCrystGroupOnLeft ], 0, function( G, N ) if IsFinite(G) or Length( TranslationBasis(G) ) <> Length( TranslationBasis(N) ) then TryNextMethod(); fi; return SparseActionHomomorphism( G, [ RightCoset(N,()) ], OnRight ); end ); cryst/gap/pcpgrp.gi0000644001325400021140000001661714372461414013772 0ustar gaehleruser############################################################################# ## #A pgpgrp.gi Cryst library Bettina Eick #A Franz G"ahler #A Werner Nickel ## #Y Copyright 1997-1999 by Bettina Eick, Franz G"ahler and Werner Nickel ## ############################################################################# ## #M IsomorphismPcpGroup(

    ) . . . . . . . . . . . . . . . . for PointGroup ## InstallMethod( IsomorphismPcpGroup, "for PointGroup", true, [ IsPointGroup ], 0, function ( P ) local mono, N, repr, F, gens, prei, iso; # compute an isomorphic permutation group mono := NiceMonomorphism( P ); N := NiceObject( P ); # distinguish between solvable and non-solvable case if not IsSolvableGroup( N ) then return fail; fi; repr := IsomorphismPcpGroup( N ); F := Image( repr ); gens := Igs( F ); prei := List( gens, x -> PreImagesRepresentativeNC( repr, x ) ); prei := List( prei, x -> PreImagesRepresentativeNC( mono, x ) ); iso := GroupHomomorphismByImagesNC( P, F, prei, gens ); SetMappingGeneratorsImages( iso, [ prei, gens ] ); SetIsBijective( iso, true ); SetKernelOfMultiplicativeGeneralMapping( iso, TrivialSubgroup( P ) ); return iso; end ); ############################################################################# ## #M IsomorphismPcpGroup( ) . . . . . . for AffineCrystGroupOnLeftOrRight ## InstallMethod( IsomorphismPcpGroup, "for AffineCrystGroup", true, [ IsAffineCrystGroupOnLeftOrRight ], 0, function( S ) local P, N, T, iso, F, gensF, gensN, matsP, d, n, t, matsT, i, mats, coll, j, r, g, e, o, s, G, new, v; # get presentation for the point group P := PointGroup( S ); N := NiceObject( P ); T := TranslationBasis( S ); iso := IsomorphismPcpGroup( N ); if IsBool( iso ) then return fail; fi; # determine preimages F := Image( iso ); gensF := Cgs(F); gensN := List( gensF, x -> PreImagesRepresentativeNC( iso, x ) ); matsP := List( gensN, x -> ImagesRepresentative( NiceToCryst( P ), x ) ); # set up some variables d := DimensionOfMatrixGroup( S ) - 1; n := Length( gensN ); t := Length( T ); # get mats of translation matsT := List( [1..t], x -> IdentityMat( d+1 ) ); for i in [1..Length( matsT )] do if IsAffineCrystGroupOnRight( S ) then matsT[i][d+1]{[1..d]} := T[i]; else matsT[i]{[1..d]}[d+1] := T[i]; fi; od; mats := Concatenation( matsP, matsT ); # compute collector coll := FromTheLeftCollector( n + t ); # point group rels for i in [1..n] do # compute power rel r := RelativeOrderPcp( gensF[i] ); g := gensF[i]^r; e := Exponents( gensF[i]^r ); s := matsP[i]^-r * MappedVector( e, matsP ); if t > 0 then if IsAffineCrystGroupOnRight( S ) then v := SolutionMat( T, - s[d+1]{[1..d]} ); else v := SolutionMat( T, - s{[1..d]}[d+1] ); fi; e := Concatenation( e, v ); fi; o := ObjByExponents( coll, e ); SetRelativeOrder( coll, i, r ); SetPower( coll, i, o ); for j in [1..i-1] do # get conjugate rel g := gensF[i]^gensF[j]; e := Exponents( gensF[i]^gensF[j] ); s := (matsP[i]^matsP[j])^-1 * MappedVector( e, matsP ); if t > 0 then if IsAffineCrystGroupOnRight( S ) then v := SolutionMat( T, - s[d+1]{[1..d]} ); else v := SolutionMat( T, - s{[1..d]}[d+1] ); fi; e := Concatenation( e, v ); fi; o := ObjByExponents( coll, e ); SetConjugate( coll, i, j, o ); od; od; # operation rels e := List( [1..n], x -> 0 ); for i in [1..n] do for j in [1..t] do s := matsT[j]^matsP[i]; if IsAffineCrystGroupOnRight( S ) then v := SolutionMat( T, s[d+1]{[1..d]} ); else v := SolutionMat( T, s{[1..d]}[d+1] ); fi; o := ObjByExponents( coll, Concatenation( e, v ) ); SetConjugate( coll, n+j, i, o ); od; od; # set up homomorphims G := PcpGroupByCollector( coll ); new := GroupHomomorphismByImagesNC( S, G, mats, Cgs(G)); SetMappingGeneratorsImages( new, [ mats, Cgs(G) ] ); SetIsFromAffineCrystGroupToPcpGroup( new, true ); SetIsBijective( new, true ); SetKernelOfMultiplicativeGeneralMapping( new, TrivialSubgroup( S ) ); return new; end ); ############################################################################# ## #M ImagesRepresentative( , ) for IsFromAffineCrystGroupToPcpGroup ## InstallMethod( ImagesRepresentative, FamSourceEqFamElm, [IsGroupGeneralMappingByImages and IsFromAffineCrystGroupToPcpGroup, IsMultiplicativeElementWithInverse ], 0, function(iso, elm) local d, S, T, P, m, l, w, N, F, gensF, gensN, matsP, e, f, g, exp, new, rem, v, s, H, h, p; # set up dim and space group d := Length(elm)-1; S := Source(iso); T := TranslationBasis(S); # set up point group P := PointGroup(S); m := NiceMonomorphism(P); # P -> N N := Image(m); l := NiceToCryst(P); # N -> S w := IsomorphismPcpGroup(N); # N -> Pcp # get preimages F := Image(w); gensF := Cgs(F); gensN := List(gensF, x -> PreImagesRepresentativeNC(w, x)); matsP := List(gensN, x -> ImagesRepresentative(l, x)); # point group part e := elm{[1..d]}{[1..d]}; f := Image(m, e); g := Image(w, f); exp := Exponents(g); # divide off new := MappedVector( exp, matsP ); rem := new^-1 * elm; if Length( T ) > 0 then if IsAffineCrystGroupOnRight( S ) then v := rem[d+1]{[1..d]}; else v := rem{[1..d]}[d+1]; fi; s := SolutionMat(T, v); exp := Concatenation( exp, s ); fi; # translate H := Image(iso); h := Cgs(H); # do some check p := List(h, x -> PreImagesRepresentativeNC(iso,x)); if MappedVector(exp, p) <> elm then Error("hier"); fi; return MappedVector(exp, h); end ); ############################################################################# ## #M NaturalHomomorphismByNormalSubgroup( , ) for solv. AffineCrystGrp ## InstallMethod( NaturalHomomorphismByNormalSubgroupOp, "for AffineCrystGroup, via pcp representation", IsIdenticalObj, [ IsAffineCrystGroupOnRight, IsAffineCrystGroupOnRight ], 10, function( G, N ) local iso, hom; if not IsSolvableGroup( G ) then TryNextMethod(); fi; iso := IsomorphismPcpGroup( G ); hom := NaturalHomomorphismByPcp( Pcp( Image(iso), Image(iso,N) ) ); return CompositionMapping( hom, iso ); end ); InstallMethod( NaturalHomomorphismByNormalSubgroupOp, "for AffineCrystGroup, via pcp representation", IsIdenticalObj, [ IsAffineCrystGroupOnLeft, IsAffineCrystGroupOnLeft ], 10, function( G, N ) local iso, hom; if not IsSolvableGroup( G ) then TryNextMethod(); fi; iso := IsomorphismPcpGroup( G ); hom := NaturalHomomorphismByPcp( Pcp( Image(iso), Image(iso,N) ) ); return CompositionMapping( hom, iso ); end ); cryst/gap/wygraph.gi0000644001325400021140000001320513232361435014142 0ustar gaehleruser############################################################################# ## #A wygraph.gi Cryst library Bettina Eick #A Franz G"ahler #A Werner Nickel ## #Y Copyright 1997-1999 by Bettina Eick, Franz G"ahler and Werner Nickel ## ## Routines for the determination and the display of a Wyckoff graph ## ############################################################################# ## #M CompareLevels( param1, param2 ) . . . . . . . . . . . . . . CompareLevels ## InstallMethod( CompareLevels, true, [ IsGraphicPosetRep and IsWyckoffGraph, IsList, IsList ], 0, function( graph, level1, level2 ) # a smaller dimension is higher if level1[1] < level2[1] then return -1; elif level1[1] > level2[1] then return 1; else # for equal dimension, the bigger size is higher if level1[2] > level2[2] then return -1; elif level1[2] > level2[2] then return 1; else return 0; fi; fi; end ); ############################################################################# ## #F WyckoffPosRelations( ) . . . incidence relations of Wyckoff positions ## WyckoffPosRelations := function( W ) local S, T, d, len, gens, G, L, m, O, o, i, j, k, Si, Sj, index, lst; S := WyckoffSpaceGroup( W[1] ); T := TranslationBasis( S ); d := DimensionOfMatrixGroup( S ) - 1; len := Length( W ); gens := GeneratorsOfGroup( S ); gens := Filtered( gens, g -> g{[1..d]}{[1..d]} <> IdentityMat( d ) ); if IsAffineCrystGroupOnLeft( S ) then gens := List( gens, TransposedMat ); fi; G := GroupByGenerators( gens, One( S ) ); L := List( W, w -> rec( translation := WyckoffTranslation( w ), basis := WyckoffBasis( w ), spaceGroup := S ) ); m := NullMat( len, len ); for i in [1..len] do O := Orbit( G, L[i], ImageAffineSubspaceLattice ); for j in [1..len] do Sj := WyckoffStabilizer( W[j] ); Si := WyckoffStabilizer( W[i] ); index := Size(Sj) / Size(Si); if Length(L[j].basis) < Length(L[i].basis) and IsInt(index) then lst := Filtered(O,o->IsSubspaceAffineSubspaceLattice(o,L[j])); m[j][i] := Length( lst ); fi; od; od; for i in Reversed([1..Length(W)]) do for j in Reversed([1..i-1]) do if m[j][i]<>0 then for k in [1..j-1] do if m[k][j]<>0 then m[k][i]:=0; fi; od; fi; od; od; return m; end; ############################################################################# ## #F WyckoffGraphRecord( ) . . . . . . . Create record for Wyckoff graph ## WyckoffGraphRecord := function( lst ) local L, m, R, i, level, j; L := List( lst, w -> rec( wypos := w, dim := Length( WyckoffBasis(w) ), size := Size( WyckoffStabilizer(w) ), class := w!.class ) ); Sort( L, function(a,b) return a.size > b.size; end ); m := WyckoffPosRelations( List( L, x -> x.wypos ) ); R := rec( levels := [], classes := [], vertices := [], edges := [] ); for i in [1..Length(L)] do level := [ L[i].dim, L[i].size ]; AddSet( R.levels, level ); AddSet( R.classes, [ L[i].class, level ] ); Add( R.vertices, [ L[i].wypos, level, L[i].class ] ); for j in [1..i-1] do if m[j][i]<>0 then Add( R.edges, [ i, j, m[j][i] ] ); fi; od; od; return R; end; ############################################################################# ## #M WyckoffGraphFun( W, def ) . . . . . . . . . . . . display a Wyckoff graph ## InstallGlobalFunction( WyckoffGraphFun, function( W, def ) local S, defaults, R, wygr, x, vertices, i, v, info, data, v1, v2; # set up defaults S := WyckoffSpaceGroup( W[1] ); defaults := rec(width := 800, height := 600, title := "WyckoffGraph"); if HasName(S) then defaults.title := Concatenation( defaults.title, " of ", Name(S) ); fi; if IsBound(def.width) then defaults.width := def.width; fi; if IsBound(def.height) then defaults.height := def.height; fi; if IsBound(def.title) then defaults.title := def.title; fi; R := WyckoffGraphRecord( W ); # open a graphic poset and make it a Wyckoff graph wygr := GraphicPoset( defaults.title, defaults.width, defaults.height ); SetFilterObj( wygr, IsWyckoffGraph ); # create levels for x in R.levels do CreateLevel( wygr, x, String( x ) ); od; # create classes for x in R.classes do CreateClass( wygr, x[2], x[1] ); od; # create vertices vertices := []; for i in [1..Length(R.vertices)] do v := R.vertices[i]; info := rec( label := String(i), levelparam := v[2], classparam := v[3] ); data := rec( wypos := v[1], info := rec() ); Add( vertices, Vertex( wygr, data, info ) ); od; # create edges for x in R.edges do v1 := vertices[ x[1] ]; v2 := vertices[ x[2] ]; Edge( wygr, v1, v2, rec( label := String( x[3]) ) ); od; # Install the info method wygr!.selector := false; wygr!.infodisplays := WyckoffInfoDisplays; InstallPopup( wygr, GGLRightClickPopup ); return wygr; end ); cryst/gap/equiv.gd0000644001325400021140000000125113232361435013603 0ustar gaehleruser############################################################################# ## #A equiv.gd Cryst library Bettina Eick #A Franz G"ahler #A Werner Nickel ## #Y Copyright 1997-1999 by Bettina Eick, Franz G"ahler and Werner Nickel ## ############################################################################# ## #O ConjugatorSpaceGroups( S1, S2 ) . . . . . . . . .returns C with S1^C = S2 ## DeclareOperation( "ConjugatorSpaceGroups", [ IsAffineCrystGroupOnLeftOrRight, IsAffineCrystGroupOnLeftOrRight ] ); cryst/gap/noxgap.gi0000644001325400021140000000126013232361435013753 0ustar gaehleruser############################################################################# ## #A noxgap.gi Cryst library Bettina Eick #A Franz G"ahler #A Werner Nickel ## #Y Copyright 1997-1999 by Bettina Eick, Franz G"ahler and Werner Nickel ## ############################################################################# ## #M WyckoffGraphFun( S, def ) . . . . . . . . . . . . display a Wyckoff graph ## InstallGlobalFunction( WyckoffGraphFun, function( W, def ) Error( "WyckoffGraph is available only under XGAP" ); end ); cryst/gap/fpgrp.gi0000644001325400021140000001361114372461414013604 0ustar gaehleruser############################################################################# ## #A fpgrp.gi Cryst library Bettina Eick #A Franz G"ahler #A Werner Nickel ## #Y Copyright 1997-1999 by Bettina Eick, Franz G"ahler and Werner Nickel ## ############################################################################# ## #M IsomorphismFpGroup(

    ) . . . . . . . IsomorphismFpGroup for PointGroup ## InstallMethod( IsomorphismFpGroup, "for PointGroup", true, [ IsPointGroup ], 0, function ( P ) local mono, N, F, gens, gensP, gensS, gensF, iso; # compute an isomorphic permutation group mono := NiceMonomorphism( P ); N := NiceObject( P ); # distinguish between solvable and non-solvable case if IsSolvableGroup( N ) then F := Image( IsomorphismFpGroupByPcgs( Pcgs( N ), "f" ) ); gens := AsList( Pcgs( N ) ); else gens := GeneratorsOfGroup( N ); F := Image( IsomorphismFpGroupByGenerators( N, gens ) ); fi; gensP := List( gens, x -> PreImagesRepresentativeNC( mono, x ) ); gensS := List( gens, x -> ImagesRepresentative( NiceToCryst( P ), x ) ); gensF := GeneratorsOfGroup( F ); iso := GroupHomomorphismByImagesNC( P, F, gensP, gensF ); SetMappingGeneratorsImages( iso, [ gensP, gensF ] ); SetIsBijective( iso, true ); SetKernelOfMultiplicativeGeneralMapping( iso, TrivialSubgroup( P ) ); iso!.preimagesInAffineCrystGroup := Immutable( gensS ); return iso; end ); ############################################################################# ## #M IsomorphismFpGroup( ) . . . . . . . for AffineCrystGroupOnLeftOrRight ## InstallMethod( IsomorphismFpGroup, "for AffineCrystGroup", true, [ IsAffineCrystGroupOnLeftOrRight ], 0, function( S ) local P, hom, T, iso, F, gensP, relsP, matsP, d, n, t, R, gensR, gensT, matsT, i, j, l, k, rels, relsR, rel, tail, vec, word, gens, ims; P := PointGroup( S ); hom := PointHomomorphism( S ); T := TranslationBasis( S ); iso := IsomorphismFpGroup( P ); F := Image( iso ); gensP := GeneratorsOfGroup( FreeGroupOfFpGroup( F ) ); relsP := RelatorsOfFpGroup( F ); matsP := iso!.preimagesInAffineCrystGroup; d := DimensionOfMatrixGroup( S ) - 1; n := Length( gensP ); t := Length( T ); R := FreeGroup( n + t ); gensR := GeneratorsOfGroup( R ){[1..n]}; gensT := GeneratorsOfGroup( R ){[n+1..n+t]}; matsT := List( gensT, x -> IdentityMat( d+1 ) ); for i in [1..Length( matsT )] do if IsAffineCrystGroupOnRight( S ) then matsT[i][d+1]{[1..d]} := T[i]; else matsT[i]{[1..d]}[d+1] := T[i]; fi; od; rels := List( relsP, rel -> MappedWord( rel, gensP, gensR ) ); relsR := []; # compute tails for rel in rels do tail := MappedWord( rel, gensR, matsP ); word := rel; if t > 0 then if IsAffineCrystGroupOnRight( S ) then vec := SolutionMat( T, - tail[d+1]{[1..d]} ); else vec := SolutionMat( T, - tail{[1..d]}[d+1] ); fi; for i in [1..t] do word := word * gensT[i]^vec[i]; od; fi; Add( relsR, word ); od; # compute operation for i in [1..n] do for j in [1..t] do rel := Comm( gensT[j], gensR[i] ); tail := Comm( matsT[j], matsP[i] ); if IsAffineCrystGroupOnRight( S ) then vec := SolutionMat( T, - tail[d+1]{[1..d]} ); else vec := SolutionMat( T, - tail{[1..d]}[d+1] ); fi; word := rel; for k in [1..t] do word := word * gensT[k]^vec[k]; od; Add( relsR, word ); od; od; # compute presentation of T for i in [1..t-1] do for j in [i+1..t] do Add( relsR, Comm( gensT[j], gensT[i] ) ); od; od; # construct isomorphism R := R / relsR; gens := Concatenation( matsP, matsT ); ims := GeneratorsOfGroup( R ); iso := GroupHomomorphismByImagesNC( S, R, gens, ims ); SetMappingGeneratorsImages( iso, [ gens, ims ] ); SetIsFromAffineCrystGroupToFpGroup( iso, true ); SetIsBijective( iso, true ); SetKernelOfMultiplicativeGeneralMapping( iso, TrivialSubgroup( S ) ); return iso; end ); ############################################################################# ## #M ImagesRepresentative( , ) for IsFromAffineCrystGroupToFpGroup ## InstallMethod( ImagesRepresentative, FamSourceEqFamElm, [IsGroupGeneralMappingByImages and IsFromAffineCrystGroupToFpGroup, IsMultiplicativeElementWithInverse ], 0, function( iso, elm ) local d, S, T, elmP, isoP, word, genP, len, genS, genF, elm2, v, i; d := Length( elm ) - 1; S := Source( iso ); T := TranslationBasis( S ); elmP := elm{[1..d]}{[1..d]}; isoP := IsomorphismFpGroup( PointGroup( S ) ); word := ImagesRepresentative( isoP, elmP ); genP := MappingGeneratorsImages( isoP )[2]; len := Length( genP ); genS := MappingGeneratorsImages( iso )[1]; genF := MappingGeneratorsImages( iso )[2]; elm2 := MappedWord( word, genP, genS{[1..len]} ); word := MappedWord( word, genP, genF{[1..len]} ); if Length( T ) > 0 then if IsAffineCrystGroupOnRight( S ) then v := SolutionMat( T, elm[d+1]{[1..d]} - elm2[d+1]{[1..d]} ); for i in [1..Length(v)] do word := word * genF[len+i]^v[i]; od; else v := SolutionMat( T, elm{[1..d]}[d+1] - elm2{[1..d]}[d+1] ); for i in [1..Length(v)] do word := genF[len+i]^v[i] * word; od; fi; fi; return word; end ); cryst/gap/wypopup.gi0000644001325400021140000001576713232361435014223 0ustar gaehleruser############################################################################# ## #A wypopup.gi Cryst library Bettina Eick #A Franz G"ahler #A Werner Nickel ## #Y Copyright 1997-1999 by Bettina Eick, Franz G"ahler and Werner Nickel ## ## Routines for text selector popup for Wyckoff graph ## ############################################################################ ## #F CCInfo . . . . . . . . . . . . . ConjugacyClassInfo of WyckoffStabilizer ## CCInfo := function( W ) local G, C, R, L, max; G := PointGroup( WyckoffStabilizer( W ) ); C := ConjugacyClasses( G ); R := List( C, Representative ); L := [ [1..Length(C)], List( R, Order ), List( R, TraceMat ), List( R, DeterminantMat ), List( C, Size ) ]; L := TransposedMat( L ); L := Concatenation( [[ "cl", "ord", "tr", "det", "sz" ]], L ); max := Maximum( List( L, l -> Maximum( List( l, x -> Length( String(x) ) ) ) ) ); max := max + 1; L := List( L, l -> Concatenation( List( l, x -> String( x, max ) ) ) ); return L; end; ############################################################################ ## #F WyckoffInfoDisplays . . . . functions call by WyckoffGraph text selector ## BindGlobal( "WyckoffInfoDisplays", rec( Isomorphism := rec( name := "Isomorphism", func := x -> IdGroup( PointGroup( WyckoffStabilizer(x) ) ) ), ConjugacyClassInfo := rec( name := "ConjugacyClassInfo", func := x -> CCInfo( x ) ) ) ); ############################################################################ ## #M GGLRightClickPopup . . . . . . . . . . called if user does a right click ## ## This is called if the user does a right click on a vertex or somewhere ## else on the sheet. This operation is highly configurable with respect ## to the Attributes of groups it can display/calculate. See the ## configuration section in "ilatgrp.gi" for an explanation. ## InstallMethod( GGLRightClickPopup, "for a Wyckoff graph", true, [ IsGraphicSheet and IsWyckoffGraph, IsObject, IsInt, IsInt ], 0, function(sheet,v,x,y) local w, r, textselectfunc, text, pg, ps, i, str, basis, vec, funcclose, funcall, maxlengthofname, names; maxlengthofname := 11; # did we get a vertex? if v = fail then return; fi; # destroy other text selectors flying around if sheet!.selector <> false then Close(sheet!.selector); sheet!.selector := false; fi; # get the Wyckoff position of w := v!.data.wypos; # how long are the names of the info displays? r := sheet!.infodisplays; # maxlengthofname := Maximum( List( RecNames(r), x -> Length( r.(x).name ) ) ); # text select function textselectfunc := function( sel, name ) local tid, text, str, curr, value; tid := sel!.selected; name := sel!.names[tid]; text := ShallowCopy(sel!.labels); if name = "ConjugacyClassInfo" then str := text[tid]{[1..Length(name)]}; else str := text[tid]{[1..maxlengthofname+1]}; fi; if name = "dummy" then return true; fi; curr := sheet!.infodisplays.(name); value := curr.func( w ); v!.data.info.(name) := value; if name = "ConjugacyClassInfo" then Append( str, ":" ); else Append( str, String( value ) ); fi; text[tid] := str; if name = "ConjugacyClassInfo" then for str in value do Add( text, str ); Add( sel!.textFuncs, textselectfunc ); Add( sel!.names, "dummy" ); od; sel!.labels := text; fi; Relabel( sel, text ); SetName( sel, tid, "dummy" ); LastResultOfInfoDisplay := value; return true; end; # construct the initial text selector text := []; names := []; pg := PointGroup( WyckoffStabilizer( w ) ); ps := PointGroup( WyckoffSpaceGroup( w ) ); # the stabilizer size str := String( "StabSize", -(maxlengthofname+1) ); Append( str, String( Size( pg ) ) ); Append( text, [ str, textselectfunc ] ); Add( names, "dummy" ); # the stabilizer dimension str := String( "StabDim", -(maxlengthofname+1) ); Append( str, String( Length( WyckoffBasis( w ) ) ) ); Append( text, [ str, textselectfunc ] ); Add( names, "dummy" ); # the orbit length modulo lattice translations str := String( "OrbitLength", -(maxlengthofname+1) ); Append( str, String( Size( ps ) / Size( pg ) ) ); Append( text, [ str, textselectfunc ] ); Add( names, "dummy" ); # the translation of the affine subspace str := String( "Translation", -(maxlengthofname+1) ); Append( str, String( WyckoffTranslation( w ) ) ); Append( text, [ str, textselectfunc ] ); Add( names, "dummy" ); # the basis of the affine subspace basis := WyckoffBasis( w ); str := String( "Basis", -(maxlengthofname+1) ); if basis = [] then Append( str, "[ ]" ); Append( text, [ str, textselectfunc ] ); Add( names, "dummy" ); elif Length( basis ) = 1 then Append( str, String( basis ) ); Append( text, [ str, textselectfunc ] ); Add( names, "dummy" ); else Append( str, "[ " ); Append( str, String( basis[1] ) ); for vec in basis{[2..Length(basis)]} do Append( text, [ str, textselectfunc ] ); Add( names, "dummy" ); str := String( " ", -(maxlengthofname+3) ); Append( str, String( vec ) ); od; Append( str, " ]" ); Append( text, [ str, textselectfunc ] ); Add( names, "dummy" ); fi; # the isomorphism type str := String( "Isomorphism", -(maxlengthofname+1) ); if HasIdGroup( pg ) then Append( str, String( IdGroup( pg ) ) ); else Append( str, "unknown" ); fi; Append( text, [ str, textselectfunc ] ); Add( names, "Isomorphism" ); # the conjugacy class info str := "ConjugacyClassInfo"; if IsBound( v!.data.info.ConjugacyClassInfo ) then Append( str, ":" ); Add( names, "dummy" ); else Add( names, "ConjugacyClassInfo" ); fi; Append( text, [ str, textselectfunc ] ); Add( names, "Isomorphism" ); if IsBound( v!.data.info.ConjugacyClassInfo ) then for str in v!.data.info.ConjugacyClassInfo do Append( text, [ str, textselectfunc ] ); Add( names, "dummy" ); od; fi; # button select functions: funcclose := function( sel, bt ) Close(sel); sheet!.selector := false; return true; end; funcall := function( sel, bt ) local i; for i in [ 1 .. Length(sel!.labels) ] do sel!.selected := i; sel!.textFuncs[i]( sel, sel!.labels[i] ); od; Enable( sel, "all", false ); return true; end; # construct text selector sheet!.selector := TextSelector( Concatenation( " Information about ", v!.label ), text, [ "all", funcall, "close", funcclose ] ); # set entry names for i in [1..Length(names)] do SetName( sheet!.selector, i, names[i] ); od; end); cryst/gap/common.gi0000644001325400021140000002227714053147612013763 0ustar gaehleruser############################################################################# ## #A common.gi Cryst library Bettina Eick #A Franz G"ahler #A Werner Nickel ## #Y Copyright 1997-1999 by Bettina Eick, Franz G"ahler and Werner Nickel ## ## Common utility routines, most of which deal with integral matrices ## ############################################################################# ## #F MutableMatrix( M ) . . . . . . . . . . . . . . . . mutable copy of matrix ## MutableMatrix := function( M ) return List( M, ShallowCopy ); end; ############################################################################# ## #F AffMatMutableTrans( M ) . . . . . .affine matrix with mutable translation ## AffMatMutableTrans := function( M ) local l; if not IsMutable( M ) then M := ShallowCopy( M ); fi; l := Length( M ); if not IsMutable( M[l] ) then M[l] := ShallowCopy( M[l] ); fi; return M; end; ############################################################################# ## #F AugmentedMatrix( , ). . . . . construct augmented matrix ## AugmentedMatrix := function( m, b ) local g, t, x; g := MutableMatrix( m ); for x in g do Add( x, 0 ); od; t := ShallowCopy( b ); Add( t, 1 ); Add( g, t ); return g; end; ############################################################################# ## #F RowEchelonForm . . . . . . . . . . row echelon form of an integer matrix ## InstallMethod( RowEchelonForm, "for matrices", [ IsMatrix ], function( M ) local a, i, j, k, m, n, r, Cleared; if M = [] then return []; fi; M := MutableMatrix( M ); m := Length( M ); n := Length( M[1] ); i := 1; j := 1; while i <= m and j <= n do k := i; while k <= m and M[k][j] = 0 do k := k+1; od; if k <= m then r := M[i]; M[i] := M[k]; M[k] := r; for k in [k+1..m] do a := AbsInt( M[k][j] ); if a <> 0 and a < AbsInt( M[i][j] ) then r := M[i]; M[i] := M[k]; M[k] := r; fi; od; if M[i][j] < 0 then M[i] := -1 * M[i]; fi; Cleared := true; for k in [i+1..m] do a := QuoInt(M[k][j],M[i][j]); if a <> 0 then M[k] := M[k] - a * M[i]; fi; if M[k][j] <> 0 then Cleared := false; fi; od; if Cleared then i := i+1; j := j+1; fi; else j := j+1; fi; od; return M{[1..i-1]}; end ); ############################################################################# ## #F RowEchelonFormVector . . . . . . . . . . . .row echelon form with vector ## RowEchelonFormVector := function( M, b ) local a, i, j, k, m, n, r, Cleared; M := MutableMatrix( M ); m := Length( M ); if m = 0 then return M; fi; n := Length( M[1] ); i := 1; j := 1; while i <= m and j <= n do k := i; while k <= m and M[k][j] = 0 do k := k+1; od; if k <= m then r := M[i]; M[i] := M[k]; M[k] := r; r := b[i]; b[i] := b[k]; b[k] := r; for k in [k+1..m] do a := AbsInt( M[k][j] ); if a <> 0 and a < AbsInt( M[i][j] ) then r := M[i]; M[i] := M[k]; M[k] := r; r := b[i]; b[i] := b[k]; b[k] := r; fi; od; if M[i][j] < 0 then M[i] := -1 * M[i]; b[i] := -1 * b[i]; fi; Cleared := true; for k in [i+1..m] do a := QuoInt(M[k][j],M[i][j]); if a <> 0 then M[k] := M[k] - a * M[i]; b[k] := b[k] - a * b[i]; fi; if M[k][j] <> 0 then Cleared := false; fi; od; if Cleared then i := i+1; j := j+1; fi; else j := j+1; fi; od; return M{[1..i-1]}; end; ############################################################################# ## #F RowEchelonFormT . . . . . . . row echelon form with transformation matrix ## RowEchelonFormT := function( M, T ) local a, i, j, k, m, n, r, Cleared; M := MutableMatrix( M ); m := Length( M ); n := Length( M[1] ); i := 1; j := 1; while i <= m and j <= n do k := i; while k <= m and M[k][j] = 0 do k := k+1; od; if k <= m then r := M[i]; M[i] := M[k]; M[k] := r; r := T[i]; T[i] := T[k]; T[k] := r; for k in [k+1..m] do a := AbsInt( M[k][j] ); if a <> 0 and a < AbsInt( M[i][j] ) then r := M[i]; M[i] := M[k]; M[k] := r; r := T[i]; T[i] := T[k]; T[k] := r; fi; od; if M[i][j] < 0 then M[i] := -1 * M[i]; T[i] := -1 * T[i]; fi; Cleared := true; for k in [i+1..m] do a := QuoInt(M[k][j],M[i][j]); if a <> 0 then M[k] := M[k] - a * M[i]; T[k] := T[k] - a * T[i]; fi; if M[k][j] <> 0 then Cleared := false; fi; od; if Cleared then i := i+1; j := j+1; fi; else j := j+1; fi; od; return M{[1..i-1]}; end; ############################################################################# ## #F FractionModOne . . . . . . . . . . . . . . . . . . a fraction modulo one ## FractionModOne := function( q ) q := q - Int(q); if q < 0 then q := q+1; fi; return q; end; ############################################################################# ## #F VectorModL . . . . . . . . . . . . . . . . .vector modulo a free Z-module ## VectorModL := function( v, L ) local l, i, x, j; for l in L do i := PositionProperty( l, x -> x<>0 ); x := v[i]/l[i]; j := Int( x ); if x < 0 and not IsInt( x ) then j := j-1; fi; v := v - j*l; od; return v; end; ############################################################################# ## #F IntSolutionMat( M, b ) . . integer solution for inhom system of equations ## IntSolutionMat := function( M, b ) local Q, den, sol, i, x; if Concatenation(M) = [] then return fail; fi; # the trivial solution if RankMat( M ) = 0 then if b = 0 * M[1] then return List( M, x -> 0 ); else return fail; fi; fi; den := Lcm( List( Flat( M ), x -> DenominatorRat( x ) ) ); if den <> 1 then M := den*M; b := den*b; fi; b := ShallowCopy(b); Q := IdentityMat( Length(M) ); M := TransposedMat(M); M := RowEchelonFormVector( M,b ); while not IsDiagonalMat(M) do M := TransposedMat(M); M := RowEchelonFormT(M,Q); if not IsDiagonalMat(M) then M := TransposedMat(M); M := RowEchelonFormVector(M,b); fi; od; # are there integer solutions? sol:=[]; for i in [1..Length(M)] do x := b[i]/M[i][i]; if IsInt( x ) then Add( sol, x ); else return fail; fi; od; # are there solutions at all? for i in [Length(M)+1..Length(b)] do if b[i]<>0 then return fail; fi; od; return sol*Q{[1..Length(sol)]}; end; ############################################################################# ## #F ReducedLatticeBasis . . . . . . . . . reduce lattice basis to normal form ## ReducedLatticeBasis := function ( trans ) local m, f, b, r, L; if trans = [] or ForAll( trans, x -> IsZero( x ) ) then return []; fi; m := ShallowCopy( trans ); f := Flat( trans ); if not ForAll( f, IsRat ) then b := Basis( Field( f ) ); m := List( m, x -> BlownUpVector( b, x ) ); f := Flat( m ); fi; if not ForAll( f, IsInt ) then m := m * Lcm( List( f, DenominatorRat ) ); fi; r := NormalFormIntMat( m, 6 ); L := r.rowtrans{[1..r.rank]} * trans; return L; end; ############################################################################# ## #F UnionModule( M1, M2 ) . . . . . . . . . . . . union of two free Z-modules ## UnionModule := function( M1, M2 ) return ReducedLatticeBasis( Concatenation( M1, M2 ) ); end; ############################################################################# ## #F IntersectionModule( M1, M2 ) . . . . . intersection of two free Z-modules ## IntersectionModule := function( M1, M2 ) local M, Q, r, T; if M1 = [] or M2 = [] then return []; fi; M := Concatenation( M1, M2 ); M := M * Lcm( List( Flat( M ), DenominatorRat ) ); # Q := IdentityMat( Length( M ) ); # M := RowEchelonFormT( M, Q ); # T := Q{[Length(M)+1..Length(Q)]}{[1..Length(M1)]}; # if not IsEmpty(T) then T := T * M1; fi; r := NormalFormIntMat( M, 4 ); T := r.rowtrans{[r.rank+1..Length(M)]}{[1..Length(M1)]}; if not IsEmpty( T ) then T := T * M1; fi; return ReducedLatticeBasis( T ); end; cryst/gap/cryst.gd0000644001325400021140000002304013473202324013614 0ustar gaehleruser############################################################################# ## #A cryst.gd Cryst library Bettina Eick #A Franz G"ahler #A Werner Nickel ## #Y Copyright 1997-1999 by Bettina Eick, Franz G"ahler and Werner Nickel ## ## The main declarations ## ############################################################################# ## ## Identification and construction of affine crystallographic groups ## ############################################################################# ############################################################################# ## #P IsAffineCrystGroupOnRight( ) . . . . AffineCrystGroup acting OnRight ## DeclareProperty( "IsAffineCrystGroupOnRight", IsCyclotomicMatrixGroup ); InstallTrueMethod( IsCyclotomicMatrixGroup, IsAffineCrystGroupOnRight ); ############################################################################# ## #P IsAffineCrystGroupOnLeft( ) . . . . . AffineCrystGroup acting OnLeft ## DeclareProperty( "IsAffineCrystGroupOnLeft", IsCyclotomicMatrixGroup ); InstallTrueMethod( IsCyclotomicMatrixGroup, IsAffineCrystGroupOnLeft ); ############################################################################# ## #P IsAffineCrystGroupOnLeftOrRight( ) . . . . . AffineCrystGroup acting #P . . . . . . . . . . . . . . . . . . . . . . . . either OnLeft or OnRight ## DeclareProperty( "IsAffineCrystGroupOnLeftOrRight",IsCyclotomicMatrixGroup ); InstallTrueMethod( IsCyclotomicMatrixGroup, IsAffineCrystGroupOnLeftOrRight ); InstallTrueMethod( IsAffineCrystGroupOnLeftOrRight, IsAffineCrystGroupOnRight ); InstallTrueMethod( IsAffineCrystGroupOnLeftOrRight, IsAffineCrystGroupOnLeft ); ############################################################################# ## #P IsAffineCrystGroup( ) . . . . . . . . . . . . AffineCrystGroup acting #P . . . . . . . . . . . . . . . . . as specified by CrystGroupDefaultAction ## DeclareGlobalFunction( "IsAffineCrystGroup" ); ############################################################################# ## #F AffineCrystGroupOnRight( ) . . . . . . . . . . . . . . . . . . . . #F AffineCrystGroupOnRight( ) . . . . . . . . . . . . . . . . . . #F AffineCrystGroupOnRight( , ) . . . . . . constructor ## DeclareGlobalFunction( "AffineCrystGroupOnRight" ); DeclareGlobalFunction( "AffineCrystGroupOnRightNC" ); ############################################################################# ## #F AffineCrystGroupOnLeft( ) . . . . . . . . . . . . . . . . . . . . #F AffineCrystGroupOnLeft( ) . . . . . . . . . . . . . . . . . . . #F AffineCrystGroupOnLeft( , ) . . . . . . . constructor ## DeclareGlobalFunction( "AffineCrystGroupOnLeft" ); DeclareGlobalFunction( "AffineCrystGroupOnLeftNC" ); ############################################################################# ## #F AffineCrystGroup( ) . . . . . . . . . . . . . . . . . . . . . . . #F AffineCrystGroup( ) . . . . . . . . . . . . . . . . . . . . . . #F AffineCrystGroup( , ) . . . . . . . . . . constructor ## DeclareGlobalFunction( "AffineCrystGroup" ); DeclareGlobalFunction( "AffineCrystGroupNC" ); ############################################################################# ## #F AsAffineCrystGroupOnRight( ) . . . . . . . . . . convert matrix group ## DeclareGlobalFunction( "AsAffineCrystGroupOnRight" ); ############################################################################# ## #F AsAffineCrystGroupOnLeft( ) . . . . . . . . . . convert matrix group ## DeclareGlobalFunction( "AsAffineCrystGroupOnLeft" ); ############################################################################# ## #F AsAffineCrystGroup( ) . . . . . . . . . . . . . convert matrix group ## DeclareGlobalFunction( "AsAffineCrystGroup" ); ############################################################################# ## ## Utility functions ## ############################################################################# ############################################################################# ## #F IsAffineMatrixOnRight( ) . . . . . . . affine matrix action OnRight ## DeclareGlobalFunction( "IsAffineMatrixOnRight" ); ############################################################################# ## #F IsAffineMatrixOnLeft( ) . . . . . . . . affine matrix action OnLeft ## DeclareGlobalFunction( "IsAffineMatrixOnLeft" ); ############################################################################# ## ## Properties and Attributes for matrix groups ## (AffineCrystGroups or PointGroups) ## ############################################################################# ############################################################################# ## #P IsSpaceGroup( ) . . . . . . . . . . . . . . . . is S a space group? ## DeclareProperty( "IsSpaceGroup", IsCyclotomicMatrixGroup ); InstallTrueMethod( IsGroup, IsSpaceGroup ); ############################################################################# ## #P IsStandardAffineCrystGroup( ) . . . AffineCrystGroup in standard form ## DeclareProperty( "IsStandardAffineCrystGroup", IsCyclotomicMatrixGroup ); InstallTrueMethod( IsGroup, IsStandardAffineCrystGroup ); ############################################################################# ## #P IsStandardSpaceGroup( ) . . . . . . . .space group in standard form? ## DeclareSynonym( "IsStandardSpaceGroup", IsSpaceGroup and IsStandardAffineCrystGroup ); ############################################################################# ## #P IsSymmorphicSpaceGroup( ) . . . . . . . . . . . . . .is S symmorphic? ## DeclareProperty( "IsSymmorphicSpaceGroup", IsCyclotomicMatrixGroup); InstallTrueMethod( IsGroup, IsSymmorphicSpaceGroup ); ############################################################################# ## #P IsPointGroup(

    ) . . . . . . . . . . PointGroup of an AffineCrystGroup ## DeclareProperty( "IsPointGroup", IsCyclotomicMatrixGroup ); InstallTrueMethod( IsGroup, IsPointGroup ); ############################################################################# ## #A NormalizerPointGroupInGLnZ(

    ) . . . . . . .Normalizer of a PointGroup ## DeclareAttribute( "NormalizerPointGroupInGLnZ", IsPointGroup ); ############################################################################# ## #A CentralizerPointGroupInGLnZ(

    ) . . . . . .Centralizer of a PointGroup ## DeclareAttribute( "CentralizerPointGroupInGLnZ", IsPointGroup ); ############################################################################# ## #A AffineCrystGroupOfPointGroup(

    ) . . AffineCrystGroup of a PointGroup ## DeclareAttribute( "AffineCrystGroupOfPointGroup", IsPointGroup ); ############################################################################# ## ## Properties and Attributes for AffineCrystGroups ## ############################################################################# ############################################################################# ## #A PointGroup( ) . . . . . . . . . . . PointGroup of an AffineCrystGroup ## DeclareAttribute( "PointGroup", IsAffineCrystGroupOnLeftOrRight ); ############################################################################# ## #A PointHomomorphism( ) . . . . PointHomomorphism of an AffineCrystGroup ## DeclareAttribute( "PointHomomorphism", IsAffineCrystGroupOnLeftOrRight ); ############################################################################# ## #A TranslationBasis( ) . . . . . . . . . . basis of translation lattice ## DeclareAttribute( "TranslationBasis", IsAffineCrystGroupOnLeftOrRight ); ############################################################################# ## #F AddTranslationBasis( , ) . . . . add basis of translation lattice ## DeclareGlobalFunction( "AddTranslationBasis" ); ############################################################################# ## #A CheckTranslationBasis( ) . . . . . check basis of translation lattice ## DeclareGlobalFunction( "CheckTranslationBasis" ); ############################################################################# ## #A InternalBasis( ) . . . . . . . . . . . . . . . . . . .internal basis ## DeclareAttribute( "InternalBasis", IsAffineCrystGroupOnLeftOrRight ); ############################################################################# ## #A TransParts( ) . . . . . translation parts (reduced modulo lattice) of ## . . . . . . . . . . . . . . . . . . . . .GeneratorsSmallest of PointGroup ## DeclareAttribute( "TransParts", IsAffineCrystGroupOnLeftOrRight ); ############################################################################# ## #A TranslationNormalizer( ) . . . . . . . . . . translational normalizer ## DeclareAttribute( "TranslationNormalizer", IsAffineCrystGroupOnLeftOrRight ); ############################################################################# ## #A AffineNormalizer( ) . . . . . . . . . . . . . . . . affine normalizer ## DeclareAttribute( "AffineNormalizer", IsAffineCrystGroupOnLeftOrRight ); ############################################################################# ## #F StandardAffineCrystGroup( ) . . . . . . . . . change basis to std rep ## DeclareGlobalFunction( "StandardAffineCrystGroup" ); ############################################################################# ## #F AffineInequivalentSubgroups( , ) reps of affine ineq. subgroups ## DeclareGlobalFunction( "AffineInequivalentSubgroups" ); cryst/gap/max.gi0000644001325400021140000006162614540066376013271 0ustar gaehleruser############################################################################# ## #A max.gi Cryst library Bettina Eick #A Franz G"ahler #A Werner Nickel ## #Y Copyright 1997-1999 by Bettina Eick, Franz G"ahler and Werner Nickel ## ## Routines for the determination of maximal subgroups of CrystGroups ## ############################################################################# ## #F CoefficientsMod( base, v ) . . . . . . . coefficients of v in factorspace ## CoefficientsMod := function( base, v ) local head, i, zero, coeff, w, j, h; if not IsBound( base.fullbase ) then base.fullbase := Concatenation( base.subspace, base.factorspace ); fi; if not IsBound( base.depth ) then head := []; for i in [1..Length( base.fullbase )] do head[i] := PositionNonZero( base.fullbase[i] ); od; base.depth := head; fi; zero := base.fullbase[1] * Zero( base.field ); coeff := ShallowCopy( zero ); w := v; while w <> zero do j := PositionNonZero( w ); h := Position( base.depth, j ); coeff[h] := coeff[h] + w[j]; w := w - w[j] * base.fullbase[h]; od; return coeff{[Length(base.subspace)+1..Length(base.fullbase)]}; end; ############################################################################# ## #F InducedMatrix( base, mat ) . . . . . . . . induced action of mat on base ## InducedMatrix := function( base, mat ) local ind, n, l, b, v, s; ind := []; n := Length(base.fullbase); l := Length(base.subspace); for b in base.factorspace do v := b * mat; s := SolutionMat( base.fullbase, v ); Add( ind, s{[l+1..n]} ); od; return ind; end; ############################################################################# ## #F TriangularizeMatVector . . . . . . . . . . compute triangularized matrix ## ## This function computes the upper triangular form of the integer ## matrix M via elementary row operations and performs the same ## operations on the (column) vector b. ## ## The function works in place. ## TriangularizeMatVector := function( M, b ) local zero, c, r, i, t; zero := M[1][1] * 0; c := 1; r := 1; while c <= Length(M[1]) and r <= Length(M) do i := r; while i <= Length(M) and M[i][c] = zero do i := i+1; od; if i <= Length(M) then t := b[r]; b[r] := b[i]; b[i] := t; t := M[r]; M[r] := M[i]; M[i] := t; b[r] := b[r] / M[r][c]; M[r] := M[r] / M[r][c]; for i in [1..r-1] do b[i] := b[i] - b[r] * M[i][c]; M[i] := ShallowCopy( M[i] ); AddCoeffs( M[i], M[r], -M[i][c] ); od; for i in [r+1..Length(M)] do b[i] := b[i] - b[r] * M[i][c]; M[i] := ShallowCopy( M[i] ); AddCoeffs( M[i], M[r], -M[i][c] ); od; r := r+1; fi; c := c+1; od; for i in Reversed( [r..Length(M)] ) do Unbind( M[i] ); od; end; ############################################################################# ## #F SolutionInhomEquations . . . solve an inhomogeneous system of equations ## ## This function computes the set of solutions of the equation ## ## X * M = b. ## SolutionInhomEquations := function( M, b ) local zero, one, i, c, d, r, heads, S, v; zero := M[1][1] * 0; one := M[1][1] ^ 0; M := MutableTransposedMat( M ); d := Length(M[1]); b := ShallowCopy( b ); TriangularizeMatVector( M, b ); for i in [Length(M)+1..Length(b)] do if b[i] <> zero then return false; fi; od; # determine the null space c := 1; r := 1; heads := []; S := []; while r <= Length(M) and c <= d do while c <= d and M[r][c] = zero do v := ShallowCopy( zero * [1..d] ); v{heads} := M{[1..r-1]}[c]; v[c] := -one; Add( S, v ); c := c+1; od; if c <= d then Add( heads, c ); c := c+1; r := r+1; fi; od; while c <= d do v := ShallowCopy( zero * [1..d] ); v{heads} := M{[1..r-1]}[c]; v[c] := -one; Add( S, v ); c := c+1; od; # one particular solution v := ShallowCopy( zero * [1..d] ); v{heads} := b{[1..Length(M)]}; if Length(S) > 0 then TriangulizeMat( S ); fi; return rec( basis := S, translation := v ); end; ############################################################################# ## #F SolutionHomEquations . . . . . . solve a homogeneous system of equations ## ## This function computes the set of solutions of the equation ## ## X * M = 0. ## SolutionHomEquations := function( M ) return SolutionInhomEquations( M, Zero(Field(M[1][1]))*[1..Length(M[1])]); end; ############################################################################# ## #F MatJacobianMatrix( G, mats ) ## MatJacobianMatrix := function( G, mats ) local gens, rels, J, D, # the result, the one `column' of J imats, # list of inverted matrices d, # dimension of matrices j, k, l, # loop variables r, # run through the relators h, p; # generator in r, its position in G.generators gens := GeneratorsOfGroup( FreeGroupOfFpGroup( G ) ); rels := RelatorsOfFpGroup( G ); if Length(gens) = 0 then return []; fi; d := Length( mats[1] ); imats := List( mats, m->m^-1 ); J := List( [1..d*Length(gens)], k->[] ); for j in [1..Length(rels)] do r := rels[j]; D := NullMat( d*Length(gens), d ); for k in [1..Length(r)] do h := Subword( r,k,k ); p := Position( gens, h ); if not IsBool( p ) then D := D * mats[p]; for l in [1..d] do D[(p-1)*d+l][l] := D[(p-1)*d+l][l] + 1; od; else p := Position( gens, h^-1 ); for l in [1..d] do D[(p-1)*d+l][l] := D[(p-1)*d+l][l] - 1; od; D := D * imats[p]; fi; J{[1..Length(gens)*d]}{[(j-1)*d+1..j*d]} := D; od; od; return J; end; ############################################################################# ## #F OneCoboundariesSG( , ) . . . . . . . . . . . . . . B^1( G, M ) ## OneCoboundariesSG := function( G, mats ) local d, I, S, i; d := Length( mats[1] ); I := IdentityMat( d ); if Length(mats) <> Length( GeneratorsOfGroup(G) ) then return Error( "As many matrices as generators expected" ); fi; S := List( [1..d], i->[] ); for i in [1..Length(mats)] do S{[1..d]}{[(i-1)*d+1..i*d]} := mats[i] - I; od; TriangulizeMat( S ); return S; end; ############################################################################# ## #F OneCocyclesVector( , , ) . . . . . . . . . . . . . . . . . . ## OneCocyclesVector := function( G, mats, b ) local J, L; J := MatJacobianMatrix( G, mats ); ## ## b needs to be inverted for the following reason (I don't know how to ## say this better without setting up a lot of notation. ## ## b was computed by CocycleInfo() by evaluating the relators of the ## group. In solving the system X * J = b we need to find all tuples of ## elements with the following property: If we modify the generating ## sequence with such a tuple by multiplying from the rigth, then the ## relators on the modified generators have to evaluate to the identity. ## For example, if we have the relation [g2,g1] = m, then [g2*y,g1*x] ## should be 1. Therefore, x and y should be chosen such that after ## collection we have [g2,g1] m^-1 = m m^-1 = 1. Hence we need to ## invert b. b := -Concatenation( b ); L := SolutionInhomEquations( J, b ); return L; end; ############################################################################# ## #F OneCocyclesSG( , ) . . . . . . . . . . . . . . . . Z^1( G, M ) ## OneCocyclesSG := function( G, mats ) local J, L; J := MatJacobianMatrix( G, mats ); L := SolutionHomEquations( J ).basis; return L; end; ############################################################################# ## #F OneCohomology( , ) . . . . . . . . . . . . . . . . H^1( G, M ) ## OneCohomologySG := function( G, mats ) return rec( cocycles := OneCocyclesSG( G, mats ), coboundaries := OneCoboundariesSG( G, mats ) ); end; ############################################################################# ## #F ListOneCohomology( ) . . . . . . . . . . . . . . . . . . . . list H^1 ## ## Run through the triangularized basis of Z and find those head ## entries which do not occur in the basis of B. For each such ## vector in the basis of Z we need to run through the coefficients ## 0..p-1. ## ListOneCohomology := function( H ) local Z, B, C, zero, coeffs, h, j, i; Z := H.cocycles; B := H.coboundaries; if Length(Z) = 0 then return B; fi; C := AsSSortedList( Field( Z[1][1] ) ); zero := Z[1][1]*0; coeffs := []; h := 1; j := 1; for i in [1..Length(Z)] do while Z[i][h] = zero do h := h+1; od; if j > Length(B) or B[j][h] = zero then coeffs[i] := C; else coeffs[i] := [ zero ]; j := j+1; fi; od; return List( Cartesian( coeffs ), t->t*Z ); end; ############################################################################# ## #F ComplementsSG . . . . . . . . . . . . compute complements up to conjugacy ## ComplementsSG := function( G, mats, b ) local Z, B, C, d, n; if Length(GeneratorsOfGroup(G)) = 0 then return [ [] ]; fi; Z := OneCocyclesVector( G, mats, b ); if Z = false then return []; fi; B := OneCoboundariesSG( G, mats ); C := ListOneCohomology( rec( cocycles := Z.basis, coboundaries := B ) ); C := List( C, c->c + Z.translation ); d := Length( mats[1] ); n := Length(GeneratorsOfGroup(G)); return List( C, c->List( [0..n-1], x->c{ [1..d] + x*d } ) ); end; ############################################################################# ## #F MaximalSubgroupRepsTG( < S > ) . .translationengleiche maximal subgroups ## ## This function computes conjugacy class representatives of the maximal ## subgroups of $S$ which contain $T$. Note that this function may be ## slow, if $S$ is not solvable. ## MaximalSubgroupRepsTG := function( S ) local d, P, N, T, Sgens, A, max, ind, l, i, gens, g, exp, h, j, trans, sub; d := DimensionOfMatrixGroup( S ) - 1; P := PointGroup( S ); N := NiceObject( P ); # catch a trivial case if Size( N ) = 1 then return []; fi; # compute the translation generators T := TranslationBasis( S ); trans := List( T, x -> IdentityMat( d+1 ) ); for i in [1..Length(T)] do trans[i][d+1]{[1..d]} := T[i]; od; # first the solvable case if IsSolvableGroup( N ) then A := GroupByPcgs( Pcgs( N ) ); Sgens := List( AsList( Pcgs( N ) ), x -> ImagesRepresentative( NiceToCryst( P ), x ) ); # compute maximal subgroups in ag group max := ShallowCopy( MaximalSubgroupClassReps( A ) ); # compute preimages in space group and construct subgroups for i in [1..Length(max)] do gens := []; for g in GeneratorsOfGroup( max[i] ) do exp := ExponentsOfPcElement( Pcgs( A ), g ); h := IdentityMat( d+1 ); for j in [1..Length(exp)] do h := h * Sgens[j]^exp[j]; od; Add( gens, h ); od; Append( gens, trans ); sub := SubgroupNC( S, gens ); AddTranslationBasis( sub, T ); SetIndexInParent( sub, IndexInParent( max[i] ) ); max[i] := sub; od; return max; fi; # now the non-solvable case max := List( ConjugacyClassesMaximalSubgroups( N ), Representative ); ind := List( max, x -> Index( N, x ) ); # go back to S, and construct the subgroups for i in [1..Length(max)] do gens := List( GeneratorsOfGroup( max[i] ), x -> ImagesRepresentative( NiceToCryst( P ), x ) ); Append( gens, trans ); sub := SubgroupNC( S, gens ); AddTranslationBasis( sub, T ); SetIndexInParent( sub, ind[i] ); max[i] := sub; od; return max; end; ############################################################################# ## #F CocycleInfo( ) . . . . . . . . . . .information about extension type ## CocycleInfo := function( S ) local P, iso, F, d, gens, mats, coc, rel, new; P := PointGroup( S ); iso := IsomorphismFpGroup( P ); F := Image( iso ); d := DimensionOfMatrixGroup( S ) - 1; gens := GeneratorsOfGroup( FreeGroupOfFpGroup( F ) ); mats := iso!.preimagesInAffineCrystGroup; coc := []; for rel in RelatorsOfFpGroup( F ) do new := MappedWord( rel, gens, mats ); Add( coc, new[d+1]{[1..d]} ); od; return coc; end; ############################################################################# ## #M CocVecs( ) . . Cocycles of extension of point group with translations ## InstallMethod( CocVecs, true, [ IsAffineCrystGroupOnRight ], 0, function( S ) return ReducedLatticeBasis( CocycleInfo( S ) ); end ); InstallMethod( CocVecs, true, [ IsAffineCrystGroupOnLeft ], 0, function( S ) return CocVecs( TransposedMatrixGroup( S ) ); end ); ############################################################################# ## #F SimpleGenerators( d, gens ) . . . . . . . . . . . simplify the generators ## SimpleGenerators := function( d, gens ) local I, new, g, trans, t, m; I := IdentityMat( d ); new := []; trans := []; for g in gens do if g{[1..d]}{[1..d]} = I then Add( trans, g[d+1]{[1..d]} ); else Add( new, g ); fi; od; trans := ReducedLatticeBasis( trans ); # add the new translation generators for t in trans do m := IdentityMat( d+1 ); m[d+1]{[1..d]} := t; Add( new, m ); od; return [ new, trans ]; end; ############################################################################# ## #F MaximalSubgroupRepsKG( < G >, ) . .klassengleiche maximal subgroups ## ## This function computes represenatives of the conjugacy classes of maximal ## subgroups of $G$ which have $p$-power index for some $p$ in the list $ps$ ## and do not contain $T$. ## In the case that $G$ is solvable it is more efficient to use the function ## 'MaximalSubgroupSG' and filter the corresponding maximal subgroups. ## MaximalSubgroupRepsKG := function( G, primes ) local P, iso, pres, coc, rep, d, n, maximals, p, field, repp, cocp, mods, sub, F, hom, cocin, repin, comp, c, modu, modgens, powers, vec, elm, basis, cocpre, gens, i, j, h, base, primeslist, Ggens, T, trans; # check argument if IsInt( primes ) then primeslist := [primes]; else primeslist := primes; fi; T := TranslationBasis( G ); n := Length( T ); # extract the point group P := PointGroup( G ); iso := IsomorphismFpGroup( P ); Ggens := iso!.preimagesInAffineCrystGroup; if not IsStandardAffineCrystGroup( G ) then Ggens := List ( Ggens, x -> G!.lconj * x * G!.rconj ); fi; pres := Image( iso ); rep := List( Ggens, x -> x{[1..n]}{[1..n]} ); coc := CocycleInfo( G ); if not IsEmpty( coc ) then coc := coc * T^-1; fi; d := DimensionOfMatrixGroup( G ) - 1; trans := List( T, x -> IdentityMat( d+1 ) ); for i in [1..n] do trans[i][d+1][i] := 1; od; # view them as matrices over GF(p) maximals := []; for p in primeslist do field := GF(p); repp := List( rep, x -> x * One( field ) ); cocp := List( coc, x -> x * One( field ) ); modu := GModuleByMats( repp, d, field ); mods := MTX.BasesMaximalSubmodules( modu ); powers:= List( trans, x -> x^p ); # compute induced operation on T/maxmod and induced cocycle for sub in mods do # compute group of translations of maximal subgroup modgens := []; for vec in sub do elm := One( G ); for j in [1..Length( vec )] do elm := elm * trans[j]^IntFFE(vec[j]); od; Add( modgens, elm ); od; Append( modgens, powers ); # compute quotient space base := BaseSteinitzVectors( IdentityMat( n, field ), sub ); TriangulizeMat(base.factorspace); base.field := field; cocin := List( cocp, x -> CoefficientsMod( base, x ) ); repin := List( repp, x -> InducedMatrix( base, x ) ); # use complement routine comp := ComplementsSG( pres, repin, cocin ); # compute generators of G corresponding to complements for i in [1..Length( comp )] do cocpre := List( comp[i], x -> x * base.factorspace ); gens := []; for j in [1..Length( cocpre )] do elm := Ggens[j]; for h in [1..Length( cocpre[j] )] do elm := elm*trans[h]^IntFFE(cocpre[j][h]); od; Add( gens, elm ); od; # append generators of group of translations Append( gens, modgens ); # conjugate generators if necessary if not IsStandardAffineCrystGroup( G ) then for j in [1..Length(gens)] do gens[j] := G!.rconj * gens[j] * G!.lconj; od; fi; # construct subgroup and append index gens := SimpleGenerators( d, gens ); comp[i] := SubgroupNC( G, gens[1] ); AddTranslationBasis( comp[i], gens[2] ); SetIndexInParent( comp[i], p^(n - Length( sub ) ) ); od; Append( maximals, comp ); od; od; return maximals; end; ############################################################################# ## #F MaximalSubgroupRepsSG( ,

    ) . . .maximal subgroups of solvable ## ## This function computes representatives of the conjugacy classes of the ## maximal subgroups of $p$-power index in $G$ in the case that $G$ is ## solvable. ## MaximalSubgroupRepsSG := function( G, p ) local iso, F, Fgens, Frels, Ffree, Ggens, T, n, d, t, gens, A, kernel, i, imgs, max, M, g, exp, h, j, Agens, pcgs, spcgs, first, weights; if not IsSolvableGroup( G ) then Error("G must be solvable \n"); fi; iso := IsomorphismFpGroup( PointGroup( G ) ); Ggens := iso!.preimagesInAffineCrystGroup; if not IsStandardAffineCrystGroup( G ) then Ggens := List ( Ggens, x -> G!.lconj * x * G!.rconj ); fi; F := Image( IsomorphismFpGroup( G ) ); Frels := RelatorsOfFpGroup( F ); Ffree := FreeGroupOfFpGroup( F ); Fgens := GeneratorsOfGroup( Ffree ); T := TranslationBasis( G ); n := Length( Ggens ); d := DimensionOfMatrixGroup( G ) - 1; t := Length( T ); gens := List( [n+1..n+t], x -> Fgens[x]^p ); F := Ffree / Concatenation( Frels, gens ); A := PcGroupFpGroup( F ); # compute maximal subgroups of S Agens := GeneratorsOfGroup( A ); if IsEmpty( Agens ) then pcgs := Pcgs(A); else pcgs := PcgsByPcSequence( FamilyObj(Agens[1]), Agens ); fi; spcgs := SpecialPcgs(A); first := LGFirst( spcgs ); weights := LGWeights( spcgs ); max := []; for i in [1..Length(first)-1] do if weights[first[i]][2] = 1 and weights[first[i]][3] = p then Append(max,ShallowCopy(MaximalSubgroupClassesRepsLayer(spcgs,i))); fi; od; # compute generators of kernel G -> A and preimages kernel := List( [1..t], x -> IdentityMat( d+1 ) ); for i in [1..t] do kernel[i][d+1][i] := 1; od; imgs := Concatenation( Ggens, List( kernel, m -> MutableMatrix( m ) ) ); for i in [1..t] do kernel[i][d+1][i] := p; od; # compute corresponding subgroups in G for i in [1..Length(max)] do M := max[i]; gens := []; for g in GeneratorsOfGroup( M ) do exp := ExponentsOfPcElement( pcgs, g ); h := Product( List( [1..Length(exp)], x -> imgs[x]^exp[x] ) ); Add( gens, h ); od; Append( gens, kernel ); if not IsStandardAffineCrystGroup( G ) then for j in [1..Length(gens)] do gens[j] := G!.rconj * gens[j] * G!.lconj; od; fi; gens := SimpleGenerators( d, gens ); M := SubgroupNC( G, gens[1] ); AddTranslationBasis( M, gens[2] ); SetIndexInParent( M, Index( A, max[i] ) ); max[i] := M; od; return max; end; ############################################################################# ## #M MaximalSubgroupClassReps( S, flags ) ## InstallOtherMethod( MaximalSubgroupClassReps, "for AffineCrystGroupOnRight", true, [ IsAffineCrystGroupOnRight, IsRecord ], 0, function( S, flags ) local reps, new, M, i; if IsBound( flags.primes ) then if not IsList( flags.primes ) or not ForAll( flags.primes, IsPrimeInt ) then Error("flags.primes must be a list of primes"); fi; fi; # the lattice-equal case if IsBound( flags.latticeequal ) and flags.latticeequal=true then if IsBound( flags.classequal ) and flags.classequal=true then Error("both classequal and latticeequal is impossible!"); fi; reps := MaximalSubgroupRepsTG( S ); if IsBound( flags.primes ) then new := []; for M in reps do i := Index( S, M ); if IsPrimePowerInt( i ) and FactorsInt(i)[1] in flags.primes then Add( new, M ); fi; od; return new; fi; return reps; fi; # the class-equal case if IsBound( flags.classequal ) and flags.classequal=true then if not IsBound( flags.primes ) then Error("flags.primes must be bound"); fi; return MaximalSubgroupRepsKG( S, flags.primes ); fi; # the p-index case if IsBound( flags.primes ) then if IsSolvableGroup( S ) then return Concatenation( List( flags.primes, x -> MaximalSubgroupRepsSG( S, x ) ) ); else reps := MaximalSubgroupRepsTG( S ); new := []; for M in reps do i := Index( S, M ); if IsPrimePowerInt( i ) and FactorsInt(i)[1] in flags.primes then Add( new, M ); fi; od; Append( new, MaximalSubgroupRepsKG( S, flags.primes ) ); return new; fi; fi; Error("inconsistent input - check manual"); end ); InstallOtherMethod( MaximalSubgroupClassReps, "for AffineCrystGroupOnLeft", true, [ IsAffineCrystGroupOnLeft, IsRecord ], 0, function( S, flags ) local G, reps, lst, max, gen, new; G := TransposedMatrixGroup( S ); reps := MaximalSubgroupClassReps( G, flags ); lst := []; for max in reps do gen := List( GeneratorsOfGroup( max ), TransposedMat ); new := SubgroupNC( S, gen ); if HasTranslationBasis( max ) then AddTranslationBasis( new, TranslationBasis( max ) ); fi; if HasIndexInParent( max ) then SetIndexInParent( new, IndexInParent( max ) ); fi; Add( lst, new ); od; return lst; end ); ############################################################################# ## #M ConjugacyClassesMaximalSubgroups( S, flags ) ## InstallOtherMethod( ConjugacyClassesMaximalSubgroups, "forAffineCrystGroup", true, [ IsAffineCrystGroupOnLeftOrRight, IsRecord ], 0, function( S, flags ) local reps, cls, M, c; reps := MaximalSubgroupClassReps( S, flags ); cls := []; for M in reps do c := ConjugacyClassSubgroups( S, M ); if not IsNormal( S, M ) then SetSize( c, IndexInParent( M ) ); else SetSize( c, 1 ); fi; Add( cls, c ); od; return cls; end ); cryst/gap/color.gi0000644001325400021140000001354213232361435013603 0ustar gaehleruser############################################################################# ## #A color.gi Cryst library Bettina Eick #A Franz G"ahler #A Werner Nickel ## #Y Copyright 1997-1999 by Bettina Eick, Franz G"ahler and Werner Nickel ## ## Cryst - the crystallographic groups package for GAP (color groups) ## ############################################################################# ## #M IsColorGroup( G ) . . . . . . . . . . . . . . . . . .is it a color group? ## # Subgroups of ColorGroups are ColorGroups InstallSubsetMaintenance( IsColorGroup, IsGroup, IsCollection ); # ColorGroups always know that they are ColorGroups InstallMethod( IsColorGroup, "fallback method", true, [ IsGroup ], 0, G -> false ); ############################################################################# ## #M ColorSubgroup( G ) . . . . . . . . . . . . . . extract the color subgroup ## InstallMethod( ColorSubgroup, "for subgroups", true, [ IsColorGroup and HasParent ], 0, function( G ) local P; P := Parent( G ); while HasParent( P ) and P <> Parent( P ) do P := Parent( P ); od; return Intersection( ColorSubgroup( P ), G ); # return Stabilizer( G, ColorCosetList( P )[1], OnRight ); end ); ############################################################################# ## #M ColorCosetList( G ) . . . . . . . . . . . . . .color labelling coset list ## InstallMethod( ColorCosetList, "generic", true, [ IsColorGroup ], 0, G -> RightCosets( G, ColorSubgroup( G ) ) ); ############################################################################# ## #M ColorOfElement( G, elm ) . . . . . . . . . . . . . . .color of an element ## InstallGlobalFunction( ColorOfElement, function( G, elm ) local P, cos, i; P := G; while HasParent( P ) and Parent( P ) <> P do P := Parent( P ); od; cos := ColorCosetList( P ); for i in [1..Length( cos )] do if elm in cos[i] then return i; fi; od; Error("elm must be an element of G"); end ); ############################################################################# ## #F ColorPermGroupHomomorphism( G ) . . . . .color PermGroup and homomorphism ## ColorPermGroupHomomorphism := function( G ) local P, pmg, hom; P := G; while HasParent( P ) and P <> Parent( P ) do P := Parent( P ); od; pmg := Action( G, ColorCosetList( P ), OnRight ); hom := ActionHomomorphism( G, pmg ); return [ pmg, hom ]; end; ############################################################################# ## #M ColorPermGroup( G ) . . . . . . . . . . . . . . . . . . . color PermGroup ## InstallMethod( ColorPermGroup, "generic", true, [ IsColorGroup ], 0, function( G ) local tmp; tmp := ColorPermGroupHomomorphism( G ); SetColorHomomorphism( G, tmp[2] ); return tmp[1]; end ); ############################################################################# ## #M ColorHomomorphism( G ) . . . . . . . . . .homomorphism to color PermGroup ## InstallMethod( ColorHomomorphism, "generic", true, [ IsColorGroup ], 0, function( G ) local tmp; tmp := ColorPermGroupHomomorphism( G ); SetColorPermGroup( G, tmp[1] ); return tmp[2]; end ); ############################################################################# ## #M PointGroup( G ) . . . . . . . . . . . . . . . . . . . . .color PointGroup ## InstallMethod( PointGroup, "for colored AffineCrystGroups", true, [ IsColorGroup and IsAffineCrystGroupOnLeftOrRight ], 0, function( G ) local tmp, P, hom, H, reps; tmp := PointGroupHomomorphism( G ); P := tmp[1]; hom := tmp[2]; SetPointGroup( G, P ); SetPointHomomorphism( G, hom ); # color the point group if possible H := ColorSubgroup( G ); if TranslationBasis( G ) = TranslationBasis( H ) then H := PointGroup( H ); SetIsColorGroup( P, true ); SetColorSubgroup( P, H ); reps := List( ColorCosetList( G ), x -> ImagesRepresentative( hom, Representative( x ) ) ); SetColorCosetList( P, List( reps, x -> RightCoset( H, x ) ) ); fi; return P; end ); ############################################################################# ## #M ColorGroup( G, H ) . . . . . . . . . . . . . . . . . . make a color group ## InstallGlobalFunction( ColorGroup, function( G, H ) local C, U, P, reps; # H must be a subgroup of G if not IsSubgroup( G, H ) then Error("H must be contained in G"); fi; # since G may contain uncolored information components, make a new group C := GroupByGenerators( GeneratorsOfGroup( G ), One( G ) ); U := GroupByGenerators( GeneratorsOfGroup( H ), One( H ) ); # make C a color group SetIsColorGroup( C, true ); SetColorSubgroup( C, U ); # if G is an AffineCrystGroup, make C am AffineCrystGroup if IsCyclotomicMatrixGroup( G ) then if IsAffineCrystGroupOnRight( G ) then SetIsAffineCrystGroupOnRight( C, true ); SetIsAffineCrystGroupOnRight( U, true ); if HasTranslationBasis( H ) then AddTranslationBasis( U, TranslationBasis( H ) ); fi; if HasTranslationBasis( G ) then AddTranslationBasis( C, TranslationBasis( G ) ); fi; fi; if IsAffineCrystGroupOnLeft( G ) then SetIsAffineCrystGroupOnLeft( C, true ); SetIsAffineCrystGroupOnLeft( U, true ); if HasTranslationBasis( H ) then AddTranslationBasis( U, TranslationBasis( H ) ); fi; if HasTranslationBasis( G ) then AddTranslationBasis( C, TranslationBasis( G ) ); fi; fi; fi; SetParent( C, C ); return C; end ); cryst/gap/orbstab.gi0000644001325400021140000003111014372461414014114 0ustar gaehleruser############################################################################# ## #A orbstab.gi Cryst library Bettina Eick #A Franz G"ahler #A Werner Nickel ## #Y Copyright 1997-1999 by Bettina Eick, Franz G"ahler and Werner Nickel ## ############################################################################# ## #M Orbit( G, H, gens, oprs, opr ) . . . . . . . . . .for an AffineCrystGroup ## InstallOtherMethod( OrbitOp, "G, H, gens, oprs, opr for AffineCrystGroups", true, [ IsAffineCrystGroupOnRight, IsAffineCrystGroupOnRight, IsList, IsList, IsFunction ], 10, function( G, H, gens, oprs, opr ) local orb, grp, gen, img; if opr = OnPoints then orb := [ H ]; for grp in orb do for gen in oprs do img := List( GeneratorsOfGroup( grp ), x -> x^gen ); if not ForAny( orb, g -> ForAll( img, x -> x in g ) ) then Add( orb, ConjugateGroup( grp, gen ) ); fi; od; od; return orb; else TryNextMethod(); fi; end ); InstallOtherMethod( OrbitOp, "G, H, gens, oprs, opr for AffineCrystGroups", true, [ IsAffineCrystGroupOnLeft, IsAffineCrystGroupOnLeft, IsList, IsList, IsFunction ], 10, function( G, H, gens, oprs, opr ) local orb, grp, gen, img; if opr = OnPoints then orb := [ H ]; for grp in orb do for gen in oprs do img := List( GeneratorsOfGroup( grp ), x -> x^gen ); if not ForAny( orb, g -> ForAll( img, x -> x in g ) ) then Add( orb, ConjugateGroup( grp, gen ) ); fi; od; od; return orb; else TryNextMethod(); fi; end ); ############################################################################# ## #M OrbitStabilizer( G, H, gens, oprs, opr ) . . . . .for an AffineCrystGroup ## InstallOtherMethod( OrbitStabilizerOp, "G, H, gens, oprs, opr for AffineCrystGroups", true, [ IsAffineCrystGroupOnRight, IsAffineCrystGroupOnRight, IsList, IsList, IsFunction ], 0, function( G, H, gens, oprs, opr ) local orb, rep, stb, grp, k, img, i, sch; if opr = OnPoints then orb := [ H ]; rep := [ One( G ) ]; if IsSubgroup( G, H ) then stb := H; else stb := Intersection2( G, H ); fi; for grp in orb do for k in [1..Length(gens)] do img := List( GeneratorsOfGroup( grp ), x -> x^oprs[k] ); i := PositionProperty( orb, g -> ForAll( img, x -> x in g ) ); if i = fail then Add( orb, ConjugateGroup( grp, oprs[k] ) ); Add( rep, rep[Position(orb,grp)] * oprs[k] ); else sch := rep[Position(orb,grp)] * gens[k] / rep[i]; if not sch in stb then stb := ClosureGroup( stb, sch ); fi; fi; od; od; return Immutable( rec( orbit := orb, stabilizer := stb ) ); else TryNextMethod(); fi; end ); InstallOtherMethod( OrbitStabilizerOp, "G, H, gens, oprs, opr for AffineCrystGroups", true, [ IsAffineCrystGroupOnLeft, IsAffineCrystGroupOnLeft, IsList, IsList, IsFunction ], 0, function( G, H, gens, oprs, opr ) local orb, rep, stb, grp, k, img, i, sch; if opr = OnPoints then orb := [ H ]; rep := [ One( G ) ]; if IsSubgroup( G, H ) then stb := H; else stb := Intersection2( G, H ); fi; for grp in orb do for k in [1..Length(gens)] do img := List( GeneratorsOfGroup( grp ), x -> x^oprs[k] ); i := PositionProperty( orb, g -> ForAll( img, x -> x in g ) ); if i = fail then Add( orb, ConjugateGroup( grp, oprs[k] ) ); Add( rep, rep[Position(orb,grp)] * oprs[k] ); else sch := rep[Position(orb,grp)] * gens[k] / rep[i]; if not sch in stb then stb := ClosureGroup( stb, sch ); fi; fi; od; od; return Immutable( rec( orbit := orb, stabilizer := stb ) ); else TryNextMethod(); fi; end ); ############################################################################# ## #M RepresentativeAction( G, d, e, opr ) . . . . . . for an AffineCrystGroup ## InstallOtherMethod( RepresentativeActionOp, "G, d, e, opr for AffineCrystGroups", true, [ IsAffineCrystGroupOnRight, IsAffineCrystGroupOnRight, IsAffineCrystGroupOnRight, IsFunction ], 0, function( G, d, e, opr ) local Td, Te, PG, f, r, n, Pd, Pe, r2, R, dim, gP, M, i, TG, tr1, tr2, tt, res, gN, orb, rep, x, g, dd, redtrans; if opr <> OnPoints then TryNextMethod(); fi; redtrans := function( TG, tr1, tr2, t2, P, U ) local dim, gen, t1, sol; dim := DimensionOfMatrixGroup( P ); gen := List( GeneratorsOfGroup( P ), x -> PreImagesRepresentativeNC( PointHomomorphism( U ), x ) ); t1 := Concatenation( List( gen, x -> x[dim+1]{[1..dim]} ) ) - t2; sol := IntSolutionMat( tr1, -t1 ); if sol = fail then return VectorModL( t2, tr2 ); else return AugmentedMatrix( One( P ), sol{[1..Length(TG)]} * TG ); fi; end; # have the translation basis the same length? Td := TranslationBasis( d ); Te := TranslationBasis( e ); if Length( Td ) <> Length( Te ) then return fail; fi; # map translation basis onto each other PG := PointGroup( G ); if Length( Td ) > 0 then f := function(x,g) return ReducedLatticeBasis( x*g ); end; r := RepresentativeAction( PG, Td, Te, f ); if r = fail then return fail; fi; n := Stabilizer( PG, Te, f ); else n := PG; r := One( PG ); fi; # map point groups onto each other Pd := PointGroup( d ); Pe := PointGroup( e ); r2 := RepresentativeAction( n, Pd^r, Pe ); if r2 = fail then return fail; fi; r := r*r2; R := PreImagesRepresentativeNC( PointHomomorphism( G ), r ); dim := DimensionOfMatrixGroup( PG ); gP := GeneratorsOfGroup( Pe ); M := NullMat( Length(gP) * Length(Te), dim * Length(gP) ); if not IsEmpty( Te ) then for i in [1..Length(gP)] do M{[1..Length(Te)]+(i-1)*Length(Te)}{[1..dim]+(i-1)*dim} := Te; od; fi; TG := TranslationBasis( G ); tr1 := List( TG, t -> Concatenation( List( gP, x -> t * ( One(Pe)-x ) ) ) ); tr1 := Concatenation( tr1, M ); tr2 := ReducedLatticeBasis( tr1 ); tt := List( gP, x -> PreImagesRepresentativeNC( PointHomomorphism(e), x )); tt := Concatenation( List( tt, x -> x[dim+1]{[1..dim]} ) ); # is there a conjugating translation? res := redtrans( TG, tr1, tr2, tt, Pe, d^R ); if IsMatrix( res ) then return R * res; fi; # now we have to try the normalizer gN := Filtered( GeneratorsOfGroup( Normalizer(n, Pe) ), x -> not x in Pe ); gN := List( gN, x -> PreImagesRepresentativeNC( PointHomomorphism(G), x ) ); orb := [ res ]; rep := [ R ]; for x in rep do for g in gN do dd := d ^ (x * g); res := redtrans( TG, tr1, tr2, tt, Pe, dd ); if IsMatrix( res ) then return x * g * res; fi; if not res in orb then Add( orb, res ); Add( rep, x * g ); fi; od; od; return fail; end ); InstallOtherMethod( RepresentativeActionOp, "G, d, e, opr for AffineCrystGroups", true, [ IsAffineCrystGroupOnLeft, IsAffineCrystGroupOnLeft, IsAffineCrystGroupOnLeft, IsFunction ], 0, function( G, d, e, opr ) local C; C := RepresentativeAction( TransposedMatrixGroup( G ), TransposedMatrixGroup( d ), TransposedMatrixGroup( e ), opr ); if C = fail then return fail; else return TransposedMat( C ); fi; end ); ############################################################################# ## #F ConjugatingTranslation( G, gen, T) ## ## returns a translation t from the Z-span of T such that the elements ## of gen conjugated with t are in G (or fail if no such t exists) ## ConjugatingTranslation := function( G, gen, T ) local d, b, TG, lt, lg, M, I, i, g, m, sol, t; d := DimensionOfMatrixGroup( G ) - 1; TG := TranslationBasis( G ); lt := Length( T ); lg := Length( TG ); b := []; M := NullMat( lt + lg * Length(gen), d * Length(gen) ); I := IdentityMat( d ); for i in [1..Length(gen)] do g := gen[i]{[1..d]}{[1..d]}; if not g in PointGroup( G ) then return fail; fi; m := PreImagesRepresentativeNC( PointHomomorphism( G ), g ); Append( b, -gen[i][d+1]{[1..d]} + m[d+1]{[1..d]} ); M{[1..lt]}{[1..d]+(i-1)*d} := T * (I - g); if lg > 0 then M{[1..lg]+lt+(i-1)*lg}{[1..d]+(i-1)*d} := TG; fi; od; sol := IntSolutionMat( M, b ); if IsList( sol ) then sol := sol{[1..lt]} * T; # t := AugmentedMatrix( I, sol ); # for g in gen do # Assert( 0, g^t in G ); # od; return sol; else return fail; fi; end; ############################################################################# ## #M Normalizer( G, H ) . . . . . . . . . . . . . . . . . . . . . . normalizer ## InstallMethod( NormalizerOp, "two AffineCrystGroupsOnRight", IsIdenticalObj, [ IsAffineCrystGroupOnRight, IsAffineCrystGroupOnRight ], 0, function( G, H ) local P, TH, TG, d, I, gens, T, t, trn, orb, rep, stb, grp, gen, img, i, sch, g, b, M, m, sol, Q, N; # we must normalize the point group and the translation subgroup P := Normalizer( PointGroup( G ), PointGroup( H ) ); TH := TranslationBasis( H ); if TH <> [] then P := Stabilizer( P, TH, function( x, g ) return ReducedLatticeBasis( x * g ); end ); fi; # lift P to G d := DimensionOfMatrixGroup( P ); I := IdentityMat( d ); gens := List( GeneratorsOfGroup( P ), x -> PreImagesRepresentativeNC( PointHomomorphism( G ), x ) ); # stabilizer of translation conjugacy class of H TG := TranslationBasis( G ); orb := [ H ]; rep := [ One( G ) ]; stb := TrivialSubgroup( G ); for grp in orb do for gen in gens do img := List( GeneratorsOfGroup( grp ), x -> x^gen ); i := PositionProperty( orb, g -> ConjugatingTranslation( g, img, TG ) <> fail ); if i = fail then Add( orb, ConjugateGroup( grp, gen ) ); Add( rep, rep[Position(orb,grp)] * gen ); else sch := rep[Position(orb,grp)] * gen / rep[i]; stb := ClosureGroup( stb, sch ); fi; od; od; gens := List( GeneratorsOfGroup( stb ), MutableMatrix ); # fix the translations for gen in gens do img := List( GeneratorsOfGroup( H ), x -> x^gen ); trn := ConjugatingTranslation( H, img, TG ); gen[d+1]{[1..d]} := gen[d+1]{[1..d]} + trn; od; gens := Set( gens ); # construct the pure translations T := TG; for g in GeneratorsOfGroup( PointGroup( H ) ) do if T <> [] then M := Concatenation( T * (g-I), TH ); M := M * Lcm( List( Flat( M ), DenominatorRat ) ); Q := IdentityMat( Length( M ) ); M := RowEchelonFormT( M, Q ); T := Q{[Length(M)+1..Length(Q)]}{[1..Length(T)]} * T; T := ReducedLatticeBasis( T ); fi; od; for t in T do Add( gens, AugmentedMatrix( I, t ) ); od; # for g in gens do # Assert( 0, H^g = H ); # od; # construct the normalizer N := AffineCrystGroupOnRight( gens, One( G ) ); AddTranslationBasis( N, T ); return N; end ); InstallMethod( NormalizerOp, "two AffineCrystGroupsOnLeft", IsIdenticalObj, [ IsAffineCrystGroupOnLeft, IsAffineCrystGroupOnLeft ], 0, function( G, H ) return TransposedMatrixGroup( Normalizer( TransposedMatrixGroup(G), TransposedMatrixGroup(H) ) ); end ); cryst/gap/color.gd0000644001325400021140000000364013232361435013574 0ustar gaehleruser############################################################################# ## #A color.gd Cryst library Bettina Eick #A Franz G"ahler #A Werner Nickel ## #Y Copyright 1997-1999 by Bettina Eick, Franz G"ahler and Werner Nickel ## ## Cryst - the crystallographic groups package for GAP (color groups) ## ############################################################################# ## #P IsColorGroup( G ) . . . . . . . . . . . . . . . . . .is it a color group? ## DeclareProperty( "IsColorGroup", IsGroup ); ############################################################################# ## #A ColorSubgroup( G ) . . . . . . . . . . . . . . extract the color subgroup ## DeclareAttribute( "ColorSubgroup", IsColorGroup ); ############################################################################# ## #A ColorCosetList( G ) . . . . . . . . . . . . . .color labelling coset list ## DeclareAttribute( "ColorCosetList", IsColorGroup ); ############################################################################# ## #A ColorPermGroup( G ) . . . . . . . . . . . . . . . . . . . color PermGroup ## DeclareAttribute( "ColorPermGroup", IsColorGroup ); ############################################################################# ## #A ColorHomomorphism( G ) . . . . . . . . . .homomorphism to color PermGroup ## DeclareAttribute( "ColorHomomorphism", IsColorGroup ); ############################################################################# ## #F ColorOfElement( G, elem ) . . . . . . . . . . . . . . color of an element ## DeclareGlobalFunction( "ColorOfElement" ); ############################################################################# ## #F ColorGroup( G, H ) . . . . . . . . . . . . . . . . . . make a color group ## DeclareGlobalFunction( "ColorGroup" ); cryst/gap/cryst.gi0000644001325400021140000006601414540072334013633 0ustar gaehleruser############################################################################# ## #A cryst.gi Cryst library Bettina Eick #A Franz G"ahler #A Werner Nickel ## #Y Copyright 1997-2012 by Bettina Eick, Franz G"ahler and Werner Nickel ## ## Methods for affine crystallographic groups ## ############################################################################# ## ## Utility functions ## ############################################################################# ############################################################################# ## #M IsAffineMatrixOnRight( ) . . . . . . . affine matrix action OnRight ## InstallGlobalFunction( IsAffineMatrixOnRight, function( mat ) local d, v; if not IsMatrix( mat ) or not IsCyclotomicCollColl( mat ) then return false; fi; d := Length( mat ); if not DimensionsMat( mat ) = [d,d] then return false; fi; v := 0 * [1..d]; v[d] := 1; return mat{[1..d]}[d] = v; end ); ############################################################################# ## #M IsAffineMatrixOnLeft( ) . . . . . . . . affine matrix action OnLeft ## InstallGlobalFunction( IsAffineMatrixOnLeft, function( mat ) local d, v; if not IsMatrix( mat ) or not IsCyclotomicCollColl( mat ) then return false; fi; d := Length( mat ); if not DimensionsMat( mat ) = [d,d] then return false; fi; v := 0 * [1..d]; v[d] := 1; return mat[d] = v; end ); ############################################################################# ## ## Methods and functions for CrystGroups and PointGroups ## ############################################################################# ############################################################################# ## #M IsAffineCrystGroupOnLeftOrRight( ) . . . . . AffineCrystGroup acting #M . . . . . . . . . . . . . . . . . . . . . . . . either OnLeft or OnRight ## InstallTrueMethod(IsAffineCrystGroupOnLeftOrRight,IsAffineCrystGroupOnRight); InstallTrueMethod(IsAffineCrystGroupOnLeftOrRight,IsAffineCrystGroupOnLeft); ############################################################################# ## #M TransposedMatrixGroup( ) . . . . . . . .transpose of AffineCrystGroup ## InstallMethod( TransposedMatrixGroup, true, [ IsAffineCrystGroupOnLeftOrRight ], 0, function( S ) local gen, grp; gen := List( GeneratorsOfGroup( S ), TransposedMat ); grp := Group( gen, One( S ) ); if IsAffineCrystGroupOnRight( S ) then SetIsAffineCrystGroupOnLeft( grp, true ); else SetIsAffineCrystGroupOnRight( grp, true ); fi; if HasTranslationBasis( S ) then AddTranslationBasis( grp, TranslationBasis( S ) ); fi; SetTransposedMatrixGroup( grp, S ); UseIsomorphismRelation( S, grp ); return grp; end ); ############################################################################# ## #M InternalBasis( S ) . . . . . . . . . . . . . . . . . . . . internal basis ## InstallMethod( InternalBasis, true, [ IsAffineCrystGroupOnLeftOrRight ], 0, function( S ) local d, T, basis, comp, i, j, k, mat; d := DimensionOfMatrixGroup( S ) - 1; T := TranslationBasis( S ); if Length( T ) = d then basis := T; elif Length( T ) = 0 then basis := IdentityMat( d ); else comp := NullMat( d - Length(T), d ); i:=1; j:=1; k:=1; while i <= Length( T ) do while T[i][j] = 0 do comp[k][j] := 1; k := k+1; j:=j+1; od; i := i+1; j := j+1; od; while j <= d do comp[k][j] := 1; k := k+1; j:=j+1; od; basis := Concatenation( T, comp ); fi; SetIsStandardAffineCrystGroup( S, basis = IdentityMat( d ) ); if not IsStandardAffineCrystGroup( S ) then mat := IdentityMat( d+1 ); mat{[1..d]}{[1..d]} := basis; if IsAffineCrystGroupOnRight( S ) then S!.lconj := mat; S!.rconj := mat^-1; else mat := TransposedMat( mat ); S!.lconj := mat^-1; S!.rconj := mat; fi; fi; return basis; end ); ############################################################################# ## #F TranslationBasisFun( S ) . . . . . determine basis of translation lattice ## TranslationBasisFun := function ( S ) local d, P, Sgens, Pgens, trans, g, m, F, Fgens, rel, new; if IsAffineCrystGroupOnLeft( S ) then Error( "use only for an AffineCrystGroupOnRight" ); fi; d := DimensionOfMatrixGroup( S ) - 1; P := PointGroup( S ); Pgens := []; Sgens := []; trans := []; # first the obvious translations for g in GeneratorsOfGroup( S ) do m := g{[1..d]}{[1..d]}; if IsOne( m ) then Add( trans, g[d+1]{[1..d]} ); else Add( Sgens, g ); Add( Pgens, m ); fi; od; # then the hidden translations if not IsTrivial( P ) then F := Image( IsomorphismFpGroupByGenerators( P, Pgens ) ); Fgens := GeneratorsOfGroup( FreeGroupOfFpGroup( F ) ); for rel in RelatorsOfFpGroup( F ) do new := MappedWord( rel, Fgens, Sgens ); Add( trans, new[d+1]{[1..d]} ); od; fi; # make translations invariant under point group trans := Set( Union( Orbits( P, trans ) ) ); return ReducedLatticeBasis( trans ); end; ############################################################################# ## #M AddTranslationBasis( S, basis ) . . . . .add basis of translation lattice ## InstallGlobalFunction( AddTranslationBasis, function ( S, basis ) local T; if not IsAffineCrystGroupOnLeftOrRight( S ) then Error("S must be an AffineCrystGroup"); fi; T := ReducedLatticeBasis( basis ); if HasTranslationBasis( S ) then if T <> TranslationBasis( S ) then Error("adding incompatible translation basis attempted"); fi; else SetTranslationBasis( S, T ); if not IsStandardAffineCrystGroup( S ) then InternalBasis( S ); # computes S!.lconj, S!.rconj fi; fi; end ); ############################################################################# ## #M TranslationBasis( S ) . . . . . . . . . . . .basis of translation lattice ## InstallMethod( TranslationBasis, true, [ IsAffineCrystGroupOnLeftOrRight ],0, function( S ) local T; if IsAffineCrystGroupOnRight( S ) then T := TranslationBasisFun( S ); else T := TranslationBasis( TransposedMatrixGroup( S ) ); fi; AddTranslationBasis( S, T ); return T; end ); ############################################################################# ## #M CheckTranslationBasis( S ) . . . . . . check basis of translation lattice ## InstallGlobalFunction( CheckTranslationBasis, function( S ) local T; if IsAffineCrystGroupOnRight( S ) then T := TranslationBasisFun( S ); else T := TranslationBasisFun( TransposedMatrixGroup( S ) ); fi; if HasTranslationBasis( S ) then if T <> TranslationBasis( S ) then Print( "#W Warning: translations are INCORRECT - you better\n", "#W start again with a fresh group!\n" ); fi; else AddTranslationBasis( S, T ); fi; end ); ############################################################################# ## #M \^( S, conj ) . . . . . . . . . . . . . . . . . . . . . . . change basis ## InstallOtherMethod( \^, IsCollsElms, [ IsAffineCrystGroupOnRight, IsMatrix ], 0, function ( S, conj ) local d, c, C, Ci, gens, i, R, W, r, w, t; d := DimensionOfMatrixGroup( S ) - 1; if not IsAffineMatrixOnRight( conj ) then Error( "conj must represent an affine transformation" ); fi; # get the conjugators; C := conj; Ci := conj^-1; c := C {[1..d]}{[1..d]}; t := C [d+1]{[1..d]}; # Translation # conjugate the generators of S gens := ShallowCopy( GeneratorsOfGroup( S ) ); for i in [1..Length(gens)] do gens[i] := Ci * gens[i] * C; od; R := AffineCrystGroupOnRight( gens, One( S ) ); # add translations if known if HasTranslationBasis( S ) then AddTranslationBasis( R, TranslationBasis( S ) * c ); fi; # add Wyckoff positions if known if HasWyckoffPositions( S ) then W := []; for w in WyckoffPositions( S ) do r := rec( basis := w!.basis, translation := w!.translation*c + t, class := w!.class, spaceGroup := R ); if r.basis <> [] then r.basis := r.basis * c; fi; ReduceAffineSubspaceLattice( r ); Add( W, WyckoffPositionObject( r ) ); od; SetWyckoffPositions( R, W ); fi; return R; end ); InstallOtherMethod( \^, IsCollsElms, [ IsAffineCrystGroupOnLeft, IsMatrix ], 0, function ( S, conj ) local d, c, C, Ci, gens, i, R, W, r, w, t; d := DimensionOfMatrixGroup( S ) - 1; if not IsAffineMatrixOnLeft( conj ) then Error( "conj must represent an affine transformation" ); fi; # get the conjugators; C := conj; Ci := conj^-1; c := TransposedMat( C {[1..d]}{[1..d]} ); t := C {[1..d]}[d+1]; # Translation # conjugate the generators of S gens := ShallowCopy( GeneratorsOfGroup( S ) ); for i in [1..Length(gens)] do gens[i] := C * gens[i] * Ci; od; R := AffineCrystGroupOnLeft( gens, One( S ) ); # add translations if known if HasTranslationBasis( S ) then AddTranslationBasis( R, TranslationBasis( S ) * c ); fi; # add Wyckoff positions if known if HasWyckoffPositions( S ) then W := []; for w in WyckoffPositions( S ) do r := rec( basis := w!.basis, translation := w!.translation*c + t, class := w!.class, spaceGroup := R ); if r.basis <> [] then r.basis := r.basis * c; fi; ReduceAffineSubspaceLattice( r ); Add( W, WyckoffPositionObject( r ) ); od; SetWyckoffPositions( R, W ); fi; return R; end ); ############################################################################# ## #M StandardAffineCrystGroup( S ) . . . . . . . . . . change basis to std rep ## InstallGlobalFunction( StandardAffineCrystGroup, function( S ) local B, d, C; if IsAffineCrystGroupOnRight( S ) then B := InternalBasis( S ); elif IsAffineCrystGroupOnLeft( S ) then B := TransposedMat( InternalBasis( S ) ); else Error( "S must be an AffineCrystGroup" ); fi; d := DimensionOfMatrixGroup( S ) - 1; C := IdentityMat( d+1 ); C{[1..d]}{[1..d]} := B^-1; return S^C; end ); ############################################################################# ## #M Size( S ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .Size ## InstallMethod( Size, "for AffineCrystGroup", true, [ IsAffineCrystGroupOnLeftOrRight ], 0, function( S ) if Length( TranslationBasis( S ) ) > 0 then return infinity; else return Size( PointGroup( S ) ); fi; end ); ############################################################################# ## #M IsFinite( S ) . . . . . . . . . . . . . . . . . . . . . . . . . .IsFinite ## InstallMethod( IsFinite, "for AffineCrystGroup", true, [ IsAffineCrystGroupOnLeftOrRight ], 0, S -> Length( TranslationBasis( S ) ) = 0 ); ############################################################################# ## #M EnumeratorSorted( S ) . . . . . . . . . . EnumeratorSorted for CrystGroup ## InstallMethod( EnumeratorSorted, "for AffineCrystGroup", true, [ IsAffineCrystGroupOnLeftOrRight ], 0, function( S ) if not IsFinite( S ) then Error("S is infinite"); else TryNextMethod(); fi; end ); ############################################################################# ## #M Enumerator( S ) . . . . . . . . . . . . . . . . Enumerator for CrystGroup ## InstallMethod( Enumerator, "for AffineCrystGroup", true, [ IsAffineCrystGroupOnLeftOrRight ], 0, function( S ) if not IsFinite( S ) then Error("S is infinite"); else TryNextMethod(); fi; end ); ############################################################################# ## #M TransParts( S ) reduced transl. parts of GeneratorsSmallest of point grp ## InstallMethod( TransParts, true, [ IsAffineCrystGroupOnLeftOrRight ], 0, function( S ) local T, P, H, d, gens; T := TranslationBasis( S ); P := PointGroup( S ); H := PointHomomorphism( S ); d := DimensionOfMatrixGroup( P ); gens := GeneratorsSmallest( P ); gens := List( gens, x -> PreImagesRepresentative( H, x ) ); if IsAffineCrystGroupOnRight( S ) then gens := List( gens, x -> VectorModL( x[d+1]{[1..d]}, T ) ); else gens := List( gens, x -> VectorModL( x{[1..d]}[d+1], T ) ); fi; return gens; end ); ############################################################################# ## #M \<( S1, S2 ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . \< ## AffineCrystGroupLessFun := function( S1, S2 ) local T1, T2, P1, P2; # first compare the translation lattices T1 := TranslationBasis( S1 ); T2 := TranslationBasis( S2 ); if not T1 = T2 then return T1 < T2; fi; # then the point groups P1 := PointGroup( S1 ); P2 := PointGroup( S2 ); if not P1 = P2 then return P1 < P2; fi; # finally the translation parts return TransParts( S1 ) < TransParts( S2 ); end; InstallMethod( \<, "two AffineCrystGroupOnRight", IsIdenticalObj, [ IsAffineCrystGroupOnRight, IsAffineCrystGroupOnRight ], 0, AffineCrystGroupLessFun ); InstallMethod( \<, "two AffineCrystGroupOnLeft", IsIdenticalObj, [ IsAffineCrystGroupOnLeft, IsAffineCrystGroupOnLeft ], 0, AffineCrystGroupLessFun ); ############################################################################# ## #M \in( m, S ) . . . . . . . . . . . . . . . .check membership in CrystGroup ## InstallMethod( \in, "for CrystGroup", IsElmsColls, [ IsMatrix, IsAffineCrystGroupOnLeftOrRight ], 0, function( m, S ) local d, P, mm, t; if not DimensionsMat( m ) = DimensionsMat( One(S) ) then return false; fi; d := DimensionOfMatrixGroup( S ) - 1; P := PointGroup( S ); mm := m{[1..d]}{[1..d]}; if not mm in P then return false; fi; mm := PreImagesRepresentativeNC( PointHomomorphism( S ), mm ); if IsAffineCrystGroupOnRight( S ) then if not IsAffineMatrixOnRight( m ) then return false; fi; t := m[d+1]{[1..d]} - mm[d+1]{[1..d]}; else if not IsAffineMatrixOnLeft( m ) then return false; fi; t := m{[1..d]}[d+1] - mm{[1..d]}[d+1]; fi; return 0*t = VectorModL( t, TranslationBasis( S ) ); end ); ############################################################################# ## #M IsSpaceGroup( S ) . . . . . . . . . . . . . . . . . . is S a space group? ## InstallMethod( IsSpaceGroup, true, [ IsCyclotomicMatrixGroup ], 0, function( S ) local d; if IsAffineCrystGroupOnLeftOrRight( S ) then d := DimensionOfMatrixGroup( S ) - 1; return d = Length( TranslationBasis( S ) ); else return false; fi; end ); ############################################################################# ## #M IsSymmorphicSpaceGroup( S ) . . . . . . . . . . . . . . .is S symmorphic? ## InstallMethod( IsSymmorphicSpaceGroup, "generic method", true, [ IsAffineCrystGroupOnLeftOrRight ], 0, S -> CocVecs( S ) = [] ); ############################################################################# ## #M IsStandardAffineCrystGroup( S ) . . . . . . . . . is S in standard form? ## InstallMethod( IsStandardAffineCrystGroup, true, [ IsCyclotomicMatrixGroup ], 0, function( S ) local d, T; if IsAffineCrystGroupOnLeftOrRight( S ) then d := DimensionOfMatrixGroup( S ) - 1; return InternalBasis( S ) = IdentityMat( d ); else return false; fi; end ); ############################################################################# ## #F PointGroupHomomorphism( S ) . . . . . . . . . . . .PointGroupHomomorphism ## PointGroupHomomorphism := function( S ) local d, gen, im, I, Pgens, Sgens, i, P, nice, N, perms, lift, H; d := DimensionOfMatrixGroup( S ) - 1; gen := GeneratorsOfGroup( S ); im := List( gen, m -> m{[1..d]}{[1..d]} ); I := IdentityMat( d ); Pgens := []; Sgens := []; for i in [1..Length( im )] do if im[i] <> I and not im[i] in Pgens then Add( Pgens, im[i] ); Add( Sgens, MutableMatrix( gen[i] ) ); fi; od; P := GroupByGenerators( Pgens, I ); SetIsPointGroup( P, true ); SetAffineCrystGroupOfPointGroup( P, S ); if not IsFinite( P ) then Error( "AffineCrystGroups must have a *finite* point group" ); fi; nice := NiceMonomorphism( P ); N := NiceObject( P ); perms := List( Pgens, x -> ImagesRepresentative( nice, x ) ); lift := GroupGeneralMappingByImagesNC( N, S, perms, Sgens : noassert ); SetNiceToCryst( P, lift ); H := GroupHomomorphismByImagesNC( S, P, gen, im : noassert ); SetIsPointHomomorphism( H, true ); return [ P, H ]; end; ############################################################################# ## #M PointGroup( S ) . . . . . . . . . . . . PointGroup of an AffineCrystGroup ## InstallMethod( PointGroup, true, [ IsAffineCrystGroupOnLeftOrRight ], 0, function( S ) local res; res := PointGroupHomomorphism( S ); SetPointHomomorphism( S, res[2] ); return res[1]; end ); ############################################################################# ## #M PointHomomorphism( S ) . . . . . PointHomomorphism of an AffineCrystGroup ## InstallMethod( PointHomomorphism, true, [IsAffineCrystGroupOnLeftOrRight], 0, function( S ) local res; res := PointGroupHomomorphism( S ); SetPointGroup( S, res[1] ); return res[2]; end ); ############################################################################# ## #M IsPointGroup(

    ) . . . . . . . . . PointGroup of an AffineCrystGroup? ## # PointGroups always know that they are PointGroups InstallMethod( IsPointGroup, "fallback method", true, [ IsCyclotomicMatrixGroup ], 0, P -> false ); ############################################################################# ## #M IsSubset( , ) . . . . . . . . . . . . . . . for AffineCrystGroups ## InstallMethod( IsSubset, IsIdenticalObj, [ IsAffineCrystGroupOnRight, IsAffineCrystGroupOnLeft ], 0, ReturnFalse); InstallMethod( IsSubset, IsIdenticalObj, [ IsAffineCrystGroupOnLeft, IsAffineCrystGroupOnRight ], 0, ReturnFalse); ############################################################################# ## ## Identification and construction of affine crystallographic groups ## ############################################################################# ############################################################################# ## #M IsAffineCrystGroupOnRight( ) . . . . AffineCrystGroup acting OnRight ## # Subgroups of AffineCrystGroups are AffineCrystGroups InstallSubsetMaintenance( IsAffineCrystGroupOnRight, IsAffineCrystGroupOnRight, IsCollection ); # AffineCrystGroups always know that they are AffineCrystGroups InstallMethod( IsAffineCrystGroupOnRight, "fallback method", true, [ IsCyclotomicMatrixGroup ], 0, S -> false ); ############################################################################# ## #M IsAffineCrystGroupOnLeft( ) . . . . . AffineCrystGroup acting OnLeft ## # Subgroups of AffineCrystGroups are AffineCrystGroups InstallSubsetMaintenance( IsAffineCrystGroupOnLeft, IsAffineCrystGroupOnLeft, IsCollection ); # AffineCrystGroups always know that they are AffineCrystGroups InstallMethod( IsAffineCrystGroupOnLeft, "fallback method", true, [ IsCyclotomicMatrixGroup ], 0, S -> false ); ############################################################################# ## #M IsAffineCrystGroup( ) . . . . . . . . . . . . AffineCrystGroup acting #M . . . . . . . . . . . . . . . . . as specified by CrystGroupDefaultAction ## InstallGlobalFunction( IsAffineCrystGroup, function( S ) if CrystGroupDefaultAction = RightAction then return IsAffineCrystGroupOnRight( S ); elif CrystGroupDefaultAction = LeftAction then return IsAffineCrystGroupOnLeft( S ); else Error(" CrystGroupDefaultAction must be RightAction or LeftAction" ); fi; end ); ############################################################################# ## #M AffineCrystGroupOnRight( ) . . . . . . . . . . . . . . . . . . . . #M AffineCrystGroupOnRight( ) . . . . . . . . . . . . . . . . . . #M AffineCrystGroupOnRight( , ) . . . . . . constructor ## InstallGlobalFunction( AffineCrystGroupOnRight, function( arg ) local G; G := CallFuncList( Group, arg ); return AsAffineCrystGroupOnRight( G ); end ); InstallGlobalFunction( AffineCrystGroupOnRightNC, function( arg ) local G; G := CallFuncList( Group, arg ); SetIsAffineCrystGroupOnRight( G, true ); return G; end ); ############################################################################# ## #M AffineCrystGroupOnLeft( ) . . . . . . . . . . . . . . . . . . . . #M AffineCrystGroupOnLeft( ) . . . . . . . . . . . . . . . . . . . #M AffineCrystGroupOnLeft( , ) . . . . . . . constructor ## InstallGlobalFunction( AffineCrystGroupOnLeft, function( arg ) local G; G := CallFuncList( Group, arg ); return AsAffineCrystGroupOnLeft( G ); end ); InstallGlobalFunction( AffineCrystGroupOnLeftNC, function( arg ) local G; G := CallFuncList( Group, arg ); SetIsAffineCrystGroupOnLeft( G, true ); return G; end ); ############################################################################# ## #M AffineCrystGroup( ) . . . . . . . . . . . . . . . . . . . . . . . #M AffineCrystGroup( ) . . . . . . . . . . . . . . . . . . . . . . #M AffineCrystGroup( , ) . . . . . . . . . . constructor ## InstallGlobalFunction( AffineCrystGroup, function( arg ) local G; G := CallFuncList( Group, arg ); if CrystGroupDefaultAction = RightAction then return AsAffineCrystGroupOnRight( G ); else return AsAffineCrystGroupOnLeft( G ); fi; end ); InstallGlobalFunction( AffineCrystGroupNC, function( arg ) local G; G := CallFuncList( Group, arg ); if CrystGroupDefaultAction = RightAction then SetIsAffineCrystGroupOnRight( G, true ); return G; else SetIsAffineCrystGroupOnLeft( G, true ); return G; fi; end ); ############################################################################# ## #M AsAffineCrystGroupOnRight( S ) . . . . . . . . . . . convert matrix group ## InstallGlobalFunction( AsAffineCrystGroupOnRight, function( S ) local ph; if HasIsAffineCrystGroupOnRight( S ) then if IsAffineCrystGroupOnRight( S ) then return S; else S := Group( GeneratorsOfGroup( S ), One( S ) ); fi; fi; # an AffineCrystGroup cannot act both OnLeft and OnRight if IsAffineCrystGroupOnLeft( S ) then S := Group( GeneratorsOfGroup( S ), One( S ) ); fi; # do a few basic checks if ForAny( GeneratorsOfGroup( S ), x -> not IsAffineMatrixOnRight( x ) ) then Error("this group can not be made an AffineCrystGroupOnRight"); fi; # check if PointGroup is finite ph := PointGroupHomomorphism( S ); # if check did not fail, we can make S an AffineCrystGroupOnRight SetIsAffineCrystGroupOnRight( S, true ); SetPointGroup( S, ph[1] ); SetPointHomomorphism( S, ph[2] ); return S; end ); ############################################################################# ## #M AsAffineCrystGroupOnLeft( S ) . . . . . . . . . . . convert matrix group ## InstallGlobalFunction( AsAffineCrystGroupOnLeft, function( S ) local ph; if HasIsAffineCrystGroupOnLeft( S ) then if IsAffineCrystGroupOnLeft( S ) then return S; else S := Group( GeneratorsOfGroup( S ), One( S ) ); fi; fi; # an AffineCrystGroup cannot act both OnLeft and OnRight if IsAffineCrystGroupOnRight( S ) then S := Group( GeneratorsOfGroup( S ), One( S ) ); fi; # do a few basic checks if ForAny( GeneratorsOfGroup( S ), x -> not IsAffineMatrixOnLeft( x ) ) then Error("this group can not be made an AffineCrystGroupOnLeft"); fi; # check if PointGroup is finite ph := PointGroupHomomorphism( S ); # if check did not fail, we can make S an AffineCrystGroupOnLeft SetIsAffineCrystGroupOnLeft( S, true ); SetPointGroup( S, ph[1] ); SetPointHomomorphism( S, ph[2] ); return S; end ); ############################################################################# ## #F AsAffineCrystGroup( ) . . . . . . . . . . . . . convert matrix group ## InstallGlobalFunction( AsAffineCrystGroup, function( S ) if CrystGroupDefaultAction = RightAction then return AsAffineCrystGroupOnRight( S ); else return AsAffineCrystGroupOnLeft( S ); fi; end ); ############################################################################# ## #M CanEasilyTestMembership( ) ## InstallTrueMethod( CanEasilyTestMembership, IsAffineCrystGroupOnLeftOrRight); ############################################################################# ## #M CanComputeSize( ) ## InstallTrueMethod( CanComputeSize, IsAffineCrystGroupOnLeftOrRight ); ############################################################################# ## #M CanComputeSizeAnySubgroup( ) ## InstallTrueMethod(CanComputeSizeAnySubgroup,IsAffineCrystGroupOnLeftOrRight); ############################################################################# ## #M CanComputeIndex( , ) ## InstallMethod( CanComputeIndex, IsIdenticalObj, [IsAffineCrystGroupOnRight,IsAffineCrystGroupOnRight], 0, ReturnTrue ); InstallMethod( CanComputeIndex, IsIdenticalObj, [IsAffineCrystGroupOnLeft,IsAffineCrystGroupOnLeft], 0, ReturnTrue ); ############################################################################# ## #M CanComputeIsSubset( , ) ## InstallMethod( CanComputeIsSubset, IsIdenticalObj, [IsAffineCrystGroupOnRight,IsAffineCrystGroupOnRight], 0, ReturnTrue ); InstallMethod( CanComputeIsSubset, IsIdenticalObj, [IsAffineCrystGroupOnLeft,IsAffineCrystGroupOnLeft], 0, ReturnTrue ); ############################################################################# ## #M HirschLength( ) . . . . . . . . . . . . . . . . .Hirsch length of ## InstallMethod( HirschLength, true, [ IsAffineCrystGroupOnLeftOrRight ], 0, function( S ) return Length( TranslationBasis( S ) ); end ); cryst/grp/0000755001325400021140000000000014540074574012170 5ustar gaehlerusercryst/grp/spacegrp.gd0000644001325400021140000000323514053147612014304 0ustar gaehleruser############################################################################# ## #A spacegrp.gd Cryst library Bettina Eick #A Franz G"ahler #A Werner Nickel ## #Y Copyright 1997-1999 by Bettina Eick, Franz G"ahler and Werner Nickel ## ## Declarations for IT space groups ## ############################################################################# ## #F SpaceGroupSettingsIT . . . . . . . .available settings of IT space groups ## DeclareGlobalFunction( "SpaceGroupSettingsIT" ); ############################################################################# ## #F SpaceGroupDataIT . . . . . . . . . . . data extractor for IT space groups ## DeclareGlobalFunction( "SpaceGroupDataIT" ); ############################################################################# ## #F SpaceGroupFunIT . . . . . . . . . constructor function for IT space group ## DeclareGlobalFunction( "SpaceGroupFunIT" ); ############################################################################# ## #F SpaceGroupOnRightIT . . . . . . . .constructor for IT space group OnRight ## DeclareGlobalFunction( "SpaceGroupOnRightIT" ); ############################################################################# ## #F SpaceGroupOnLeftIT . . . . . . . . .constructor for IT space group OnLeft ## DeclareGlobalFunction( "SpaceGroupOnLeftIT" ); ############################################################################# ## #F SpaceGroupIT . . . . . . . . . . . . . . . constructor for IT space group ## DeclareGlobalFunction( "SpaceGroupIT" ); cryst/grp/spacegrp.grp0000644001325400021140000035312414053147612014507 0ustar gaehleruser############################################################################# ## #A spacegrp.grp Cryst library Bettina Eick #A Franz G"ahler #A Werner Nickel ## #Y Copyright 1997-1999 by Bettina Eick, Franz G"ahler and Werner Nickel ## ## Data for IT space groups ## ############################################################################# ## #M SpaceGroupList2d . . . . . . . . . . . . . . .data for 2d IT space groups ## BindGlobal("SpaceGroupList2d", [rec( 1:=rec(generators:=[],basis:=[[1,0],[0,1]], normgens:=[[[1,0],[0,1]],[[-1,0],[0,-1]],[[0,1],[1,0]], [[1,1],[0,-1]],[[-1,-2],[1,1]]], normsize:=infinity)), rec(1:=rec(generators:=[[[-1,0,0],[0,-1,0],[0,0,1]]] ,basis:=[[1,0],[0,1]], normgens:=[[[-1,0],[0,-1]],[[-1,0],[0,-1]], [[0,1],[1,0]],[[1,1],[0,-1]], [[-1,-2],[1,1]]],normsize:=infinity)), rec(1:=rec(generators:=[[[-1,0,0],[0,1,0],[0,0,1]]], basis:=[[1,0],[0,1]], normgens:=[[[-1,0],[0,1]],[[-1,0],[0,-1]], [[1,0],[0,-1]],[[-1,0],[0,1]], [[1,0],[0,1]]],normsize:=4)), rec(1:=rec(generators:=[[[-1,0,0],[0,1,0],[0,1/2,1]] ],basis:=[[1,0],[0,1]], normgens:=[[[-1,0],[0,1]],[[-1,0],[0,-1]], [[1,0],[0,-1]],[[-1,0],[0,1]], [[1,0],[0,1]]],normsize:=4)), rec(1:=rec(generators:=[[[-1,0,0],[0,1,0],[0,0,1]]], basis:=[[1/2,1/2],[0,1]], normgens:=[[[-1,0],[0,1]],[[-1,0],[0,-1]], [[1,0],[0,-1]],[[-1,0],[0,1]]], normsize:=4)), rec(1:=rec(generators:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]], basis:=[[1,0],[0,1]], normgens:=[[[-1,0],[0,-1]],[[-1,0],[0,1]], [[-1,0],[0,-1]],[[1,0],[0,-1]], [[0,1],[1,0]]],normsize:=8)), rec(1:=rec(generators:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[1/2,0,1]]], basis:=[[1,0],[0,1]], normgens:=[[[-1,0],[0,-1]],[[-1,0],[0,1]], [[-1,0],[0,-1]],[[1,0],[0,-1]], [[0,1],[1,0]]],normsize:=8)), rec(1:=rec(generators:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[1/2,1/2,1]]], basis:=[[1,0],[0,1]], normgens:=[[[-1,0],[0,-1]],[[-1,0],[0,1]], [[-1,0],[0,-1]],[[1,0],[0,-1]], [[0,1],[1,0]]],normsize:=8)), rec(1:=rec(generators:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]], basis:=[[1/2,1/2],[0,1]], normgens:=[[[-1,0],[0,-1]],[[-1,0],[0,1]], [[-1,0],[0,-1]],[[1,0],[0,-1]], [[0,1],[-1,0]]],normsize:=8)), rec(1:=rec(generators:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]]], basis:=[[1,0],[0,1]], normgens:=[[[-1,0],[0,-1]],[[0,1],[-1,0]], [[-1,0],[0,-1]],[[0,1],[1,0]], [[1,0],[0,-1]]],normsize:=8)), rec(1:=rec(generators:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]], basis:=[[1,0],[0,1]], normgens:=[[[-1,0],[0,-1]],[[0,1],[-1,0]], [[-1,0],[0,1]],[[-1,0],[0,-1]], [[0,1],[1,0]],[[1,0],[0,-1]]], normsize:=8)), rec(1:=rec(generators:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[1/2,1/2,1]]], basis:=[[1,0],[0,1]], normgens:=[[[-1,0],[0,-1]],[[0,1],[-1,0]], [[-1,0],[0,1]],[[-1,0],[0,-1]], [[0,1],[1,0]],[[1,0],[0,-1]]], normsize:=8)), rec(1:=rec(generators:=[[[0,1,0],[-1,-1,0],[0,0,1]]] ,basis:=[[1,0],[0,1]], normgens:=[[[0,1],[-1,-1]],[[1,1],[-1,0]], [[1,1],[0,-1]]],normsize:=12)), rec(1:=rec(generators:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[0,-1,0],[-1,0,0],[0,0,1]]], basis:=[[1,0],[0,1]], normgens:=[[[0,1],[-1,-1]],[[0,-1],[-1,0]], [[1,1],[-1,0]],[[1,1],[0,-1]]], normsize:=12)), rec(1:=rec(generators:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]]], basis:=[[1,0],[0,1]], normgens:=[[[0,1],[-1,-1]],[[0,1],[1,0]], [[1,1],[-1,0]],[[1,1],[0,-1]]], normsize:=12)), rec(1:=rec(generators:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,1]]], basis:=[[1,0],[0,1]], normgens:=[[[0,1],[-1,-1]],[[-1,0],[0,-1]], [[1,1],[-1,0]],[[1,1],[0,-1]]], normsize:=12)), rec(1:=rec(generators:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,1]], [[0,-1,0],[-1,0,0],[0,0,1]]], basis:=[[1,0],[0,1]], normgens:=[[[0,1],[-1,-1]],[[-1,0],[0,-1]], [[0,-1],[-1,0]],[[1,1],[-1,0]], [[1,1],[0,-1]]],normsize:=12))]); ############################################################################# ## #M SpaceGroupList3d . . . . . . . . . . . . . . .data for 3d IT space groups ## BindGlobal("SpaceGroupList3d", [rec( 1:=rec(generators:=[],basis:=[[1,0,0],[0,1,0],[0, 0,1]], normgens:=[[[1,0,0],[0,1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,-1],[0,-1,0],[1,1,1]], [[0,1,1],[-1,0,0],[0,0,-1]], [[1,1,1],[0,0,1],[0,-1,-1]]], normsize:=infinity)), rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0], [0,0,-1,0],[0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,-1],[0,-1,0],[1,1,1]], [[0,1,1],[-1,0,0],[0,0,-1]], [[1,1,1],[0,0,1],[0,-1,-1]]], normsize:=infinity)), rec(b:=rec(generators:=[[[-1,0,0,0],[0,1,0,0], [0,0,-1,0],[0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[0,0,-1],[0,1,0],[1,0,1]], [[1,0,0],[0,1,0],[-1,0,-1]], [[1,0,2],[0,1,0],[0,0,-1]]], normsize:=infinity), c:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0], [0,0,1,0],[0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,1,0],[0,0,-1]], [[1,1,0],[-1,0,0],[0,0,1]], [[-1,-1,0],[0,1,0],[0,0,1]], [[2,1,0],[-1,0,0],[0,0,1]]], normsize:=infinity)), rec(b:=rec(generators:=[[[-1,0,0,0],[0,1,0,0], [0,0,-1,0],[0,1/2,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[0,0,-1],[0,1,0],[1,0,1]], [[1,0,0],[0,1,0],[-1,0,-1]], [[1,0,2],[0,1,0],[0,0,-1]]], normsize:=infinity), c:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0], [0,0,1,0],[0,0,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,1,0],[0,0,-1]], [[1,1,0],[-1,0,0],[0,0,1]], [[-1,-1,0],[0,1,0],[0,0,1]], [[2,1,0],[-1,0,0],[0,0,1]]], normsize:=infinity)), rec(b:=rec(generators:=[[[-1,0,0,0],[0,1,0,0], [0,0,-1,0],[0,0,0,1]]], basis:=[[1/2,1/2,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,2],[0,1,0],[0,0,-1]], [[1,0,4],[0,-1,0],[-1,0,-3]], [[1,0,-2],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[-1,0,-1]], [[-1,0,-2],[0,1,0],[1,0,1]]], normsize:=infinity), c:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0], [0,0,1,0],[0,0,0,1]]], basis:=[[1,0,0],[0,1/2,1/2],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,1,0],[0,0,-1]], [[1,-1,0],[0,1,0],[0,0,-1]], [[1,0,0],[-2,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]], [[-1,-1,0],[0,1,0],[0,0,1]]], normsize:=infinity)), rec(b:=rec(generators:=[[[1,0,0,0],[0,-1,0,0], [0,0,1,0],[0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[0,0,-1],[0,1,0],[1,0,1]], [[1,0,0],[0,1,0],[-1,0,-1]], [[1,0,2],[0,1,0],[0,0,-1]]], normsize:=infinity), c:=rec(generators:=[[[1,0,0,0],[0,1,0,0], [0,0,-1,0],[0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,1,0],[0,0,-1]], [[1,1,0],[-1,0,0],[0,0,1]], [[-1,-1,0],[0,1,0],[0,0,1]], [[2,1,0],[-1,0,0],[0,0,1]]], normsize:=infinity)), rec(b:=rec(generators:=[[[1,0,0,0],[0,-1,0,0], [0,0,1,0],[0,0,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[0,0,-1],[0,1,0],[1,0,1]], [[1,0,0],[0,1,0],[-1,0,-1]], [[1,0,2],[0,1,0],[0,0,-1]]], normsize:=infinity), c:=rec(generators:=[[[1,0,0,0],[0,1,0,0], [0,0,-1,0],[1/2,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,1,0],[0,0,-1]], [[1,1,0],[-1,0,0],[0,0,1]], [[-1,-1,0],[0,1,0],[0,0,1]], [[2,1,0],[-1,0,0],[0,0,1]]], normsize:=infinity)), rec(b:=rec(generators:=[[[1,0,0,0],[0,-1,0,0], [0,0,1,0],[0,0,0,1]]], basis:=[[1/2,1/2,0],[0,1,0],[0,0,1]], normgens:=[[[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,2],[0,1,0],[0,0,-1]], [[1,0,4],[0,-1,0],[-1,0,-3]], [[1,0,-2],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[-1,0,-1]], [[-1,0,-2],[0,1,0],[1,0,1]]], normsize:=infinity), c:=rec(generators:=[[[1,0,0,0],[0,1,0,0], [0,0,-1,0],[0,0,0,1]]], basis:=[[1,0,0],[0,1/2,1/2],[0,0,1]], normgens:=[[[1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,1,0],[0,0,-1]], [[1,-1,0],[0,1,0],[0,0,-1]], [[1,0,0],[-2,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]], [[-1,-1,0],[0,1,0],[0,0,1]]], normsize:=infinity)), rec(b:=rec(generators:=[[[1,0,0,0],[0,-1,0,0], [0,0,1,0],[0,0,1/2,1]]], basis:=[[1/2,1/2,0],[0,1,0],[0,0,1]], normgens:=[[[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,2],[0,1,0],[0,0,-1]], [[1,0,4],[0,-1,0],[-1,0,-3]], [[1,0,-2],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[-1,0,-1]], [[-1,0,-2],[0,1,0],[1,0,1]]], normsize:=infinity), c:=rec(generators:=[[[1,0,0,0],[0,1,0,0], [0,0,-1,0],[1/2,0,0,1]]], basis:=[[1,0,0],[0,1/2,1/2],[0,0,1]], normgens:=[[[1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,1,0],[0,0,-1]], [[1,-1,0],[0,1,0],[0,0,-1]], [[1,0,0],[-2,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]], [[-1,-1,0],[0,1,0],[0,0,1]]], normsize:=infinity)), rec(b:=rec(generators:=[[[-1,0,0,0],[0,1,0,0], [0,0,-1,0],[0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[0,0,-1],[0,1,0],[1,0,1]], [[1,0,0],[0,1,0],[-1,0,-1]], [[1,0,2],[0,1,0],[0,0,-1]]], normsize:=infinity), c:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0], [0,0,1,0],[0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,1,0],[0,0,-1]], [[1,1,0],[-1,0,0],[0,0,1]], [[-1,-1,0],[0,1,0],[0,0,1]], [[2,1,0],[-1,0,0],[0,0,1]]], normsize:=infinity)), rec(b:=rec(generators:=[[[-1,0,0,0],[0,1,0,0], [0,0,-1,0],[0,1/2,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[0,0,-1],[0,1,0],[1,0,1]], [[1,0,0],[0,1,0],[-1,0,-1]], [[1,0,2],[0,1,0],[0,0,-1]]], normsize:=infinity), c:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0], [0,0,1,0],[0,0,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,1,0],[0,0,-1]], [[1,1,0],[-1,0,0],[0,0,1]], [[-1,-1,0],[0,1,0],[0,0,1]], [[2,1,0],[-1,0,0],[0,0,1]]], normsize:=infinity)), rec(b:=rec(generators:=[[[-1,0,0,0],[0,1,0,0], [0,0,-1,0],[0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,1/2,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,2],[0,1,0],[0,0,-1]], [[1,0,4],[0,-1,0],[-1,0,-3]], [[1,0,-2],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[-1,0,-1]], [[-1,0,-2],[0,1,0],[1,0,1]]], normsize:=infinity), c:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0], [0,0,1,0],[0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1/2,1/2],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,1,0],[0,0,-1]], [[1,-1,0],[0,1,0],[0,0,-1]], [[1,0,0],[-2,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]], [[-1,-1,0],[0,1,0],[0,0,1]]], normsize:=infinity)), rec(b:=rec(generators:=[[[-1,0,0,0],[0,1,0,0], [0,0,-1,0],[0,0,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[0,0,-1],[0,1,0],[1,0,1]], [[1,0,0],[0,1,0],[-1,0,-1]], [[1,0,2],[0,1,0],[0,0,-1]]], normsize:=infinity), c:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0], [0,0,1,0],[1/2,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,1,0],[0,0,-1]], [[1,1,0],[-1,0,0],[0,0,1]], [[-1,-1,0],[0,1,0],[0,0,1]], [[2,1,0],[-1,0,0],[0,0,1]]], normsize:=infinity)), rec(b:=rec(generators:=[[[-1,0,0,0],[0,1,0,0], [0,0,-1,0],[0,1/2,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[0,0,-1],[0,1,0],[1,0,1]], [[1,0,0],[0,1,0],[-1,0,-1]], [[1,0,2],[0,1,0],[0,0,-1]]], normsize:=infinity), c:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0], [0,0,1,0],[1/2,0,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,1,0],[0,0,-1]], [[1,1,0],[-1,0,0],[0,0,1]], [[-1,-1,0],[0,1,0],[0,0,1]], [[2,1,0],[-1,0,0],[0,0,1]]], normsize:=infinity)), rec(b:=rec(generators:=[[[-1,0,0,0],[0,1,0,0], [0,0,-1,0],[0,0,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,1/2,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,2],[0,1,0],[0,0,-1]], [[1,0,4],[0,-1,0],[-1,0,-3]], [[1,0,-2],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[-1,0,-1]], [[-1,0,-2],[0,1,0],[1,0,1]]], normsize:=infinity), c:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0], [0,0,1,0],[1/2,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1/2,1/2],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,1,0],[0,0,-1]], [[1,-1,0],[0,1,0],[0,0,-1]], [[1,0,0],[-2,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]], [[-1,-1,0],[0,1,0],[0,0,1]]], normsize:=infinity)), rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0], [0,0,1,0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,0,1],[-1,0,0],[0,1,0]], [[1,0,0],[0,0,1],[0,1,0]]],normsize:=48)), rec( 1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1, 0],[0,0,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,0,1],[-1,0,0],[0,1,0]], [[1,0,0],[0,0,1],[0,1,0]]],normsize:=48)), rec( 1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1, 0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,1/2,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,0,1],[-1,0,0],[0,1,0]], [[1,0,0],[0,0,1],[0,1,0]]],normsize:=48)), rec( 1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1, 0],[1/2,0,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,1/2,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,0,1],[-1,0,0],[0,1,0]], [[1,0,0],[0,0,1],[0,1,0]]],normsize:=48)), rec( 1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1, 0],[0,0,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,1/2,1]]], basis:=[[1/2,1/2,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,-1,0],[1,0,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,1/2,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,-1,0],[1,0,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,0,1/2],[0,1/2,1/2],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[0,0,-1],[1,0,0]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[1,0,0],[0,0,1],[0,1,0]], [[0,1,0],[1,0,0],[0,0,1]]],normsize:=48)), rec( 1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1, 0],[1/2,0,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,1/2,1/2,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[1,0,0],[0,0,1],[0,1,0]], [[0,1,0],[1,0,0],[0,0,1]]],normsize:=48)), rec( 1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1, 0],[0,0,0,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,-1,0],[1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[0,-1,0],[-1,0,0],[0,0,1]]],normsize:=16) ), rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,1/2,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,-1,0],[1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[0,-1,0],[-1,0,0],[0,0,1]]],normsize:=16) ), rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,-1,0],[1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[0,-1,0],[-1,0,0],[0,0,1]]],normsize:=16) ), rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [1/2,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,-1,0],[1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[0,-1,0],[-1,0,0],[0,0,1]]],normsize:=16) ), rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,1/2,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [1/2,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,-1,0],[1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[0,-1,0],[-1,0,0],[0,0,1]]],normsize:=16) ), rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,1/2,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,-1,0],[1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[0,-1,0],[-1,0,0],[0,0,1]]],normsize:=16) ), rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[1/2,0,1/2,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [1/2,0,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,-1,0],[1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[0,-1,0],[-1,0,0],[0,0,1]]],normsize:=16) ), rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [1/2,1/2,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,-1,0],[1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[0,-1,0],[-1,0,0],[0,0,1]]],normsize:=16) ), rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,1/2,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [1/2,1/2,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,-1,0],[1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[0,-1,0],[-1,0,0],[0,0,1]]],normsize:=16) ), rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [1/2,1/2,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,-1,0],[1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[0,-1,0],[-1,0,0],[0,0,1]]],normsize:=16) ), rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,0,1]]], basis:=[[1/2,1/2,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,-1,0],[1,0,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,1/2,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,1/2,1]]], basis:=[[1/2,1/2,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,-1,0],[1,0,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,1/2,1]]], basis:=[[1/2,1/2,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,-1,0],[1,0,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1/2,1/2],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]]],normsize:=8)), rec( 1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1, 0],[0,0,0,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,1/2,0,1]]], basis:=[[1,0,0],[0,1/2,1/2],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]]],normsize:=8)), rec( 1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1, 0],[0,0,0,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [1/2,0,0,1]]], basis:=[[1,0,0],[0,1/2,1/2],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]]],normsize:=8)), rec( 1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1, 0],[0,0,0,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [1/2,1/2,0,1]]], basis:=[[1,0,0],[0,1/2,1/2],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]]],normsize:=8)), rec( 1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1, 0],[0,0,0,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,0,1]]], basis:=[[1/2,0,1/2],[0,1/2,1/2],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,-1]], [[1,0,0],[0,1,0],[0,0,1]]],normsize:=16)), rec( 1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1, 0],[0,0,0,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [1/4,1/4,1/4,1]]], basis:=[[1/2,0,1/2],[0,1/2,1/2],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,-1]], [[1,0,0],[0,1,0],[0,0,1]]],normsize:=16)), rec( 1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1, 0],[0,0,0,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,0,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [1/2,1/2,0,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [1/2,0,0,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,0,1],[-1,0,0],[0,1,0]], [[1,0,0],[0,0,1],[0,1,0]]],normsize:=48)), rec( 1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1, 0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [1/2,1/2,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,0,1],[-1,0,0],[0,1,0]], [[1,0,0],[0,0,1],[0,1,0]]],normsize:=48), 2:= rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1,0 ],[1/2,1/2,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,0,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,0,1],[-1,0,0],[0,1,0]], [[1,0,0],[0,0,1],[0,1,0]]],normsize:=48)), rec( 1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1, 0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,0,1],[-1,0,0],[0,1,0]], [[1,0,0],[0,0,1],[0,1,0]]],normsize:=48)), rec( 1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1, 0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [1/2,1/2,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,0,1],[-1,0,0],[0,1,0]], [[1,0,0],[0,0,1],[0,1,0]]],normsize:=48), 2:= rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1,0 ],[1/2,1/2,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,0,1],[-1,0,0],[0,1,0]], [[1,0,0],[0,0,1],[0,1,0]]],normsize:=48)), rec( 1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1, 0],[1/2,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,0,1],[-1,0,0],[0,1,0]], [[1,0,0],[0,0,1],[0,1,0]]],normsize:=48)), rec( 1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1, 0],[1/2,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,1/2,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,0,1],[-1,0,0],[0,1,0]], [[1,0,0],[0,0,1],[0,1,0]]],normsize:=48)), rec( 1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1, 0],[1/2,0,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,0,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,0,1],[-1,0,0],[0,1,0]], [[1,0,0],[0,0,1],[0,1,0]]],normsize:=48)), rec( 1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1, 0],[1/2,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,0,1],[-1,0,0],[0,1,0]], [[1,0,0],[0,0,1],[0,1,0]]],normsize:=48)), rec( 1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1, 0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,1/2,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,0,1],[-1,0,0],[0,1,0]], [[1,0,0],[0,0,1],[0,1,0]]],normsize:=48)), rec( 1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1, 0],[1/2,1/2,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,1/2,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,0,1],[-1,0,0],[0,1,0]], [[1,0,0],[0,0,1],[0,1,0]]],normsize:=48)), rec( 1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1, 0],[0,0,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,1/2,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,0,1],[-1,0,0],[0,1,0]], [[1,0,0],[0,0,1],[0,1,0]]],normsize:=48)), rec( 1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1, 0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,1/2,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,0,1],[-1,0,0],[0,1,0]], [[1,0,0],[0,0,1],[0,1,0]]],normsize:=48)), rec( 1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1, 0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,1/2,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [1/2,1/2,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,0,1],[-1,0,0],[0,1,0]], [[1,0,0],[0,0,1],[0,1,0]]],normsize:=48), 2:= rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1,0 ],[1/2,1/2,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,1/2,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,0,1],[-1,0,0],[0,1,0]], [[1,0,0],[0,0,1],[0,1,0]]],normsize:=48)), rec( 1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1, 0],[1/2,1/2,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,0,1],[-1,0,0],[0,1,0]], [[1,0,0],[0,0,1],[0,1,0]]],normsize:=48)), rec( 1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1, 0],[1/2,0,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,1/2,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,0,1],[-1,0,0],[0,1,0]], [[1,0,0],[0,0,1],[0,1,0]]],normsize:=48)), rec( 1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1, 0],[1/2,0,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,1/2,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,0,1],[-1,0,0],[0,1,0]], [[1,0,0],[0,0,1],[0,1,0]]],normsize:=48)), rec( 1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1, 0],[0,0,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,1/2,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,-1,0],[1,0,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,1/2,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,1/2,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,1/2,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,-1,0],[1,0,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,1/2,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,-1,0],[1,0,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,1/2,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,-1,0],[1,0,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,1/2,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,1/2,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,1/2,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,-1,0],[1,0,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[1/2,1/2,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,1/2,1/2,1]]], basis:=[[1/2,1/2,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,-1,0],[1,0,0],[0,0,1]]],normsize:=16), 2:= rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1,0 ],[1/2,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,1/2,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,-1,0],[1,0,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,0,1/2],[0,1/2,1/2],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[0,0,-1],[1,0,0]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [1/4,1/4,1/4,1]]], basis:=[[1/2,0,1/2],[0,1/2,1/2],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[0,0,-1],[1,0,0]]],normsize:=48), 2:= rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1,0 ],[3/4,3/4,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [3/4,0,3/4,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,0,1/2],[0,1/2,1/2],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[0,0,-1],[1,0,0]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[1,0,0],[0,0,1],[0,1,0]], [[0,1,0],[1,0,0],[0,0,1]]],normsize:=48)), rec( 1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1, 0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,1/2,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[1,0,0],[0,0,1],[0,1,0]], [[0,1,0],[1,0,0],[0,0,1]]],normsize:=48)), rec( 1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1, 0],[1/2,0,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,1/2,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[1,0,0],[0,0,1],[0,1,0]], [[0,1,0],[1,0,0],[0,0,1]]],normsize:=48)), rec( 1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1, 0],[0,1/2,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,1/2,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[1,0,0],[0,0,1],[0,1,0]], [[0,1,0],[1,0,0],[0,0,1]]],normsize:=48)), rec( 1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1, 0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,1/2,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,1/4,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,1/2,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,3/4,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,0,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[1/2,1/2,1/2,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,1/2,1/4,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,-1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,-1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,-1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,-1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [1/2,1/2,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [1/2,1/2,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16), 2:= rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1,0 ],[1/2,1/2,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [1/2,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [1/2,1/2,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [1/2,1/2,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16), 2:= rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1,0 ],[1/2,1/2,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,1/2,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[1/2,1/2,1/2,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,1/2,1/4,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,1/2,1/4,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]]],normsize:=16), 2:= rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1,0 ],[1/2,0,1/2,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [3/4,1/4,1/4,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [1/2,1/2,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,1/2,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,1/2,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,1/4,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,1/2,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [1/2,1/2,1/4,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,1/2,1/4,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [1/2,1/2,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,1/2,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,1/2,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,3/4,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,1/2,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [1/2,1/2,3/4,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,1/2,3/4,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[1/2,1/2,1/2,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,1/2,1/4,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,0,3/4,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,0,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,0,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [1/2,1/2,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,1/2,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [1/2,1/2,1/2,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [1/2,1/2,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,0,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,0,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [1/2,1/2,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,1/2,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,1/2,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [1/2,1/2,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,0,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,0,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,0,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,1/2,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[1/2,1/2,1/2,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,1/2,1/4,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,0,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[1/2,1/2,1/2,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,1/2,1/4,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,1/2,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,-1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,-1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,-1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,-1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,-1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,1/2,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,-1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,-1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,1/2,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,-1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,-1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,0,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,-1,0],[1,0,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,-1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,0,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,-1,0],[1,0,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,-1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,0,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [1/2,1/2,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,-1,0],[1,0,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,-1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,0,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [1/2,1/2,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,-1,0],[1,0,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,-1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,0,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,0,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,-1,0],[1,0,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,-1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,0,1]], [[1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,1/2,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,-1,0],[1,0,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,-1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,-1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,-1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,0,3/4,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,-1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [1/2,1/2,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16), 2:= rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1,0 ],[1/2,1/2,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [1/2,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [1/2,1/2,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16), 2:= rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1,0 ],[1/2,1/2,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [1/2,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,0,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,1/2,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,1/2,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [1/2,1/2,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,1/2,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [1/2,1/2,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16), 2:= rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1,0 ],[1/2,1/2,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [1/2,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,1/2,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [1/2,1/2,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,1/2,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [1/2,1/2,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16), 2:= rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1,0 ],[1/2,1/2,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [1/2,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,1/2,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [1/2,1/2,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [1/2,1/2,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16), 2:= rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1,0 ],[1/2,1/2,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [1/2,0,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [1/2,1/2,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [1/2,1/2,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16), 2:= rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1,0 ],[1/2,1/2,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [1/2,0,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,0,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,1/2,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [1/2,1/2,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,1/2,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [1/2,1/2,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,1/2,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [1/2,1/2,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16), 2:= rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1,0 ],[1/2,1/2,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [1/2,0,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,1/2,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [1/2,1/2,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,1/2,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [1/2,1/2,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16), 2:= rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1,0 ],[1/2,1/2,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [1/2,0,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,1/2,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[1/2,1/2,1/2,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,1/2,1/4,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,0,3/4,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,1/2,1/4,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]]],normsize:=16), 2:= rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1,0 ],[1/2,0,1/2,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [1/4,3/4,1/4,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,0,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]]],normsize:=16)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[1/2,1/2,1/2,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [0,1/2,1/4,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,0,1/4,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,1/2,1/4,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]]],normsize:=16), 2:= rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1,0 ],[1/2,0,1/2,1]], [[0,1,0,0],[-1,0,0,0],[0,0,1,0], [1/4,3/4,1/4,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,-1]], [[1,0,0],[0,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]]],normsize:=16)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,1/3,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,2/3,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(h:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,0,1]]], basis:=[[1/3,2/3,2/3],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,-1,0],[1,0,0],[0,0,1]], [[1,1,0],[0,-1,0],[0,0,1]]],normsize:=12), r:= rec(generators:=[[[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[0,0,1],[1,0,0]], [[0,-1,0],[0,0,-1],[-1,0,0]], [[1,0,0],[0,0,1],[0,1,0]]],normsize:=12)), rec( 1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0,1, 0],[0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(h:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/3,2/3,2/3],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,-1,0],[1,0,0],[0,0,1]], [[1,1,0],[0,-1,0],[0,0,1]]],normsize:=12), r:= rec(generators:=[[[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[0,0,1],[1,0,0]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[0,0,-1],[-1,0,0]], [[1,0,0],[0,0,1],[0,1,0]]],normsize:=12)), rec( 1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0,1, 0],[0,0,0,1]], [[0,-1,0,0],[-1,0,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[0,-1,0],[-1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,1/3,1]], [[0,-1,0,0],[-1,0,0,0],[0,0,-1,0], [0,0,2/3,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[0,-1,0],[-1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,1/3,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,2/3,1]], [[0,-1,0,0],[-1,0,0,0],[0,0,-1,0], [0,0,1/3,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[0,-1,0],[-1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,2/3,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(h:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/3,2/3,2/3],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,-1,0],[1,0,0],[0,0,1]], [[1,1,0],[0,-1,0],[0,0,1]]],normsize:=12), r:= rec(generators:=[[[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[0,-1,0,0],[-1,0,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[0,0,1],[1,0,0]], [[0,-1,0],[-1,0,0],[0,0,-1]], [[0,-1,0],[0,0,-1],[-1,0,0]], [[1,0,0],[0,0,1],[0,1,0]]],normsize:=12)), rec( 1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0,1, 0],[0,0,0,1]], [[0,-1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,-1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,1,0], [0,0,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(h:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,-1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,0,1]]], basis:=[[1/3,2/3,2/3],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,-1,0],[1,0,0],[0,0,1]], [[1,1,0],[0,-1,0],[0,0,1]]],normsize:=12), r:= rec(generators:=[[[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[0,0,1],[1,0,0]], [[0,1,0],[1,0,0],[0,0,1]], [[0,-1,0],[0,0,-1],[-1,0,0]], [[1,0,0],[0,0,1],[0,1,0]]],normsize:=12)), rec( h:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0,1, 0],[0,0,0,1]], [[0,-1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,1/2,1]]], basis:=[[1/3,2/3,2/3],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,-1,0],[1,0,0],[0,0,1]], [[1,1,0],[0,-1,0],[0,0,1]]],normsize:=12), r:= rec(generators:=[[[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,1,0], [1/2,1/2,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[0,0,1],[1,0,0]], [[0,1,0],[1,0,0],[0,0,1]], [[0,-1,0],[0,0,-1],[-1,0,0]], [[1,0,0],[0,0,1],[0,1,0]]],normsize:=12)), rec( 1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0,1, 0],[0,0,0,1]], [[0,-1,0,0],[-1,0,0,0],[0,0,-1,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[0,-1,0],[-1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,-1,0,0],[-1,0,0,0],[0,0,-1,0], [0,0,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[0,-1,0],[-1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(h:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/3,2/3,2/3],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,-1,0],[1,0,0],[0,0,1]], [[1,1,0],[0,-1,0],[0,0,1]]],normsize:=12), r:= rec(generators:=[[[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[0,-1,0,0],[-1,0,0,0],[0,0,-1,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[0,0,1],[1,0,0]], [[0,-1,0],[-1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[0,0,-1],[-1,0,0]], [[1,0,0],[0,0,1],[0,1,0]]],normsize:=12)), rec( h:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0,1, 0],[0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/3,2/3,2/3],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,-1,0],[1,0,0],[0,0,1]], [[1,1,0],[0,-1,0],[0,0,1]]],normsize:=12), r:= rec(generators:=[[[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[0,-1,0,0],[-1,0,0,0],[0,0,-1,0], [1/2,1/2,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[0,0,1],[1,0,0]], [[0,-1,0],[-1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[0,0,-1],[-1,0,0]], [[1,0,0],[0,0,1],[0,1,0]]],normsize:=12)), rec( 1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0,1, 0],[0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,1/3,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,2/3,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,2/3,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,1/3,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,1/3,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,1/2,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,1/3,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,2/3,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,1/2,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,2/3,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,2/3,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,2/3,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,1/3,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,1/3,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,1/2,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,0,1]], [[0,-1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,0,1]], [[0,-1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,1/2,1]], [[0,-1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,1/2,1]], [[0,-1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[0,-1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,1/2,1]], [[0,-1,0,0],[-1,0,0,0],[0,0,1,0], [0,0,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,1/2,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,1/2,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[0,1,0,0],[-1,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,1,0], [0,0,1/2,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[0,1,0],[-1,-1,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[-1,0,0],[0,0,1]], [[0,1,0],[1,0,0],[0,0,1]], [[1,1,0],[-1,0,0],[0,0,1]]],normsize:=24)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[0,-1,0],[0,0,1],[1,0,0]], [[1,0,0],[0,0,1],[0,1,0]], [[1,0,0],[0,-1,0],[0,0,1]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]]], basis:=[[1/2,0,1/2],[0,1/2,1/2],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[1,0,0],[0,0,1]], [[0,0,1],[0,1,0],[1,0,0]], [[1,0,0],[0,0,-1],[0,-1,0]], [[1,0,0],[0,1,0],[0,0,-1]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[0,-1,0],[0,0,-1],[-1,0,0]], [[1,0,0],[0,0,1],[0,1,0]], [[1,0,0],[0,0,-1],[0,1,0]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[1/2,0,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,1/2,1/2,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[0,-1,0],[0,0,1],[1,0,0]], [[1,0,0],[0,0,1],[0,1,0]], [[1,0,0],[0,-1,0],[0,0,1]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[1/2,0,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,1/2,1/2,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[0,-1,0],[0,0,-1],[-1,0,0]], [[1,0,0],[0,0,1],[0,1,0]], [[1,0,0],[0,0,-1],[0,1,0]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[0,0,1],[1,0,0]], [[1,0,0],[0,0,1],[0,1,0]], [[1,0,0],[0,-1,0],[0,0,1]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [1/2,1/2,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[0,0,1],[1,0,0]], [[1,0,0],[0,0,1],[0,1,0]], [[1,0,0],[0,-1,0],[0,0,1]]],normsize:=48), 2:= rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1,0 ],[1/2,1/2,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,0,1/2,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[0,0,1],[1,0,0]], [[1,0,0],[0,0,1],[0,1,0]], [[1,0,0],[0,-1,0],[0,0,1]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,0,1/2],[0,1/2,1/2],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[1,0,0],[0,0,1]], [[0,0,1],[0,1,0],[1,0,0]], [[1,0,0],[0,0,-1],[0,-1,0]], [[1,0,0],[0,1,0],[0,0,-1]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [1/4,1/4,1/4,1]]], basis:=[[1/2,0,1/2],[0,1/2,1/2],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[1,0,0],[0,0,1]], [[0,0,1],[0,1,0],[1,0,0]], [[1,0,0],[0,0,-1],[0,-1,0]], [[1,0,0],[0,1,0],[0,0,-1]]],normsize:=48), 2:= rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1,0 ],[1/4,1/4,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/4,0,1/4,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,0,1/2],[0,1/2,1/2],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[1,0,0],[0,0,1]], [[0,0,1],[0,1,0],[1,0,0]], [[1,0,0],[0,0,-1],[0,-1,0]], [[1,0,0],[0,1,0],[0,0,-1]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[0,0,-1],[-1,0,0]], [[1,0,0],[0,0,1],[0,1,0]], [[1,0,0],[0,0,-1],[0,1,0]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[1/2,0,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,1/2,1/2,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[0,0,1],[1,0,0]], [[1,0,0],[0,0,1],[0,1,0]], [[1,0,0],[0,-1,0],[0,0,1]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[1/2,0,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,1/2,1/2,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[0,0,-1],[-1,0,0]], [[1,0,0],[0,0,1],[0,1,0]], [[1,0,0],[0,0,-1],[0,1,0]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[0,1,0],[1,0,0],[0,0,-1]], [[0,-1,0],[0,0,1],[1,0,0]], [[1,0,0],[0,0,1],[0,1,0]], [[1,0,0],[0,-1,0],[0,0,1]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [1/2,1/2,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[0,1,0],[1,0,0],[0,0,-1]], [[0,-1,0],[0,0,1],[1,0,0]], [[1,0,0],[0,0,1],[0,1,0]], [[1,0,0],[0,-1,0],[0,0,1]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,0,1/2],[0,1/2,1/2],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[0,1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[1,0,0],[0,0,1]], [[0,0,1],[0,1,0],[1,0,0]], [[1,0,0],[0,0,-1],[0,-1,0]], [[1,0,0],[0,1,0],[0,0,-1]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,1/2,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,1/2,0,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [3/4,1/4,3/4,1]]], basis:=[[1/2,0,1/2],[0,1/2,1/2],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[0,1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[1,0,0],[0,0,1]], [[0,0,1],[0,1,0],[1,0,0]], [[1,0,0],[0,0,-1],[0,-1,0]], [[1,0,0],[0,1,0],[0,0,-1]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[0,1,0],[1,0,0],[0,0,-1]], [[0,-1,0],[0,0,-1],[-1,0,0]], [[1,0,0],[0,0,1],[0,1,0]], [[1,0,0],[0,0,-1],[0,1,0]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[1/2,0,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,1/2,1/2,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [1/4,3/4,3/4,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[0,1,0],[1,0,0],[0,0,-1]], [[0,-1,0],[0,0,1],[1,0,0]], [[1,0,0],[0,0,1],[0,1,0]], [[1,0,0],[0,-1,0],[0,0,1]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[1/2,0,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,1/2,1/2,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [3/4,1/4,1/4,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[0,1,0],[1,0,0],[0,0,-1]], [[0,-1,0],[0,0,1],[1,0,0]], [[1,0,0],[0,0,1],[0,1,0]], [[1,0,0],[0,-1,0],[0,0,1]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[1/2,0,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,1/2,1/2,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [3/4,1/4,1/4,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[0,1,0],[1,0,0],[0,0,-1]], [[0,-1,0],[0,0,-1],[-1,0,0]], [[1,0,0],[0,0,1],[0,1,0]], [[1,0,0],[0,0,-1],[0,1,0]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[0,1,0],[1,0,0],[0,0,1]], [[0,-1,0],[0,0,1],[1,0,0]], [[1,0,0],[0,0,1],[0,1,0]], [[1,0,0],[0,-1,0],[0,0,1]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,1,0], [0,0,0,1]]], basis:=[[1/2,0,1/2],[0,1/2,1/2],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[0,1,0],[1,0,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[1,0,0],[0,0,1]], [[0,0,1],[0,1,0],[1,0,0]], [[1,0,0],[0,0,-1],[0,-1,0]], [[1,0,0],[0,1,0],[0,0,-1]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,1,0], [0,0,0,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[0,1,0],[1,0,0],[0,0,1]], [[0,-1,0],[0,0,-1],[-1,0,0]], [[1,0,0],[0,0,1],[0,1,0]], [[1,0,0],[0,0,-1],[0,1,0]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,1,0], [1/2,1/2,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[0,1,0],[1,0,0],[0,0,1]], [[0,-1,0],[0,0,1],[1,0,0]], [[1,0,0],[0,0,1],[0,1,0]], [[1,0,0],[0,-1,0],[0,0,1]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,1,0], [1/2,1/2,1/2,1]]], basis:=[[1/2,0,1/2],[0,1/2,1/2],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[0,1,0],[1,0,0],[0,0,1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[1,0,0],[0,0,1]], [[0,0,1],[0,1,0],[1,0,0]], [[1,0,0],[0,0,-1],[0,-1,0]], [[1,0,0],[0,1,0],[0,0,-1]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[1/2,0,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,1/2,1/2,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,1,0], [1/4,1/4,1/4,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[0,1,0],[1,0,0],[0,0,1]], [[0,-1,0],[0,0,-1],[-1,0,0]], [[1,0,0],[0,0,1],[0,1,0]], [[1,0,0],[0,0,-1],[0,1,0]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[0,1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[0,0,1],[1,0,0]], [[1,0,0],[0,0,1],[0,1,0]], [[1,0,0],[0,-1,0],[0,0,1]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [1/2,1/2,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[0,1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[0,0,1],[1,0,0]], [[1,0,0],[0,0,1],[0,1,0]], [[1,0,0],[0,-1,0],[0,0,1]]],normsize:=48), 2:= rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1,0 ],[1/2,1/2,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,0,1/2,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[0,1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[0,0,1],[1,0,0]], [[1,0,0],[0,0,1],[0,1,0]], [[1,0,0],[0,-1,0],[0,0,1]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [1/2,1/2,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[0,1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[0,0,1],[1,0,0]], [[1,0,0],[0,0,1],[0,1,0]], [[1,0,0],[0,-1,0],[0,0,1]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [1/2,1/2,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [1/2,1/2,1/2,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[0,1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[0,0,1],[1,0,0]], [[1,0,0],[0,0,1],[0,1,0]], [[1,0,0],[0,-1,0],[0,0,1]]],normsize:=48), 2:= rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1,0 ],[1/2,1/2,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,0,1/2,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [1/2,1/2,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1,0,0],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[0,1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[0,0,1],[1,0,0]], [[1,0,0],[0,0,1],[0,1,0]], [[1,0,0],[0,-1,0],[0,0,1]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,0,1/2],[0,1/2,1/2],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[0,1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[1,0,0],[0,0,1]], [[0,0,1],[0,1,0],[1,0,0]], [[1,0,0],[0,0,-1],[0,-1,0]], [[1,0,0],[0,1,0],[0,0,-1]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [1/2,1/2,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,0,1/2],[0,1/2,1/2],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[0,1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[1,0,0],[0,0,1]], [[0,0,1],[0,1,0],[1,0,0]], [[1,0,0],[0,0,-1],[0,-1,0]], [[1,0,0],[0,1,0],[0,0,-1]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,1/2,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,1/2,0,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [3/4,1/4,3/4,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [1/4,1/4,1/4,1]]], basis:=[[1/2,0,1/2],[0,1/2,1/2],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[0,1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[1,0,0],[0,0,1]], [[0,0,1],[0,1,0],[1,0,0]], [[1,0,0],[0,0,-1],[0,-1,0]], [[1,0,0],[0,1,0],[0,0,-1]]],normsize:=48), 2:= rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1,0 ],[3/4,1/4,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/4,1/2,3/4,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [3/4,1/4,1/2,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,0,1/2],[0,1/2,1/2],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[0,1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[1,0,0],[0,0,1]], [[0,0,1],[0,1,0],[1,0,0]], [[1,0,0],[0,0,-1],[0,-1,0]], [[1,0,0],[0,1,0],[0,0,-1]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,1/2,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [1/2,1/2,0,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [3/4,1/4,3/4,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [3/4,3/4,3/4,1]]], basis:=[[1/2,0,1/2],[0,1/2,1/2],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[0,1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[1,0,0],[0,0,1]], [[0,0,1],[0,1,0],[1,0,0]], [[1,0,0],[0,0,-1],[0,-1,0]], [[1,0,0],[0,1,0],[0,0,-1]]],normsize:=48), 2:= rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0,1,0 ],[1/4,3/4,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [3/4,1/2,1/4,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [3/4,1/4,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,0,1/2],[0,1/2,1/2],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[0,1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,1,0],[1,0,0],[0,0,1]], [[0,0,1],[0,1,0],[1,0,0]], [[1,0,0],[0,0,-1],[0,-1,0]], [[1,0,0],[0,1,0],[0,0,-1]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[0,0,0,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,0,0,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [0,0,0,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[0,1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[0,0,-1],[-1,0,0]], [[1,0,0],[0,0,1],[0,1,0]], [[1,0,0],[0,0,-1],[0,1,0]]],normsize:=48)) , rec(1:=rec(generators:=[[[-1,0,0,0],[0,-1,0,0],[0,0, 1,0],[1/2,0,1/2,1]], [[-1,0,0,0],[0,1,0,0],[0,0,-1,0], [0,1/2,1/2,1]], [[0,1,0,0],[0,0,1,0],[1,0,0,0], [0,0,0,1]], [[0,1,0,0],[1,0,0,0],[0,0,-1,0], [3/4,1/4,1/4,1]], [[-1,0,0,0],[0,-1,0,0],[0,0,-1,0], [0,0,0,1]]], basis:=[[1/2,1/2,1/2],[0,1,0],[0,0,1]], normgens:=[[[-1,0,0],[0,-1,0],[0,0,1]], [[-1,0,0],[0,1,0],[0,0,-1]], [[0,1,0],[0,0,1],[1,0,0]], [[0,1,0],[1,0,0],[0,0,-1]], [[-1,0,0],[0,-1,0],[0,0,-1]], [[0,-1,0],[0,0,-1],[-1,0,0]], [[1,0,0],[0,0,1],[0,1,0]], [[1,0,0],[0,0,-1],[0,1,0]]],normsize:=48) )]); cryst/grp/spacegrp.gi0000644001325400021140000001207313232361435014310 0ustar gaehleruser############################################################################# ## #A spacegrp.gi Cryst library Bettina Eick #A Franz G"ahler #A Werner Nickel ## #Y Copyright 1997-1999 by Bettina Eick, Franz G"ahler and Werner Nickel ## ## Extraction functions for IT space groups ## ############################################################################# ## #M SpaceGroupSettingsIT . . . . . . . .available settings of IT space groups ## InstallGlobalFunction( SpaceGroupSettingsIT, function( dim, nr ) if dim = 2 then if nr in [1..17] then return List( RecNames( SpaceGroupList2d[nr] ), x -> x[1] ); else Error( "space group number must be in [1..17]" ); fi; elif dim = 3 then if nr in [1..230] then return List( RecNames( SpaceGroupList3d[nr] ), x -> x[1] ); else Error( "space group number must be in [1..230]" ); fi; else Error( "only dimensions 2 and 3 are supported" ); fi; end ); ############################################################################# ## #M SpaceGroupDataIT . . . . . . . . . . . data extractor for IT space groups ## InstallGlobalFunction( SpaceGroupDataIT, function( r ) local settings; if r.dim = 2 then if r.nr in [1..17] then if IsBound( r.setting ) and r.setting <> '1' then Error( "requested setting is not available" ); fi; r.setting := '1'; return SpaceGroupList2d[r.nr].1; else Error( "in 2d, space group number must be in [1..17]" ); fi; elif r.dim = 3 then if r.nr in [1..230] then settings := SpaceGroupSettingsIT( 3, r.nr ); if IsBound( r.setting ) then if r.setting in settings then return SpaceGroupList3d[r.nr].([r.setting]); else Error( "requested setting is not available" ); fi; else if 'b' in settings then r.setting := 'b'; return SpaceGroupList3d[r.nr].b; elif '2' in settings then r.setting := '2'; return SpaceGroupList3d[r.nr].2; elif 'h' in settings then r.setting := 'h'; return SpaceGroupList3d[r.nr].h; else r.setting := '1'; return SpaceGroupList3d[r.nr].1; fi; fi; else Error( "space group number must be in [1..230]" ); fi; else Error( "only dimensions 2 and 3 are supported" ); fi; end ); ############################################################################# ## #M SpaceGroupFunIT . . . . . . . . . constructor function for IT space group ## InstallGlobalFunction( SpaceGroupFunIT, function( r ) local data, gens, vec, name, norm, S, P, N; data := SpaceGroupDataIT( r ); gens := ShallowCopy( data.generators ); for vec in data.basis do Add( gens, AugmentedMatrix( IdentityMat( r.dim ), vec ) ); od; if r.action = LeftAction then gens := List( gens, TransposedMat ); norm := List( data.normgens, TransposedMat ); name := "SpaceGroupOnLeftIT("; S := AffineCrystGroupOnLeftNC( gens, IdentityMat( r.dim+1 ) ); else norm := data.normgens; name := "SpaceGroupOnRightIT("; S := AffineCrystGroupOnRightNC( gens, IdentityMat( r.dim+1 ) ); fi; AddTranslationBasis( S, data.basis ); SetName( S, Concatenation( name, String(r.dim), ",", String(r.nr), ",'", [r.setting], "')" ) ); P := PointGroup( S ); N := GroupByGenerators( norm, One(P) ); SetSize( N, data.normsize ); SetNormalizerPointGroupInGLnZ( P, N ); if data.basis = One(P) then SetNormalizerInGLnZ( P, N ); fi; return S; end ); ############################################################################# ## #M SpaceGroupOnRightIT . . . . . . . .constructor for IT space group OnRight ## InstallGlobalFunction( SpaceGroupOnRightIT, function( arg ) local r; r := rec( dim := arg[1], nr := arg[2], action := RightAction ); if IsBound( arg[3] ) then r.setting := arg[3]; fi; return SpaceGroupFunIT( r ); end ); ############################################################################# ## #M SpaceGroupOnLeftIT . . . . . . . . .constructor for IT space group OnLeft ## InstallGlobalFunction( SpaceGroupOnLeftIT, function( arg ) local r; r := rec( dim := arg[1], nr := arg[2], action := LeftAction ); if IsBound( arg[3] ) then r.setting := arg[3]; fi; return SpaceGroupFunIT( r ); end ); ############################################################################# ## #M SpaceGroupIT . . . . . . . . . . . . . . . constructor for IT space group ## InstallGlobalFunction( SpaceGroupIT, function( arg ) local r; r := rec( dim := arg[1], nr := arg[2], action := CrystGroupDefaultAction ); if IsBound( arg[3] ) then r.setting := arg[3]; fi; return SpaceGroupFunIT( r ); end ); cryst/tst/0000755001325400021140000000000014540074574012212 5ustar gaehlerusercryst/tst/manual.tst0000644001325400021140000001347514540072334014225 0ustar gaehlerusergap> START_TEST( "Cryst: manual.tst" ); gap> SetAssertionLevel(1); gap> S := SpaceGroupIT(3,222); SpaceGroupOnRightIT(3,222,'2') gap> L := MaximalSubgroupClassReps( S, rec( primes := [3,5] ) );; gap> List( L, IndexInParent ); [ 3, 27, 125 ] gap> L := MaximalSubgroupClassReps( S, > rec( classequal := true, primes := [3,5] ) );; gap> List( L, IndexInParent ); [ 27, 125 ] gap> L := MaximalSubgroupClassReps( S, > rec( latticeequal := true, primes := [3,5] ) );; gap> List( L, IndexInParent ); [ 3 ] gap> L := MaximalSubgroupClassReps( S, rec( latticeequal := true ) );; gap> Length(L); 5 gap> List( L, IndexInParent ); [ 2, 2, 2, 3, 4 ] gap> P := Group([ [ [ -1, 0 ], [ 0, -1 ] ], [ [ -1, 0 ], [ 0, 1 ] ] ]); Group([ [ [ -1, 0 ], [ 0, -1 ] ], [ [ -1, 0 ], [ 0, 1 ] ] ]) gap> norm := [ [ [ -1, 0 ], [ 0, -1 ] ], [ [ -1, 0 ], [ 0, 1 ] ], [ [ -1, 0 ], > [ 0, -1 ] ], [ [ 1, 0 ], [ 0, -1 ] ], [ [ 0, 1 ], [ 1, 0 ] ] ]; [ [ [ -1, 0 ], [ 0, -1 ] ], [ [ -1, 0 ], [ 0, 1 ] ], [ [ -1, 0 ], [ 0, -1 ] ], [ [ 1, 0 ], [ 0, -1 ] ], [ [ 0, 1 ], [ 1, 0 ] ] ] gap> if IsPackageMarkedForLoading( "CaratInterface", "" ) then > if not norm = GeneratorsOfGroup( NormalizerInGLnZ( P ) ) then > Error( "Cryst: NormalizerInGLnZ failed" ); > fi; > fi; gap> SpaceGroupsByPointGroupOnRight( P ); [ , , , ] gap> SpaceGroupsByPointGroupOnRight( P, norm ); [ , , ] gap> SpaceGroupsByPointGroupOnRight( P, norm, true ); [ [ ], [ , ], [ ] ] gap> if IsPackageMarkedForLoading( "CaratInterface", "" ) then > if not ( 3 = Length( SpaceGroupTypesByPointGroupOnRight( P ) ) and > [1,2,1] = List( SpaceGroupTypesByPointGroupOnRight( P, true ), Length ) ) > then > Error( "Cryst: NormalizerInGLnZ failed" ); > fi; > fi; gap> S := SpaceGroupIT(2,14); SpaceGroupOnRightIT(2,14,'1') gap> W := WyckoffPositions(S); [ < Wyckoff position, point group 3, translation := [ 0, 0 ], basis := [ ] > , < Wyckoff position, point group 3, translation := [ 2/3, 1/3 ], basis := [ ] > , < Wyckoff position, point group 3, translation := [ 1/3, 2/3 ], basis := [ ] > , < Wyckoff position, point group 2, translation := [ 0, 0 ], basis := [ [ 1, -1 ] ] > , < Wyckoff position, point group 1, translation := [ 0, 0 ], basis := [ [ 1, 0 ], [ 0, 1 ] ] > ] gap> sub := Group([ [ [ 0, -1 ], [ -1, 0 ] ] ]); Group([ [ [ 0, -1 ], [ -1, 0 ] ] ]) gap> IsSubgroup( PointGroup( S ), sub ); true gap> WyckoffPositionsByStabilizer( S, sub ); [ < Wyckoff position, point group 1, translation := [ 0, 0 ], basis := [ [ 1, -1 ] ] > ] gap> ForAll( W, IsWyckoffPosition ); true gap> WyckoffBasis( W[4] ); [ [ 1, -1 ] ] gap> WyckoffTranslation( W[3] ); [ 1/3, 2/3 ] gap> WyckoffSpaceGroup( W[1] ); SpaceGroupOnRightIT(2,14,'1') gap> stab := WyckoffStabilizer( W[4] ); Group([ [ [ 0, -1, 0 ], [ -1, 0, 0 ], [ 0, 0, 1 ] ] ]) gap> IsAffineCrystGroupOnRight( stab ); true gap> orb := WyckoffOrbit( W[4] ); [ < Wyckoff position, point group 2, translation := [ 0, 0 ], basis := [ [ 1, -1 ] ] > , < Wyckoff position, point group 2, translation := [ 0, 0 ], basis := [ [ 1, 2 ] ] > , < Wyckoff position, point group 2, translation := [ 0, 0 ], basis := [ [ -2, -1 ] ] > ] gap> Set(orb); [ < Wyckoff position, point group 2, translation := [ 0, 0 ], basis := [ [ 1, -1 ] ] > ] gap> G := Group( (1,2,3), (2,3,4) ); Group([ (1,2,3), (2,3,4) ]) gap> H := Group( (1,2,3) ); Group([ (1,2,3) ]) gap> C := ColorGroup( G, H ); Group([ (1,2,3), (2,3,4) ]) gap> ColorSubgroup( C ) = H; true gap> ColorCosetList( C ); [ RightCoset(Group( [ (1,2,3) ] ),()), RightCoset(Group( [ (1,2,3) ] ),(1,2) (3,4)), RightCoset(Group( [ (1,2,3) ] ),(1,3)(2,4)), RightCoset(Group( [ (1,2,3) ] ),(1,4)(2,3)) ] gap> List( last, x -> ColorOfElement( C, Representative(x) ) ); [ 1, 2, 3, 4 ] gap> U := Subgroup( C, [(1,3)(2,4)] ); Group([ (1,3)(2,4) ]) gap> IsColorGroup( U ); true gap> ColorSubgroup( U ); Group(()) gap> ColorCosetList( U ); [ RightCoset(Group( () ),()), RightCoset(Group( () ),(1,3)(2,4)) ] gap> List( last, x -> ColorOfElement( U, Representative(x) ) ); [ 1, 3 ] gap> S := SpaceGroupIT( 2, 10 ); SpaceGroupOnRightIT(2,10,'1') gap> m := MaximalSubgroupClassReps( S, rec( primes := [2] ) ); [ , , ] gap> List( last, x -> TranslationBasis(x) = TranslationBasis(S) ); [ false, true, false ] gap> C := ColorGroup( S, m[1] );; IsColorGroup( PointGroup( C ) ); false gap> C := ColorGroup( S, m[2] );; IsColorGroup( PointGroup( C ) ); true gap> sub := MaximalSubgroupClassReps( S, rec( primes := [2] ) ); [ , , ] gap> List( sub, Size ); [ infinity, infinity, infinity ] gap> sub := Filtered( sub, s -> IndexInParent( s ) = 2 ); [ , , ] gap> Length( AffineInequivalentSubgroups( S, sub ) ); 2 gap> SpaceGroupSettingsIT( 3, 146 ); "hr" gap> SpaceGroupOnRightIT( 3, 146 ); SpaceGroupOnRightIT(3,146,'h') gap> SpaceGroupOnRightIT( 3, 146, 'r' ); SpaceGroupOnRightIT(3,146,'r') gap> STOP_TEST( "manual.tst", 10000 ); cryst/tst/cryst.tst0000644001325400021140000002674214540072334014115 0ustar gaehlerusergap> START_TEST( "Cryst: cryst.tst" ); gap> SetAssertionLevel(1); gap> C := SpaceGroupIT( 3, 133 ); SpaceGroupOnRightIT(3,133,'2') gap> m := IdentityMat(4); [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ] gap> C^m; gap> C := SpaceGroupIT( 3, 133 ); SpaceGroupOnRightIT(3,133,'2') gap> P := PointGroup( C ); gap> NormalizerInGLnZ( P ); gap> G := SpaceGroupIT(3,68); SpaceGroupOnRightIT(3,68,'2') gap> pos := WyckoffPositions(G); [ < Wyckoff position, point group 3, translation := [ 0, 3/4, 1/4 ], basis := [ ] > , < Wyckoff position, point group 3, translation := [ 0, 3/4, 3/4 ], basis := [ ] > , < Wyckoff position, point group 6, translation := [ 0, 0, 1/2 ], basis := [ ] > , < Wyckoff position, point group 6, translation := [ 1/4, 1/4, 1/2 ], basis := [ ] > , < Wyckoff position, point group 2, translation := [ 1/4, 0, 0 ], basis := [ [ 0, 0, 1 ] ] > , < Wyckoff position, point group 2, translation := [ 0, 3/4, 0 ], basis := [ [ 0, 0, 1 ] ] > , < Wyckoff position, point group 4, translation := [ 0, 0, 1/4 ], basis := [ [ 0, 1, 0 ] ] > , < Wyckoff position, point group 5, translation := [ 1/4, 1/4, 1/4 ], basis := [ [ 1, 0, 0 ] ] > , < Wyckoff position, point group 1, translation := [ 0, 0, 0 ], basis := [ [ 1/2, 1/2, 0 ], [ 0, 1, 0 ], [ 0, 0, 1 ] ] > ] gap> WyckoffStabilizer(pos[5]); Group( [ [ [ -1, 0, 0, 0 ], [ 0, -1, 0, 0 ], [ 0, 0, 1, 0 ], [ 1/2, 0, 0, 1 ] ] ]) gap> S := SpaceGroupIT(2,7); SpaceGroupOnRightIT(2,7,'1') gap> P := PointGroup(S); Group([ [ [ -1, 0 ], [ 0, -1 ] ], [ [ -1, 0 ], [ 0, 1 ] ] ]) gap> N := NormalizerInGLnZ(P); Group([ [ [ -1, 0 ], [ 0, -1 ] ], [ [ -1, 0 ], [ 0, 1 ] ], [ [ -1, 0 ], [ 0, -1 ] ], [ [ 1, 0 ], [ 0, -1 ] ], [ [ 0, 1 ], [ 1, 0 ] ] ]) gap> gen := Filtered( GeneratorsOfGroup(N), x -> not x in P ); [ [ [ 0, 1 ], [ 1, 0 ] ] ] gap> n := AugmentedMatrix( gen[1], [1/5,1/7] ); [ [ 0, 1, 0 ], [ 1, 0, 0 ], [ 1/5, 1/7, 1 ] ] gap> S2 := S^n; gap> c := ConjugatorSpaceGroupsStdSamePG( S, S2 );; gap> S^c=S2; true gap> if IsPackageMarkedForLoading( "CaratInterface", "" ) then > c := ConjugatorSpaceGroupsStdSamePG( S2, S );; > if not S2^c=S then > Error( "Cryst: conjugator test failed" ); > fi; > fi; gap> C1 := [ [ 4, -3, 0 ], [ -3, -1, 0 ], [ 1/5, 1/7, 1 ] ]; [ [ 4, -3, 0 ], [ -3, -1, 0 ], [ 1/5, 1/7, 1 ] ] gap> C2 := [ [ -1, 4, 0 ], [ -1, -2, 0 ], [ 1/9, 1/13, 1 ] ]; [ [ -1, 4, 0 ], [ -1, -2, 0 ], [ 1/9, 1/13, 1 ] ] gap> S1 := S^C1; IsSpaceGroup(S1); true gap> S2 := S^C2; IsSpaceGroup(S2); true gap> C := ConjugatorSpaceGroups( S1, S2 );; gap> S1^C = S2; true gap> S1 := AffineCrystGroupOnRight( > [ [ [ -1, 0, 2, 0 ], [ -2, 1, 2, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 1/2, 1 ] ], > [ [ -1, 0, 0, 0 ], [ 0, -1, 0, 0 ], [ 0, 0, -1, 0 ], [ 0, 1/2, 0, 1 ] ], > [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 1, 0, 0, 1 ] ], > [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 1, 0, 1 ] ], > [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 1, 1 ] ] ] ); gap> gap> S2 := AffineCrystGroupOnRight( > [ [ [ -1, 0, 0, 0 ], [ 0, -1, 0, 0 ], [ 0, 0, -1, 0 ], [ 0, 0, 0, 1 ] ], > [ [ 1, 0, -2, 0 ], [ 2, -1, -2, 0 ], [ 0, 0, -1, 0 ], [ 0, 1/2, 0, 1 ] ], > [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 1, -1, 0, 1 ] ], > [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 1, 0, -1, 1 ] ], > [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ -1, 1, 1, 1 ] ] ] ); gap> if IsPackageMarkedForLoading( "CaratInterface", "" ) then > c1 := ConjugatorSpaceGroups(S1,S2);; > c2 := ConjugatorSpaceGroups(S2,S1);; > if not ( S1^c1 = S2 and S2^c2 = S1 ) then > Error( "Cryst: conjugator test 2 failed" ); > fi; > fi; gap> G := SpaceGroupIT(3, 214);; gap> iso := IsomorphismPcpGroup(G);; gap> H := Image(iso);; gap> h := Cgs(H)[1];; gap> g := PreImage(iso, h);; gap> h = Image(iso, g); true gap> IsomorphismPcpGroup( PointGroup( G ) );; gap> gen := GeneratorsOfGroup( SpaceGroupIT(3,149) ){[1..3]};; gap> Gr := AffineCrystGroup( gen ); gap> Gr = AsAffineCrystGroup( Group( gen ) ); true gap> TranslationBasis( Gr ); [ [ 1, 0, 0 ], [ 0, 1, 0 ] ] gap> InternalBasis( Gr ); [ [ 1, 0, 0 ], [ 0, 1, 0 ], [ 0, 0, 1 ] ] gap> CheckTranslationBasis( Gr ); gap> StandardAffineCrystGroup( Gr ); gap> TransParts( Gr ); [ [ 0, 0, 0 ], [ 0, 0, 0 ] ] gap> PointHomomorphism( Gr ); [ [ [ 0, 1, 0, 0 ], [ -1, -1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ], [ [ 0, -1, 0, 0 ], [ -1, 0, 0, 0 ], [ 0, 0, -1, 0 ], [ 0, 0, 0, 1 ] ], [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 1, 0, 0, 1 ] ] ] -> [ [ [ 0, 1, 0 ], [ -1, -1, 0 ], [ 0, 0, 1 ] ], [ [ 0, -1, 0 ], [ -1, 0, 0 ], [ 0, 0, -1 ] ], [ [ 1, 0, 0 ], [ 0, 1, 0 ], [ 0, 0, 1 ] ] ] gap> Gl := AffineCrystGroupOnLeft( List( gen, TransposedMat ) ); gap> Gl = AsAffineCrystGroupOnLeft( Group( List( gen, TransposedMat ) ) ); true gap> TranslationBasis( Gl ); [ [ 1, 0, 0 ], [ 0, 1, 0 ] ] gap> InternalBasis( Gl ); [ [ 1, 0, 0 ], [ 0, 1, 0 ], [ 0, 0, 1 ] ] gap> CheckTranslationBasis( Gl ); gap> StandardAffineCrystGroup( Gl ); gap> TransParts( Gl ); [ [ 0, 0, 0 ], [ 0, 0, 0 ] ] gap> PointHomomorphism( Gl ); [ [ [ 0, -1, 0, 0 ], [ 1, -1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ], [ [ 0, -1, 0, 0 ], [ -1, 0, 0, 0 ], [ 0, 0, -1, 0 ], [ 0, 0, 0, 1 ] ], [ [ 1, 0, 0, 1 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ] ] -> [ [ [ 0, -1, 0 ], [ 1, -1, 0 ], [ 0, 0, 1 ] ], [ [ 0, -1, 0 ], [ -1, 0, 0 ], [ 0, 0, -1 ] ], [ [ 1, 0, 0 ], [ 0, 1, 0 ], [ 0, 0, 1 ] ] ] gap> SpaceGroupIT(3,213) < SpaceGroupIT(3,217); false gap> G := SpaceGroupIT(3,183);; gap> W := WyckoffPositions(G);; gap> C := [ [ 3, 1, 0, 0 ], [ -1, -2, 0, 0 ], [ 2, 0, 1, 0 ], [ 0, 0, 0, 1 ] ];; gap> IsSpaceGroup( G^C ); true # The next checks verify that including a translation component in conjugation # works correctly, as from . gap> C := [ [ 3, 1, 0, 0 ], [ -1, -2, 0, 0 ], [ 2, 0, 1, 0 ], [ 1/2, 0, 0, 1 ] ];; gap> IsSpaceGroup( G^C ); true # Test that caching of Wyckoff followed by conjugation works as expected # Use Set because the order of the Wyckoff positions is semi-arbitrary. gap> Set(WyckoffPositions( G^C )) = Set(WyckoffPositions(SpaceGroupIT(3,183)^C)); true gap> G := TransposedMatrixGroup( G ); gap> W := WyckoffPositions(G);; gap> IsSpaceGroup( G^TransposedMat(C) ); true gap> Set(WyckoffPositions( G^TransposedMat(C) )) = Set(WyckoffPositions(SpaceGroupOnLeftIT(3,183)^TransposedMat(C))); true # Test Wyckoff positions in a case that involves an empty basis (see ). gap> G := SpaceGroupIT( 3, 12 );; gap> W := WyckoffPositions(G);; gap> IsSpaceGroup( G^C ); true gap> G := SpaceGroupIT( 3, 208 ); SpaceGroupOnRightIT(3,208,'1') gap> M := MaximalSubgroupClassReps( G, rec( primes := [2,3] ) ); [ , , , , , , , ] gap> List( M, x -> Index( G, x ) ); [ 2, 2, 2, 4, 4, 4, 3, 27 ] gap> List( Cartesian(M{[2,3,5]},M{[4,7,8]}), > x -> Index( G, Intersection2(x[1],x[2]) ) ); [ 8, 6, 54, 8, 6, 54, 16, 12, 108 ] gap> gen := GeneratorsOfGroup( M[1] );; gap> Centralizer( M[1], gen[1] ); gap> Centralizer( M[1], Subgroup( M[1], gen{[3]} ) ); gap> C := RightCosets( G, M[3] );; gap> CanonicalRightCosetElement( M[3], Representative(C[2]) ); [ [ -1, 0, 0, 0 ], [ 0, -1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 1, 1 ] ] gap> List( M, TranslationNormalizer ); [ , , , , , , , ] gap> if IsPackageMarkedForLoading( "CaratInterface", "" ) then > List( M, AffineNormalizer );; > fi; gap> List( M{[2,5,7]}, x -> Orbit( G, x, OnPoints ) );; gap> List( M{[3,6]}, x -> OrbitStabilizer( G, x, OnPoints ) );; gap> List( M, x -> IsomorphismPcpGroup( PointGroup(x) ) );; gap> G := SpaceGroupOnLeftIT( 3, 208 ); SpaceGroupOnLeftIT(3,208,'1') gap> M := MaximalSubgroupClassReps( G, rec( primes := [2,3] ) ); [ , , , , , , , ] gap> List( M, x -> Index( G, x ) ); [ 2, 2, 2, 4, 4, 4, 3, 27 ] gap> List( Cartesian(M{[4,6,7]},M{[2,5,8]}), > x -> Index( G, Intersection2(x[1],x[2]) ) ); [ 8, 16, 108, 8, 16, 108, 6, 12, 81 ] gap> gen := GeneratorsOfGroup( M[1] );; gap> Centralizer( M[1], gen[1] ); gap> Centralizer( M[1], Subgroup( M[1], gen{[3]} ) ); gap> C := RightCosets( G, M[3] );; gap> CanonicalRightCosetElement( M[3], Representative(C[2]) ); [ [ -1, 0, 0, 0 ], [ 0, -1, 0, 0 ], [ 0, 0, 1, 1 ], [ 0, 0, 0, 1 ] ] gap> List( M, TranslationNormalizer ); [ , , , , , , , ] gap> if IsPackageMarkedForLoading( "CaratInterface", "" ) then > List( M, AffineNormalizer );; > fi; gap> List( M{[3,7]}, x -> Orbit( G, x, OnPoints ) );; gap> List( M{[5,6]}, x -> OrbitStabilizer( G, x, OnPoints ) );; gap> List( M, x -> IsomorphismPcpGroup( PointGroup(x) ) );; gap> G := SpaceGroupOnRightIT( 3, 214 );; gap> K := Kernel( PointHomomorphism( G ) ); gap> NaturalHomomorphismByNormalSubgroup( G, K );; gap> G := SpaceGroupOnLeftIT( 3, 222 );; gap> K := Kernel( PointHomomorphism( G ) ); gap> NaturalHomomorphismByNormalSubgroup( G, K );; gap> G := SpaceGroupOnRightIT( 3, 222 );; gap> C := ConjugacyClassesMaximalSubgroups( G, rec(primes:=[2,3,5] ) );; gap> List( C, Size ); [ 1, 1, 1, 4, 3, 27, 125 ] gap> List( C{[1..6]}, x -> Length( AsList(x) ) ); [ 1, 1, 1, 4, 3, 27 ] gap> L := AsList( C[5] ); [ , , ] gap> List(L, x -> RepresentativeAction( G, L[1], x, OnPoints ) );; gap> List( C, x -> Normalizer( G, Representative(x) ) );; gap> G := SpaceGroupOnLeftIT( 3, 222 );; gap> C := ConjugacyClassesMaximalSubgroups( G, rec(primes:=[2,3,5] ) );; gap> List( C, Size ); [ 1, 1, 1, 4, 3, 27, 125 ] gap> List( C{[1..6]}, x -> Length( AsList(x) ) ); [ 1, 1, 1, 4, 3, 27 ] gap> L := AsList( C[5] ); [ , , ] gap> List(L, x -> RepresentativeAction( G, L[1], x, OnPoints ) );; gap> List( C, x -> Normalizer( G, Representative(x) ) );; gap> STOP_TEST( "cryst.tst", 10000 ); cryst/tst/subgrp.tst0000644001325400021140000000300513246017026014235 0ustar gaehlerusergap> START_TEST( "Cryst: subgrp.tst" ); gap> SetAssertionLevel(1); gap> le := rec( latticeequal := true ); rec( latticeequal := true ) gap> ce := rec( classequal := true, primes := [2,3,5] ); rec( classequal := true, primes := [ 2, 3, 5 ] ) gap> so := rec( primes := [2,3,5] ); rec( primes := [ 2, 3, 5 ] ) gap> l1 := List( [1..17], i -> Length( MaximalSubgroupClassReps( > SpaceGroupIT( 2, i ), le ) ) ); [ 0, 1, 1, 1, 1, 3, 3, 3, 3, 1, 3, 3, 1, 2, 2, 2, 4 ] gap> l2 := List( [1..17], i -> Length( MaximalSubgroupClassReps( > SpaceGroupIT( 2, i ), ce ) ) ); [ 13, 16, 10, 6, 6, 16, 8, 4, 8, 5, 6, 2, 5, 5, 3, 3, 3 ] gap> l3 := List( [1..17], i -> Length( MaximalSubgroupClassReps( > SpaceGroupIT( 2, i ), so ) ) ); [ 13, 17, 11, 7, 7, 19, 11, 7, 11, 6, 9, 5, 6, 7, 5, 5, 7 ] gap> l1 + l2 = l3; true gap> l1 := List( [1..23], i -> Length( MaximalSubgroupClassReps( > SpaceGroupIT( 3, 10*i ), le ) ) ); [ 3, 3, 3, 3, 7, 7, 7, 1, 3, 3, 3, 3, 7, 7, 2, 2, 2, 4, 4, 3, 3, 3, 5 ] gap> l2 := List( [1..23], i -> Length( MaximalSubgroupClassReps( > SpaceGroupIT( 3, 10*i ), ce ) ) ); [ 40, 10, 10, 10, 14, 6, 6, 7, 8, 8, 4, 8, 4, 12, 9, 6, 4, 8, 5, 8, 4, 2, 2 ] gap> l3 := List( [1..23], i -> Length( MaximalSubgroupClassReps( > SpaceGroupIT( 3, 10*i ), so ) ) ); [ 43, 13, 13, 13, 21, 13, 13, 8, 11, 11, 7, 11, 11, 19, 11, 8, 6, 12, 9, 11, 7, 5, 7 ] gap> l1 + l2 = l3; true gap> STOP_TEST( "subgrp.tst", 10000 ); cryst/tst/testall.g0000644001325400021140000000070114053147612014021 0ustar gaehleruserLoadPackage( "cryst" ); alltests := DirectoriesPackageLibrary( "cryst", "tst" ); # crystcat tests will only be run if crystcat is present exclude := ["crystcat.tst"]; if LoadPackage( "crystcat" ) = true then exclude := []; fi; TestDirectory( alltests, rec( exclude := exclude, exitGAP := true, testOptions := rec( compareFunction := "uptowhitespace") ) ); FORCE_QUIT_GAP(1); # if we ever get here, there was an error cryst/tst/crystcat.tst0000644001325400021140000000340114540072334014570 0ustar gaehlerusergap> START_TEST( "Cryst: crystcat.tst" ); gap> SetAssertionLevel(1); gap> S := SpaceGroupBBNWZ( 4, 29, 7, 2, 1 ); SpaceGroupOnRightBBNWZ( 4, 29, 7, 2, 1 ) gap> S := WyckoffStabilizer( WyckoffPositions(S)[1] ); gap> cl := ConjugacyClasses( S ); [ [ [ 1, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0 ], [ 0, 0, 1, 0, 0 ], [ 0, 0, 0, 1, 0 ], [ 0, 0, 0, 0, 1 ] ]^G, [ [ -1, -1, -1, -1, 0 ], [ 0, 1, 0, 1, 0 ], [ 1, 1, 0, 0, 0 ], [ 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 1 ] ]^G, [ [ -1, -1, 0, 0, 0 ], [ 0, 0, -1, -1, 0 ], [ 1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 1 ] ]^G, [ [ -1, -1, 0, 0, 0 ], [ 0, 1, 0, 0, 0 ], [ 1, 1, 1, 1, 0 ], [ 0, -1, 0, -1, 0 ], [ 0, 0, 0, 0, 1 ] ]^G, [ [ -1, -1, 0, 0, 0 ], [ 1, 0, 0, 0, 0 ], [ 0, 0, -1, -1, 0 ], [ 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 1 ] ]^G, [ [ -1, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0 ], [ 1, 0, 1, 0, 0 ], [ 0, 1, 0, 1, 0 ], [ 0, 0, 0, 0, 1 ] ]^G, [ [ 0, -1, 0, -1, 0 ], [ 0, 1, 0, 0, 0 ], [ 1, 1, 1, 1, 0 ], [ -1, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 1 ] ]^G, [ [ 0, -1, 0, -1, 0 ], [ 1, 1, 1, 1, 0 ], [ 0, 1, 0, 0, 0 ], [ -1, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 1 ] ]^G, [ [ -1, -1, -1, -1, 0 ], [ 0, 0, 1, 1, 0 ], [ 1, 0, 1, 0, 0 ], [ 0, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 1 ] ]^G ] gap> Size( cl[1] ); 1 gap> G := SpaceGroupBBNWZ( 4, 29, 7, 2, 1 ); SpaceGroupOnRightBBNWZ( 4, 29, 7, 2, 1 ) gap> H := MaximalSubgroupRepsTG( G )[4];; gap> C := ColorGroup( G, H ); gap> ColorPermGroup( C ); Group([ (2,4)(3,8)(5,6), (2,5,6,4)(3,7,8,9), (1,2,6)(3,7,5)(4,9,8), (1,3,8) (2,7,4)(5,9,6), (), (), (), () ]) gap> P := PointGroup( C ); gap> IsColorGroup( P ); true gap> STOP_TEST( "crystcat.tst", 10000 ); cryst/tst/zass.tst0000644001325400021140000000077013254463540013726 0ustar gaehlerusergap> START_TEST( "Cryst: zass.tst" ); gap> SetAssertionLevel(1); gap> List( List( [1..17], i -> SpaceGroupIT( 2, i ) ), > g -> Length( SpaceGroupsByPointGroup( PointGroup( g ) ) ) ); [ 1, 1, 2, 2, 2, 4, 4, 4, 4, 1, 2, 2, 1, 1, 1, 1, 1 ] gap> List( List( [1..23], i -> SpaceGroupIT( 3, 10*i-7 ) ), > g -> Length( SpaceGroupsByPointGroup( PointGroup( g ) ) ) ); [ 2, 8, 8, 16, 16, 64, 64, 64, 4, 8, 8, 4, 16, 16, 3, 3, 2, 6, 4, 4, 4, 4, 4 ] gap> STOP_TEST( "zass.tst", 10000 ); cryst/tst/wyckoff.tst0000644001325400021140000000062213554311016014403 0ustar gaehlerusergap> START_TEST( "Cryst: wyckoff.tst" ); gap> SetAssertionLevel(1); gap> List( [1..17], i -> Length( WyckoffPositions( SpaceGroupIT(2,i) ) ) ); [ 1, 5, 3, 1, 2, 9, 4, 3, 6, 4, 7, 4, 4, 5, 4, 4, 6 ] gap> List( [1..23], i -> Length( WyckoffPositions( SpaceGroupIT(3,10*i-3) ) ) ); [ 1, 5, 5, 4, 27, 5, 15, 4, 9, 11, 5, 9, 12, 8, 7, 4, 6, 14, 15, 6, 11, 8, 9 ] gap> STOP_TEST( "wyckoff.tst", 10000 ); cryst/Changelog0000644001325400021140000001140314540073616013205 0ustar gaehleruserVersion 4.1.27 - fixed incomplete conjugation of Wyckoff positions (thanks to Bernard Field and Max Horn) Version 4.1.26 - Bugfix in SolveInhomEquationsModZ - Bugfix in comparison of affine cryst groups. - Catch the case of a trivial point group in ConjugatorSpaceGroups. - Corrected the documentation regarding conjugation of space groups. Version 4.1.25 - Improved documentation conversion and formatting Version 4.1.24 - Catch another trivial case in IntSolutionMat. - Turn RowEchelonForm into an attribute, to make it read-only. - Switch to GitHub Actions CI. - Test CrystCat functionality only when CrystCat is available. Version 4.1.23 - Make Cryst work at assertion level 2. Version 4.1.22 - Adjustments due to name change from Carat to CaratInterface. Version 4.1.21 - Make silent assumption on pcgs in MaximalSubgroupRepsSG explicit. - Fixed bug in WyckoffPositions. Some Wyckoff positions were listed more than once, due to improper normalization of the representative affine subspace. Version 4.1.20 - Catch trivial case before calling IsDiagonalMat Version 4.1.19 - Compatibility fixes for GAP 4.11. Version 4.1.18 - Fixed trivial changes in output of a manual example and several test examples. Version 4.1.17 - Bug in ConjugatorSpaceGroups fixed. Version 4.1.16 - Bug in ImagesRepresentative for isomorphism to PcpGroup fixed. - Bug in kernel of PointHomomorphism for left-acting group fixed. - Bugs in Centralizer and CanonicalRightCosetElement fixed. - Test files with better code coverage. Version 4.1.15 - PackageInfo record corrected Version 4.1.14 - Corrected incompatible standardizations of affine subspaces. - Added various testfiles. Version 4.1.13 - Fixed a bug in ImagesRepresentative for IsFromAffineCrystGroupToPcpGroup Version 4.1.12 - Fixed a bug in RepresentativeAction for AffineCrystGroups Version 4.1.11 - Fixed a bug in the conjugation of left-acting AffineCrystGroups - Changed outdated RequirePackage in manual Version 4.1.10 - Fixed file permission problem Version 4.1.9 - Minor Update Version 4.1.8 - Bugfix in AffineNormalizer Version 4.1.7 - Adapted to GAP 4.5 Version 4.1.6 - TranslationBasis for trivial point group fixed - Bug in ImagesRepresentative for IsomorphismFpGroup of an AffineCrystGroupOnLeft fixed - Multiplication with empty matrix in WyckoffPositions fixed - Membership test in AffineCrystGroups improved Version 4.1.5 - Incomplete translation basis fixed Version 4.1.4 - Two instances of multiplying an empty list with a matrix fixed Version 4.1.3: - Mutability problem fixed Version 4.1.2: - File manual.toc added Version 4.1.1: - Online help should now work for all functions. - Fixed several manual examples changed output or wrong input. - Avoided some multiplications of an empty list with a matrix. - Support for new package loading mechanism in GAP 4.4 Version 4.1: - Name change from CrystGAP (or CrystGap) to just Cryst. This avoids confusion, as even CrystGAP was always loaded as "cryst". - A second algorithm for the computation of Wyckoff positions (due to Ad Thiers) has been implemented. It avoids the computation of a subgroup lattice, and is faster in small dimensions. It is used by default for dimensions <= 4. The two available algorithms can be called directly using the functions WyPosAT( S ); # algorithm due to Ad Thiers WyPosSGL( S ); # algorithm using the subgroup lattice These functions are still undocumented. - A bug in WyckoffGraph was fixed. The labels of the lines in the graph were not what was intended, and the manual was even selfcontradictory in this respect. This required code for intersections of affine subspace lattices, and a better subset test for affine subspace lattices. These are still undocumented. - The function ConjugatorSpaceGroups is now documented. - Cryst now tries to load the package polycyclic, and then installs methods for IsomorphismPcpGroup for PointGroups and AffineCrystGroups. - A method for ImagesRepresentative for an IsomorphismFpGroup of an AffineCrystGroup has been added, so that the resulting isomorphism can now really be used. - Switch to the new attribute MappingGeneratorsImages. Compatibility with GAP 4.2 and GAP 4.1 is maintained. - A bug in Normalizer for two AffineCrystGroupsOnLeft was fixed; it returned an AffineCrystGroupOnRight. - The number of generators returned by Normalizer for two AffineCrystGroups was reduced. - A bug in ConjugacyClassesMaximalSubgroups for space groups was fixed; their size was set to a wrong value in certain cases. - A mutability bug in AffineNormalizer was fixed. Version 4.0: Initial release for GAP 4. cryst/PackageInfo.g0000644001325400021140000000733614540073735013726 0ustar gaehleruser############################################################################# ## ## PackageInfo.g for Cryst ## SetPackageInfo( rec( PackageName := "Cryst", Subtitle := "Computing with crystallographic groups", Version := "4.1.27", Date := "18/12/2023", # dd/mm/yyyy format License := "GPL-2.0-or-later", ArchiveURL := Concatenation( "https://www.math.uni-bielefeld.de/~gaehler/gap/Cryst/cryst-", ~.Version ), ArchiveFormats := ".tar.gz", BinaryFiles := [ "doc/manual.pdf", "doc/manual.dvi" ], Persons := [ rec( LastName := "Eick", FirstNames := "Bettina", IsAuthor := true, IsMaintainer := true, Email := "beick@tu-bs.de", WWWHome := "http://www.iaa.tu-bs.de/beick", PostalAddress := Concatenation( "Institut Analysis und Algebra\n", "TU Braunschweig\n", "Universitätsplatz 2\n", "D-38106 Braunschweig\n", "Germany" ), Place := "Braunschweig", Institution := "TU Braunschweig" ), rec( LastName := "Gähler", FirstNames := "Franz", IsAuthor := true, IsMaintainer := true, Email := "gaehler@math.uni-bielefeld.de", WWWHome := "https://www.math.uni-bielefeld.de/~gaehler/", #PostalAddress := "", Place := "Bielefeld", Institution := "Mathematik, Universität Bielefeld" ), rec( LastName := "Nickel", FirstNames := "Werner", IsAuthor := true, IsMaintainer := false, Email := "nickel@mathematik.tu-darmstadt.de", ) ], Status := "accepted", CommunicatedBy := "Herbert Pahlings (Aachen)", AcceptDate := "02/2000", README_URL := "https://www.math.uni-bielefeld.de/~gaehler/gap/Cryst/README.cryst", PackageInfoURL := "https://www.math.uni-bielefeld.de/~gaehler/gap/Cryst/PackageInfo.g", AbstractHTML := "This package, previously known as CrystGAP, \ provides a rich set of methods for the computation with affine \ crystallographic groups, in particular space groups. Affine \ crystallographic groups are fully supported both in representations \ acting from the right or from the left, the latter one being preferred \ by crystallographers. Functions to determine representatives of all \ space group types of a given dimension are also provided. Where necessary, \ Cryst can also make use of functionality \ provided by the package CaratInterface.", PackageWWWHome := "https://www.math.uni-bielefeld.de/~gaehler/gap/packages.php", SourceRepository := rec( Type := "git", URL := Concatenation( "https://github.com/gap-packages/", LowercaseString( ~.PackageName ) ) ), IssueTrackerURL := Concatenation( ~.SourceRepository.URL, "/issues" ), SupportEmail := "gaehler@math.uni-bielefeld.de", PackageDoc := rec( BookName := "Cryst", ArchiveURLSubset := ["doc", "htm"], HTMLStart := "htm/chapters.htm", PDFFile := "doc/manual.pdf", SixFile := "doc/manual.six", LongTitle := "Computing with crystallographic groups", ), Dependencies := rec( GAP := ">=4.11", NeededOtherPackages := [ [ "polycyclic", ">=2.16" ] ], SuggestedOtherPackages := [ [ "CrystCat", ">=1.1.9" ], [ "CaratInterface", ">=2.3.3" ], [ "XGAP", ">=4.22" ] ], ExternalConditions := [] ), AvailabilityTest := ReturnTrue, #BannerString := "", TestFile := "tst/testall.g", Keywords := [ "crystallographic groups", "affine crystallographic groups", "space groups", "color groups", "point group", "Wyckoff positions", "International Tables for Crystallography", "maximal subgroups", "normalizer" ] ));