cryst/COPYING0000644000371700037170000004367613573723022014511 0ustar gap-jenkinsgap-jenkinsPackage Cryst is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License (GPL) as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. The text of the GPL v2 is appended below, and can also be found at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. 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/README0000664000371700037170000000421513573723022014322 0ustar gap-jenkinsgap-jenkins 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.g0000644000371700037170000000234013573723022014550 0ustar gap-jenkinsgap-jenkins############################################################################# ## #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 ## ############################################################################# ## #R read the declaration files ## 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/read.g0000644000371700037170000000461413573723022014526 0ustar gap-jenkinsgap-jenkins############################################################################# ## #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/PackageInfo.g0000664000371700037170000000764613573723022015774 0ustar gap-jenkinsgap-jenkins############################################################################# ## ## PackageInfo.g for Cryst ## SetPackageInfo( rec( PackageName := "Cryst", Subtitle := "Computing with crystallographic groups", Version := "4.1.23", Date := "10/12/2019", # 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 := true, Email := "nickel@mathematik.tu-darmstadt.de", WWWHome := "http://www.mathematik.tu-darmstadt.de/~nickel/", #PostalAddress := "", Place := "Darmstadt", Institution := "Fachbereich 4, AG 2, TU Darmstadt" ) ], 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", Autoload := true ), Dependencies := rec( GAP := ">=4.9", NeededOtherPackages := [ [ "polycyclic", ">=2.9" ] ], SuggestedOtherPackages := [ [ "CrystCat", ">=1.1.4" ], [ "CaratInterface", ">=2.3.1" ], [ "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" ] )); cryst/doc/introduction.tex0000664000371700037170000000507313573723022017455 0ustar gap-jenkinsgap-jenkins%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \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.tex0000664000371700037170000011230313573723022016073 0ustar gap-jenkinsgap-jenkins%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %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> 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.tex0000664000371700037170000000226613573723022016212 0ustar gap-jenkinsgap-jenkins\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.23} \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--2019 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 http://www.gnu.org/licenses/.} } \OneColumnTableOfContents \FrontMatter \Chapters \Input{introduction} \Input{cryst} \Appendices \Bibliography \Index \EndOfBook cryst/htm/theindex.htm0000664000371700037170000001626713573723022016566 0ustar gap-jenkinsgap-jenkinscryst : 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 2019
cryst/htm/CHAP002.htm0000664000371700037170000013553313573723022015711 0ustar gap-jenkinsgap-jenkins[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 S conj^-1 is returned. conj must be an affine matrix acting on the right. If S is an AffineCrystGroupOnLeft, the group conj^-1 S conj 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] ) );
    [ <matrix group with 7 generators>, <matrix group with 8 generators>, 
      <matrix group with 8 generators> ]
    gap> List( L, IndexInParent );
    [ 3, 27, 125 ]
    gap> L := MaximalSubgroupClassReps( S,             
    >                  rec( classequal := true, primes := [3,5] ) );
    [ <matrix group with 8 generators>, <matrix group with 8 generators> ]
    gap> List( L, IndexInParent );                                                 
    [ 27, 125 ]
    gap> L := MaximalSubgroupClassReps( S,
    >                  rec( latticeequal := true, primes := [3,5] ) );
    [ <matrix group with 7 generators> ]
    gap> List( L, IndexInParent );                                       
    [ 3 ]
    gap> L := MaximalSubgroupClassReps( S, rec( latticeequal := true ) );
    [ <matrix group with 7 generators>, <matrix group with 7 generators>, 
      <matrix group with 7 generators>, <matrix group with 7 generators>, 
      <matrix group with 6 generators> ]
    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 2019
    cryst/htm/CHAP001.htm0000664000371700037170000001003313573723022015673 0ustar gap-jenkinsgap-jenkins[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 2019
    cryst/htm/chapters.htm0000664000371700037170000000106613573723022016556 0ustar gap-jenkinsgap-jenkinscryst : a GAP 4 package - Chapters

    cryst : a GAP 4 package - Chapters

    1. Introduction
    2. Affine crystallographic groups

    cryst manual
    Dezember 2019
    cryst/htm/biblio.htm0000664000371700037170000000234413573723022016205 0ustar gap-jenkinsgap-jenkinscryst : 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 2019
    cryst/gap/equiv.gi0000644000371700037170000001333413573723022015663 0ustar gap-jenkinsgap-jenkins############################################################################# ## #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 ); 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 -> PreImagesRepresentative( PointHomomorphism( S1 ), x ) ); t1 := Concatenation( List( gen1, x -> x[d+1]{[1..d]} ) ); gen2 := List( GeneratorsOfGroup( P ), x -> PreImagesRepresentative( 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 -> PreImagesRepresentative( 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.gd0000644000371700037170000000116513573723022015311 0ustar gap-jenkinsgap-jenkins############################################################################# ## #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.gi0000664000371700037170000006730013573723022015764 0ustar gap-jenkinsgap-jenkins############################################################################# ## #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 := PreImagesRepresentative( 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 := PreImagesRepresentative( 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 -> PreImagesRepresentative( PointHomomorphism( G1 ), x) ); gen2 := List( gen, x -> PreImagesRepresentative( 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 := PreImagesRepresentative( PointHomomorphism( G1 ), g ); g1 := AffMatMutableTrans( g1 ); if Length(T1) > 0 then g2 := PreImagesRepresentative( 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 -> PreImagesRepresentative( 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 -> PreImagesRepresentative( 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( PreImagesRepresentative( 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.gi0000664000371700037170000003302113573723022015507 0ustar gap-jenkinsgap-jenkins############################################################################# ## #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 := PreImagesRepresentative( 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.gd0000644000371700037170000000750513573723022016200 0ustar gap-jenkinsgap-jenkins############################################################################# ## #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.gi0000664000371700037170000005526713573723022016217 0ustar gap-jenkinsgap-jenkins############################################################################# ## #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 ); 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 ); 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 = true then Q := IdentityMat( Length(M) ); M := TransposedMat(M); M := RowEchelonFormVector( M,b ); else Q := IdentityMat( Length(M[1]) ); fi; 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.gd0000644000371700037170000000275513573723022015315 0ustar gap-jenkinsgap-jenkins############################################################################# ## #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.gd0000644000371700037170000000364713573723022015513 0ustar gap-jenkinsgap-jenkins############################################################################# ## #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.gi0000644000371700037170000000734313573723022015320 0ustar gap-jenkinsgap-jenkins############################################################################# ## #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 PreImagesRepresentative( , ) . . . . . . for PointHomomorphism ## InstallMethod( PreImagesRepresentative, 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.gi0000644000371700037170000001660513573723022016031 0ustar gap-jenkinsgap-jenkins############################################################################# ## #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 -> PreImagesRepresentative( repr, x ) ); prei := List( prei, x -> PreImagesRepresentative( 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 -> PreImagesRepresentative( 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 -> PreImagesRepresentative(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 -> PreImagesRepresentative(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.gi0000644000371700037170000001320513573723022016210 0ustar gap-jenkinsgap-jenkins############################################################################# ## #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.gd0000644000371700037170000000125113573723022015651 0ustar gap-jenkinsgap-jenkins############################################################################# ## #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.gi0000644000371700037170000000126013573723022016021 0ustar gap-jenkinsgap-jenkins############################################################################# ## #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.gi0000644000371700037170000001360713573723022015653 0ustar gap-jenkinsgap-jenkins############################################################################# ## #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 -> PreImagesRepresentative( 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.gi0000644000371700037170000001576713573723022016271 0ustar gap-jenkinsgap-jenkins############################################################################# ## #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.gi0000644000371700037170000002215013573723022016016 0ustar gap-jenkinsgap-jenkins############################################################################# ## #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 ## RowEchelonForm := 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 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.gd0000644000371700037170000002304013573723022015664 0ustar gap-jenkinsgap-jenkins############################################################################# ## #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.gi0000664000371700037170000006253313573723022015326 0ustar gap-jenkinsgap-jenkins############################################################################# ## #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 DepthVector( vec ) . . . . . . . . . . . . . . . . . . . . depth of vetor ## #DepthVector := function( vec ) # local i; # for i in [1..Length(vec)] do # if not vec[i] = 0 * vec[i] then # return i; # fi; # od; # return Length(vec) + 1; #end; ############################################################################# ## #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] := DepthVector( base.fullbase[i] ); 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 := DepthVector( w ); 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.gi0000644000371700037170000001354213573723022015651 0ustar gap-jenkinsgap-jenkins############################################################################# ## #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.gi0000644000371700037170000003107613573723022016171 0ustar gap-jenkinsgap-jenkins############################################################################# ## #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 -> PreImagesRepresentative( 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 := PreImagesRepresentative( 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 -> PreImagesRepresentative( 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 -> PreImagesRepresentative( 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 := PreImagesRepresentative( 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 -> PreImagesRepresentative( 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.gd0000644000371700037170000000364013573723022015642 0ustar gap-jenkinsgap-jenkins############################################################################# ## #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.gi0000664000371700037170000006547413573723022015714 0ustar gap-jenkinsgap-jenkins############################################################################# ## #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; 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]}; # 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*c, translation := w!.translation*c, class := w!.class, spaceGroup := R ); 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; 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]} ); # 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*c, translation := w!.translation*c, class := w!.class, spaceGroup := R ); 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, d, gens; T := TranslationBasis( S ); P := PointGroup( S ); d := DimensionOfMatrixGroup( P ); gens := GeneratorsSmallest( NiceObject( P ) ); gens := List( gens, x -> ImagesRepresentative( NiceToCryst( P ), 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 := PreImagesRepresentative( 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/spacegrp.gd0000644000371700037170000000407513573723022016354 0ustar gap-jenkinsgap-jenkins############################################################################# ## #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 SpaceGroupList2d . . . . . . . . . . . . . . .data for 2d IT space groups ## DeclareGlobalVariable( "SpaceGroupList2d" ); ############################################################################# ## #F SpaceGroupList3d . . . . . . . . . . . . . . .data for 3d IT space groups ## DeclareGlobalVariable( "SpaceGroupList3d" ); ############################################################################# ## #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.grp0000644000371700037170000035312413573723022016554 0ustar gap-jenkinsgap-jenkins############################################################################# ## #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 ## InstallValue(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 ## InstallValue(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.gi0000644000371700037170000001207313573723022016356 0ustar gap-jenkinsgap-jenkins############################################################################# ## #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/manual.tst0000664000371700037170000001426213573723022016270 0ustar gap-jenkinsgap-jenkinsgap> 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> 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.tst0000664000371700037170000003144413573723022016160 0ustar gap-jenkinsgap-jenkinsgap> 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> 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> 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 gap> G := TransposedMatrixGroup( G ); gap> W := WyckoffPositions(G);; gap> IsSpaceGroup( G^TransposedMat(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] ); [ RightCoset(,[ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ]), RightCoset(,[ [ 0, 1, 0, 0 ], [ 1, 0, 0, 0 ], [ 0, 0, -1, 0 ], [ 1/2, 1/2, 1/2, 1 ] ]) ] 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] ); [ RightCoset(,[ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ]), RightCoset(,[ [ 0, 1, 0, 1/2 ], [ 1, 0, 0, 1/2 ], [ 0, 0, -1, 1/2 ], [ 0, 0, 0, 1 ] ]) ] 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.tst0000644000371700037170000000300513573723022016304 0ustar gap-jenkinsgap-jenkinsgap> 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.g0000644000371700037170000000041713573723022016072 0ustar gap-jenkinsgap-jenkinsLoadPackage( "cryst" ); LoadPackage( "crystcat" ); TestDirectory( DirectoriesPackageLibrary( "cryst", "tst" ), rec( exitGAP := true, testOptions := rec( compareFunction := "uptowhitespace") ) ); FORCE_QUIT_GAP(1); # if we ever get here, there was an error cryst/tst/zass.tst0000644000371700037170000000077013573723022015770 0ustar gap-jenkinsgap-jenkinsgap> 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.tst0000664000371700037170000000062213573723022016456 0ustar gap-jenkinsgap-jenkinsgap> 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/Changelog0000664000371700037170000001015613573723022015255 0ustar gap-jenkinsgap-jenkinsVersion 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/doc/manual.lab0000644000371700037170000001142113573723022016137 0ustar gap-jenkinsgap-jenkins\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.toc0000644000371700037170000000116513573723022016172 0ustar gap-jenkinsgap-jenkins\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_doc0000755000371700037170000000044313573723022015674 0ustar gap-jenkinsgap-jenkins#!/bin/sh 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 mkdir -p ../htm ../../../etc/convert.pl -c -i -u -n cryst . ../htm dvips -o manual.ps manual ps2pdf manual.ps manual.pdf cryst/doc/manual.mst0000644000371700037170000000046413573723022016211 0ustar gap-jenkinsgap-jenkinspreamble "" 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.six0000644000371700037170000000672713573723022016221 0ustar gap-jenkinsgap-jenkinsC 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.pdf0000664000371700037170000037411713573723022016172 0ustar gap-jenkinsgap-jenkins%PDF-1.4 %쏢 5 0 obj <> stream xWn7 ߯ +zPRwI( .E݅{EHli!/3{y^EE:k7_n^vc͇ Տo=!w>1v͸:c&ɰ&Yom1C?Bї--߸Pcغnx8 *ǖ8cD{f .zp&uƻS9sq|7 ߀ QG 3O[SxZ}p)죐ADPAxL`Y^jy\L`Im8/=osh&VnjU"ZsA N˾q#K$O8'FC`rQ4gw _EZ Կ9S"՜<dOC`|؈RDIgNUUh Ev%гTY4wSvւ]`-YP7H^ W*| ɐS1{m!0 UYnzL1C$DvglN_Fּu̮XWXp* }ڌniUΈbvX9W.TjRWqU6"ؽtr\}|h{>&Y_i?U Eʅ*^U@/NׯŭjZKr -[o\Óԅ"jtأʛf#خY~ޖwC!Sy#ԭCƒK:A\`Njǎ4‹ }C?[V}^Rl2".JA21PŚ_ȨB-Wq%}!8͛9ن³=O Aλڮ/aA:[%nƹw]jN92&1y-=p웉.C&P;CBɼ"tߜ߉YS.z12y5SڍU[9ȫãPt";:LT.[!~]h9  Tu|UQ>BdVݺ8|W>׮UHx>WyH8D ThZ*aE͖&ZCM:JA}"e\0JF;廒*(Dnp<}F%@I~hl6Շ\0w+-k!UפzvB,DI(iTN[9?DhjRʴ6ΞS GI^`S"~LqѴ6yf}ģ=S6uaiW¬y%*Os2lFZOw2endstream endobj 6 0 obj 1379 endobj 17 0 obj <> stream xYKo7zԯne8 "E[!"َm!~EۺCj]:c8aU}Nc o2\&RYuD"(%њ-\,ބ$'nuϭV%A$KB6u\#%(dLC  .SL2p*q#.MZC* tnmU0n z?p:2a޹ k3C\/_ ?e1LR7!nG,C7ݵb Ra FQBͰZswSUb@yQi,Io0 ' yrOvCr]C!s ή#;,[w ؂^}w/PثԞ_&x$XX֟d y tj缗'yQ{!"eTBC_p. ~9/&8 ~k.bTeD5hб`Dpjr3f}>).hvxKʲ rϼ:ȼcʿieNJY19\2f!f61rGx;! + С \cPn8Uɷl1TL—/Wۧs>` 3#ug F.za\`35uUc.L@:>x< ?< _DB #[yD0#ٿ-j -a^g0?j.o/BL=D$w4hendstream endobj 18 0 obj 1156 endobj 24 0 obj <> stream x\[GxXtʙLߧHa]Z{s]E+ U}9g"<3S]]յyG3K<͓7OD(wzs1y3Y-'CqdYLj9:yl#@)mǿ _)3-J‡gUNLrYYқ[9Oesw^lC}<RK)/}\@إEp;iiֳ+=R~s~)Yk29}϶yr,eRͻJM}{XW"HxT0zžp1lv:iv҅I_r҈/ry!>.v&c֛;M0ymxAt&-6^H筨9Hɞ41 t f6Z )l>Gxi|ՓVm"_ WaTa~B*$`:)\n2Vo^TJ+~DDq+&]RtJ:AeNpSy--YpшRB֫Lx~Zlт4~^8%6lʕ\oQz\ q|}G;*j.>`Y/\v" 泚M0*GH ',*)Hq(\H:9y-;#(|"be mBW]H3ppۋ (0|E# <9 UI/zίփJ/k1uBO+^C^`:' C4hBkVұù(M&9~B+T"KH3|]@RQ!9YG~duW HUa)/_Jaz<ɢ٭"u.e o?ᑘ$#T M?$ 엌=h:7%H\U,8>}A⦯`|`_b@ݲqU!N76 Dz~'y1qBY8\wVS;9%K#A#L*(NlII8&a1 pC cMu!AαTΓ~-.갢Z+F\^9pj " 2#b Z -(`"`Q;^w+=(BL<{bt)!D@t0 ՙ^5 #C6n(8}CX4?YHqSK"'TH}QR(@P^Yp]co-#a;Ry*Z;0݂@/^'d<=ocnp 3})Sos6C E?{GFӫnuܘqc8ًI?*|$|Su¤8Ƀ`?/( !M&$mRu1K0;Xv4$SCd+N"e_|c?yݗ" :OĪ*|:8}n1v%?)07 ;#;[xmI~/` yV~J Vwh`!䘣hf]"s-Ə#z.]^kD, y0À*BV8ntDeWSD|QZEI?wwp 2$I y5 Cr+\*/i(mN*@U㋗!;s9OcƼw0Ca9[*(ފ O8tn2=2u.~-k_]vH-aNAҖb_`lun op~L6~-z1n6uUVE]V+r;**yWAr1Dd g>*NJE)7ߗY!I'ƛԀ,qXQ󴓊0l-X`8Ⱦ TjpɽwR \ulRaOl{Fyh9t6Ժ}6D"8a9ݯ4ltHV.FUE]oS/3~t[- )dG7rr:  ݯ{ǝeO5(~#-GVi^R#찐KFʆKp6Wj]LlTJ%x ?@M_<{"Zf\fC6bO0֠['N*[Њ'CU8vD2  &Iޘ6@ 5s37 cA/iCtшM=+]~iw5)L A3lF-֖rl$MUvCAmP|m:w40ҼIhPT:x~k0MFS}O,8=3@PGx@cRErtT:|Uje$(&f}DҶ큂5;T;!<ҬZo9ͫ87 bQdUIqzE@4 |f؀7Xu)yGwS]#5">#6gH;N΀dSC]Fhvͩ@GЃS9Zms^#\Vl;EsXpMZLh=YtF<ӛ ϶֪*7\e44# :Sy*.a~|J+"$[`I O)*O9^WЗ95&МV;&(\UPuOZ) KY:栰ALӢh%7vP%!ٓQ(bIny;& okOAfRN)^ c\\U'`$DPɮJ A]wOy.\BB=ΔPr Bdb=iʗuu`YA]Rxq(yEXmdMЋ>_7DMt߰xm;;_9߰@ԄOgK`[]5S'5{ـAyS4;)UADuBY)1hXi1ȮTY\܌I\Wkl{Bө&1 9۩C:.ӮZY{\zcJ 6NTa-5Yf!@dФ÷Fr->vnY)bQL` Vur7;RRbH묇c;N8A|>ߦQ".xt2G:zRGOKᢎ`|:zZ}]G7>"A*<ճʊ>74'onyViV[rf1-OY` 5GC8+¢YJ٧MI,MĹ'E}W$r.w̮@Y Y'_ed[)pJHYWR]/#3J4n*;[x[u#L,ωWҠ~uK 1@,U4a/%r%7 F |ZFߍGE+v)b,_Pn#L>VzsrN}U%WBD\mŢYE&kjc$OX2r6_z ]@EoWwa?7gMiՖWx=m68#D\g+BxRBjg i麇MIm"I"kPi\hԈv@ms @ d7L rD Q ^``}ΛH ]6(J}_ Vp˹ CL->4^T;a^u{ҝzman5_ؑ/CUq;8~b_73~ 䬚̒=wͦ:5 ;QW?U24?s\>bti{CTRCf- ̚IZ/~@~W5fuQ$w툎FWsb4Mm8h ]Hd)ZCϷ? { ] z$1%k!hfoWe41qW?zMσ|bt_>T゚RȷӵUʗx!~6utrSSQ- Pjl=r}5hZI}}ci$Ewz;|Xj%vځ_mQyrp/z7!F1m. hp+,\ڏkp"$y_e0I~\GI\{كR};Щ펢YB ^u6uL銣4T_G?}>&y]I?i߿ !endstream endobj 25 0 obj 4719 endobj 33 0 obj <> stream x\YsG >vk 7~PxaE=őH7G!d5IZo(B*UP82@t2Od?ޝ\}~5\镈??)4'LV urz*=(N5vW-6oRf|J91yD'<NL+7һ 6z7AJOvZ߱0*l>mwaFzs:woR+D2Zz x/r0]}ok_i7g `l@X֣y`Cx} ua VZ˾4 Uw,%O tjC ma7d[¢l<';K,eZ~ު:XwM ~wӥ1RKW;?]m^^׮`Rͦt j_U˫jiU*Ejɫ^idjvs;iŤ "\Z\`i8AyLs@*C0 ɑ_/q"#Eǰ&QzrZov;_=w۝5Q ؤs1谱U E[>4N5^~#WMJ;rNL$萐e-qRb@AJ];|3`#%$}[Z2'".mz^_KF+vht }$;,.r6:][t.8"%#ܣ0'Vش&n<Ծzu~dc! dmSl%fI-m[U $VXu,Ta ]dUgb_[X:ul* ⾨JE*4MX3,wt#DDb h  x[),\oQ|فqsu\[&RM8fmP'"tbvރ<Ŷ?fdW_;˸ L'[F7G&:a};t<x= Ok y+B|Cg+kLЯ2\f)z] X ze itiKꢶ}WЃEO5>囨ZJ5l­%nTpnڔPOJHݴnoGSArv|X.s>}1p8[sy;~D0`2ZR337cP`ZHhaad~d@$;qm97BEHojy."ʣ{rJM'b{J~OG 4&5GԤx[:l$UgUc9\ux28( ml ^|Գ\ʸsו7ؙ,R#zʵb)R6ia0 C-ädTR*'c|bQ!_tU0@Z,)<|qa. |`t*47>+P{+y(*V moOrTq3- Iܬj%р"Ub` Zyr÷BĢȔ̝>PbFD::&~5PSK25,5h$,c B;$nD\1B2b: f>q0k Rt=QFA9Q*O$oa-AL N3:¢ @7[GG:W *a¡A2i&w3~ vRRDKVQ׵Hl'}a'gc[?v%dӺDnIm/IZ%q3}VAEg# 7o{uGqƓq}# a?0ŠF! *j"F~z79q]w>tsN >KSo0+}^~aC!4M8WāCzjrlr~I>@+# %b;hg,N쓻ɲe8|k^q@` .L|:{U]C@5X.#B!qD1#|j0G^8 Sr};W_PFM%ϦFHV硗"=W!_g[#\E6kaeU\ԣuyDey͋1-m/A \ن&g&Oគ]hl+Y(1p "j~MBX:'E壓>yV〕JXVc#_'A:6 :\/{u!՝EɃX{p(Rh\pi4c9Ѱ"HGz$ҁ+KNd_t cxAjCfըsV%ٍ] fiٳyAJ}Y57"4z{a&%4XӞnOm;жnD5qx+ Cb_Rg~-ZY=!kK\()# />|td W6d`гGK<И$3o+ÖWV+kYo꒿ޢ?`KTX(ԀX0kD,/k -g`]-0Revh|. JѨ7a={%mEb/67}%ʪz. vF!!|ķ)e/3C?D$I$J 衪5ƔFzZg"/[\cWc+c%wqu:_x&5~&.`XbH sijdtvAā1f|:^` n8-VwYgt,fu^クӺx/q_~& jpeG4̦]Xy:;m(X VvvK.Mĥ56/stUǹF }(jkA Y6^$EVʵ!◙nR;)1fjvR˓{w"7IJbƃoJ#W1ratݕ혺n@RQXb.r2UTVl*(m6C5[qbGx;ALFf({į>n ijFe-:z*v 2АH֧mcGǐ+=X36OJCś&{ⲓHmWMT91Ů֬$6Q$6utY)IϤ"'Gc-k.WNr%e9'ʲ~D'WNJAgSWӖphZB/k6C3%b RλψxqfRq>$`WyK ˠ~l-Bڦh( PJ}C4ZةH>ׂ.b7c2!t֎Ұam_fh%ldω`Aұ<6 mU-ǿ, ɔMN6$ݷ򉉵h Mʵb|W\YY®J&ϖ+' RJ㶜Y"ޖRaH@)"E&Iv&vc#(C랃 %ərEp"oeQ X{\S/"Y1>#U4{9~ĪDZ`KN =Pyr@ 4 |g|_׋,Uts:/_팈Җ{24X͌X_7[?q%t6uz³!d>3nìD3SF[ne+w%$V('%^ Cz>YcK+aT|o%*'GH&yϳM.O0|WK>;~#MR,q\j-&saj6XNGY+}Rd"\AlKrH"~xT_f =y?DM7Pt*'x۬hVa:g~ v88+һfW,tH:l&kZjoz-#ZlPv Fvw/12 nIki<ޝm ʙߝ3?GPendstream endobj 34 0 obj 4720 endobj 46 0 obj <> stream xr\*G~gu9;U*3A8+¹Ǻ\41>N'2Ж^;S`UF#\l\X0lKcr '~-$c+͕g3WynBeqӦYoq=WJq s 8Tk%<>pb]yZF|W:4~a.~Ƚs}νfRO*}[!E~N2}}?/S爫I%a^ `NO)a#c=Õϫr$3J}/ W_+5*tok'&鈝+<ﴅ2w2O(C>6 .yL{t{FyYnf W# k;%af *._!cr/te6M`])`.nIj 0 Ctf/ XWag^`u xdZ._*۪"!&ą\|[ oIh)L"ggK,h2(ޤ4\lO\|p?!{H=wW!WMM,s,6OŰ3G0"ȶWFĿ .ˮ«nif1,sk;.qV3c7wVBcSy橌٥<z{#aAWH]` zSW~_%tyYpbmgЯ ĸq_#(k// 7=+Bߊ+uD?#xY|fnJJGo]p9U+r'KkS%D>+;C6t+{gS8S8X_H º/ŏD{\4`0G]~ Rh AFf2|"3XOeU촴wՐC4gu+7Qbm%(ʬz 6afu@&m*; N6Hx3TQݿItž*h cUrsGw5x] 1-4`E't֙YPAUP!4~(e#V CNAգ+}}EquP&h wY ڕ;ҮbBKŜ#>.F& l{:5* 7Vcg?D}sޣV \t\3J`yhC_A1AS ɗ T@8V`;}BC!p2@,/n+ ܔ۠5&AbN^#*V^!Ze w*iEOO>"t}anCOQe b]?MbuW3Qd+o2ye0N9h ԻESj sܕBfK+ f S #!ƝW\ʚA w /2W\2qtg+#ƿ@J[P >Mj]ၘWJ ;0跦X@TX $ ?dUȀC窂|KLf!DH)'% 8M5)܌;{(T1cAQE:BzSf6=%5ƪ=%!XJNOzZGS{gw@~CV*ܴRn;fY۔&0br 5R#rZQ?=Npra|M7OS<~N٦cm:Pi-,(|` 0b%06+|&FHzѰX*Tξjgb;f2P;Jfm=^ĪJ0BeO"&!ٱY4w"6K5((1pwH 8`WW{2Yi_ŌOKƍChʈI}r|`5c_M}q5nNRD˱ [i[2̺|%vE1t#D:3JOܼCM&Uj}-P}(0D]Ĉr~k$]Tg-r8@ :ԧ*䔦˙ӜF8J@ۋ &u)Oj4ҦM@f0hh6 cf0bTycNx4S XbCdcMd˓/dpjG#lM#Cv@ qq }]{ްm#^lΦwu z6G,hs[?/ 5M>$NPLU#_]ҡuA_H&n Ov 9Eit>bx40$qhN _$jArPFnmJQ_ivDsKimƁ`+捃} }A>3OoVn7AfE5$ir ?Gᭋ?| ]jgCQ.kOMP9!Or‹Y^0S] ;2ū;*+3C. }> (KzZ{~Jp13UI`\,USJ7.3TURѼNs9оly7DʼnV~%D*3NJW9SD*b|ꥢPbvzo4|endstream endobj 47 0 obj 3473 endobj 51 0 obj <> stream x]KsQݔv  ggɮ|`0@_?:v4O?>ͳOXQǣ Ns-_?dG+ˏ?>y;5X7*CB8\sg/[9(ۼ OYk6'Unَ0 ۜowlZ8qa􆗧h0y݉;+9c7*=/s?ZXxoBans4+8óPZO3J7[=05:yS~25(XiUPeX F2x _0=k;ٴQ>kQoU.,;j+1n N}/vq.±z[Ui&_$%`?o'P" { WYX㪅aNGDpGXU]A(H)I^MR_enѦMaR#$Ism%npӖ N0 rQN37Q򟔦Im/A,}Awe$?='oDMC#LfPZo O}ѴAUFm>Q3DW,ѕ.Ȳ4~wT>8I5wei5p+2"ͲQZIžؿ}X(?`)+Y|5d֙U jV3ܒ/'@dG;Ɛ@V@#[5id*zSZ#Իh[o(Ej8Fdd n+GsBbDɪ5M %RF^rxi/F6rjaȥe!oh<)&jgn1S>Xӷ*3ƣ>!?F),Ze([/?~t8YF/ۦb7zYMߢqun <)lN-7CTM^ϵMwBzluE(ѿ+r]~&~-`!`mAB44q aD j=X!"=U=t_ s _;Pj yI$\#uFLCMtPD %k htCCVk:X1 3@a`s9qy+<1uQEl~NނyT'P]yQ~ޔ߅ƁBmi*lr3-Z53Vm3t!n^|G*.B^RL$ʷEQߊɳ:!X-쾵sR''3C$7;k] EJ;zvv9~X'8Tګg_+u HM |v(J+ 8(''d[ @M,LѢ~&hgQ{ @OG'n–ڳґjrwnFMbii7EQ#Oz *]?fN$a~_z!|\<_L%(N{M Fm)Za ⓱JM[]WfcXBRߐWLKrkr[p*c^?/(_HŻT}W{f p:] Ot@z~i-KqmQn{Pc`s|REޥ}/e uAZO6*R rf90}JRI{jQ޺omӣ9i.HFl]H^x v5ya4p*?Rs(Vbgn3};<0.y|AN>`Ai:)}rV|ڙp89rW?8_ $Hͩ ~TM+ IOͣ|d1YPƹ*ӗ.Yt)~8iXʢ6|*d?Jd99t╼K˱+L̚=Ի-YH ~m;#Aa]*~ u'_,clunƮ*Lc>Pco0"T0 Գ:dz_Aب=.혚\L|Kƛǯ=B4B4ކ@N>UiF.#*GeѠl UR^/aW&>}OM,`wCF'roT6Rts_.>S'uVvTw ֯ dB}-`5yhOKͦ(A'D*悍xL_i4|G.HV_("C1$$(%4GWt4eMir lKVO'٨omr'WA*ѵ 3B-s+=0NMoD|߲ӱij2#gmn{s|}"E\S&4]|ñ dЗoz ߥ2Ԣq}7 kuśc"PN 훣)-4*DC5 YWIA$M|mI#yJLHK."*5r ۲x)]. PW7H+6*-1}Ԁ( u%}xnpV` >`T- CiK:rtbCfoB:ye\3n%| ?j}B@GQ,ڶI՛1k2F?j$) i{A!F9E.$#EkI"$$!T*62tu8WNB76Hy{a0SkE(#LhU+_MlXU\>.{ym}C2N&>Bؗ-ƅxne>Gb]{"՞N r\/y%!`"B }uDI&V*/iGzH|+ҟ}y 9zd8^<>X:JPL/9.}CyZR>bIvu{M.M<,T iSZBp [!F2,ĊJt;@y<ڟ..5BuG;z" Xwx1p3_@Yi}QZ%I.G93wc ZGߨPjPWk^oVU/VĞr4j()UkٕtɰJkj''zyTz~(MlD,~{NMendstream endobj 52 0 obj 4937 endobj 56 0 obj <> stream x]Io%7XBGIeOclx6dI[ gOLTU>4|4_& #⋍dɈ/n^__^'_BO?7'^P$ JO^z1})NQ'Л 6AQoaqs'0>51;(7z0̏ߗLJx^o iչBl}WZ/K֋zUZ9sDۻ{I%SN&r4Xa7,tDQWʐL AZ'q=~'GMwOU~AVqpj =pbҎ[0aq"`(l~#0(q|Sr9˙W؁![m»bt܈zC LG/(ɻ@(xeKvnv뎅 ? hb8O>]M$.5M<K댿>qv|H- 'n@KC?Y*VyfyU2rʡq^`O6I 7%|⸸eQLOƐ2խ_d2TrkK4ynxÏv{ }>BVy"E \CꁿP#5"zpVp{04e ;$9<` O3 ^wfhv8!B&OpY<%ݜv85JMN hSu7pt.v<_NFy<"s %=G(/*Z#ZJ\Z$( zSvˏ}4ʚ[#H 3 9j*2[)%sxUv[j9M}uȣJ*%FMU%51aOyzBZ`2 )l6Fq:(H8 SJ$P vu\*!%`;2d3q / YuX<̪8+tXBr_/> @ y&M|R P~Pzr@_Y ]Y ^+j[A`cM73XLn*b)e)uuP(D tJy<ύ .TTcwT6pvOmB) 8x8Aw,;\"!&T/Q5¹h`e`»Dy]Rf(rۀDbOZWqߤiH(d}TZ-E7|bRp[Ź*;%5igaAbc} ȍ0e=5"VSk #N| bӬ*U 'Ueޖ3Z.ӨrA J: ӢU 2t4!3&"]5;VQM#@%Zt@1~y~EԢ,-E^M%{"vU H_wH D"t* vē )iJ4vx@(Q*a,#4=CVP¡_yY}޲Ү{}@^7Zp48 gNߒT(gcJoP5FQbPpvX*r.(|a΀k=`CK*2Ï!c3,W}j^Y,,C" avb՛'zAQ$#¼ڐ)lnCh aM.H臂X*NDuAIGb*V%g-t4tN 1dE܏_*l$Rpp<(ӫFGK/j\^=E҄[J*Ub= XH輸~X] }6<a'q=/=kTw"mpFD'&I`*i? b=8b"8qF[LlG!bO!eA10ɢ eVU͢~ʎc@2ЅhͺhI Yʍijmx9"~bKEBCv^C",)7+Ch"xь%SFS QgqMeeB?4֐{5IY FHAcF:uˢp8V"~kijs裋I#$m.K׏ʛ߭M0<"4I`]~}d؆[wGx 14xdL:،x)@+|~U^ӈ.@ri0`Վ 'oEw0v ]w:[@,֢`FKx5X.DQw F6u4k3sEj  ہȔ^U0:<e-,uq H<,w#10;p8*JKHE:%C=}Xgu_B?\li@RZ뫤 -#@~ !a|vFG"eȮ#9E,"窠 !IqSdypa)%(6Jgd>0ipy1.Zw$]Ifh5~r԰rjźtV"Z<.kt =lA)׬ y$YD^kw {` Wvʻ%GBҳtbg+ɡT\頪@8sְj|WM%c-csDi1|6u[2B[7Pv|1;I-lpC4% z֤}?>J̻J3Ln8Okn]nBݶ* R;&_ݔ}T`K:w"rOlԎ%yN~?̑u' "WhgȂ;yЇ'95 >6S~qXC4duJNV9.H}Ubh\)Un*(GL;Ir! ǔ̎lXa&ZGFmv8VGcJ詌#k%3F.X V`snU}ZU)A2ױCPK"QəNIJ%1)[sA"dWcs\&@.c<4yGʹ\V'I bb=, b[G Ǖ= gĞiWt ݐX'K^|VK#'0ͩGir;QFc~5=3f8On- eq?>"E/.X=RI]+X aܡw[S_a|F& U075k9zMWMKr-j#rWL0QPf6wm=rHԛ5ed=Ky|líP{r {yn9it({G05[tz3Er|)|S)`5-e[dIHվoսv9TGBv\2] \ӔfKWjtRN#٨m1*%hMX%hgiΞ͗⩜o)G: dVjYD]#bD ZMtUtr*,A\R㱝BQ9IOLߪ5PAVVWFGYHx1a )|84!E쐮!Q 6l."wc=\ z-Z*-kC "R;B t~)p@rsx;p\1?X#ZtrXHd>1׵(;R)$Iݺ_Fk;{X˲jXlL8{DyP 3NQeDL*6uQMTǂLS3T#7yS2-X]-A]gevɪ 4Wmnjz'1l_z[[=VNTb.dթE.'cvl7ԫ#k . ϟlBuƯ^Z%pcG>\xI\ɟ~}~s`U9L9,S>ЪK# HrmP ˤh`+z'/e KtuҸɅ(\.#U;X X3w$ͺE:Xoj/YM/HL66c 2 q6/8l*ijHȌh&uS\oYQ}v7cmSR@.-rS2<5'81\:PRGXkIHֿmm՘;|׉ݦBFe;Ymy$"!"N SSz)[X_15ȯٻwz"8һV}ykmD-Cwߨfٌɜ_.;FiGfZQlGxhoQoKd_]/e`9,]L )/pTx'No&6vWuw^[kj0;ΚT>eR]A2])cZñϪsTR Ŧt}#{-׏bDhvei1Q%?My|W¬xquh=G19HIE D*ch=u*q:nHZ+Ɂr-#FDzP)KEHDjLr56poTIU_;r~51RRKILP) k7]=QfDMT]TMAYAegź-ZUq+3n|biorSVڌ@ۺf'.J7Rq:e!__c+?:Ubه\%c)dcœk{ǃ/p5joMUhxoF~䐟5?wkiH=)Tr M#EoP]aQ.EqaQWnVUo!˪3f \lXOvh[@;~hOGUR<)L/_73endstream endobj 57 0 obj 5805 endobj 61 0 obj <> stream x\[o\7 eОɶ E"AZ[o$YXlY;Cr<]IY:F8M}]g{D?wrC?!Xi᳽4R;?<{˕|~rO q>?,`a<-x!.GCN,N+1XZYr2v!iT +5]<[ 9O󂚧8ыUPJHtBU!]#KƦWK;38o x5?ul& ^T'j.#.U׳iqrtC~yc ZM7KG.Jn5*onjG{N;~cЦN ǩ(t`SYP׬ejk+l݋XPHO{~xCA^A" FJ}}*-%}>z [=?:bM`gD}A !{^-Q$"5Q/ <ZiGO?3 6\akB+1j. AvA6*Ʈ w}¼/ DXiD&Ux\X/L% }HD)5X@oaҦ.zDQяki1yQ Fc%`P^lQ_p 8n v kv; V{Mz:Lc3k!u4հUZZ"n SM@r]%lTwaM8#X S3ԡQb5.g]QΘh3A}s[ 's upK΂AJހ~, >\a誔Cuvx6RsuNS`aqW$V}HtHtu,[ mvCtEIHdPҎo Uί;_ 1x\mӤ j^P2p,PX̂o1XrUos==[[8@ .he[L ='RLv)#K 2R8RfQ}x#muΎv0 (vf HvКA{BؠK;FziOROQwvN(&͇%1ۙKSjO%"G0gi*E8Z:udւDmȟΘؐOĕc++$\״,mBG{#n|WE47娠52[dY2C4z*(1Y@^CKߡB;Oj.fʠ J6,pنa$;{<*^I5X(gefXNi bvg6C;fzv_Ycyl9Ѥ 1<^ut<8OZUwp%k$r ׄӂ G kz `UQRtIf1VlSV;5U&7Ur)]]^'7qjWzr)ST9[%2|{;t~9Hd~s3t|"\ o@,W>̰1swIt1ǎU /ӿB'!QYU?qTّ5]j_+ =F1b{zX*b˿Dy#9ss.G.:im&F,=wUټ^$}U6:e٧|Ll 1g2,,h8E8ȹu)pC_I"[m k$81q*<Iw_1Ŋ>7ZcŔϻ qUμLk-8h*b!fM}_u2iX9X&15jO/JZ5zsy|f |;kM|keDt?_lO)X<1Mmc߸U[ڙwP>c,S20[`˶9#/jBS.NJE9 ;+i?61KT ~ӭO,3<_q25Nh\_ri ܂]gpUS?شy55Gg\ʅ4wZV|j{+uĘƾNs} }\+tվaZeyۢ Ԛ[Z uՍp'"";44(cԨ?)Yz |ÛUi| ](6&dߚ=P/>)O-l;IL ,&;i/V85Gӻ-ՂTc;87Lendstream endobj 62 0 obj 3853 endobj 66 0 obj <> stream xnHn I=;0cd[(9)SeSK2of~AfWuu_ v?e?qw3¨{Hož07{?,;XatL%Qy<}jn &Zūy,TUza|\ Ъ`Vo9Zs Z@Jªz Y?P0r%t0*`aN;`dύFNv¹ %,tq1Ncezo+U>P{ Ҩ4u`:Ƨ!hS5Nyd26QǴ67Já[h߈G tc[?]=6I Wd 80C#-vvTuгiNI4Tޙu7&2=Ҹ֬Rr(o`=5v4n Fiװ? r6i|e10~<~?tVi;^ַ]n"~ȭֳ OsE )@\$yMʍ'~ 06\LߖWRAEA dǃHO,@A phx^@>ٖ2(Q8w.!QE(ռ3||Se la.ԄT,V4hNi7^Ygd('b~ƶ8`ܞV\)ZMܷb~E.y!V}<ݞ2=bs7$Bgbe/!#FQHLEW9`;ᔢnBS[ E "ɹAUq EK$ {sQS@²aӱ|Q% s, 5%f (o`Cqs}^n#R(BאDdA*K[[dRj%3De8(D8 ]9 C:l2iKIuXt2fCʭ7"|,v֍sYDJ2jou%o h[b 皈r\ zK^Jh.^ {"^+Ef m6mrzWl|EбHh%5='PfjT^݌ %]aYIccuOfn!f%bu?UjU`2@0Z1_>aEj*D0u[~dxdY6I߇B$K LjXt4ϦRL, +=dLgE"&_ <)b}}fW^h :V "L6z[OM|jXYlnMqFiG9 1~LGFH<{YbPBs=!@ץ=+R!q,Kʿ ~sQ{|d <#$qN°3S33b[)#fRrte ,&A`ߜW\ċ6JΠ60&'wK[k4|s8L*xڹrZZ]F hʀ(SN㶼GAY8P<+EWz;p' xC 5jySKm"Q a/'yb"aiFL9۲^?v×hOTAPgnZdJwؙ@&`8V &)Z~mU#RP' p$w*8z{{}R28ȳP67Dj&]8TƓB f#$0zR%|n:NtM/w>ÔaeA`F>͐s{zk wU)wP5>|Smio2"hڒ`lJ|)kef{x%sDZy `D]?glBPPWmnq&𚾰 6C5q3fqe_vxRK}4&6F$&*5=R쪋:CZ&Y]d}ר4 y[2Zl$TwW,Al/񛮮*4]ȞSQ5*"Am5DBD80hY"۳BWvQb._J,Zh!iech0_4W1g,^?y|4>ORvyHs*`~xFHibKB2܍wѹH H[;؞}&qy[܇P9ښ&AA7^ j%plPbhA7C1ڢ#@7% ֽ*) Cyjڄ6(nl ΪkurI.˚3ffJ;t|d~~Dl,v/G B-1m]6)a"]җ{L/endstream endobj 67 0 obj 4727 endobj 73 0 obj <> stream x]Yo7 e7>؀|p`@E@h"I,v_ꞞLɑCAھt y {|^g~'ӏ_'>=8D98zro):AA=J7vQX1Ĩ8'זB Ggk3Xd\_CIiW/ z-` -\7rpNGz(mJQV=[=YK5/Oq(1qLT׉ W8Z%5=zaZ] ruFM_,l+A Zeĩ ٰ8Vy=-%FK?ps 9..F8袃.0.+XqCr>tBl>3D4-7? =Gྗ{܆L/zDD}AS"k?ボz%7 J+8%3e--: QpʗDOS'#=!uP{)AY<G[p cjVr?me#ph=)ܱ{JFnY ZWH$mmh UYԟ'zven,p9fnu YYpʂ&]=-FE) ,9toAFG#f%+cɼoy2foL6îpޝ: q.tlIow dYo i/zB0[6YZuloK "N|m(}L7  0P0j6U# [MMtL^ȯ: (vJȼVMD0<2aF58N_saEB5J<)hDcD7i&LoF Ć۲uj'Y^A"w#@G#Gx^Zz}#yFB($ӣ!OZdݫL#k-t`?2;!:? Prˢ"FM.GW~=raP%z[?%z'!-<:!<߆p#{jJTr9[E|J Fh$ KRDˀxF@.Ђ_ cuGsL.0&%$FWӮ+5C0R- 7?m0"o:6:=/d M_I8ԯap2,wԠg^ +&Oi47>?z.Gt.Zzy6&qiZ1*u$i ՠad'FY|z)KfőG*3Rnz))#y8xs:QBTÈlTk`/t?><˒|3R#UOb$z5J]a g3"/$ =9 ɢEe4R깫;!KNH8.m>H,Eƕ#²3V&06K\?Ⱗ \j%<[ n1>+mT\;:`Q.1zsŏ>(K Tflf +HKZ*ٙ2*VB~so]FDJT[43hT,YU$dghuzaN®$SY׍{`@b xN: t5 TFs*KX8CB2jt51.TVgV_'Xlǭ@|>w6pWDhn؄5r0yqbHk\FlV0m9&guu LӍ`V0aALF`|l2Y'jܮ [4*uhLb#it\& ~qyiH\MFơ(-&n=ߘ'(T V0 `w95ܰ(! 30ïk4m!OV72}}'8m+pU#RR'|"M85jI URTWJ rzmθfk2IZͱC ;)q%"L.o.)/@VJ2E&6#4d*/eD_@R6z { v8i݊qPgrP[Kab9C$Ihn*޷0~o-h?< +`ssC@ "Ĥ戮Nb(΃ߖ00.Rd:p2H#)Ʊt(Ls̗a\I̩}7(RI͋e ve*0"צ&OL眏 S@AyZw~|gn7zEh)S3SϭlW|k;({)%ݪGzM,I&RBU,5KLK>BPh[-A墚)KC6%e!ϒ4UfԖy>,moMd-L߶b>["0N擲7"EZZ-([|^PjFjD͵հ.?#dyj~RՇ$]O4q"+%n~<,nj]}T&1KUʯPg9D=2~f9Ĕ!Ԕ?$ND)I[ KNm鴏ڣ,wBԧ]k,O8i=;Q(xjdf#?0]eً7{.M%Мw(fK zII IFq`5mx3j3 1 :&DQďt۴*]2X"\l+;:Rw=[fPoAV t2K=j0+69s*dŌYq\MV=-={U4_a?MY[oe;`yweZ^,] dC`Ѥ-ysàjsvÜRg*7hKBVZ S$W,&=0,ӭ -~]}]-,D_"B%T7x:bX9Jvr (w-OcLI *z66Fl|uˏuf2˼*Չ L+Z.y&̹XRܵq InI:eگ<5~B'FһPIrxZ)iw?Tj0<(l mvF.qI[wR \H|ص;$|"'hXA:w?*hzp @k; Ky%{5 HS8N_؞-3nމT_4TwO rrb%|*6N> _`n.D;lR,'[i7xP:ot"JEzBq4E+|6WUؗFBC˷9U/VHWw*ڈ8CS9W>MZ[J[ޏ8&bT]!Vqu?ŔݢO1)߽}xS]« --#S9tOtav;ox]U+Kt|͕5\{u *7u8oQ$0$: l2AF޿R-endstream endobj 74 0 obj 4513 endobj 78 0 obj <> stream x\[o_o-/I E?8zŖ˒bI _C9ًrwf3'o~jgg7{lvg( wf|f:91;xblԝLŒw(HIvV\,TUznc^;UЍ?_Xq=zS,8뤳>5+Zp1&,B;7Bv0c1+x̱etR ͔6P`S0̹&ɾpR)17@'KaPטc8Mʵv~փS` 陝Uke/ ]dLƆsy7gXr?kK{X #7}c2Z]֚[p*}2V__ c&?>>Y'UYb.òl1-¡oYٙ?ogS5a;̽;̽&Zn{{?=m1ysdRivk؜y)y&/.s4{ i"+}?74嶙K`;> ߭*[= Np6*&/J$P vϙq茕is86aSpjyr Z%nxbf.Ⲱr`,]pʣM(Bh q[a:Ǝc kw,;ڳ.t3Ѭu>e@![ʛlg=Ao.b4l0 t|Pq>T*Ii\): ԑN::FɄk9-# 襪1'ș1'(tK}'t%LTi1k'`+V@~4?]N i㰖JâƥM;sK*Q5MQXxon4!!II.ae93[i @vD9(X`G!):ۀ&қ֎Wz4ƍ&$,J=]j%,뻘{5ԿAu^imT{r+4኏j̎H>8P$m꺽%GNNw&M|m)+aoUqw[!V-YkFǵ'_$7!'Yy|~+3TMAr\I0 ${`r [!2%^#qZu0 bGn32U ;r,%gX0΀Dtq$$+^&V0if`H]Ε$"p"{əȗgb~?INFئd枠`RѸp[)"GT,𥼓%IO#;~PtT<'⩱ T  ,0ǾIxa't߯c W? uߩ+9h2".w,[hLےz/P6@?a64pG -Q$nQݑ?wY0 w())Ql Or_M[õfcǦCp*.4 e_7l0^1o13 Msg{m$?78S3dC:`9w7u l3q"`F8(|DM* ƃe,,0gBA?,>={OKw 'M?! s{=WB J'F0~P{K5\Qr.w1x w18h~g #4[~LrbR MX[y/ͷd Gne!MruZtgEJmPp-ɻrr@X4)|l;ddl.$5=Wh[g* /! QBJNlP &kɚ FM15Gy^v'E*lW$~ HK\}˔cBYZE`l2VӰRZ@*CmRH.z艤W A1 gH=&(np Jl&;}:bw[[g7Ӿ?VO3Դ!ݧ!ʳtWqTԚ+ &$ñq^w(w`fS-FG&4iNBX0\BojˎVwXb e*XQ!줸:yT<rlCIUԭ^Fr?nlMԤ$Q[J874tpu__M?3NٸǕ_q}=B/ZՏ3?ZGSK0w0uo^+WOTkVhJqYc1"psɁ /O>ir_SdvGD^E6@h&H-^kJ Q܎u)~({ (0/%]E˫ΒM +LD * !rAwH3P$>.m@+r HL}H]:4%oKɺ<$ ӕ|[\z_{T︟|R0l>ÍD-5Lc$~No΋=CiNl oadD)Tci1*ե1ӲCYxelcbAE66\lQ5u+S\n!@0F}.MH.ކS#)Ae O&AF`§4z%]9!@`DSaD`sfuu]w1cHއT #-6"Cw R VOpѵ@EW6Z CPOJ?jJ͗`UOy2H{8ruSN˯ 8JnS!($Q=F#G!l^?#cxM?qQ= @HS;`NYw@JY|CA`RqU?GFϐIh3xm`씪"m*j)Cmd2޹57EYNT@q֐!׎.C*^6O( _AYq>,2}Gj" >ZpL"6i/T##eIc9 aeL^Vm9!u !"D=\SӎOUf} "G:!4=hu3B!͈"׋(H.Qdi-ndrn+*Lۍ`wќCG#1xqvuE_61V6uNl܏`? pHendstream endobj 79 0 obj 3333 endobj 83 0 obj <> stream x][sq#RfǮ]NJ.DL\&мH~}=3={! Ebwv.=_o'$Nf/'ߞǓoN~?NV<~'NEMy/wF.Zdrwn:!r3)hpf-N̫N~2jKkՖ>Un~욅 ɅЙ\4/'~gWHOgj|͋ٿasBҭ^..~ +n޽.kK>qw;{w__[9YN_RK78俜,0k<0ݿLe-w{ۍK>qwK/Ω ,IarNCւ}ĻoӀ&}Rbb>7Q4cƜI2n {tYvws""A+Vwr&Dwqo=6*W.>;û>/] $Rp>dm+gd_guχ1(`<,[,"7gm+AM#f H=;K{̙غCx$%+oRpr/WUpxU ^JNM3]';~Bkw8x4DLZy;^8e|E?ۂ{xy#@KF%M秦!d&!:rj#0"?5WF<1ae(;wǼ;Oίzyՙɟ'yj-+eC-5Û'%G[*3eTgڬAҺ\!= ١Hsf`I)DV'$.ϾʚWȅ~vWU b_V=UK; Hww (\u Qy.w;H&7vkE[gtYD_(kWe!%ݰGޝ=JUNtK[ 3o_Js. K(%>JzSW+l}gNUJGv!vc-7ӣi, z|hj)SLlKxn/̣@{Te+y ]92wK ʹ+r|ř*"Z@O6&{md L1aO7e eZljZ eX6)Hv JTi)\g%w_ı]'G Fb9%̟MH'+8 (EkyQU,EMUZDt]2^#r)$j=؝F-Y29~oQIx_p(-J-iIl[$`Unvpnܮr_ 8{kz)Set WΙ;p>Va::VQ/5`9%v:rچ-QDZ |vB'5$[=;v4jIQa 뼖t,莤@((ÄV)vv@:uȆBÒDEMնsNQ~w@|]D2 I/2hz .@=/vv +E"L1E> g8ɷim4e5 =‹AxѺOО+gD߲UnYt_t5}l7vUnm/a`ai啴] fhfk1DPh0yƒNRC/Lp}#RMS{ۮwd/"L.m[m-޽63-CVmcP赗~ݱm0 *jn+tNVzrqI|K-߀_RmQriBʼnm%% ݖu9bނ{[aoc, ;쮍gJ:Se%.j/3LYLđ=m4w j43o.fFl F} xz*v;{Z t^oj[%wACuRk'fiI3+9c3: gC ?R5ŐOSgAզ8yxūƈd)W:PDy0EF=wX`{9b҃zW!m,W[i.6V>CպdTM&~Etg1ܴ/¹dQ-h*u=R0A*@{-obO=<%8k9NϕGaA/y|lvm=7+Z [}KɋP*o|]pGhAQZ8je)8~g 3t"7P>_RaVJ@Vڒ pӭͤ/KᎂS }|ϼkZ|_US(9]8UsHSfPGW16n FYLޙ\oK7V-,ІMC>&+2[5h@rO||' rd ` n97HNs5D]cҾCsbQ OX%8H.Nd5.^Hx{ EI씖ís TpE>G_r絏 &Pz;{/X cKέ~>HnM+Xk!-,r=rŠVr]ǟs~|"A % ᒸ,ōťTZ;,jaX(3s93DscTF){fi=A%2^4**ڤzɵPɘ ǔ1y4 sJ ʭz0WcZnv(嚬Kށm pV/{ e]Śԝ{ÍZLhh2jtA^皊 iwG.i' qD|";=r#&iu{gik՞D ZM9ˌt)plpN0E"]xLB6OըA%)S$mel׺4M%x_ӯ:3߀eoN6lR'3(lRRZE؍+;&$] \<67`cx:w+j-DZ;KV^0Lhw7[[unpgxlѹg3afLdF fW S3A,X,Q;ԇdUϬjOìI-gݼVa#N}/Y Y>Ҡ$?=,ajعma"ĈG?yR#A 0\qMHB獶ͦM~lMLr'y`U(N瑍HuaRrrBCJrQt I)mV/,G Il68ȗOb$qZ#AWa#CT/HzZh{+ymDyu`Z> HF(.c["[$CJΥXJb 1&ZPb|ϩb$+ӭf)7N Wʵfo 1,Q41+HT%)!x:9Zޙ1C)!aWH?ܔg;\siZB_],A%PNYas2ҒLiUxW^0XR ɝ:|*[N+#WU`03)}'pveJrTq'h`hB{164I}I3)o |wȎV)"p$Np\)]c-J($)S[5MA#Nh̆je#{ҦNAyos]TBdG)ר2~57:o"W7a売Ü*~oBSWmq(瑪 UА#Y^ mČ$@T*Ӗ*6rrxdCV ݲJZKZéx w9k4Uq b; N-i AkBN ާ.څ[\iYI~YU"񱇝5c. "zĐMi?/Iꈔ*20rJ9-ϒ+ēȚm^Ȋ<Łca~bT*پi*7>b ͒Gy/3w5xIϻ-븝H3HYTsaU!ovIˆYaR:RpF5A\{z=DmsZw'L=m[IN Y`f/$v›-E 6!RmjC{Q¥IG;E"`aͲˆ&0ʰ5ږưNaܗh*~ "PSK{G+N~/]\"9>6($gV>nIZ"#!+ }̛ r\ 'a䊆AW n~ش|%*&D1߅"T,oBWD)s,2gEXRJhzCF].a:;ڥ;Ti&$:(o,֏9+) |cw%ڢ) OJyԯ0M$`?}&s ^"s=hh_0RhI,9Hʫ5YsZx0U3pMKEjS\hR@Ē1 7tmXG'F"f66r:0,z {sA ujDri^rs:K$5Q *ʼ(E {,Xrw_ݻND ƛ:黇T i6+_n9W#RAmu+뛊5u\դwӋ*Vʇ ؋czNvs81s8Q'weoݘ&K5CyUaA {@=T{cZʧHHMXm}o#k_j.A+ɒ )rnj+%t!9o)#M y эY5<;6?###twu~uAV֎GPASY}uLߚt]VTg"L )$9ސ M2c(K20* CvgCr-O%nT:6ѵkn=T=ޚxb;!> stream x]KoVOM.fy $3;dK=ז[J)(sdE,ܡx$XbybG/st|t,(їPA#79͵<:}`%;2X1Y~twOOdݬMZKx|<*w34gM r2R\(Ή^w夸t:(UT(}&a*6zS.I)'L%9-`LD~\~fb$ kݟ5,a,,45Wz'_:CFkCNB|_Tu v@f&K M0 M!=F66o.f-t[C sV"ډIx$Ĥ"&XRZ$K7Gج)9F O}u7g ;~+k4g5 }Mc2G~16? ;>bkMʹ4(-nk;, k 7e =Ӊ8|W$, bs6#9gcrƮ&籧Ma~+/绠X1F?38>ПI$g3 >9΁^OWk uߗGd#{aCgoץ,#Nq g' [ۑۓEbFt +bsמF|w$TO^" ezHI1ake|N}s~1:DMUa"p>G">^~P_(8Gpe%CQեY 5ִIwuSMi$ڣ=ҶL^.İ?N'*oz'7dqCnL- Y^bz^ϛJ%-:bvY̱>a̔eZ-G͋n`mA]!'`Pr3\E_l IhMNEў _J^z kVeI8''؅2^O~`]U{1=`ru!N6.ۢ:]`)uêeٜlZ 2B [ZHepUNwB{@s~2`G(0CeqcZyTv Rk4~ZޅW7FP(tN8x&e7HMv=Mv.Zi3fTW ww TŢXĜqV6>#7:A xCTx73hY_hΪeNWIe-4~\yr:0ڶsEA~fy8,%[Ucff"ow*]P*l?'jk^(q]jlcF c\ppU~m(] ,as +ڲaǮ8$d+HN9u.9ҕ);iQ/&xT: /:([kH=äJGffᆫiG l&I:lp-( ;~ }p[rr6HF*': B\oˑa^P:Kg={1o'zcM'f˥vU⛘Vn=%d|hZ:W5 \ |8)CJ^ٖ;*^+9<"<h hҩ.ު)֨>Kgރ B_JҲ@il$!XfDHqg g(:пF7(J8RWXrUuVNW ^ REnM1P1^l1sD4,!C ُ̘nxhYqUfC4RsKrmwlp,$\V4* Kr5CIJhyju##p$aS[zn]=AB}I߾aqK*u < JD2[Kdx֬J1 `(.MU;oԷ哕p3XWaYm/RP Vih@&ġ}-ώ {.jI˘+|lh!M{OG;y7s٩O%E{oDNy $ZrUNM'Ʀ#P7TF XN왵 Lr_\>Q'+gA-͵5ݲMek]1zS·Z ;6 ҬwQ}h%C6.4zP:>H9ZC7藵Ю䈜mm%5Dm56u`:Yҏ huIDG n:Hp$JVh*# LpB6*J#(շhQ~/HKh_K)}"#Q*g.z@6T(v1/ۭ#S0]O$0T0'\)rnDR.Gģz`p M}$:nÁFE1څ?bQ 9p3By9}([Osəu5}?4;[.B/$zn12 8QjUF[\*PJ,ޟD VDY1U\?[k5-aeG#o|*S{˩BO%U]Lx4/;IZ=0NעFxiҬ[Ł7JՇwoi\oڜ ˍ] xˣxMƢϓ^RFr[rMz*Q0v |TWto˽sLhX{̞իtipmB1 SzƷތ=&L5W &{1L62ITk6G{]_Ǻk[]\tГqNx2tE-Q(Bw?YWoe>N%[@3?e0 lnR~jG,6o=jSLW1q9ȸ5j:tCtE^.&jQW5+?jƠ@ջ<ΉmHS.jjWN,qHC0C;j?pR:F0;菤9?mt)NR V]Ta>MFge%9ղSq ق42`q||Io/n HB5"2Pk' dHœ`[ პwrrM"e6ERC2Kvs-\q*y[sYu[sü|/#[x[sn w+?pk.4m z+K`b΋5߽A7?Pu;Ddfw(-D .D7 .DǗr˞=/O;&FnߢM0j4Ŧ$nfPߢZ9IJ5j4V(LsDžT/7F:MR^37}uuŤ\q)/Z4mVm-Q iEP= (T"jXXRza;*T:TbJ_ l{"kW`iÌ~TH{9.X* ft }(iid)*DC Ҽauea, :~GNoV2P( Ufn]Kb&d}_s(x{Sҗ-fNؠC‚X\|9fho`ȓW$g{_IQY{N})%oEBu#}HӝnD%]p-CW֏}Ʈj4}8`jS/߮[4f*Jh뀜mc'jx]*Ѳ+lRQ#-tpW@8 $xel}-)bίczv:ft::zNf[n0^;-c5Iږϗ_io7#$=pc=h@endstream endobj 89 0 obj 7027 endobj 93 0 obj <> stream x\Yo7_Ǚۼ]$@&YHQ?ز,R-]ţY,6ųXW.7Oۣ#x<_'7¨WGH~lűu9q|rqt÷;͜ڨ鼗N㥦e1`0V1- (g78כv|sqfrs if#pV[3/;Ʉwl^m`[ {^YͨiL]l\۱ߕւ]vJ0;7f5@񳧊7 Nu{ҜYRc]5mk2^d'u>pwr6 KK"UǸtSwYsR2vkOJ5A8)4L MIq+*--V+u #bj䕋~/aP-aUBXrf9G]qzQXXN&ą%Ѓ0Kl@QK;q6d Njt񎋞8f*9t/PΰTFƤbVBݦńL+h]!I{M;Z5ZnjnQg΄e{^QrPaS?5TAmmDnPaҭ7ሶ(=Mȉٻ آ=ƾM{d)YPw;y<,6 X*p[r 7A"ymAr-6GWl'Će$u+XXFȘ/< kox6}isN#9Q $~_f'N 3=ZDDtv R`;[F fQraDMNJOXyP$*X2kFd/zmbf_fR+lVEN1A:Xk!)DB3D_mAK#'YC\ ΌE ~@!@I֥F]9 :nF6 ڧV pռ+>uk Mp%)pXE6 Yy'^D3J8<:349][of8[/fz>H=$HD;$H +XE,Q9/Ae37t#`n"'v8Gcp/$xE[wS@ז1ۗ2-x4͐ qqpK@ăz4;-ܘ"pi*K`1TD{i`}A)<8e& qO4p?F=0ca1\1ۢj@[},4bqRbq{*/h[eMWrJ#a~>uwL2[cV8 $*O1jsٴy2K D#vɉRF9qxBq6p%\f,ͦd%H)>^qJ溝ń; S59{$ReR~Zj ߥ,mEEI_栃uNNUZ4r>eZMF,,Nfi C#>J@oQN,!a3ĶԨso vH%L9,E<)B1 C;_N޽bi~}f}LV= j\eAHzS(G#eW(\S3ȴ^9W\5IYĬ.+ iԅL܀,R6Cה0{ะXqym,5T}2/9h!8_U6|2?7}weaIž[Rw::NjZP]:D=x*}f溤*rOHQ.ڒF4%I2ze4j aA+&Ad%:Ť@(1\KQ;Ԭ)i9h9EsٿE?-~Ka-  J 6WfuQO5Vu=NVԇdJ5\־/+:>}^ejejO0ZBx4yD*,_/:~lHC5I^0 \M?ppL:g`PTbt*ODi=q&$lNMG#, y9$!QN8*ue dk}J{:蘿F$JԼQ+%Tj3SUUAW4ULkU[.V@=1 eʮ|,ޕ+h=g.BMfa ,0zEJW]օM'BAVoY3YżUqhW2O@<6rD?_9~mt_ܫEVZT(+ƍŰI sRIoOG8k7bc2 S7N/4LB%:"A V%5 Va@f<=r+Hmj\+!=+,T~  ncA@:c m &^.~VmPԏ2'=Blڻ:FNTHW1x'wDΠKAۨI .w饔LuOV\ow2yӹ]|߈Y`6xG]?yC. xDƅcCb|CF`s/`NWjC["y'IToGSEz8y|9BgٜY3*ߞh!NTgiEuibkM\fu4H}`*{#2W#Yygd[+xǰ :ţw~0 Zxe»/Ls$a͜S nAg9rP59p"M 0 D'xf]騰GSP;Bu US.eh@eI'TsTTu`3\;S+ȁudB(8EpD]|6,-;l,lN;{^F!ʅh".=w !2I"L1jф2{/cI@Q9R|x7+WtY9sZPUܬE"q:eK..l=(})勹61jKr}Ħ |'<%q4׸5nj{7j-޷\rKlvΝN(^K'٪T]iޗ[ PSx<~Ji;Q^쬝(гA89?:jstT"/5M&:9/?Kendstream endobj 94 0 obj 4178 endobj 98 0 obj <> stream x\KsboMqǃ7تUJ)'rD$@%%C ]z+* h| YۈYl}͎Ϸ->Of?Bef VZ==Z3Uld|g4R4j(wE#bc+lZ,ҍf.Շ-G1R3H_&BƵqDVq-A;??Zل;lb@Ac Gm맭%|X0[hy/;Qa112^ʧ!Km= ŮRkٴ~NZ5?^,uO3)SB ;S]`,` WH}RϐH=Es([ IX n=ukO`E)aeCxГ&b@vة?C1Rϐ H=E*J,TKu$ثje:,X#I>+5ʇH@H}sniD:q;? 'N:%*N3B.?u{vAm]Q}T=qJ>xMFUL:[-Rmi|bgIЍ(By4ĠPVx p)LmFJZiȶ1B:^=]Y qm!*ԁ)Fu`_`+ˣ( l#W|HFF]FX圔/:R 227[W钔O) \a)!u)YꚕG€9+s]@=\9@7G5N9zRY{}%0ʼn`h:0{脎.dWH%E"bWVO‚[m\|A6I# PfTcX[*NuzBnN Tjj2+Q\ :'>Ef/S{@`0\p?ɝRA FAX{ /2B="%|ک[Iۆi(44$|>:%p`J_Tk;:n-hbT?ʃ8; =^`qEr] $,PwALisTwaqc<^L8eNOdE=̉T { Cl0ecU}B=>j6bcJ4.~7M!5#y>;ZJ#`Iqx$FUo6y< IgJqZ,TW>_&-6)Zc}Ծ ؊6U;:)g( $~*ŷRw@u(%" q'zKM{w2\{ /bJhiQͤ}^Ǎzqp|fTC0 v9[XFx ;ol$bɫFQϵ){}2zNي;ee[a'b!آkwE/DM?ٺIG4DJ0xj:f╦sm>%6Q^q=}Se';~S?>տ .H#٣K%, wseRC N)aN\^`Fn@7!h#v~IuD4V2J25"gR?MlF?0+/&dDvяvRD*g3lCҒ͹{k6:Ct6HPIBlp՗$qerw)ovOq$^"Oqja!sDCF5o uMnU_dc]ŭ5ԼʄR%YU_M}?a 0r@f,wwE S`%J49i},K@d5[R*Q5"82f̂*" %ڴkgd =,JVśaЛ9 <9 (87c }'ϐMɈc1x[Nϑ}lQxGb oXXx5 C f>If& ,11j^E&d8g'n]l\Q6dOkʍT؅jNK?F)ߣ-廤9VQR=5j *bw4HOpa'״aSzO1_(7%_p:PrE!\$ݫލZ.Pwc"k/CWgz;1VaX4&M:P7lǔT#JɖRWHӖhSrG`֗Pn<۰a| h`/ਞѥnTjFNH?w5o-|z!>V2;75P r6cwf| ] VOeDYg-% v19lI(X %Ցsȷ4 9$~KLSI(MA\φ} bNB4 + a"j{NԃR ؈}Tj}9FHY=!+֞Ijn0|{Lz:vL\&/ sj90>d7u@bÞ_NJ,+M~Ajz<m{ͨ׌wHnMH%xt/Uw=5SF/S# Dˆ1 Ć%ٌPNa ԞOЄNU+~b24?A*!ď:)kOEF_n%[qdڌf oߟD^"62b?./E<D?M@V4U$Wh@ V7dh;SJ-ӈdRP$>JiU3e)]GFM_7)(?ߪ"@yzMxZM .D6YQN>#\* %=pO/> stream x\[o_!%>Di.AWۀ-;3r9ET1cjיop;q<_}?{w4?;H?O;ux`'WGMqj/+ޘ蕍?}_'q.N.z0Ҋznu¬̍7PF ֪Voܠ]fW߭7jkZ 9uy]0:OXa5\}NHz77Y#QKz0cgѷka۶\uv%XxE̵ˈiC͍b_ c# f:!~$>:Qo7ۃpEw[=&&\tJo$_WbZ6?Ӱ+] k]Xa#ҫ0'~pFŽ$])+Ӯz!ɟ~Y J|DGyyЃ7b:5TtT&hȽ꛵10T \`>YbOk7"}e~dP7{漖ZGgf4;LoMg ʛ uF8($ʎ4ЙH8Fw.J΍?Q<O:⚋)8F+;y2uB8l"xҪY (׊uS1Jlw9v`c"?kGT%HhTx;KBP%d0I9:-i< 7B|֙> Utkn>J0R -YѦ$ 51,О2Sz;L 5i+RLyhd]Ql|Q I}xN6_ĭ;΂QqA#Mdux.8BzaUy-le;(PT.P4I1O#L;Fɖ(cU|[1D'G+畚ex-e(I;&8)deC/cR ̈́lq{*?=g/tCjz]l|V)iDͲM?2Fra&aG 2x)~佌L xy;ds): L"v1 7=t;3E "b I}H?:3&0 q([N^xGub1jwn ptfkI+H)K*&*zac"Xb ]M~u&E<,!BeSԆV^b&71% _}jvg~Ѧ,B5db8أOkG' ^6>J@ 4Q)VÅAS\D9.NJP#sI nJ$EZ[0Z6(M` $ExF{^P4_!CJ0'*D[AJH6E҃ƴq` 2NNR!+thVJaθH\ ZQ M x{źm 6Kĥk _U@UX;HplZ8ŴpzBvt2TZu0^K XcWkt  ;3x(&~D @Yq',P@IP$MV OXH|%&qB^:l/)\S|vOm?gќvl͡ӑNUߒ% =~|5}hrR{8);S꜁o(MuN B IݖK/ח$7>sb"W}7zc {[~~(?I).)!%+2ybn8-1Ε-9@"z7m賲m08"}o8[3ŀWрFK?O;m-8\?u]|s]:W({oäٓB?l]S[7N!t Ơwk>Y"L~!싐߃W[/jKendstream endobj 104 0 obj 4437 endobj 108 0 obj <> stream xXn7+ x1Nb$H[x@yf794 .UZ+c#j$7CsD6'OTlyx1ND\sߨ!7lszs}mRZgN R.b}?~6Jj/ b4 .bSo?yg0'h 8sX] 6[M}TΡml_`&2ڤ6t8$dژ?t} ) %}$q6:}K *Z޳MUÃ?&-vuL wVؘ?~z˴ui 4~P{\AL3W{C7 TP0 SQV1wX\ﵢj9[gYb}endstream endobj 109 0 obj 1801 endobj 113 0 obj <> stream xioG8[dkH~tu+h$NtY#} Z>R .w_7f^5ӽ7{;:_|{BڴJ-^uBJU7f9_}_=\65Jr[],WnNu5eɒVV` v mm[JJh^n5cX`nyaWX+װm8n`~mt' $M-ZI`;[ȝmke[3T?V+$|\F-[[`ΰElŃۈYHV,W[1 FŰh4jo[ {nYSWWVt k֨p|7Ez'`T6?ʰTu0ֹKG^ha<-{pjVS4 aL |d/d0F@?ЁlD-up_McK2xe I 5V7sLn'-  '|u,Qa t*X#qr(]Or4?d4ܝvp,gI!9rb]C۳p>i'O9bRՀ$dc(]sМoІ~A/RN:1͡-/|x%?W(եNy$932VH4,dSJ 4 9mWS]Bi- b];O42Ԥ9bHv( !vN) eaΤ讻λ`l %^S8c1)a՚E2|5`9"?GV1&/"q^*XE~,d,C]veFV!݆01u0 J9+yVegEhُ隆qC# f;eQf40FI1=sc[0auXRΒ̥V, dϐ$]D SH"@s}Q$¶ gݹ֭(g鴫yҀ_t6'cX_yb&qnyaZ{_oP+c P/d5(e8,'aP F꭮1w6g ]dc[nS!2''c+DGbŞ0u^ %g`>e`3&TL4Kq]xÄUQȎ.Y$\BI IJ$iאCVOC961ώޯ+8~ p{ql)h b ș@ cb&8v^qwET7 l|n8OCQQz͛O&E]䚥]e@я<ƌfHf74$IB'4/{SA.Z$EEzceJ ;ie#W=eHzZTY[d}.DiZ8Ufd'>'sYY,]o7e<T8EhkGgX/_^Xq`9*D8{)NGv`JZlVIM,W|A_m.0q`piX[UxBl>[7{ +HfZ Ӽ&JDYS<[|PA>r"B@s[ Z:2X&>>1Ͼ 0ߠ? lt뺇7z}Dzz)ܳ<Ξ! /-銽CywxG W7mjQc~AЈ# zd|ed(qU6NⅆR>_H(+!qG}3[gDğ^?&OD?mSW|X Bg[" 9ZiX6&)48NhxOj ⋱TVCSwEֈv,'A#R>ֽ\|n/&n~:23(CQ2MF*+d5#31с51wQ`wW.9$)T&)t&"R_h|]hul yۖ"燶E;;m4ILAYXfǜEb+@[;R cE>Cjp\_='|3ep™ F򐪱8 l,lҊF93WG/K퍌`?ϱF;rL!y}BJ}rbHy @&%@Qi((OK[1U3n}R?kN o#ln x916"lX endstream endobj 114 0 obj 3818 endobj 118 0 obj <> stream xYKs7 W(u*v&MI'[G39dzmĖKjԒRv4L`8W_f݉_nFrq9lz7¨bc+Ix~3z?y=)&7~4sjr{9YN`JUj0qfO`>G+mP9{[˽pTmVU|6ïzr.pQ\ZRk'(ݡB_((]M-u< [znÀU|\TK[pQcTc\Mxk1hMDE?8Y's591$Y2 C8˙f0>Q-JmGۀ(|)6(y{J3i:i7&/YB Dp+,rpSB /ñ0 h%.ŌZLɟYŌFj%ւXyyeL8Њ)w?q#K<6$ARu>6:;?>w3+XvH?C9PŴ&J৔ׇX _H%١C';Ǚs#/QIGsLX_hJ%QRVLJ$m!t6.%춘k\7ߣ`t]LPz_JXQ9юZJ!9شK2OPdҷ̾W+a)./qyˡ/^̣,U/J>4`͸IlDRHxtD)-dQa&,R4CS1wNԷawo{f-5LfTU6Q=NH~i[\CA< KQ2hMh@Xf .ѻ"\ ܶqoM橰dպS)I1Hu^Z,U8 a)N:caTBLZoD9qa8A>\-">2v/* :kFG>B(=ýK!jxpPt'j͢uIL%ѯLIy~D{J䩵 γD'A태-D}9B+-UV4וe|Mu󊹧| M-endstream endobj 119 0 obj 1631 endobj 4 0 obj <> /Contents 5 0 R >> endobj 16 0 obj <> /Contents 17 0 R >> endobj 23 0 obj <> /Contents 24 0 R >> endobj 32 0 obj <> /Contents 33 0 R >> endobj 45 0 obj <> /Contents 46 0 R >> endobj 50 0 obj <> /Contents 51 0 R >> endobj 55 0 obj <> /Contents 56 0 R >> endobj 60 0 obj <> /Contents 61 0 R >> endobj 65 0 obj <> /Contents 66 0 R >> endobj 72 0 obj <> /Contents 73 0 R >> endobj 77 0 obj <> /Contents 78 0 R >> endobj 82 0 obj <> /Contents 83 0 R >> endobj 87 0 obj <> /Contents 88 0 R >> endobj 92 0 obj <> /Contents 93 0 R >> endobj 97 0 obj <> /Contents 98 0 R >> endobj 102 0 obj <> /Contents 103 0 R >> endobj 107 0 obj <> /Contents 108 0 R >> endobj 112 0 obj <> /Contents 113 0 R >> endobj 117 0 obj <> /Contents 118 0 R >> endobj 3 0 obj << /Type /Pages /Kids [ 4 0 R 16 0 R 23 0 R 32 0 R 45 0 R 50 0 R 55 0 R 60 0 R 65 0 R 72 0 R 77 0 R 82 0 R 87 0 R 92 0 R 97 0 R 102 0 R 107 0 R 112 0 R 117 0 R ] /Count 19 >> endobj 1 0 obj <> endobj 7 0 obj <>endobj 14 0 obj <> endobj 15 0 obj <> endobj 21 0 obj <> endobj 22 0 obj <> endobj 30 0 obj <> endobj 31 0 obj <> endobj 43 0 obj <> endobj 44 0 obj <> endobj 48 0 obj <> endobj 49 0 obj <> endobj 53 0 obj <> endobj 54 0 obj <> endobj 58 0 obj <> endobj 59 0 obj <> endobj 63 0 obj <> endobj 64 0 obj <> endobj 70 0 obj <> endobj 71 0 obj <> endobj 75 0 obj <> endobj 76 0 obj <> endobj 80 0 obj <> endobj 81 0 obj <> endobj 85 0 obj <> endobj 86 0 obj <> endobj 90 0 obj <> endobj 91 0 obj <> endobj 95 0 obj <> endobj 96 0 obj <> endobj 100 0 obj <> endobj 101 0 obj <> endobj 105 0 obj <> endobj 106 0 obj <> endobj 110 0 obj <> endobj 111 0 obj <> endobj 115 0 obj <> endobj 116 0 obj <> endobj 120 0 obj <> endobj 121 0 obj <> endobj 19 0 obj <> endobj 133 0 obj <> endobj 12 0 obj <> endobj 134 0 obj <> endobj 10 0 obj <> endobj 135 0 obj <> endobj 8 0 obj <> endobj 136 0 obj <> endobj 68 0 obj <> endobj 137 0 obj <>stream x]OA0j ~SmSK x0Lvݵ&'_UeeEȸ<(> endobj 138 0 obj <> endobj 39 0 obj <> endobj 139 0 obj <> endobj 37 0 obj <> endobj 35 0 obj <> endobj 140 0 obj <> endobj 28 0 obj <> endobj 141 0 obj <> endobj 26 0 obj <> endobj 20 0 obj <> endobj 122 0 obj <>stream xVyXSg?!s\ƒI`q)Rk˸ (=l}I &D $jXD@@*vP[tF;sk.}|~>ss=}﷼#|}'eA>}J{ džKfvDb󁿯+4:pf3>?c^4Ư^vv)۬Uk,HZM=BP2Z^2:I4X"CJ%m(iVMMGYce:ޫ+ r52iZn4(Dпdh)͘r-H%W:ڤ4 i-CRE-FZk\yh&8S #7kMW-hq6 <;?be#S -cIq]dεh JԬ)*?ɩ&.{[[0J*bX3+5И\z/ͱH_Mifƒ;C*˖+*F77m!~bK 80qXCۈ1bM"v{}D !$~N`BO_BGo8}??;-( fc8K+Q0-,h^d…*`F<0j2Nxɛ  -.@ 6 yvTa;n1d[mive  z6A:((Ԕ)3|DΖA[X* `' V( (԰R:F Bc$O)IUSIچzJnr-;g:$AH*Ֆ◭nRQU.S||z$cJ0x.=/&F"1 q̼#{(5EymE0 p+}F4^悶eg %Awx7q z, ?|M97"a+|/4ϺSXjD?+e^v灯Íu>f"$ _Bъg+a=a׾D"INt5"2f~ W'pI$mp3PZp]pc6 FrȊV0:Ș'2Ď@A߽P cՖ:pIe;v@M {0ດ7߅wa݁96gkD`_}^5CL׃A&zlA_VBXcpHr÷Pej.FbIg;ODžbd6_qAw`"+%aɘjk3rk8Qjjwk@"0ILPv%ؐ^^As>| t$ܚFKu:6޷yPw)$Чؙ4$ClDAcۙzPJ;.@W _Dh^sӖ.nlnIc}P‡ހ[͂'Q 3,7=xCbsc27?m%ڷ$ Ŋ݁wpS|^ nqW߭ vɕa ΢$/m ]$6Yc 2PQs_ xW}[@3#|@Bv~T16 AMY0A5m/(za&??ՖĩF;yl6ZWyS1`48{;L.n-?΄ZOe%ܨ!]eg++^wȠ?!Xu[݁,(FKR VGTXXVVv/wHYL(<4=[lu e4 0HhXʜBLbNܹy9~]x=*^ǥ!J)22 ._]n6vs|͜x#ގ:qC\PIv:z5݅&Hz}9B>k'@vs4 e~ g=YFWb0? >vBEuJRQSQVeJS& Mr} W˂]nhVafcn- O) }}{Rd;#^[u=07QJ$K8\[sHw n`09,kA%Æ-|)BQ'z,7Y?&/]_ɏSgewޣ`yc'/$9pW7UhEDUUZst5YʣTGx˻~}K fM:M6~2 [7[KˊK R(tLoI]LI)Nn'P7iv}\ ՗A@`&kH6/A 7^mNu%LkX{&;JﶽTlZz?&#ؒYu}P2zz x:C`zE?{D$W۵Ԥ7\#m].p-g.kUFDdg_|mku̽ Ƈ 2qej?v^ꪂn2ċw6y~ ףUԞB(\slJ).JDEnRSc= .ad*Jh'zRGFz{F})37u/?@5׽*'S[6)"_5EGǟ<"Tx~id}U]UUegPDɬ9)]&7T洀G;Mri` xpY3Ta$ Ku__>CCD$Tk EEu S]jW7e$gŝI;I~@뇟,~qXxT81w:'\Fg t0~'Nݹ}mٽ~+J3Wކ|)~sX\c0=q]\g/=6By=%?HBKAG]Q]'VAfXfx %7OiLklnw5Y.ۚwt2)[ X.uznF!m*\X lKpR L'+uxgC/ߏ 2 endstream endobj 13 0 obj <> endobj 123 0 obj <>stream x%MKQF)ƾ6M~ #0 Ct8\oЌAɄhUHhz--RZ%PJ\4 LpX|2\,b(ڭ]o;ƹ.YX*d[dX1Vc9MhsC6Rw uՌ^lYA4s)ȮIvY'c[UԸpSI$ GRϏ?򆟞t!c4`KPF :ЅpxB(1 [8<4@B xxyl7߇o~x\dVY9VgWU$H endstream endobj 11 0 obj <> endobj 124 0 obj <>stream xyiXSVmKJDNkk[b3NAE0C $aZ@0(8Vv@;O֦}\ok=,XbqwELJ%K}ī"ǯn,zz6{3JcәL%T6T=Q+ώ/{䱚XìW{u޼ERtd}ɪU{ё /_RDqbI(AW$rE#Dv{nߵo%BܽݽE Rѫ$Gˢ ҅R(<$$|w()>Z*ſGK#Bd2{tBx\ax1p#f"''7 OL# 14 , p"DV”Szj6t;|soқ'<=OqyB|LיGf5U4lbٗS+ G ̟>05o[n}_< ۗ/C/Pg,='Ԉyc#RiG/]0),x{;rɜJ}6]^D)0UR>*/i+PKQ<] @~h# 3q6ɥy2p$|\Dcc '=Nt1iSA:P嫊*U#n杢M [Vt _RTm^qo$3%|tdJx-&EᨡJe\n3%l^Iì/">Dq_V {\)oSp S| _l5ߐ!»)ooJOɇ絜5Q~~t}zdiRP¡=_md*Z))vTV6)ș>񋳊HAOɬҟȚ x`V.MIH/|S-,ߙ 'r}cI:37Q;c{{WDd7$.Tr2Jsvir{fpUp^;_r< w~5zؐbU<]#J+' `֑G< mK#92xGԭZcM{ aIvG32+'"( '٥.$?6Ճ*ҩ5Ja?6s!L45 FUd'8\9ydU͓YڈtL$-DIh4b1ȭJ8GdmxcQITP.5YUgljOqDc$OxS/QvBcz!c0_o&ɵrp %P*{W__u fpë /rqӍ99o<]!ŭ,NN.Ht{'`o[`hLgjCbq >VsJC GUʳkqMU33qi.!"WA#i\KZ}}6ȡݿe_yX**3ҋd^'cwI6s!ȥƫ,F+$ZF:'sLr:AZ|v ~LosѡWן^N|!$8_f-VIzjf`1-!űtSQ/;Iq&cLMqB9+[;.Д$)ɀj|[{I8% G`#x a7JK1նɻR4וz&vr}Ɗ h? 'V2ߨT\[ohq^瀮tXAKInUҒ@V$qx@r+}S *s} ʳA nR|ʆTdOY?<NE}y|cHQd(Elu-E|=ŶybZjf2cYn)`W`y%,|P]VQڦ"k5 }Z_.Zր{s+(0Ta k@~S?3Jֹ z׻$<'3Uu]ހZ!KHv昅%9L54&"J!Qr:PC'/ }U)naHOJ@E;!a#6d|, @KvdY_ڌVPt{2 di'0B&w տpgiO (:e樝ܗ,a+W/W_-,ࠗXyxƉqC9jolhRْm15j2LZ&Up(:[-8wThZ"Z7dU%)Z6Cx>9r/0噀̘lX<6L e䅪$~9,-f@ '*ȸ1CGp |>D zvw| ;V;X[{cxk${p#O)RTʨ~ @mlu x\//_͑[G{ӝ1(aK@ԪՊSQjF$,2gZ'<&2+uJA9[|S`E$PJ楌W'&r@1*iKr,sZm|>s3.~.obx(X\{GWF C[zB>W%h>OMme UX0NǛĸ>n q}L׭[ FI8|:ܺsjd?C:G:0&`ˆΡu<,vkay*ϴ;%`'>#'xsAo?5Sf\+ 5.=zJ|sc{E ^.뛓T`B?L VXɯoĀ݃y:/Nl]Г?]IBg܃|,,v,h[|zpßY.׵]p+tPޚ-ғI2YTA?8VE0QӷG3z9&֏8zQ{kOu>JPXT+aNɁDab!2g5*Ct6괛1jÝVW nS N>V5}83N|1D<x ٕ9 8mu =M 0**9JLYbЯ3>7UL7)Nfs#tkށLU,q.s0LĦchW^Z2ςbWER {5ލ )#&A;CJ?s$DPB}aठ K6#^^R sN>g[s@7賵67:qМQnqb&iPk";i5[ ᗼMí AUTpM:;7ǗnY7.%pKe/Gn lkZ쵘5 ?~;T#3I4|b!D,GL{ 8H_d20;>Z:P,rbm)kolk`Pӝ,h` }T]ϔY .B,!H̓3\LyM}C SB#QyٌX?eti\=zkʟ&b KY5&'& 6u[\mB9 \:$2X\#kjin&+AhPX}q%p2e: |)n{yDDq!IS}`/t!:V/*)-ƥ^g@ӂk8\/{nY v#Igs2r.|a4t \:2 Ɩ'Vx) :Ɲ&b/^/#[&x+0l-Q>MuYIT^mPЛՊZuIq erl4r|A!`|?7q,hMBQԢ)T:O\Z:NdڡϷl6jh)$ؗo56257<x'zM JO7irLqB'xK|[Ayb:fbeHWh6J{y"maO?yq;G?Cle1cl;A4,w6zp"{ *Z ۻO)oQ';4k|'s*ɪ1H3Jh̓4-̕Zin9sf#0gbƁIhcX،qnfd=^N3w %iBTئ%HJpd`{0UI<(>#~Il#4UH k$+Pn BXE&yh?7q̓?'2p$ Ŕg~]^O6A)fr,WN4jʜ)7ǯd6Ew Bz5\>y-MOS, m,+,-(ȫ2W`Wb1UP&64 8FNNw[,C6-yMAG|z~epw_ۗ!V*=3\v Pc|V9pR!ڂ8k̮X_|~޸/1{ .΃Kɽ>` Ts] Jif$J5 GGFp"hBkj,Nq\;Z}z;. QF %ݶLG#!^Ȥ$a|XU:([{x/{B8&?܅qжwxȁF #,8nN(7|nV3RpDBz,As@6? Ϩ@2N 5o5JsM VfbZ$:*=vqs!<2SV{~b{^9z3Ju<`T[#.2 yb)2b{#$_D; :iuBuQ_ @o 1G B6 ΢CxIq Iͭ ͭ B drs nwcŸHpb7*όa z{1=O^nH>[VmqlRӥwXKC; v٣c5ڴi{5F5V/j<$^0%OI4V)_NZmQH,V}wwǧ(NnlilՊ0=c,r]2J]Ew8`N㛍!r'o 4;3~_.Y;杢3! Ynh  VMKpXmlZnObP0>LaZMm3Z8/pZ+jpvZ?"(qjMfv/`LۃFX0)!-:g{1U;x#)*!qV7 #=x~ TWI G}CNHG 0X9zRN`b/4C;BWQG pzw@?OOj4¸ endstream endobj 9 0 obj <> endobj 125 0 obj <>stream xWyXW353n(T+ (~ "khHV=h[E% @M\@ĺjۯVmm-b߉'gk3gΜ߻ (L#JgIMצK{^bNg_/7/E쑓Á.\[=lldGd? ^a's s5YFaZ(y# LAj>'[3z 1j`R Z<=zNDT04,j֩sSBt^V&LӤu!MK5z[4)!G! 9ҋB:7[c01)::]0.M.'zQՓ *Zo0r59FXa4f% y-3t}Zw FNZHr).*'Wcg2>\Ugk+'딜m[[AEU a5)+DQ5&Pj3E/L)H-L\ΈʎUh1c}ytj M fP)*BRC,ʋfSAj2OSTBCRa(*P>jIRQBTO\^՛rVSTwʙKI9PȆ( $}maW`Wk}}¡77fsi{cN֗d]uܥG&ǫk|ׯNzݎ(T.E}w?P3 ;M0$ i<%g09d{ 8s=T I: ^ʆ+bg"{Wj_:44$M7xe{P̀=ϮWFyF{}؁%,/8Y9ir;KrB3nl{XKD7tKYV35re'nߺa] WE(&%;U|%N1u[2eL$n?߳i6t\K7vz`Fġ~cC}6my>_^cE0>؊(pJnsIjɶ}pf>Ž ~PVSYS4jF7w3n%+Jө#"\n0`]@$R+I$A SW-L]0`DbԽg<[DwUmQL!&2@^$s{x9QWM 0 xpw;ېCžM[˗_a%b3Vmk}5&ƒ$]*cԹ)aӳ+,Xkko:pF5U d2dW8h{u&tBXE YxE5̰Tф! #Cb H 'aL[jK߃tg/YdYvc11;RAf=;r0p%Y&"/XޗS1dA?u7,]pOln\Zb}5M6lKA0q}G` }40?@c twc]| y:謓RJsϡ;ʻyh8QBf& %rpħS!CDcFp蓁?La>g&bvڴ/;\QV.9e|ۦV" hE+^㠗Mx\/s6Η㞖{MGc)#1I~ 66b vBOb!Vt,&}AUqVԆN;bG\&$K [¿NRZzY0V\CE֢ x +*Aͨeeՙ}.Z;ñOUU̢( ߱2ڽϰpLTȤ/]I :ѝϓglo%, KT =7i$?e]K8b#TM$=)w?[pC)p p߱/r *kR`Fxڗ1-)Ao{q8H>%~nȬ'VHVge]Z-P99S܍ACyviwN9-cM ,dƉ/8А`Z`ygexQ8q $B?s?0 i ZVVdJrp,%9?[$K rvV&TSR(ffgn˻-G{!c|hu ajz:9xB*1m ŊI wjlB~prTF&͍Ȭ e'K`Oգ̖oZOh~qi*}ֲ4]MwVT@JMtpjܦ >\0o #TQ$Fn<`9@$V' Ddn#.5,ݙif:~Q7{_(MŅuRڈ{<A?KRz?k6Cih|C l)敠T8>583h49=98%tQŠw"v?o+f/JL7AåWkϣp\pjgO95kU.9OCPıG.äY }w3"qMȒ _Ο+tm[QYnaW5*ef;vOִܿ׫?aw.שcg&GE&}z XruaIs’nܬol7` !MXxPǨfՕݿ!`PǢ KJx(v?l7_Zx~QkԮS}/7ujڙk^I1@! vwzs+!(\Jϓ;<6vL:WRdt)h؂CyǻGfֆ{JE.Ns.zhv8-ܑ-$zJlc@EǗ^}=E> endobj 126 0 obj <>stream xcd`ab`ddd v541U~H3a!S#k7s7ˊB߃``fd/r/,L(QHT04Q020TpM-LNSM,HM,rr3SK*4l2JJ s4u3K2RSRSJsS nӃP9E Q L,kt^:Ɠ~c⧬ݽ}sk+ıewwwtc6iI{O~b vsaWS]wgwdr?_{ĴI5rUڿ9~+)-zͪéGt -,lhKpg+q웹6sq\7yɚq endstream endobj 42 0 obj <> endobj 127 0 obj <>stream xcd`ab`ddd v5T~H3a!msɏ+<<,/(={ #c^qEs~AeQfzFFcnjQfrbobIFjnb ZRaQRR`_^^[_nPYZZTWvt-I-*)LK2@V0000z20v1012%`S;O =ߋEgM2{V5|]nRK7GQwI%K&M(WҩgNξk|εxxm endstream endobj 40 0 obj <> endobj 128 0 obj <>stream xcd`ab`dddw441U~H3a!;{Wnn}=\19(3=DA#YS\GR17(391O7$#57QOL-Tа())///K-/JQ(,PJ-N-*KMQp+QKMUMB9)槤1000Z302012xw_{.d#zhSJVyQ~5gO*U៕%2}´7s.璉<< ; n endstream endobj 38 0 obj <> endobj 129 0 obj <>stream xE=laR<А.&441~b41VbNzpx\=F?I*WVCӘթqp."˓<ZqDr2׎8<ӻRwȇx9.WXLI4x<6JG"qz!+)IQMKYQC:%2Z3iU͟4-,f aY972JRARKSU1+p?r6?J MӒ#c '_%լ̓L3ep?ϞA E88A,Xꕅe6|=pY18\ '=[nzN~]GZ`U }d'Ig=%9*+o89- a:vpLoFA{ZruXg\MkA3=hjܳm3z5^;֘! _ž! տV endstream endobj 36 0 obj <> endobj 130 0 obj <>stream xxy|SU5fGATFE@e.C̝64M M34I3'+s)itni @,EdIFO=Y{ ~?d>l`$g( ]5m0G\./M3gF&Qw41<{jژƧ=Ay]#Ro~yʔ j('W!9w\AZb\#LoiP.  BAH,,ZeeI,Jt Y!e V2eAvL @%R $rA@.fřBi|a@*r^ rd0K($beVx}vD! z>^[%LH/㎊tE\/ / 2h{M. a"~NP%Kj|.J*=R.uTL. g:]*|B.gO\tWXJ/8]&Y௲ 7H,ʖʗ)S./RgRgff'6ޘ"9s/z>ɏJ}1oGO/~"972Ɩ%Lz1Iqy}>/_4zG`F7=6Ơ?r!B:8옏xL3O FSf?hpAB)+& y@XbZi%Е8̃ +Jha{o>MbAG9ElP(@ijf0WuqƬ֢&?'XdM&wUZ X]Vm {5_ |z nڅ2_S%UMu^mnc|x Jbd Xp&$>#{ ]zJՠ\deOdo@>*ײ"fPtvE^UX7+/s.>{|@Ӹ XNWF+*4|¯<h\SZxUDB}9h#ڎZ l~,뵷kъ>2jJt:@ "`P*x#0 >qޣk.m;"w4l7w0Q]Λ_ܞ8NyAfuV~V-y&bFNZZ&a͹L*-8jg*^ys>Xc 0(вX*lRbWXd;.:7G7՞IxΊF/7lkC hAw\UMĕhe'[}&,{ب'ShvlLm$v*y ]{<@u.<\ZfX;SnMo0E|ó^cYo$WpMf$FsՋ-"&sj<S`"_".E$;5F624P9e浞p|^˭9<=+du~Q9F~PQM%?5]=dGasR/ 5Z~o`rx8kYOo~P6 I5FώÑ$vOs]^wxJŠyfq=YsߥT:(UX "uu|0G2_rLkTF;ק{€ \*_6zKkdN*i+;δǸ4946Oe/$΀(a*esZa'ӞN"8c-ٜF,柀͇;6?w)Ysy婂T0Osl}7C; 'A7OL҄u'@L]$ۥj2Y)㯥/=&D艜Jo]AD֏ޭ^= 4@k UP4 ,^cHWah x'í.'Zd1_)u!cLϯ5Mdf5=$W`rف\9Mx9JMSu/aoYʭ\/:x틮N@`91lNDYN 0HɞXSήXF $Sq[g&t y~:6&rKYm4iYjWuѝpm'v\M+A(z$ufos:X4%ɋ{.^>eʘɮVN6gh y y*']l#/^mZ֠`Q8W,DkY:}M5:W6 X1Vzc:ȢqfxYÂi9xa;dp%볻OEoIB\#Χs׋Hz6%Nz3h2BBEh[)4g4qU{A$L6ZgzZ߿{=Gn\4VҤ. Ŏ]bMy5#[ꋓʨUcBwށS~69 ]&JTrZ@2ԖA.'8o;40 "d./?r~z'Yc1wt}qqy]e=xuo}߅=h-,7=S+ߞkU,bBe\| xN-Ě"e5EWZcF>˲5%bᄥSU`D QbUalzʽ{\6~9-eZ+6j[k)1ћ PYy\jhtg9,FzIt{Ϥb#ˁI,U -jY@EfGUm=mETϫ-jmjhhiU4IPwÝq>u?=Υs9y)X%E&OsW"ٷY5Fn>"+A&9ۥkp!p>8?>轝 y:5j`y[Qn)-EpY& =;܈/6^NDW^w` gMZ[`.u r4xm2/؃`5U5/cR4VdԒ]Fњ%f@óPdi*-:ĦsT2Y'Nq^LA֔_T^;~cZY.5ڜZ4l{1(Wiu8ncCb2ֲN-Sh2}!Z;7*O3a,rѻ]dB1^'6vMF_qŌsUZ[~ֱ ?i>^WD8Ž> 5R'/ N֬~u'j'0;N.qR\CvQ|K|[/艐ȷSYg(|~Wr|~jT$YTg\,81; 2A1PKb@hKdEU4%ﵓD|]}ԛKWgpxzAoVT|^` >HFX[R]V?\f_\ kL+C=xMa5\c0k0u?u%u[&1łd ;wVEWZ{$$_8 -*΃`|沮{'6yyE"4{@"?}xVcp;:z_]P hR<`rOҲUyݪck.҈LX:J*,ܴBe9ݢcGjjcQ~ުڰz=`6K-*(eDkV7!k _gw ڹ Zy9~uu}bW*+Pv-`sup &^QvfO¢iCfГ`3-`-9Ȅ,i+ORyp+3'1蹏hWB.VrRڔ^6҈yj:OcPtʿ}rbkU44-(Ii6lڬN`waVO`?q}QwNyuxv)&~UIbbSV JIYfOcuuぴֵ6ʳrUX*sZFa81IJbѣpBQ9[Śq(wٿӏt>Ʒ.`l).JՌ6ȲӶeD²1b铍)hf+"zu3珊qbjϊ\ _? 'tFS6x>NJ&2U-ñHp ndu,iQmRcz?Y$&K>n<π]0AUL( :9BQѴ)?--C-ϡ9LSQ12 Y?싴Q?޸ 8&7o)j&.dJޱ/~;꾰%U^;bwF5{ (g endstream endobj 29 0 obj <> endobj 131 0 obj <>stream xY \S!psUH{iKVEkŭVQZ k %@AȄAZmVj[[՞kB}r'3sw3(k+J$I溹Oos0X$ o*a+Wd+F CvS "<R. w^i|eV 0q)SkN3f~0bwgY;zϱSRj(zA SéʝIޥVQ(j)5CQc5|jO}DMR.$ʕL-PFQR P){ʊr`j&Q S=[L75C}HQE$H5^E{8_ Mc lm*tDJN2}1~b7N'.MP>.\6fJ4d!ۇ<~s Ծ͇DPp[]A&UkQ0AI>w^(5#!551Au{NנȗCm|#Q`P *eua[>5+"Y-} l=ݱ)vO n( 7FTC(Bu?[כG0.&T~=̧{d|)#7I:m7c9/~/*1O5! 0Y8B*7Q;4@%w:֢R~{8m k.9U.RaM&dT=|1@A,B q/[c鏣 ~ 8셧n7k]Ǐul\"A/E pXn6HelAq udA/s0D|ʻNaވ?%wl;zS1Ӏ=HWi +0N;K/y]Nw)0 ;X~?I;`b ?L59Ț6Bvx-'6KqF#M:*j`]RKFܰ^._=}땇yx gnwca- Olo2l\)C8 x=QUq7zXEw{dgV?kqˤ1Xp0(` ù7 +ELUe>YZKmZ [ݖƭN%X;w7~`Q B= Cמ}Ck]jȎ5;ڃJkzJqgّY쏊L]- љ;; 1^uJ^EPN">nN&nՠ͛ǯ]QxKo) E1"(I R4jfߓ$q&6~/}~ì. HvCz^XlpV/zUq(c֞ JLѹuGi ~ac9;x0v́J>E~vFG63$Qĝnjȁ])^y[NMF sH\,lp=E&MvX ȯCFܢgR!A,3#C*B*_*fS|FCo;_u!PI>$lܖHFC{qfjPPe+b!}(\_@[Uh&#;(&U]tkaCEVlU"GTXĜd%WWlbjJ j+3PbD<^zO}?}oЂ 9iDj;I M*hO7ݟ7ka|)'}`6]qC;M]:vj}4#q?Jҕ;Y@8">ΒfDZڼ߻t`,zCG=^yf[z+\l^n >_.\cwf #b,ݣAkiXܞMVC EY{y!V=-$t! j#g VW^3{7>φ GJNJ?Y$Gc1yWi?0ʿɪ28z"BA|@nj;7g'!.XqtFrmvA7ўd% KX"4b"F'yrEj9J5p[ 6.??̘n2j?í-jVf w  ?v~%8e矟@ yJ':tԁ_OY{͈ytZ[CҎz^WTMR1eE;vLX[*!f̼S7DRL%$ BbEA'%0S^,75}󪚀t2CəF%8XS2QvfqVz 46V:bMY?{ÈNQL .4,y ͫC?4t>vD $sc`f7b.co#i\l  (?ߡԩ {<]@ZAx6f@oQ|fl&aL+"ð"'},Z(RiuwhW{X4қa$g/HlXZShxa E 6 }LWi^>Д᫛H0VFb^CW"d]<q73@<|$6?8ڕjIT#ˤ:%(;'yms@Ap#@u@EzQ r.8ӂ/^ԋka&7ZHcIcMs# h*RNy"pIDף^K_k̑Ր¡HYy .{i0=Oa6#OQ=NZ4lQiTMD3򴒊{qN%fz6d|ω ,Ԍ"G&A\)N}Z\D0`;&{Μ>us}B(m[RWrӈպIWnƻCmK İ0A ٖϠS̍9_b fҸXq,nΫ^1_ϠXYH8X%`F1q#/~dg srcj*؀O>&9G9tu9NnBJю+ht6)HHƿ e'9r( syV/%ߏa(M xnK:o n[e whXZrH17\E$BB윭g fsxyKߗ/?-'Sw(K#b6M;/AI6gRLoj$uGr?-~F 9i#ȺʲfS {r8-Гڰ'(#z>y Mz!_Iag lŨ\4?WY8-Z26~(< ?"i"{*KB+{;;){*<.ӓzM:Ҙ|3e^ҞҞ>N2EB܍'P-'Z֙5d~aL{ag:-?ס4$vIYBE<<ܹ"+7xB{l&M)qH&ۅxxGM?t?yDqӺhA %zc _mnWT*r(FIQsgӈ2uqKYˡ-5%&{c.H&!&&*^E^Mav;!VeE|iAظtݫ0jg}Jdp5zx}ia^6is*Cl p#|ʝssE br*ybJαz{(;0(R#c SryE%x Q#6cbt5q\ P-0E,#̎:;u 8h8_B!⏠vLJw쨗t|FoûϞZ8qI5_ezu}|ўiWCVQ,}՛5sK\$ ḾFjNӽRV ƫqlpDFRyG9Uȡ<\ޔ P댙0|E#Jdnkc$H)1")o|FePŮD:"P> endobj 132 0 obj <>stream xU{LSW7V*21a*(8>@+ E(H(G)0AdFEus*i5Qe`f[/;$!"HYHQz2z.#ͱk,QH,#ʷ3 |: Mէ%%$ #·,rssGDJOJ]"SMU4rr| )qik1=@EPZB6NS{A#™Dl&+HDjBA,!lx6BH Wd4mjUV%hB_a4K,1&n4eV;-jSZ2V_XMFDDmq0ղv&kN胶J)kcw\ԁ[vWґf@ހ[q Ԥ: w$:3LޘX\9jӄ"2%"lmP|8sKћ_ qE'ekax64מ5U`$0e }<]_)4ycmRsXcOc^ȹcppLr7E7JV*]}vZfΩD*=Tuܪ#U-gT)ֻ5m6̷FqZSZn\k}xID*p f}5 ,Q.HGp%bE^(H,$gbz#i@ns%GPOd)8/Gr*Pr✴;[|1 -24Co^ Ңf=ީ_PrdT oo Qb4dpP|ϕ-0U&b۴Q %ff=ɹRbqǃȆNT*K iO%FLv˹ϔdܰl/,/tdz9w!swg$"/QNV֡FT^wtX$>޲?]הpS/\O,āǃ0BY#.1;M+dSC2š^6\ɑ٭IZ.?>>P/Pnul}mw[LI/[0bKPQq},8@♽EÙeQq*;1ny('cرPn&OWP,.]u+5CVwSOP!~%Z3()GbHxA ] endstream endobj 142 0 obj <>stream 2019-12-10T14:16:55+01:00 2019-12-10T14:16:55+01:00 dvips(k) 5.997 Copyright 2017 Radical Eye Software manual.dvi endstream endobj 2 0 obj <>endobj xref 0 143 0000000000 65535 f 0000081449 00000 n 0000125881 00000 n 0000081259 00000 n 0000078165 00000 n 0000000015 00000 n 0000001464 00000 n 0000081515 00000 n 0000085212 00000 n 0000101048 00000 n 0000084361 00000 n 0000092740 00000 n 0000084118 00000 n 0000092091 00000 n 0000081556 00000 n 0000081586 00000 n 0000078325 00000 n 0000001484 00000 n 0000002712 00000 n 0000083581 00000 n 0000088440 00000 n 0000081638 00000 n 0000081668 00000 n 0000078487 00000 n 0000002733 00000 n 0000007524 00000 n 0000088135 00000 n 0000122722 00000 n 0000087570 00000 n 0000115939 00000 n 0000081720 00000 n 0000081750 00000 n 0000078649 00000 n 0000007545 00000 n 0000012337 00000 n 0000086936 00000 n 0000108236 00000 n 0000086772 00000 n 0000107405 00000 n 0000086537 00000 n 0000106786 00000 n 0000086274 00000 n 0000106169 00000 n 0000081813 00000 n 0000081843 00000 n 0000078811 00000 n 0000012358 00000 n 0000015903 00000 n 0000081950 00000 n 0000081980 00000 n 0000078973 00000 n 0000015924 00000 n 0000020933 00000 n 0000082054 00000 n 0000082084 00000 n 0000079135 00000 n 0000020954 00000 n 0000026831 00000 n 0000082180 00000 n 0000082210 00000 n 0000079297 00000 n 0000026852 00000 n 0000030777 00000 n 0000082295 00000 n 0000082325 00000 n 0000079459 00000 n 0000030798 00000 n 0000035597 00000 n 0000085887 00000 n 0000105469 00000 n 0000082399 00000 n 0000082429 00000 n 0000079621 00000 n 0000035618 00000 n 0000040203 00000 n 0000082536 00000 n 0000082566 00000 n 0000079783 00000 n 0000040224 00000 n 0000043629 00000 n 0000082651 00000 n 0000082681 00000 n 0000079945 00000 n 0000043650 00000 n 0000050918 00000 n 0000082746 00000 n 0000082776 00000 n 0000080107 00000 n 0000050939 00000 n 0000058038 00000 n 0000082852 00000 n 0000082882 00000 n 0000080269 00000 n 0000058059 00000 n 0000062309 00000 n 0000082978 00000 n 0000083008 00000 n 0000080431 00000 n 0000062330 00000 n 0000066073 00000 n 0000083073 00000 n 0000083104 00000 n 0000080595 00000 n 0000066094 00000 n 0000070605 00000 n 0000083201 00000 n 0000083232 00000 n 0000080761 00000 n 0000070627 00000 n 0000072502 00000 n 0000083318 00000 n 0000083349 00000 n 0000080927 00000 n 0000072524 00000 n 0000076416 00000 n 0000083391 00000 n 0000083422 00000 n 0000081093 00000 n 0000076438 00000 n 0000078143 00000 n 0000083486 00000 n 0000083517 00000 n 0000088750 00000 n 0000092315 00000 n 0000093284 00000 n 0000101436 00000 n 0000105679 00000 n 0000106394 00000 n 0000107006 00000 n 0000107645 00000 n 0000108697 00000 n 0000116488 00000 n 0000122986 00000 n 0000084034 00000 n 0000084266 00000 n 0000085114 00000 n 0000085803 00000 n 0000086042 00000 n 0000086438 00000 n 0000086684 00000 n 0000087483 00000 n 0000088042 00000 n 0000124425 00000 n trailer << /Size 143 /Root 1 0 R /Info 2 0 R /ID [<9A8A15E4BBB0F5A7F4C54BF018C10C92><9A8A15E4BBB0F5A7F4C54BF018C10C92>] >> startxref 126086 %%EOF cryst/doc/manual.bbl0000644000371700037170000000160313573723022016141 0ustar gap-jenkinsgap-jenkins\begin{thebibliography}{} \bibitem[BBNWZ78]{BBNWZ78} H. Brown, R. B{\accent127 u}low, J. Neub{\accent127 u}ser, H. Wondratschek, and H. Zassenhaus. \newblock {\em Crystallographic Groups of Four-Dimensional Space}. \newblock John Wiley, New York, 1978. \bibitem[EGN97]{EGN97} F. G{\"a}hler, B. Eick and W. Nickel. \newblock Computing maximal subgroups and wyckoff positions of space groups. \newblock {\em Acta Cryst A} 53, 467--474 (1997). \bibitem[Hah95]{Hah95} T. Hahn, editor. \newblock {\em International Tables for Crystallography, Volume A, Space-group Symmetry, 4th Edition}. \newblock Kluwer, Dordrecht, 1995. \bibitem[Won95]{Won95} H. Wondratschek. \newblock Introduction to space-group symmetry. \newblock In {\em Internation Tables for Crystallography, Vol. A} \cite{Hah95}, pages 711--735. \end{thebibliography}