alnuth-4.0.0/0000755000000000000000000000000015201210200007713 5ustar00alnuth-4.0.0/CHANGES.md0000644000000000000000000000473415201210200011315 0ustar00This file describes changes between different versions of Alnuth ================================================================ ## 4.0.0 (2026-05-14) - added support for using OSCAR as external CAS (in addition to PARI/GP); by default OSCAR support is automatically activated when Alnuth is loaded in GAP running inside OSCAR, in all other situations PARI/GP remains the default. - converted the manual to GAPDoc - renamed `FactorsPolynomialPari` to `FactorsPolynomialAlnuth` to better reflect that it uses the active external CAS, not just PARI/GP (the old name is still supported as a synonym for now) - replaced the old `AL_*` configuration globals by GAP's user preference system; the old variables are still used a fallback, but user preferences are preferred if set. For details, please consult the README and the package manual. ## 3.2.1 (2022-04-05) - set the GAP Team as maintainer of this package - various janitorial changes ## 3.2.0 (2022-03-02) - upgraded to support PARI 2.13 (thanks to Bill Allombert for the patch) ## 3.1.2 (2020-01-28) - updated authors contact data ## 3.1.1 (2019-06-04) - added implications IsUnitGroup => IsGroup and IsNumberFieldByMatrices => IsNumberField for improved compatibility with future GAP releases - fixed a link in the README - removed outdated author contact information ## 3.1.0 (2017-12-01) - upgraded to support PARI 2.9.0 (this required to remove support for PARI < 2.4.3) - migrated the package to GitHub ## 3.0.0 (2011-10-26) - added this file to document the changes between different versions - adjusted documentation to GAP 4.5 - switched interface from KANT/KASH to PARI/GP - replaced all Unix specific code to allow running Alnuth under Windows - removed some errorneous `Set` calls - replaced some calls to `PrimeField` by `Rationals` - removed functions in `unithom.gi` covered by Polycyclic - replaced (possibly expensive) call to `FieldOfPolynomial` - added `SubsetMaintencance` for `IsNumberFieldByMatrices` - renamed `IsPrimitiveElement` to `IsPrimitiveElementOfNumberField` - renamed `IsFieldByMatrices` to `AL_MatricesGeneratingNumberField` ## 2.3.1 (2011-05-31) ## 2.2.5 (2007-07-10) ## 2.2.4 (2007-06-17) ## 2.2.3 (2007-06-11) ## 2.2.2 (2006-11-24) ## 2.2.1 (2006-11-21) ## 2.2.0 (2006-09-02) ## 2.1.3 (2005-08-09) ## 2.1.2 (2005-08-04) ## 2.1.1 (2005-03-10) ## 2.1 (2004-12-20) ## 1.0 (2003-10-09) - initial release alnuth-4.0.0/GPL0000644000000000000000000004311015201210200010257 0ustar00 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. alnuth-4.0.0/Makefile0000644000000000000000000000073215201210200011355 0ustar00.PHONY: run doc html clean check GAP ?= gap GAP_ARGS = -q --quitonbreak --packagedirs $(abspath .) # run GAP and load the package run: $(GAP) --packagedirs $(abspath .) -c 'LoadPackage("alnuth");' doc: $(GAP) $(GAP_ARGS) makedoc.g -c 'QUIT;' html: NOPDF=1 $(GAP) $(GAP_ARGS) makedoc.g -c 'QUIT;' clean: cd doc && rm -f *.{aux,lab,log,dvi,ps,pdf,bbl,ilg,ind,idx,out,html,tex,pnr,txt,blg,toc,six,brf,css,js} _*.xml title.xml check: $(GAP) $(GAP_ARGS) tst/testall.g alnuth-4.0.0/PackageInfo.g0000644000000000000000000001310715201210200012234 0ustar00############################################################################# ## ## PackageInfo.g GAP4 Package "Alnuth" Bjoern Assmann ## Andreas Distler ## SetPackageInfo( rec( PackageName := "Alnuth", Subtitle := "ALgebraic NUmber THeory and an interface to PARI/GP and OSCAR", Version := "4.0.0", Date := "14/05/2026", # dd/mm/yyyy format License := "GPL-2.0-or-later", SourceRepository := rec( Type := "git", URL := Concatenation( "https://github.com/gap-packages/", LowercaseString(~.PackageName) ), ), IssueTrackerURL := Concatenation( ~.SourceRepository.URL, "/issues" ), PackageWWWHome := Concatenation( "https://gap-packages.github.io/", LowercaseString(~.PackageName) ), README_URL := Concatenation( ~.PackageWWWHome, "/README.md" ), PackageInfoURL := Concatenation( ~.PackageWWWHome, "/PackageInfo.g" ), ArchiveURL := Concatenation( ~.SourceRepository.URL, "/releases/download/v", ~.Version, "/", LowercaseString(~.PackageName), "-", ~.Version ), ArchiveFormats := ".tar.gz", Persons := [ rec( LastName := "Assmann", FirstNames := "Björn", IsAuthor := true, IsMaintainer := false, ), rec( LastName := "Distler", FirstNames := "Andreas", IsAuthor := true, IsMaintainer := false, Email := "a.distler@tu-bs.de", ), rec( LastName := "Eick", FirstNames := "Bettina", IsAuthor := true, IsMaintainer := false, Email := "beick@tu-bs.de", WWWHome := "http://www.iaa.tu-bs.de/beick", GitHubUsername:= "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 := "Horn", FirstNames := "Max", IsAuthor := false, IsMaintainer := true, Email := "mhorn@rptu.de", WWWHome := "https://www.quendi.de/math", GitHubUsername:= "fingolfin", PostalAddress := Concatenation( "Fachbereich Mathematik\n", "RPTU Kaiserslautern-Landau\n", "Gottlieb-Daimler-Straße 48\n", "67663 Kaiserslautern\n", "Germany" ), Place := "Kaiserslautern, Germany", Institution := "RPTU Kaiserslautern-Landau" ), rec( LastName := "GAP Team", FirstNames := "The", IsAuthor := false, IsMaintainer := true, Email := "support@gap-system.org", ), ], Status := "accepted", CommunicatedBy := "Charles Wright (Eugene)", AcceptDate := "01/2004", AbstractHTML := "The Alnuth package provides various methods to compute with number fields which are given by a defining polynomial or by generators. Some of the methods provided in this package are written in GAP code. The other part of the methods is imported from an another computer algebra system, currently either PARI/GP or OSCAR. Hence this package contains some GAP functions and an interface to some functions in the computer algebra systems PARI/GP and OSCAR. The main methods included in Alnuth are: creating a number field, computing its maximal order (using the external CAS), computing its unit group (using the external CAS) and a presentation of this unit group, computing the elements of a given norm of the number field (using the external CAS), determining a presentation for a finitely generated multiplicative subgroup (using the external CAS), and factoring polynomials defined over number fields (using the external CAS).", PackageDoc := rec( BookName := "Alnuth", ArchiveURLSubset := ["doc"], HTMLStart := "doc/chap0_mj.html", PDFFile := "doc/manual.pdf", SixFile := "doc/manual.six", LongTitle := "ALgebraic NUmber THeory and an interface to PARI/GP and OSCAR", ), Dependencies := rec( GAP := ">= 4.8", NeededOtherPackages := [[ "polycyclic", ">=1.1" ]], SuggestedOtherPackages := [], NeededSystemPackages := rec( Ubuntu := [["pari-gp"]], Homebrew := [["pari"]] ), ExternalConditions := [["needs the PARI/GP computer algebra system Version 2.5 or higher", "https://pari.math.u-bordeaux.fr/" ] ] ), Extensions := [ rec( needed := [ [ "OscarInterface", ">= 1.0.0" ] ], filename := "gap/oscar.gi" ), ], AvailabilityTest := ReturnTrue, TestFile := "tst/testall.g", Keywords := ["algebraic number theory", "number field" , "maximal order", "interface to PARI/GP", "interface to number theory in OSCAR", "unit group", "elements of given norm" ], AutoDoc := rec( entities := rec( VERSION := ~.Version, RELEASEYEAR := ~.Date{[7..10]}, RELEASEDATE := function(date) local day, month, year, allMonths; day := Int(date{[1,2]}); month := Int(date{[4,5]}); year := Int(date{[7..10]}); allMonths := [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; return Concatenation(String(day)," ", allMonths[month], " ", String(year)); end(~.Date), Polycyclic := "Polycyclic", ), ), )); alnuth-4.0.0/README.md0000644000000000000000000002132715201210200011177 0ustar00[![CI](https://github.com/gap-packages/alnuth/actions/workflows/CI.yml/badge.svg)](https://github.com/gap-packages/alnuth/actions/workflows/CI.yml) [![Code Coverage](https://codecov.io/github/gap-packages/alnuth/coverage.svg?branch=master&token=)](https://codecov.io/gh/gap-packages/alnuth) # The GAP package Alnuth Alnuth is an extension, a so called package, for the computer algebra system GAP and forms part of a standard installation. For information about GAP see . The functionality of Alnuth lies in ALgebraic NUmber THeory. It provides an interface from GAP to certain number theoretic functions from other computer algebra systems, namely either PARI/GP or OSCAR (in the past also KANT/KASH). Most computations with Alnuth rely on this interface. The interface is an integral part of the package, but the external software (so PARI/GP or OSCAR) has to be obtained independently. ## New in Version 4 Alnuth now has two backends: besides the existing interface to PARI/GP, it now also integrates with the OSCAR computer algebra system when loaded in GAP running inside OSCAR. Moreover many settings in Alnuth that were so far controlled by proprietary controls now use the GAP user preferences system. In particular, the old globals `AL_EXECUTABLE`, `AL_OPTIONS`, `AL_STACKSIZE`, and `PRIM_TEST` are deprecated in favor of `SetUserPreference("alnuth", ...)`, while `AL_PATH` is gone entirely. Deprecated globals still trigger a warning, but except for `AL_PATH` they are used as a fallback if the corresponding new user preference is not set or invalid. ## New in Version 3 Up to and including Version 2.3.1, Alnuth was restricted to operating systems based on Unix. This is no longer the case and Alnuth can now also be used under Windows. Moreover, former versions of Alnuth provided an interface to KANT, respectively its shell KASH, instead of one to PARI/GP. This change did not influence the availability of GAP functions in the package. Note that any further changes and bugfixes will only be made to Version 3 of Alnuth which contains the interface to PARI/GP. ## Installing Alnuth The package Alnuth is part of the standard distribution of GAP so that in most cases there is no need to install it separately. If you are using OSCAR, then Alnuth is already bundled and set up to interface with OSCAR, and you can stop reading this section. Otherwise, if you are using it outside of OSCAR, you need to have PARI/GP installed. See the following section for information on PARI/GP. In case you want to update Alnuth independently of your main GAP installation, you can download it from its homepage . If you are interested in an old version of Alnuth interfacing to KANT/KASH you can find all released versions of Alnuth starting from v1.0 (09/10/2003) at . There are two ways of installing a GAP package. If you have permission to add files to the installation of GAP on your system you may install Alnuth into the `pkg` subdirectory of the GAP installation tree. Otherwise you may install Alnuth in a private `pkg` directory (for details see '76.1 Installing a GAP Package' and '9.2 GAP Root Directories' in the GAP reference manual). To install the latest version of Alnuth download the `alnuth.tar.gz` archive, move it to the directory `pkg` in which you want to install, and unpack the archive. If you are using the command line you can unpack with the command `tar xzf alnuth.tar.gz`. ### Getting PARI/GP Using Alnuth outside of OSCAR requires an installation of PARI/GP Version 2.5 or higher. PARI/GP is freely available at . Note that the place where PARI/GP is located in your system is independent of the place where Alnuth is installed. In many Linux distributions PARI/GP can be installed via the software package manager, but this might sometimes be an older version which cannot be used together with Alnuth. If you install PARI/GP from source make sure you install with GMP support for better performance and complete the installation with `make install` so that you can start GP by just calling `gp` from the command line. For Windows it is sufficient to get the basic GP binary which can be found at . ### Adjust the path of the executable for GP This package needs to know where the executable for GP is. In the default setting Alnuth looks for an executable program named `gp` in the search paths of the system. More precisely, for a file `gp` inside one of the directories in the list returned by `DirectoriesSystemPrograms()`. Under Linux the default setting should work with a standard installation of PARI/GP. For the default setting to work under Windows the downloaded executable file, for example `gp-2-5-0.exe` has to be renamed to `gp.exe` and moved to one of the directories listed by `DirectoriesSystemPrograms()`. If you cannot use the default setting for you purpose, you can find more information in the last chapter of the Alnuth manual. The most important user preferences are: - `SetUserPreference("alnuth", "PariGpPath", "/path/to/gp");` - `SetUserPreference("alnuth", "PariStackSize", 256);` - `SetUserPreference("alnuth", "PrimitiveElementTrials", 40);` Then call `WriteGapIniFile();` to write the current non-default settings to your `gap.ini`. Users upgrading from older Alnuth versions should note these replacements: - `AL_EXECUTABLE` becomes `PariGpPath` - `AL_OPTIONS` becomes `PariGpOptions` - `AL_STACKSIZE` becomes `PariStackSize` - `PRIM_TEST` becomes `PrimitiveElementTrials` - `AL_PATH` no longer exists; Alnuth now locates its bundled GP code itself The deprecated globals still act as a fallback if the corresponding user preference is unusable, but they trigger a warning and should be replaced. The old functions `SetAlnuthExternalExecutable` and `SetAlnuthExternalExecutablePermanently` still exist as deprecated compatibility wrappers around the new preferences. ## Loading the package If Alnuth is not loaded when GAP is started you have to request it explicitly to use it. This is done by calling `LoadPackage("Alnuth");` in a GAP session. If Alnuth had not been loaded already a short banner will be displayed. gap> LoadPackage("Alnuth"); Loading Alnuth 4.0.0 (ALgebraic NUmber THeory and an interface to PARI/GP and OSCAR) by Björn Assmann, Andreas Distler (a.distler@tu-bs.de), and Bettina Eick (http://www.iaa.tu-bs.de/beick). maintained by: Max Horn (https://www.quendi.de/math) and The GAP Team (support@gap-system.org). Homepage: https://gap-packages.github.io/alnuth Report issues at https://github.com/gap-packages/alnuth/issues true gap> To load a certain version of Alnuth you can specify the version number as second argument in the call to `LoadPackage`. (See '76.2 Loading a GAP package' in the reference manual or type `?LoadPackage` within a GAP session). ## Testing the package Once the package is loaded, it is possible to check the correct installation running a short test by calling `ReadPackage("Alnuth", "tst/testinstall.g");`. gap> ReadPackage("Alnuth", "tst/testinstall.g"); Architecture: aarch64-apple-darwin24-default64-kv10 testing: GAPROOT/pkg/alnuth/tst/ALNUTH.tst 72 ms (41 ms GC) and 10.9MB allocated for GAPROOT/pkg/alnuth/tst/ALNUTH.tst ----------------------------------- total 72 ms (41 ms GC) and 10.9MB allocated 0 failures in 1 files #I No errors detected while testing If the test suite runs into an error in the first part, which verifies the availability of PARI/GP, check your installation of PARI/GP and consult the last chapter of the documentation of Alnuth for more information. ## Contact If you find any bugs or have any suggestions or comments, we would very much appreciate it if you would let us know by submitting an issue at the Alnuth issue tracker on GitHub or by writing an mail to . ## License > Copyright (C) 2011 Bjoern Assmann, Andreas Distler, Bettina Eick > > 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, see . alnuth-4.0.0/doc/0000755000000000000000000000000015201210200010460 5ustar00alnuth-4.0.0/doc/_AutoDocMainFile.xml0000644000000000000000000000014115201210200014300 0ustar00   alnuth-4.0.0/doc/_Chunks.xml0000644000000000000000000000000015201210200012562 0ustar00alnuth-4.0.0/doc/_entities.xml0000644000000000000000000000027515201210200013171 0ustar00Alnuth'> Polycyclic'> alnuth-4.0.0/doc/_main.tex0000644000000000000000000012444615201210200012300 0ustar00% generated by GAPDoc2LaTeX from XML source (Frank Luebeck) \documentclass[a4paper,11pt]{report} \usepackage[top=37mm,bottom=37mm,left=27mm,right=27mm]{geometry} \sloppy \pagestyle{myheadings} \usepackage{amssymb} \usepackage[utf8]{inputenc} \usepackage{makeidx} \makeindex \usepackage{color} \definecolor{FireBrick}{rgb}{0.5812,0.0074,0.0083} \definecolor{RoyalBlue}{rgb}{0.0236,0.0894,0.6179} \definecolor{RoyalGreen}{rgb}{0.0236,0.6179,0.0894} \definecolor{RoyalRed}{rgb}{0.6179,0.0236,0.0894} \definecolor{LightBlue}{rgb}{0.8544,0.9511,1.0000} \definecolor{Black}{rgb}{0.0,0.0,0.0} \definecolor{linkColor}{rgb}{0.0,0.0,0.554} \definecolor{citeColor}{rgb}{0.0,0.0,0.554} \definecolor{fileColor}{rgb}{0.0,0.0,0.554} \definecolor{urlColor}{rgb}{0.0,0.0,0.554} \definecolor{promptColor}{rgb}{0.0,0.0,0.589} \definecolor{brkpromptColor}{rgb}{0.589,0.0,0.0} \definecolor{gapinputColor}{rgb}{0.589,0.0,0.0} \definecolor{gapoutputColor}{rgb}{0.0,0.0,0.0} %% for a long time these were red and blue by default, %% now black, but keep variables to overwrite \definecolor{FuncColor}{rgb}{0.0,0.0,0.0} %% strange name because of pdflatex bug: \definecolor{Chapter }{rgb}{0.0,0.0,0.0} \definecolor{DarkOlive}{rgb}{0.1047,0.2412,0.0064} \usepackage{fancyvrb} \usepackage{mathptmx,helvet} \usepackage[T1]{fontenc} \usepackage{textcomp} \usepackage[ pdftex=true, bookmarks=true, a4paper=true, pdftitle={Written with GAPDoc}, pdfcreator={LaTeX with hyperref package / GAPDoc}, colorlinks=true, backref=page, breaklinks=true, linkcolor=linkColor, citecolor=citeColor, filecolor=fileColor, urlcolor=urlColor, pdfpagemode={UseNone}, ]{hyperref} \newcommand{\maintitlesize}{\fontsize{50}{55}\selectfont} % write page numbers to a .pnr log file for online help \newwrite\pagenrlog \immediate\openout\pagenrlog =\jobname.pnr \immediate\write\pagenrlog{PAGENRS := [} \newcommand{\logpage}[1]{\protect\write\pagenrlog{#1, \thepage,}} %% were never documented, give conflicts with some additional packages \newcommand{\GAP}{\textsf{GAP}} %% nicer description environments, allows long labels \usepackage{enumitem} \setdescription{style=nextline} %% depth of toc \setcounter{tocdepth}{1} %% command for ColorPrompt style examples \newcommand{\gapprompt}[1]{\color{promptColor}{\bfseries #1}} \newcommand{\gapbrkprompt}[1]{\color{brkpromptColor}{\bfseries #1}} \newcommand{\gapinput}[1]{\color{gapinputColor}{#1}} \begin{document} \logpage{[ 0, 0, 0 ]} \begin{titlepage} \mbox{}\vfill \begin{center}{\maintitlesize \textbf{ Alnuth \\ \mbox{}}}\\ \vfill \hypersetup{pdftitle={ Alnuth }} \markright{\scriptsize \mbox{}\hfill Alnuth \hfill\mbox{}} {\Huge \textbf{ ALgebraic NUmber THeory\\ and an interface to\\ PARI/GP and OSCAR \\ \mbox{}}}\\ \vfill {\Huge 4.0.0 \mbox{}}\\[1cm] { 14 May 2026 \mbox{}}\\[1cm] \mbox{}\\[2cm] {\Large \textbf{\strut GAP code by Bj{\"o}rn Assmann, Andreas Distler and Bettina Eick \strut\mbox{}}}\\ {\Large \textbf{\strut PARI/GP code by Bill Allombert \strut\mbox{}}}\\ {\Large \textbf{\strut OSCAR code by Claus Fieker and Max Horn \strut\mbox{}}}\\ \hypersetup{pdfauthor={ GAP code by Bj{\"o}rn Assmann, Andreas Distler and Bettina Eick ; PARI/GP code by Bill Allombert ; OSCAR code by Claus Fieker and Max Horn }} \mbox{}\\[2cm] \begin{minipage}{12cm}\noindent \emph{Note:} PARI/GP is \emph{not} part of this package. It can be obtained from \href{https://pari.math.u-bordeaux.fr/} {\texttt{https://pari.math.u\texttt{\symbol{45}}bordeaux.fr/}}. If you use GAP via OSCAR, then OSCAR will automatically be used instead of PARI/GP. \end{minipage} \end{center}\vfill \mbox{}\\ \end{titlepage} \newpage\setcounter{page}{2} {\small \section*{Copyright} \logpage{[ 0, 0, 1 ]} 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, see \href{https://www.gnu.org/licenses/} {\texttt{https://www.gnu.org/licenses/}} \mbox{}}\\[1cm] {\small \section*{Acknowledgements} \logpage{[ 0, 0, 2 ]} To begin with we are very grateful for all the feedback by users of former versions of \textsf{Alnuth}. We thank Bill Allombert who wrote the GP code for the interface to PARI/GP and who was extremely helpful in the transition from KANT to PARI/GP. For feedback on the development version, including a code patch, we are much obliged to Max Horn. The second author acknowledges the financial support at CAUL within the projects PTDC/MAT/101993/2008 and ISFL\texttt{\symbol{45}}1\texttt{\symbol{45}}143, financed by FEDER and FCT, in the development of Version 3 of \textsf{Alnuth}. Support for using OSCAR instead of PARI/GP was added by Claus Fieker and Max Horn. \mbox{}}\\[1cm] \newpage \def\contentsname{Contents\logpage{[ 0, 0, 3 ]}} \tableofcontents \newpage \chapter{\textcolor{Chapter }{Introduction}}\label{Introduction} \logpage{[ 1, 0, 0 ]} \hyperdef{L}{X7DFB63A97E67C0A1}{} { A number field is a finite extension of the field of rational numbers. \textsf{Alnuth} provides various methods to compute with number fields which are given by a defining polynomial or by generators. For background on number fields we refer to \cite{Sta79}. Some of the methods provided in this package are written in \textsf{GAP} code. The other part of the methods is imported from the Computer Algebra Systems PARI/GP \cite{PARI2} respectively OSCAR \cite{Oscar25}, \cite{OSCAR}. Hence this package contains some \textsf{GAP} functions and an interface to some functions to these computer algebra systems. Therefore one has to have PARI/GP or OSCAR installed to use the full functionality of \textsf{Alnuth}. We note that only a very small part of the functions available in PARI/GP respectively OSCAR are linked to \textsf{GAP} and they provides many more methods for computations in number fields. The main methods included in \textsf{Alnuth} are: creating a number field, computing its maximal order, computing its unit group and a presentation of this unit group, computing the elements of a given norm of the number field, determining a presentation for a finitely generated multiplicative subgroup, and factoring polynomials defined over number fields. For background on algorithms for number fields we refer to \cite{Poh93}, \cite{PZa89} and \cite{Coh93}. The functions provided by \textsf{Alnuth} are introduced in the following chapter. Then an example application is outlined. In the final chapter of this manual the installation of the package and configuration of the interface, including hints on the installation of PARI/GP respectively OSCAR, are described. } \chapter{\textcolor{Chapter }{Working with number fields}}\label{Working with number fields} \logpage{[ 2, 0, 0 ]} \hyperdef{L}{X7DC995CB8412F8E2}{} { An algebraic number field is a finite\texttt{\symbol{45}}dimensional extension of the rational numbers ${\ensuremath{\mathbb Q}}$. Such a number field has a primitive element and it can be defined by the minimal polynomial of this primitive element. Another important way to define an algebraic number field is by a set of rational matrices which generate a number field. \section{\textcolor{Chapter }{Creation of number fields}}\label{Creation of number fields} \logpage{[ 2, 1, 0 ]} \hyperdef{L}{X86AD0C3F7D38C269}{} { We provide functions to create number fields defined by rational matrices or by rational polynomials. \subsection{\textcolor{Chapter }{FieldByMatricesNC}} \logpage{[ 2, 1, 1 ]}\nobreak \hyperdef{L}{X8085204B7DE2C8BA}{} {\noindent\textcolor{FuncColor}{$\triangleright$\enspace\texttt{FieldByMatricesNC({\mdseries\slshape matrices})\index{FieldByMatricesNC@\texttt{FieldByMatricesNC}} \label{FieldByMatricesNC} }\hfill{\scriptsize (function)}}\\ \noindent\textcolor{FuncColor}{$\triangleright$\enspace\texttt{FieldByMatrices({\mdseries\slshape matrices})\index{FieldByMatrices@\texttt{FieldByMatrices}} \label{FieldByMatrices} }\hfill{\scriptsize (function)}}\\ Creates a field generated by the rational matrices \mbox{\texttt{\mdseries\slshape matrices}}. In the faster NC version, the function assumes that the input generates a field and there are no checks on this performed. } \subsection{\textcolor{Chapter }{FieldByMatrixBasisNC}} \logpage{[ 2, 1, 2 ]}\nobreak \hyperdef{L}{X805CFBEB877FCBA3}{} {\noindent\textcolor{FuncColor}{$\triangleright$\enspace\texttt{FieldByMatrixBasisNC({\mdseries\slshape matrices})\index{FieldByMatrixBasisNC@\texttt{FieldByMatrixBasisNC}} \label{FieldByMatrixBasisNC} }\hfill{\scriptsize (function)}}\\ \noindent\textcolor{FuncColor}{$\triangleright$\enspace\texttt{FieldByMatrixBasis({\mdseries\slshape matrices})\index{FieldByMatrixBasis@\texttt{FieldByMatrixBasis}} \label{FieldByMatrixBasis} }\hfill{\scriptsize (function)}}\\ Creates a field with basis \mbox{\texttt{\mdseries\slshape matrices}}. The list \mbox{\texttt{\mdseries\slshape matrices}} must consist of rational matrices which form a basis for a number field. In the faster NC version, the function assumes that the input is a matrix basis for a field and no checks are performed. } \subsection{\textcolor{Chapter }{FieldByPolynomialNC}} \logpage{[ 2, 1, 3 ]}\nobreak \hyperdef{L}{X7AD9823687E61ABC}{} {\noindent\textcolor{FuncColor}{$\triangleright$\enspace\texttt{FieldByPolynomialNC({\mdseries\slshape polynomial})\index{FieldByPolynomialNC@\texttt{FieldByPolynomialNC}} \label{FieldByPolynomialNC} }\hfill{\scriptsize (function)}}\\ \noindent\textcolor{FuncColor}{$\triangleright$\enspace\texttt{FieldByPolynomial({\mdseries\slshape polynomial})\index{FieldByPolynomial@\texttt{FieldByPolynomial}} \label{FieldByPolynomial} }\hfill{\scriptsize (function)}}\\ Creates a field defined by \mbox{\texttt{\mdseries\slshape polynomial}}. The polynomial \mbox{\texttt{\mdseries\slshape polynomial}} must be an irreducible rational polynomial. In the faster NC version, no checks on the input are performed. } } \section{\textcolor{Chapter }{Methods for number fields}}\label{Methods for number fields} \logpage{[ 2, 2, 0 ]} \hyperdef{L}{X79007A477D53B572}{} { We outline a number of functions for number fields. \subsection{\textcolor{Chapter }{PrimitiveElement}} \logpage{[ 2, 2, 1 ]}\nobreak \hyperdef{L}{X86DB31B57FB4F570}{} {\noindent\textcolor{FuncColor}{$\triangleright$\enspace\texttt{PrimitiveElement({\mdseries\slshape F})\index{PrimitiveElement@\texttt{PrimitiveElement}} \label{PrimitiveElement} }\hfill{\scriptsize (function)}}\\ \noindent\textcolor{FuncColor}{$\triangleright$\enspace\texttt{DefiningPolynomial({\mdseries\slshape F})\index{DefiningPolynomial@\texttt{DefiningPolynomial}} \label{DefiningPolynomial} }\hfill{\scriptsize (function)}}\\ Computes a primitive element and a defining polynomial for the given number field. The defining polynomial is the minimal polynomial of the primitive element. Since \mbox{\texttt{\mdseries\slshape F}} contains various primitive elements, \texttt{PrimitiveElement} tries to find a primitive element which has a minimal polynomial with small coefficients. Via the user preference \texttt{PrimitiveElementTrials} the user can decide how many primitive elements will be compared. The default value is 20. (See \texttt{SetUserPreference} (\textbf{Reference: SetUserPreference}) for more information about user preferences.) } \subsection{\textcolor{Chapter }{IsPrimitiveElementOfNumberField}} \logpage{[ 2, 2, 2 ]}\nobreak \hyperdef{L}{X843C2BE881A3576A}{} {\noindent\textcolor{FuncColor}{$\triangleright$\enspace\texttt{IsPrimitiveElementOfNumberField({\mdseries\slshape F, a})\index{IsPrimitiveElementOfNumberField@\texttt{IsPrimitiveElementOfNumberField}} \label{IsPrimitiveElementOfNumberField} }\hfill{\scriptsize (function)}}\\ Checks if the given element generates the field. } \subsection{\textcolor{Chapter }{DegreeOverPrimeField}} \logpage{[ 2, 2, 3 ]}\nobreak \hyperdef{L}{X7845CECE86A83219}{} {\noindent\textcolor{FuncColor}{$\triangleright$\enspace\texttt{DegreeOverPrimeField({\mdseries\slshape F})\index{DegreeOverPrimeField@\texttt{DegreeOverPrimeField}} \label{DegreeOverPrimeField} }\hfill{\scriptsize (function)}}\\ Returns the degree of \mbox{\texttt{\mdseries\slshape F}} over the rationals. } \subsection{\textcolor{Chapter }{EquationOrderBasis}} \logpage{[ 2, 2, 4 ]}\nobreak \hyperdef{L}{X8185FEF1811EA43F}{} {\noindent\textcolor{FuncColor}{$\triangleright$\enspace\texttt{EquationOrderBasis({\mdseries\slshape F})\index{EquationOrderBasis@\texttt{EquationOrderBasis}} \label{EquationOrderBasis} }\hfill{\scriptsize (function)}}\\ \noindent\textcolor{FuncColor}{$\triangleright$\enspace\texttt{MaximalOrderBasis({\mdseries\slshape F})\index{MaximalOrderBasis@\texttt{MaximalOrderBasis}} \label{MaximalOrderBasis} }\hfill{\scriptsize (function)}}\\ \noindent\textcolor{FuncColor}{$\triangleright$\enspace\texttt{IsIntegerOfNumberField({\mdseries\slshape F, k})\index{IsIntegerOfNumberField@\texttt{IsIntegerOfNumberField}} \label{IsIntegerOfNumberField} }\hfill{\scriptsize (function)}}\\ These functions return bases for the equation order or the maximal order of the number field \mbox{\texttt{\mdseries\slshape F}}. Also, they allow to check if a given element is an integer in the given number field. } \subsection{\textcolor{Chapter }{UnitGroup}} \logpage{[ 2, 2, 5 ]}\nobreak \hyperdef{L}{X7902A7877B65FDA1}{} {\noindent\textcolor{FuncColor}{$\triangleright$\enspace\texttt{UnitGroup({\mdseries\slshape F})\index{UnitGroup@\texttt{UnitGroup}} \label{UnitGroup} }\hfill{\scriptsize (function)}}\\ determines the unit group of \mbox{\texttt{\mdseries\slshape F}}. Recall that the unit group of \mbox{\texttt{\mdseries\slshape F}} is a finitely generated abelian group. The function \texttt{IsomorphismPcpGroup} from the \textsf{Polycyclic} \cite{Polycyclic} package gives an isomorphism to a pcp group which can be used for various computations with the unit group. } \subsection{\textcolor{Chapter }{IsUnitOfNumberField}} \logpage{[ 2, 2, 6 ]}\nobreak \hyperdef{L}{X7D9484BA7AF4201C}{} {\noindent\textcolor{FuncColor}{$\triangleright$\enspace\texttt{IsUnitOfNumberField({\mdseries\slshape F, k})\index{IsUnitOfNumberField@\texttt{IsUnitOfNumberField}} \label{IsUnitOfNumberField} }\hfill{\scriptsize (function)}}\\ checks whether the element \mbox{\texttt{\mdseries\slshape k}} is a unit in \mbox{\texttt{\mdseries\slshape F}}. } \subsection{\textcolor{Chapter }{ExponentsOfUnits}} \logpage{[ 2, 2, 7 ]}\nobreak \hyperdef{L}{X80389D828474FC64}{} {\noindent\textcolor{FuncColor}{$\triangleright$\enspace\texttt{ExponentsOfUnits({\mdseries\slshape F, elms})\index{ExponentsOfUnits@\texttt{ExponentsOfUnits}} \label{ExponentsOfUnits} }\hfill{\scriptsize (function)}}\\ This function determines the exponent vectors of the elements in \mbox{\texttt{\mdseries\slshape elms}} with respect to the generators of the unit group of \mbox{\texttt{\mdseries\slshape F}}. If the unit group of \mbox{\texttt{\mdseries\slshape F}} is not known, then the function computes this unit group also. } \subsection{\textcolor{Chapter }{IsCyclotomicField}} \logpage{[ 2, 2, 8 ]}\nobreak \hyperdef{L}{X84CAE4627F0CD639}{} {\noindent\textcolor{FuncColor}{$\triangleright$\enspace\texttt{IsCyclotomicField({\mdseries\slshape F})\index{IsCyclotomicField@\texttt{IsCyclotomicField}} \label{IsCyclotomicField} }\hfill{\scriptsize (function)}}\\ Check whether \mbox{\texttt{\mdseries\slshape F}} is cyclotomic. } \subsection{\textcolor{Chapter }{NormCosetsOfNumberField}} \logpage{[ 2, 2, 9 ]}\nobreak \hyperdef{L}{X7A43318584DB3756}{} {\noindent\textcolor{FuncColor}{$\triangleright$\enspace\texttt{NormCosetsOfNumberField({\mdseries\slshape F, norm})\index{NormCosetsOfNumberField@\texttt{NormCosetsOfNumberField}} \label{NormCosetsOfNumberField} }\hfill{\scriptsize (function)}}\\ Returns a description for the set of all elements of norm \mbox{\texttt{\mdseries\slshape norm}} in \mbox{\texttt{\mdseries\slshape F}}. These elements can be written as a finite union of cosets of the unit group of \mbox{\texttt{\mdseries\slshape F}}. The function returns coset representatives for these cosets. } } \section{\textcolor{Chapter }{Presentations of multiplicative subgroups}}\label{Presentations of multiplicative subgroups} \logpage{[ 2, 3, 0 ]} \hyperdef{L}{X833A0296798E0463}{} { Suppose that a finite number of invertible elements of a number field are given. Then these elements generate a finitely generated abelian group. However, it is a non\texttt{\symbol{45}}trivial task to provide a presentation for this abelian group. The most useful representation for such groups is as pcp group. \subsection{\textcolor{Chapter }{PcpPresentationOfMultiplicativeSubgroup}} \logpage{[ 2, 3, 1 ]}\nobreak \hyperdef{L}{X7975303583E6058B}{} {\noindent\textcolor{FuncColor}{$\triangleright$\enspace\texttt{PcpPresentationOfMultiplicativeSubgroup({\mdseries\slshape F, elms})\index{PcpPresentationOfMultiplicativeSubgroup@\texttt{Pcp}\-\texttt{Presentation}\-\texttt{Of}\-\texttt{Multiplicative}\-\texttt{Subgroup}} \label{PcpPresentationOfMultiplicativeSubgroup} }\hfill{\scriptsize (function)}}\\ \noindent\textcolor{FuncColor}{$\triangleright$\enspace\texttt{IsomorphismPcpGroup({\mdseries\slshape F, elms})\index{IsomorphismPcpGroup@\texttt{IsomorphismPcpGroup}} \label{IsomorphismPcpGroup} }\hfill{\scriptsize (function)}}\\ Determine a pcp presentation for the multiplicative group of $\mbox{\texttt{\mdseries\slshape F}}\backslash\{0\}$ generated by \mbox{\texttt{\mdseries\slshape elms}} and an isomorphism on this presentation. Note, that the method \texttt{IsomorphismPcpGroup} is defined in the \textsf{Polycyclic} package \cite{Polycyclic}. We refer to the manual of this package for further background. In the determination of the Pcp\texttt{\symbol{45}}presentation of a multiplicative subgroup generated by \mbox{\texttt{\mdseries\slshape elms}} the relations between the elements in \mbox{\texttt{\mdseries\slshape elms}} play an important role. Let $elms=\{e_1,\dots,e_l\}$ be a finite subset of a field \mbox{\texttt{\mdseries\slshape F}}. The relation lattice for \mbox{\texttt{\mdseries\slshape elms}} is \[ rl(elms):=\left\{(h_1,\dots,h_l) \in {\ensuremath{\mathbb Z}}^l | e_1^{h_1} \cdots e_l^{h_l} = 1\right\} . \] } \subsection{\textcolor{Chapter }{RelationLattice}} \logpage{[ 2, 3, 2 ]}\nobreak \hyperdef{L}{X7C6E88FE82BB9DE3}{} {\noindent\textcolor{FuncColor}{$\triangleright$\enspace\texttt{RelationLattice({\mdseries\slshape F, elms})\index{RelationLattice@\texttt{RelationLattice}} \label{RelationLattice} }\hfill{\scriptsize (function)}}\\ Determines a generating set for the relation lattice of the field elements \mbox{\texttt{\mdseries\slshape elms}}. } } \section{\textcolor{Chapter }{Methods to compute with subgroups of the unit group}}\label{Methods to compute with subgroups of the unit group} \logpage{[ 2, 4, 0 ]} \hyperdef{L}{X86F68B4883142B5A}{} { \subsection{\textcolor{Chapter }{RelationLatticeOfUnits}} \logpage{[ 2, 4, 1 ]}\nobreak \hyperdef{L}{X82B056EC85CF150D}{} {\noindent\textcolor{FuncColor}{$\triangleright$\enspace\texttt{RelationLatticeOfUnits({\mdseries\slshape F, elms})\index{RelationLatticeOfUnits@\texttt{RelationLatticeOfUnits}} \label{RelationLatticeOfUnits} }\hfill{\scriptsize (function)}}\\ Determines a basis for the relation lattice of the units \mbox{\texttt{\mdseries\slshape elms}} in triangularized form. Note that this method is more efficient than the method \texttt{RelationLattice}. } \subsection{\textcolor{Chapter }{IntersectionOfUnitSubgroups}} \logpage{[ 2, 4, 2 ]}\nobreak \hyperdef{L}{X7B8C89C980CB15F7}{} {\noindent\textcolor{FuncColor}{$\triangleright$\enspace\texttt{IntersectionOfUnitSubgroups({\mdseries\slshape F, gen1, gen2})\index{IntersectionOfUnitSubgroups@\texttt{IntersectionOfUnitSubgroups}} \label{IntersectionOfUnitSubgroups} }\hfill{\scriptsize (function)}}\\ The lists \mbox{\texttt{\mdseries\slshape gen1}} and \mbox{\texttt{\mdseries\slshape gen2}} are supposed to generate two subgroups $U_1$ and $U_2$ of the unit group of \mbox{\texttt{\mdseries\slshape F}}. This function determines the intersection of $U_1$ with $U_2$. The result is returned as a list of vectors generating the lattice $\{ e \in {\ensuremath{\mathbb Z}}^n \mid g_1^{e_1} \cdots g_n^{e_n} \in U_2 \}$ for \mbox{\texttt{\mdseries\slshape gen1}} = $[g_1, \ldots, g_n]$. For efficiency reasons this function does not check the input and it may return wrong results if the input generators do not fulfil the requirements. } } \section{\textcolor{Chapter }{Factorisation of polynomials over a number field}}\label{Factorisation of polynomials over a number field} \logpage{[ 2, 5, 0 ]} \hyperdef{L}{X7F656B217EF114DA}{} { \subsection{\textcolor{Chapter }{FactorsPolynomialAlgExt}} \logpage{[ 2, 5, 1 ]}\nobreak \hyperdef{L}{X815A5FBE805119CC}{} {\noindent\textcolor{FuncColor}{$\triangleright$\enspace\texttt{FactorsPolynomialAlgExt({\mdseries\slshape F, pol})\index{FactorsPolynomialAlgExt@\texttt{FactorsPolynomialAlgExt}} \label{FactorsPolynomialAlgExt} }\hfill{\scriptsize (function)}}\\ embeds the rational polynomial \mbox{\texttt{\mdseries\slshape pol}} into the polynomial ring over the number field \mbox{\texttt{\mdseries\slshape F}}, which has to be constructed by \texttt{FieldByPolynomial} or \texttt{AlgebraicExtension}, and returns the factorization of the embedded polynomial. By default \mbox{\texttt{\mdseries\slshape a}} denotes the primitive element of the field one can obtain from \texttt{PrimitiveElement(\mbox{\texttt{\mdseries\slshape F}})}, that is, a root of the defining polynomial of \mbox{\texttt{\mdseries\slshape F}}. } \subsection{\textcolor{Chapter }{FactorsPolynomialAlnuth}} \logpage{[ 2, 5, 2 ]}\nobreak \hyperdef{L}{X7CC3F0458523CB22}{} {\noindent\textcolor{FuncColor}{$\triangleright$\enspace\texttt{FactorsPolynomialAlnuth({\mdseries\slshape pol})\index{FactorsPolynomialAlnuth@\texttt{FactorsPolynomialAlnuth}} \label{FactorsPolynomialAlnuth} }\hfill{\scriptsize (function)}}\\ takes a polynomial \mbox{\texttt{\mdseries\slshape pol}} defined over an algebraic extension of the Rationals and factors it using the external CAS (PARI/GP or OSCAR). The alias \texttt{FactorsPolynomialPari} is provided for backwards compatibility. \begin{Verbatim}[commandchars=@|C,fontsize=\small,frame=single,label=Example] @gapprompt|gap>C @gapinput|x := Indeterminate( Rationals, "x" );;C @gapprompt|gap>C @gapinput|pol := 2*x^7+2*x^5+8*x^4+8*x^2;C 2*x^7+2*x^5+8*x^4+8*x^2 @gapprompt|gap>C @gapinput|L := FieldByPolynomial( x^3-4 );C @gapprompt|gap>C @gapinput|y := Indeterminate( L, "y" );;C @gapprompt|gap>C @gapinput|FactorsPolynomialAlgExt( L, pol );C [ !2*y, y, y+a, y^2+!1, y^2+(-a)*y+a^2 ] @gapprompt|gap>C @gapinput|FactorsPolynomialAlnuth( last[5] );C [ y^2+(-a)*y+a^2 ] \end{Verbatim} } } \section{\textcolor{Chapter }{Examples}}\label{Examples} \logpage{[ 2, 6, 0 ]} \hyperdef{L}{X7A489A5D79DA9E5C}{} { \subsection{\textcolor{Chapter }{ExampleMatField}} \logpage{[ 2, 6, 1 ]}\nobreak \hyperdef{L}{X7B4AE27B7BB8A9ED}{} {\noindent\textcolor{FuncColor}{$\triangleright$\enspace\texttt{ExampleMatField({\mdseries\slshape l})\index{ExampleMatField@\texttt{ExampleMatField}} \label{ExampleMatField} }\hfill{\scriptsize (function)}}\\ This function returns some examples of fields generated by matrices. There are 9 such example fields provided and they can be obtained by assigning the input \mbox{\texttt{\mdseries\slshape l}} to an integer between 1 and 9. Some of the properties of the examples are summarized in the following table. \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] degree over Q number of generators dim. of generators ExampleMatField(1) 4 4 4 ExampleMatField(2) 4 4 4 ExampleMatField(3) 4 4 4 ExampleMatField(4) 4 13 4 ExampleMatField(5) 4 13 4 ExampleMatField(6) 4 7 4 ExampleMatField(7) 4 18 4 ExampleMatField(8) 4 13 4 ExampleMatField(9) 4 7 4 \end{Verbatim} } } } \chapter{\textcolor{Chapter }{An example application}}\label{An example application} \logpage{[ 3, 0, 0 ]} \hyperdef{L}{X81CAD2F27B2066C4}{} { In this section we outline two example computations with the functions of the previous chapter. The first example uses number fields defined by matrices and the second example considers number fields defined by a polynomial. \section{\textcolor{Chapter }{Number fields defined by matrices}}\label{Number fields defined by matrices} \logpage{[ 3, 1, 0 ]} \hyperdef{L}{X7981DB6C79742C4C}{} { \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@m1 := [ [ 1, 0, 0, -7 ], | !gapprompt@>| !gapinput@ [ 7, 1, 0, -7 ], | !gapprompt@>| !gapinput@ [ 0, 7, 1, -7 ], | !gapprompt@>| !gapinput@ [ 0, 0, 7, -6 ] ];;| # !gapprompt@gap>| !gapinput@m2 := [ [ 0, 0, -13, 14 ], | !gapprompt@>| !gapinput@ [ -1, 0, -13, 1 ], | !gapprompt@>| !gapinput@ [ 13, -1, -13, 1 ], | !gapprompt@>| !gapinput@ [ 0, 13, -14, 1 ] ];;| # !gapprompt@gap>| !gapinput@F := FieldByMatricesNC( [m1, m2] );| # !gapprompt@gap>| !gapinput@DegreeOverPrimeField(F);| 4 !gapprompt@gap>| !gapinput@PrimitiveElement(F);| [ [ 0, -1, 1, 0 ], [ 0, -1, 0, 1 ], [ 0, -1, 0, 0 ], [ 1, -1, 0, 0 ] ] # !gapprompt@gap>| !gapinput@Basis(F);| Basis( , [ [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ], [ [ 0, 1, 0, 0 ], [ -1, 1, 1, 0 ], [ -1, 0, 1, 1 ], [ -1, 0, 0, 1 ] ], [ [ 0, 0, 1, 0 ], [ -1, 0, 1, 1 ], [ -1, -1, 1, 1 ], [ 0, -1, 0, 1 ] ], [ [ 0, 0, 0, 1 ], [ -1, 0, 0, 1 ], [ 0, -1, 0, 1 ], [ 0, 0, -1, 1 ] ] ] ) # !gapprompt@gap>| !gapinput@MaximalOrderBasis(F);| Basis( , [ [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ], [ [ 0, -1, 1, 0 ], [ 0, -1, 0, 1 ], [ 0, -1, 0, 0 ], [ 1, -1, 0, 0 ] ], [ [ 0, 0, 0, -1 ], [ 1, 0, 0, -1 ], [ 0, 1, 0, -1 ], [ 0, 0, 1, -1 ] ], [ [ -1, 1, 0, 0 ], [ -1, 0, 1, 0 ], [ -1, 0, 0, 1 ], [ -1, 0, 0, 0 ] ] ] ) # !gapprompt@gap>| !gapinput@U := UnitGroup(F);| # !gapprompt@gap>| !gapinput@u := GeneratorsOfGroup( U );;| # !gapprompt@gap>| !gapinput@nat := IsomorphismPcpGroup(U);;| !gapprompt@gap>| !gapinput@H := Image(nat);| Pcp-group with orders [ 10, 0 ] !gapprompt@gap>| !gapinput@ImageElm( nat, u[1] );| g1 !gapprompt@gap>| !gapinput@ImageElm( nat, u[2] );| g2 !gapprompt@gap>| !gapinput@ImageElm( nat, u[1]*u[2] );| g1*g2 !gapprompt@gap>| !gapinput@u[1] = PreImagesRepresentative(nat, GeneratorsOfGroup(H)[1] );| true \end{Verbatim} } \section{\textcolor{Chapter }{Number fields defined by a polynomial}}\label{Number fields defined by a polynomial} \logpage{[ 3, 2, 0 ]} \hyperdef{L}{X85ADC6A27B26C804}{} { \begin{Verbatim}[commandchars=@|D,fontsize=\small,frame=single,label=Example] @gapprompt|gap>D @gapinput|g := UnivariatePolynomial( Rationals, [ 16, 64, -28, -4, 1 ] );D x^4-4*x^3-28*x^2+64*x+16 # @gapprompt|gap>D @gapinput|F := FieldByPolynomialNC(g);D @gapprompt|gap>D @gapinput|PrimitiveElement(F);D a @gapprompt|gap>D @gapinput|MaximalOrderBasis(F);D Basis( , [ !1, 1/2*a, 1/4*a^2, 1/56*a^3+1/14*a^2+1/14*a-2/7 ] ) # @gapprompt|gap>D @gapinput|U := UnitGroup(F);D # @gapprompt|gap>D @gapinput|natU := IsomorphismPcpGroup(U);;D @gapprompt|gap>D @gapinput|elms := List( [1..10], x-> Random(F) );;D # @gapprompt|gap>D @gapinput| PcpPresentationOfMultiplicativeSubgroup( F, elms );D Pcp-group with orders [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] # @gapprompt|gap>D @gapinput|isom := IsomorphismPcpGroup( F, elms );;D @gapprompt|gap>D @gapinput|y := RandomGroupElement( elms );;D @gapprompt|gap>D @gapinput|z := ImageElm( isom, y );;D @gapprompt|gap>D @gapinput|y = PreImagesRepresentative( isom, z );D true # @gapprompt|gap>D @gapinput|FactorsPolynomialAlgExt( F, g );D [ x_1+(-a), x_1+(a-2), x_1+(-1/7*a^3+3/7*a^2+31/7*a-40/7), x_1+(1/7*a^3-3/7*a^2-31/7*a+26/7) ] \end{Verbatim} } } \chapter{\textcolor{Chapter }{Installation}}\label{Installation} \logpage{[ 4, 0, 0 ]} \hyperdef{L}{X8360C04082558A12}{} { This package provides an interface between \textsf{GAP} and either PARI/GP or OSCAR. When \textsf{Alnuth} is loaded in \textsf{GAP} running inside OSCAR, it automatically uses OSCAR. Otherwise, \textsf{Alnuth} uses PARI/GP, which has to be obtained and installed independently of this package. \textsf{Alnuth} works with PARI/GP Version 2.5 or higher. \section{\textcolor{Chapter }{Installing Alnuth}}\label{Installing Alnuth} \logpage{[ 4, 1, 0 ]} \hyperdef{L}{X821B9C2D817C0BE7}{} { The package \textsf{Alnuth} is part of the standard distribution of \textsf{GAP} so that in most cases there is no need to install it separately. If you are using \textsf{GAP} inside OSCAR, then \textsf{Alnuth} is already bundled and automatically uses OSCAR, so no further installation is required. Otherwise, to use \textsf{Alnuth} you need to have PARI/GP installed. See the following section for information on PARI/GP. In case you want to update \textsf{Alnuth} independently of your main \textsf{GAP} installation or if you are interested in an old version of \textsf{Alnuth} interfacing to KANT/KASH you can find all released versions of \textsf{Alnuth} in the form of gzipped tar\texttt{\symbol{45}}archives at \href{https://github.com/gap-packages/alnuth/releases} {\texttt{https://github.com/gap\texttt{\symbol{45}}packages/alnuth/releases}} There are two ways of installing a \textsf{GAP} package. If you have permission to add files to the installation of \textsf{GAP} on your system you may install \textsf{Alnuth} into the \texttt{pkg} subdirectory of the \textsf{GAP} installation tree. Otherwise you may install \textsf{Alnuth} in a private \texttt{pkg} directory (for details see Subsections (\textbf{Reference: Installing a GAP Package}) and (\textbf{Reference: GAP Root Directories}) in the \textsf{GAP} reference manual). To install the latest version of \textsf{Alnuth} download one of the archives \texttt{alnuth.tar.gz}, move it to the directory \texttt{pkg} in which you want to install, and unpack the archive. If you are using the command line you can unpack with the command \texttt{tar xzf alnuth.tar.gz}. } \section{\textcolor{Chapter }{Getting PARI/GP}}\label{Getting PARI/GP} \logpage{[ 4, 2, 0 ]} \hyperdef{L}{X83B28FDC7FACCE51}{} { Using \textsf{Alnuth} outside OSCAR requires an installation of PARI/GP in Version 2.5 or higher. The software PARI/GP is freely available at \href{https://pari.math.u-bordeaux.fr/} {\texttt{https://pari.math.u\texttt{\symbol{45}}bordeaux.fr/}} Note that the place where PARI/GP is located in your system is independent of the place where \textsf{Alnuth} is installed. \begin{enumerate} \item \emph{Installing under Linux} In many Linux distributions PARI/GP can be installed via the software package manager, but this might sometimes be an older version which cannot be used together with \textsf{Alnuth}. (Starting GP from the command line with the option \texttt{\texttt{\symbol{45}}\texttt{\symbol{45}}version\texttt{\symbol{45}}short} will show you the version number.) If you install PARI/GP from source make sure you install with GMP support for better performance and complete the installation with \texttt{make install} so that you can start GP by just calling \texttt{gp} from the command line. \item \emph{Installing under Windows} For Windows it is sufficient to get the basic GP binary which can be found at \href{https://pari.math.u-bordeaux.fr/download.html} {\texttt{https://pari.math.u\texttt{\symbol{45}}bordeaux.fr/download.html}} \end{enumerate} } \section{\textcolor{Chapter }{Adjust the path of the executable for GP}}\label{Adjust the path of the executable for GP} \logpage{[ 4, 3, 0 ]} \hyperdef{L}{X815DF28A87D65A3A}{} { When \textsf{Alnuth} is used outside OSCAR, it needs to know where the executable for GP is. In the default setting \textsf{Alnuth} looks for an executable program named \texttt{gp} in the search paths of the system. More precisely, for a file \texttt{gp} inside one of the directories in the list returned by \texttt{DirectoriesSystemPrograms()} (called in a \textsf{GAP} session). Under Linux the default setting should work with a standard installation of PARI/GP. For the default setting to work under Windows the downloaded executable file, for example \texttt{gp\texttt{\symbol{45}}2\texttt{\symbol{45}}5\texttt{\symbol{45}}0.exe} has to be renamed to \texttt{gp.exe} and moved to one of the directories listed by \texttt{DirectoriesSystemPrograms()} (Ignore the leading \texttt{cygdrive} in each path name and note that the single letter specifies the drive, for example \texttt{/cygdrive/c/Windows/} denotes the folder \texttt{Windows} on drive \texttt{C:}). To check whether an executable of GP in Version 2.5 or higher is available with the default setting, you can use the function \subsection{\textcolor{Chapter }{PariVersion}} \logpage{[ 4, 3, 1 ]}\nobreak \hyperdef{L}{X84E2E83F8251DC49}{} {\noindent\textcolor{FuncColor}{$\triangleright$\enspace\texttt{PariVersion({\mdseries\slshape })\index{PariVersion@\texttt{PariVersion}} \label{PariVersion} }\hfill{\scriptsize (function)}}\\ which prints the version number, if the user preference \texttt{PariGpPath} refers to a usable GP executable. } If you cannot use the default setting for you purpose, you have several ways to configure Alnuth. The recommended approach is to use the \textsf{GAP} user preference system: \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@SetUserPreference("alnuth", "PariGpPath", "/home/my/pari-2.5.0/gp");| !gapprompt@gap>| !gapinput@SetUserPreference("alnuth", "PariStackSize", 256);| !gapprompt@gap>| !gapinput@WriteGapIniFile();| \end{Verbatim} This changes the current session immediately. \texttt{WriteGapIniFile()} writes the current non\texttt{\symbol{45}}default settings to your personal \texttt{gap.ini}, so they are used again in future \textsf{GAP} sessions. See (\textbf{Reference: Configuring User preferences}) for background on the user preference system. The user preferences relevant for Alnuth are shown by \texttt{ShowUserPreferences("alnuth");}. The most important ones are \texttt{PariGpPath}, \texttt{PariGpOptions}, \texttt{PariStackSize}, and \texttt{PrimitiveElementTrials}. In older versions of \textsf{Alnuth} configuration was done via the global variables \texttt{AL{\textunderscore}EXECUTABLE}, \texttt{AL{\textunderscore}PATH}, \texttt{AL{\textunderscore}OPTIONS}, \texttt{AL{\textunderscore}STACKSIZE}, and \texttt{PRIM{\textunderscore}TEST}. These globals are deprecated, and they trigger a warning when used. The globals except for \texttt{AL{\textunderscore}PATH} still serve as a fallback if the corresponding user preference is unusable. Their replacements are as follows: \begin{description} \item[{\texttt{AL{\textunderscore}EXECUTABLE}}] use the user preference \texttt{PariGpPath} \item[{\texttt{AL{\textunderscore}OPTIONS}}] use the user preference \texttt{PariGpOptions} \item[{\texttt{AL{\textunderscore}STACKSIZE}}] use the user preference \texttt{PariStackSize} \item[{\texttt{PRIM{\textunderscore}TEST}}] use the user preference \texttt{PrimitiveElementTrials} \item[{\texttt{AL{\textunderscore}PATH}}] has been removed; Alnuth now always uses the bundled GP helper files. \end{description} For backwards compatibility, the following functions still exist after loading the package (see Section \ref{Loading and testing the package}), but they are deprecated wrappers around the user preference system. \subsection{\textcolor{Chapter }{SetAlnuthExternalExecutable}} \logpage{[ 4, 3, 2 ]}\nobreak \hyperdef{L}{X7F2835FB7C5069DD}{} {\noindent\textcolor{FuncColor}{$\triangleright$\enspace\texttt{SetAlnuthExternalExecutable({\mdseries\slshape path})\index{SetAlnuthExternalExecutable@\texttt{SetAlnuthExternalExecutable}} \label{SetAlnuthExternalExecutable} }\hfill{\scriptsize (function)}}\\ sets the user preference \texttt{PariGpPath} for the current \textsf{GAP} session. Depending on your installation of PARI/GP and your operating system the string \mbox{\texttt{\mdseries\slshape path}} can be either the command to start GP in a terminal (for example \texttt{gp}) or the complete path to the executable of GP. The function is deprecated; new code should call \texttt{SetUserPreference("alnuth", "PariGpPath", path);} directly. The function returns the stored preference value. } \subsection{\textcolor{Chapter }{SetAlnuthExternalExecutablePermanently}} \logpage{[ 4, 3, 3 ]}\nobreak \hyperdef{L}{X81CD0C70812FC6F3}{} {\noindent\textcolor{FuncColor}{$\triangleright$\enspace\texttt{SetAlnuthExternalExecutablePermanently({\mdseries\slshape path})\index{SetAlnuthExternalExecutablePermanently@\texttt{Set}\-\texttt{Alnuth}\-\texttt{External}\-\texttt{Executable}\-\texttt{Permanently}} \label{SetAlnuthExternalExecutablePermanently} }\hfill{\scriptsize (function)}}\\ does the same as \texttt{SetAlnuthExternalExecutable} and then calls \texttt{WriteGapIniFile()} to persist the current user preference settings in your personal \texttt{gap.ini}. The function is deprecated; new code should call \texttt{SetUserPreference("alnuth", "PariGpPath", path); WriteGapIniFile();} instead. } \subsection{\textcolor{Chapter }{RestoreAlnuthExternalExecutablePermanently}} \logpage{[ 4, 3, 4 ]}\nobreak \hyperdef{L}{X7F648B427EB19552}{} {\noindent\textcolor{FuncColor}{$\triangleright$\enspace\texttt{RestoreAlnuthExternalExecutablePermanently({\mdseries\slshape })\index{RestoreAlnuthExternalExecutablePermanently@\texttt{Restore}\-\texttt{Alnuth}\-\texttt{External}\-\texttt{Executable}\-\texttt{Permanently}} \label{RestoreAlnuthExternalExecutablePermanently} }\hfill{\scriptsize (function)}}\\ restores the default value of \texttt{PariGpPath} and then calls \texttt{WriteGapIniFile()}. The function is deprecated; new code should set \texttt{PariGpPath} to the desired default command or path and then call \texttt{WriteGapIniFile()} directly. } } \section{\textcolor{Chapter }{Loading and testing the package}}\label{Loading and testing the package} \logpage{[ 4, 4, 0 ]} \hyperdef{L}{X781C2F107F76F8A4}{} { If \textsf{Alnuth} is not loaded when GAP is started you have to request it explicitly to use it. This is done by calling \texttt{LoadPackage("alnuth");} in a GAP session. If \textsf{Alnuth} had not been loaded already a short banner will be displayed. \begin{Verbatim}[commandchars=!|F,fontsize=\small,frame=single,label=Example] !gapprompt|gap>F !gapinput|LoadPackage("alnuth");F Loading Alnuth 4.0.0 (ALgebraic NUmber THeory and an interface to PARI/GP and OSCAR) by Björn Assmann, Andreas Distler (a.distler@tu-bs.de), and Bettina Eick (http://www.iaa.tu-bs.de/beick). maintained by: Max Horn (https://www.quendi.de/math) and The GAP Team (support@gap-system.org). Homepage: https://gap-packages.github.io/alnuth Report issues at https://github.com/gap-packages/alnuth/issues true gap> \end{Verbatim} To load a certain version of \textsf{Alnuth} you can specify the version number as second argument in the call to \texttt{LoadPackage}. (See \texttt{LoadPackage} (\textbf{Reference: LoadPackage}) in the \textsf{GAP} reference manual or type \texttt{?LoadPackage} within a GAP session). Once the package is loaded, it is possible to check the correct installation running a short test by calling \texttt{ReadPackage("Alnuth", "tst/testinstall.tst");}. \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@ReadPackage("Alnuth", "tst/testinstall.g");| Architecture: aarch64-apple-darwin21.4.0-default64-kv8 testing: GAPROOT/pkg/alnuth/tst/ALNUTH.tst 66 ms (33 ms GC) and 11.0MB allocated for GAPROOT/pkg/alnuth/tst/ALNUTH.tst testing: GAPROOT/pkg/alnuth/tst/version.tst 21 ms (21 ms GC) and 29.6KB allocated for GAPROOT/pkg/alnuth/tst/version.tst ----------------------------------- total 87 ms (54 ms GC) and 11.0MB allocated 0 failures in 2 files #I No errors detected while testing gap> \end{Verbatim} The architecture, timings and memory usage will usually differ; other discrepancies in the output indicate some problem. If the test suite runs into an error in the first part, which when running outside OSCAR verifies the availability of PARI/GP, check your installation of PARI/GP and consult the last chapter of the documentation of \textsf{Alnuth} for more information. If you find any bugs or have any suggestions or comments, we would very much appreciate it if you would let us know by submitting an issue at the \textsf{Alnuth} issue tracker on GitHub \href{https://github.com/gap-packages/alnuth/issues} {\texttt{https://github.com/gap\texttt{\symbol{45}}packages/alnuth/issues}} or by writing an mail to \href{mailto://support@gap-system.org} {\texttt{support@gap\texttt{\symbol{45}}system.org}}. } } {\nobreakspace} \def\bibname{References\logpage{[ "Bib", 0, 0 ]} \hyperdef{L}{X7A6F98FD85F02BFE}{} } \bibliographystyle{alpha} \bibliography{manual.bib} \addcontentsline{toc}{chapter}{References} \def\indexname{Index\logpage{[ "Ind", 0, 0 ]} \hyperdef{L}{X83A0356F839C696F}{} } \cleardoublepage \phantomsection \addcontentsline{toc}{chapter}{Index} \printindex \immediate\write\pagenrlog{["Ind", 0, 0], \arabic{page},} \newpage \immediate\write\pagenrlog{["End"], \arabic{page}];} \immediate\closeout\pagenrlog \end{document} alnuth-4.0.0/doc/_main.xml0000644000000000000000000000073715201210200012274 0ustar00 ] > <#Include SYSTEM "title.xml"> <#Include SYSTEM "intro.xml"> <#Include SYSTEM "fields.xml"> <#Include SYSTEM "example.xml"> <#Include SYSTEM "install.xml"> <#Include SYSTEM "_AutoDocMainFile.xml"> alnuth-4.0.0/doc/chap0.html0000644000000000000000000002517315201210200012351 0ustar00 GAP (Alnuth) - Contents
Goto Chapter: Top 1 2 3 4 Bib Ind

Alnuth

ALgebraic NUmber THeory and an interface to PARI/GP and OSCAR

4.0.0

14 May 2026

Note: PARI/GP is not part of this package. It can be obtained from https://pari.math.u-bordeaux.fr/. If you use GAP via OSCAR, then OSCAR will automatically be used instead of PARI/GP.

GAP code by Björn Assmann, Andreas Distler and Bettina Eick

PARI/GP code by Bill Allombert

OSCAR code by Claus Fieker and Max Horn

Copyright

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, see https://www.gnu.org/licenses/

Acknowledgements

To begin with we are very grateful for all the feedback by users of former versions of Alnuth.

We thank Bill Allombert who wrote the GP code for the interface to PARI/GP and who was extremely helpful in the transition from KANT to PARI/GP.

For feedback on the development version, including a code patch, we are much obliged to Max Horn.

The second author acknowledges the financial support at CAUL within the projects PTDC/MAT/101993/2008 and ISFL-1-143, financed by FEDER and FCT, in the development of Version 3 of Alnuth.

Support for using OSCAR instead of PARI/GP was added by Claus Fieker and Max Horn.

Goto Chapter: Top 1 2 3 4 Bib Ind

generated by GAPDoc2HTML

alnuth-4.0.0/doc/chap0.txt0000644000000000000000000001011315201210200012210 0ustar00  Alnuth   ALgebraic NUmber THeory and an interface to PARI/GP and OSCAR  4.0.0 14 May 2026 GAP code by Björn Assmann, Andreas Distler and Bettina Eick PARI/GP code by Bill Allombert OSCAR code by Claus Fieker and Max Horn Note: PARI/GP is not part of this package. It can be obtained from https://pari.math.u-bordeaux.fr/. If you use GAP via OSCAR, then OSCAR will automatically be used instead of PARI/GP. ------------------------------------------------------- Copyright 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, see https://www.gnu.org/licenses/ ------------------------------------------------------- Acknowledgements To begin with we are very grateful for all the feedback by users of former versions of Alnuth. We thank Bill Allombert who wrote the GP code for the interface to PARI/GP and who was extremely helpful in the transition from KANT to PARI/GP. For feedback on the development version, including a code patch, we are much obliged to Max Horn. The second author acknowledges the financial support at CAUL within the projects PTDC/MAT/101993/2008 and ISFL-1-143, financed by FEDER and FCT, in the development of Version 3 of Alnuth. Support for using OSCAR instead of PARI/GP was added by Claus Fieker and Max Horn. ------------------------------------------------------- Contents (Alnuth) 1 Introduction 2 Working with number fields 2.1 Creation of number fields 2.1-1 FieldByMatricesNC 2.1-2 FieldByMatrixBasisNC 2.1-3 FieldByPolynomialNC 2.2 Methods for number fields 2.2-1 PrimitiveElement 2.2-2 IsPrimitiveElementOfNumberField 2.2-3 DegreeOverPrimeField 2.2-4 EquationOrderBasis 2.2-5 UnitGroup 2.2-6 IsUnitOfNumberField 2.2-7 ExponentsOfUnits 2.2-8 IsCyclotomicField 2.2-9 NormCosetsOfNumberField 2.3 Presentations of multiplicative subgroups 2.3-1 PcpPresentationOfMultiplicativeSubgroup 2.3-2 RelationLattice 2.4 Methods to compute with subgroups of the unit group 2.4-1 RelationLatticeOfUnits 2.4-2 IntersectionOfUnitSubgroups 2.5 Factorisation of polynomials over a number field 2.5-1 FactorsPolynomialAlgExt 2.5-2 FactorsPolynomialAlnuth 2.6 Examples 2.6-1 ExampleMatField 3 An example application 3.1 Number fields defined by matrices 3.2 Number fields defined by a polynomial 4 Installation 4.1 Installing Alnuth 4.2 Getting PARI/GP 4.3 Adjust the path of the executable for GP 4.3-1 PariVersion 4.3-2 SetAlnuthExternalExecutable 4.3-3 SetAlnuthExternalExecutablePermanently 4.3-4 RestoreAlnuthExternalExecutablePermanently 4.4 Loading and testing the package  alnuth-4.0.0/doc/chap0_mj.html0000644000000000000000000002566115201210200013041 0ustar00 GAP (Alnuth) - Contents
Goto Chapter: Top 1 2 3 4 Bib Ind

Alnuth

ALgebraic NUmber THeory and an interface to PARI/GP and OSCAR

4.0.0

14 May 2026

Note: PARI/GP is not part of this package. It can be obtained from https://pari.math.u-bordeaux.fr/. If you use GAP via OSCAR, then OSCAR will automatically be used instead of PARI/GP.

GAP code by Björn Assmann, Andreas Distler and Bettina Eick

PARI/GP code by Bill Allombert

OSCAR code by Claus Fieker and Max Horn

Copyright

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, see https://www.gnu.org/licenses/

Acknowledgements

To begin with we are very grateful for all the feedback by users of former versions of Alnuth.

We thank Bill Allombert who wrote the GP code for the interface to PARI/GP and who was extremely helpful in the transition from KANT to PARI/GP.

For feedback on the development version, including a code patch, we are much obliged to Max Horn.

The second author acknowledges the financial support at CAUL within the projects PTDC/MAT/101993/2008 and ISFL-1-143, financed by FEDER and FCT, in the development of Version 3 of Alnuth.

Support for using OSCAR instead of PARI/GP was added by Claus Fieker and Max Horn.

Goto Chapter: Top 1 2 3 4 Bib Ind

generated by GAPDoc2HTML

alnuth-4.0.0/doc/chap1.html0000644000000000000000000001017215201210200012343 0ustar00 GAP (Alnuth) - Chapter 1: Introduction
Goto Chapter: Top 1 2 3 4 Bib Ind

1 Introduction

A number field is a finite extension of the field of rational numbers. Alnuth provides various methods to compute with number fields which are given by a defining polynomial or by generators. For background on number fields we refer to [ST79].

Some of the methods provided in this package are written in GAP code. The other part of the methods is imported from the Computer Algebra Systems PARI/GP [PAR11] respectively OSCAR [DEF+25], [OSC24]. Hence this package contains some GAP functions and an interface to some functions to these computer algebra systems. Therefore one has to have PARI/GP or OSCAR installed to use the full functionality of Alnuth.

We note that only a very small part of the functions available in PARI/GP respectively OSCAR are linked to GAP and they provides many more methods for computations in number fields.

The main methods included in Alnuth are: creating a number field, computing its maximal order, computing its unit group and a presentation of this unit group, computing the elements of a given norm of the number field, determining a presentation for a finitely generated multiplicative subgroup, and factoring polynomials defined over number fields. For background on algorithms for number fields we refer to [Poh93], [PZ89] and [Coh93].

The functions provided by Alnuth are introduced in the following chapter. Then an example application is outlined. In the final chapter of this manual the installation of the package and configuration of the interface, including hints on the installation of PARI/GP respectively OSCAR, are described.

Goto Chapter: Top 1 2 3 4 Bib Ind

generated by GAPDoc2HTML

alnuth-4.0.0/doc/chap1.txt0000644000000000000000000000360115201210200012215 0ustar00 1 Introduction A number field is a finite extension of the field of rational numbers. Alnuth provides various methods to compute with number fields which are given by a defining polynomial or by generators. For background on number fields we refer to [ST79]. Some of the methods provided in this package are written in GAP code. The other part of the methods is imported from the Computer Algebra Systems PARI/GP [PAR11] respectively OSCAR [DEF+25], [OSC24]. Hence this package contains some GAP functions and an interface to some functions to these computer algebra systems. Therefore one has to have PARI/GP or OSCAR installed to use the full functionality of Alnuth. We note that only a very small part of the functions available in PARI/GP respectively OSCAR are linked to GAP and they provides many more methods for computations in number fields. The main methods included in Alnuth are: creating a number field, computing its maximal order, computing its unit group and a presentation of this unit group, computing the elements of a given norm of the number field, determining a presentation for a finitely generated multiplicative subgroup, and factoring polynomials defined over number fields. For background on algorithms for number fields we refer to [Poh93], [PZ89] and [Coh93]. The functions provided by Alnuth are introduced in the following chapter. Then an example application is outlined. In the final chapter of this manual the installation of the package and configuration of the interface, including hints on the installation of PARI/GP respectively OSCAR, are described. alnuth-4.0.0/doc/chap1_mj.html0000644000000000000000000001052315201210200013031 0ustar00 GAP (Alnuth) - Chapter 1: Introduction
Goto Chapter: Top 1 2 3 4 Bib Ind

1 Introduction

A number field is a finite extension of the field of rational numbers. Alnuth provides various methods to compute with number fields which are given by a defining polynomial or by generators. For background on number fields we refer to [ST79].

Some of the methods provided in this package are written in GAP code. The other part of the methods is imported from the Computer Algebra Systems PARI/GP [PAR11] respectively OSCAR [DEF+25], [OSC24]. Hence this package contains some GAP functions and an interface to some functions to these computer algebra systems. Therefore one has to have PARI/GP or OSCAR installed to use the full functionality of Alnuth.

We note that only a very small part of the functions available in PARI/GP respectively OSCAR are linked to GAP and they provides many more methods for computations in number fields.

The main methods included in Alnuth are: creating a number field, computing its maximal order, computing its unit group and a presentation of this unit group, computing the elements of a given norm of the number field, determining a presentation for a finitely generated multiplicative subgroup, and factoring polynomials defined over number fields. For background on algorithms for number fields we refer to [Poh93], [PZ89] and [Coh93].

The functions provided by Alnuth are introduced in the following chapter. Then an example application is outlined. In the final chapter of this manual the installation of the package and configuration of the interface, including hints on the installation of PARI/GP respectively OSCAR, are described.

Goto Chapter: Top 1 2 3 4 Bib Ind

generated by GAPDoc2HTML

alnuth-4.0.0/doc/chap2.html0000644000000000000000000005673315201210200012361 0ustar00 GAP (Alnuth) - Chapter 2: Working with number fields
Goto Chapter: Top 1 2 3 4 Bib Ind

2 Working with number fields

An algebraic number field is a finite-dimensional extension of the rational numbers . Such a number field has a primitive element and it can be defined by the minimal polynomial of this primitive element. Another important way to define an algebraic number field is by a set of rational matrices which generate a number field.

2.1 Creation of number fields

We provide functions to create number fields defined by rational matrices or by rational polynomials.

2.1-1 FieldByMatricesNC
‣ FieldByMatricesNC( matrices )( function )
‣ FieldByMatrices( matrices )( function )

Creates a field generated by the rational matrices matrices. In the faster NC version, the function assumes that the input generates a field and there are no checks on this performed.

2.1-2 FieldByMatrixBasisNC
‣ FieldByMatrixBasisNC( matrices )( function )
‣ FieldByMatrixBasis( matrices )( function )

Creates a field with basis matrices. The list matrices must consist of rational matrices which form a basis for a number field. In the faster NC version, the function assumes that the input is a matrix basis for a field and no checks are performed.

2.1-3 FieldByPolynomialNC
‣ FieldByPolynomialNC( polynomial )( function )
‣ FieldByPolynomial( polynomial )( function )

Creates a field defined by polynomial. The polynomial polynomial must be an irreducible rational polynomial. In the faster NC version, no checks on the input are performed.

2.2 Methods for number fields

We outline a number of functions for number fields.

2.2-1 PrimitiveElement
‣ PrimitiveElement( F )( function )
‣ DefiningPolynomial( F )( function )

Computes a primitive element and a defining polynomial for the given number field. The defining polynomial is the minimal polynomial of the primitive element. Since F contains various primitive elements, PrimitiveElement tries to find a primitive element which has a minimal polynomial with small coefficients. Via the user preference PrimitiveElementTrials the user can decide how many primitive elements will be compared. The default value is 20. (See SetUserPreference (Reference: SetUserPreference) for more information about user preferences.)

2.2-2 IsPrimitiveElementOfNumberField
‣ IsPrimitiveElementOfNumberField( F, a )( function )

Checks if the given element generates the field.

2.2-3 DegreeOverPrimeField
‣ DegreeOverPrimeField( F )( function )

Returns the degree of F over the rationals.

2.2-4 EquationOrderBasis
‣ EquationOrderBasis( F )( function )
‣ MaximalOrderBasis( F )( function )
‣ IsIntegerOfNumberField( F, k )( function )

These functions return bases for the equation order or the maximal order of the number field F. Also, they allow to check if a given element is an integer in the given number field.

2.2-5 UnitGroup
‣ UnitGroup( F )( function )

determines the unit group of F.

Recall that the unit group of F is a finitely generated abelian group. The function IsomorphismPcpGroup from the Polycyclic [EHN11] package gives an isomorphism to a pcp group which can be used for various computations with the unit group.

2.2-6 IsUnitOfNumberField
‣ IsUnitOfNumberField( F, k )( function )

checks whether the element k is a unit in F.

2.2-7 ExponentsOfUnits
‣ ExponentsOfUnits( F, elms )( function )

This function determines the exponent vectors of the elements in elms with respect to the generators of the unit group of F. If the unit group of F is not known, then the function computes this unit group also.

2.2-8 IsCyclotomicField
‣ IsCyclotomicField( F )( function )

Check whether F is cyclotomic.

2.2-9 NormCosetsOfNumberField
‣ NormCosetsOfNumberField( F, norm )( function )

Returns a description for the set of all elements of norm norm in F. These elements can be written as a finite union of cosets of the unit group of F. The function returns coset representatives for these cosets.

2.3 Presentations of multiplicative subgroups

Suppose that a finite number of invertible elements of a number field are given. Then these elements generate a finitely generated abelian group. However, it is a non-trivial task to provide a presentation for this abelian group. The most useful representation for such groups is as pcp group.

2.3-1 PcpPresentationOfMultiplicativeSubgroup
‣ PcpPresentationOfMultiplicativeSubgroup( F, elms )( function )
‣ IsomorphismPcpGroup( F, elms )( function )

Determine a pcp presentation for the multiplicative group of Fbackslash{0} generated by elms and an isomorphism on this presentation. Note, that the method IsomorphismPcpGroup is defined in the Polycyclic package [EHN11]. We refer to the manual of this package for further background.

In the determination of the Pcp-presentation of a multiplicative subgroup generated by elms the relations between the elements in elms play an important role. Let elms={e_1,dots,e_l} be a finite subset of a field F. The relation lattice for elms is

rl(elms):=\left\{(h_1,\dots,h_l) \in ℤ^l | e_1^{h_1} \cdots e_l^{h_l} = 1\right\} .

2.3-2 RelationLattice
‣ RelationLattice( F, elms )( function )

Determines a generating set for the relation lattice of the field elements elms.

2.4 Methods to compute with subgroups of the unit group

2.4-1 RelationLatticeOfUnits
‣ RelationLatticeOfUnits( F, elms )( function )

Determines a basis for the relation lattice of the units elms in triangularized form. Note that this method is more efficient than the method RelationLattice.

2.4-2 IntersectionOfUnitSubgroups
‣ IntersectionOfUnitSubgroups( F, gen1, gen2 )( function )

The lists gen1 and gen2 are supposed to generate two subgroups U_1 and U_2 of the unit group of F. This function determines the intersection of U_1 with U_2. The result is returned as a list of vectors generating the lattice { e ∈ ℤ^n ∣ g_1^e_1 ⋯ g_n^e_n ∈ U_2 } for gen1 = [g_1, ..., g_n].

For efficiency reasons this function does not check the input and it may return wrong results if the input generators do not fulfil the requirements.

2.5 Factorisation of polynomials over a number field

2.5-1 FactorsPolynomialAlgExt
‣ FactorsPolynomialAlgExt( F, pol )( function )

embeds the rational polynomial pol into the polynomial ring over the number field F, which has to be constructed by FieldByPolynomial or AlgebraicExtension, and returns the factorization of the embedded polynomial. By default a denotes the primitive element of the field one can obtain from PrimitiveElement(F), that is, a root of the defining polynomial of F.

2.5-2 FactorsPolynomialAlnuth
‣ FactorsPolynomialAlnuth( pol )( function )

takes a polynomial pol defined over an algebraic extension of the Rationals and factors it using the external CAS (PARI/GP or OSCAR).

The alias FactorsPolynomialPari is provided for backwards compatibility.

gap> x := Indeterminate( Rationals, "x" );;
gap> pol := 2*x^7+2*x^5+8*x^4+8*x^2;
2*x^7+2*x^5+8*x^4+8*x^2
gap> L := FieldByPolynomial( x^3-4 );
<algebraic extension over the Rationals of degree 3>
gap> y := Indeterminate( L, "y" );;
gap> FactorsPolynomialAlgExt( L, pol );
[ !2*y, y, y+a, y^2+!1, y^2+(-a)*y+a^2 ]
gap> FactorsPolynomialAlnuth( last[5] );
[ y^2+(-a)*y+a^2 ]

2.6 Examples

2.6-1 ExampleMatField
‣ ExampleMatField( l )( function )

This function returns some examples of fields generated by matrices. There are 9 such example fields provided and they can be obtained by assigning the input l to an integer between 1 and 9. Some of the properties of the examples are summarized in the following table.

                    degree over Q  number of generators  dim. of generators
ExampleMatField(1)              4                     4                   4
ExampleMatField(2)              4                     4                   4
ExampleMatField(3)              4                     4                   4
ExampleMatField(4)              4                    13                   4
ExampleMatField(5)              4                    13                   4
ExampleMatField(6)              4                     7                   4
ExampleMatField(7)              4                    18                   4
ExampleMatField(8)              4                    13                   4
ExampleMatField(9)              4                     7                   4
Goto Chapter: Top 1 2 3 4 Bib Ind

generated by GAPDoc2HTML

alnuth-4.0.0/doc/chap2.txt0000644000000000000000000002775515201210200012236 0ustar00 2 Working with number fields An algebraic number field is a finite-dimensional extension of the rational numbers ℚ. Such a number field has a primitive element and it can be defined by the minimal polynomial of this primitive element. Another important way to define an algebraic number field is by a set of rational matrices which generate a number field. 2.1 Creation of number fields We provide functions to create number fields defined by rational matrices or by rational polynomials. 2.1-1 FieldByMatricesNC FieldByMatricesNC( matrices )  function FieldByMatrices( matrices )  function Creates a field generated by the rational matrices matrices. In the faster NC version, the function assumes that the input generates a field and there are no checks on this performed. 2.1-2 FieldByMatrixBasisNC FieldByMatrixBasisNC( matrices )  function FieldByMatrixBasis( matrices )  function Creates a field with basis matrices. The list matrices must consist of rational matrices which form a basis for a number field. In the faster NC version, the function assumes that the input is a matrix basis for a field and no checks are performed. 2.1-3 FieldByPolynomialNC FieldByPolynomialNC( polynomial )  function FieldByPolynomial( polynomial )  function Creates a field defined by polynomial. The polynomial polynomial must be an irreducible rational polynomial. In the faster NC version, no checks on the input are performed. 2.2 Methods for number fields We outline a number of functions for number fields. 2.2-1 PrimitiveElement PrimitiveElement( F )  function DefiningPolynomial( F )  function Computes a primitive element and a defining polynomial for the given number field. The defining polynomial is the minimal polynomial of the primitive element. Since F contains various primitive elements, PrimitiveElement tries to find a primitive element which has a minimal polynomial with small coefficients. Via the user preference PrimitiveElementTrials the user can decide how many primitive elements will be compared. The default value is 20. (See SetUserPreference (Reference: SetUserPreference) for more information about user preferences.) 2.2-2 IsPrimitiveElementOfNumberField IsPrimitiveElementOfNumberField( F, a )  function Checks if the given element generates the field. 2.2-3 DegreeOverPrimeField DegreeOverPrimeField( F )  function Returns the degree of F over the rationals. 2.2-4 EquationOrderBasis EquationOrderBasis( F )  function MaximalOrderBasis( F )  function IsIntegerOfNumberField( F, k )  function These functions return bases for the equation order or the maximal order of the number field F. Also, they allow to check if a given element is an integer in the given number field. 2.2-5 UnitGroup UnitGroup( F )  function determines the unit group of F. Recall that the unit group of F is a finitely generated abelian group. The function IsomorphismPcpGroup from the Polycyclic [EHN11] package gives an isomorphism to a pcp group which can be used for various computations with the unit group. 2.2-6 IsUnitOfNumberField IsUnitOfNumberField( F, k )  function checks whether the element k is a unit in F. 2.2-7 ExponentsOfUnits ExponentsOfUnits( F, elms )  function This function determines the exponent vectors of the elements in elms with respect to the generators of the unit group of F. If the unit group of F is not known, then the function computes this unit group also. 2.2-8 IsCyclotomicField IsCyclotomicField( F )  function Check whether F is cyclotomic. 2.2-9 NormCosetsOfNumberField NormCosetsOfNumberField( F, norm )  function Returns a description for the set of all elements of norm norm in F. These elements can be written as a finite union of cosets of the unit group of F. The function returns coset representatives for these cosets. 2.3 Presentations of multiplicative subgroups Suppose that a finite number of invertible elements of a number field are given. Then these elements generate a finitely generated abelian group. However, it is a non-trivial task to provide a presentation for this abelian group. The most useful representation for such groups is as pcp group. 2.3-1 PcpPresentationOfMultiplicativeSubgroup PcpPresentationOfMultiplicativeSubgroup( F, elms )  function IsomorphismPcpGroup( F, elms )  function Determine a pcp presentation for the multiplicative group of Fbackslash{0} generated by elms and an isomorphism on this presentation. Note, that the method IsomorphismPcpGroup is defined in the Polycyclic package [EHN11]. We refer to the manual of this package for further background. In the determination of the Pcp-presentation of a multiplicative subgroup generated by elms the relations between the elements in elms play an important role. Let elms={e_1,dots,e_l} be a finite subset of a field F. The relation lattice for elms is rl(elms):=\left\{(h_1,\dots,h_l) \in ℤ^l | e_1^{h_1} \cdots e_l^{h_l} = 1\right\} .  2.3-2 RelationLattice RelationLattice( F, elms )  function Determines a generating set for the relation lattice of the field elements elms. 2.4 Methods to compute with subgroups of the unit group 2.4-1 RelationLatticeOfUnits RelationLatticeOfUnits( F, elms )  function Determines a basis for the relation lattice of the units elms in triangularized form. Note that this method is more efficient than the method RelationLattice. 2.4-2 IntersectionOfUnitSubgroups IntersectionOfUnitSubgroups( F, gen1, gen2 )  function The lists gen1 and gen2 are supposed to generate two subgroups U_1 and U_2 of the unit group of F. This function determines the intersection of U_1 with U_2. The result is returned as a list of vectors generating the lattice { e ∈ ℤ^n ∣ g_1^e_1 ⋯ g_n^e_n ∈ U_2 } for gen1 = [g_1, ..., g_n]. For efficiency reasons this function does not check the input and it may return wrong results if the input generators do not fulfil the requirements. 2.5 Factorisation of polynomials over a number field 2.5-1 FactorsPolynomialAlgExt FactorsPolynomialAlgExt( F, pol )  function embeds the rational polynomial pol into the polynomial ring over the number field F, which has to be constructed by FieldByPolynomial or AlgebraicExtension, and returns the factorization of the embedded polynomial. By default a denotes the primitive element of the field one can obtain from PrimitiveElement(F), that is, a root of the defining polynomial of F. 2.5-2 FactorsPolynomialAlnuth FactorsPolynomialAlnuth( pol )  function takes a polynomial pol defined over an algebraic extension of the Rationals and factors it using the external CAS (PARI/GP or OSCAR). The alias FactorsPolynomialPari is provided for backwards compatibility.  Example  gap> x := Indeterminate( Rationals, "x" );; gap> pol := 2*x^7+2*x^5+8*x^4+8*x^2; 2*x^7+2*x^5+8*x^4+8*x^2 gap> L := FieldByPolynomial( x^3-4 );  gap> y := Indeterminate( L, "y" );; gap> FactorsPolynomialAlgExt( L, pol ); [ !2*y, y, y+a, y^2+!1, y^2+(-a)*y+a^2 ] gap> FactorsPolynomialAlnuth( last[5] ); [ y^2+(-a)*y+a^2 ]  2.6 Examples 2.6-1 ExampleMatField ExampleMatField( l )  function This function returns some examples of fields generated by matrices. There are 9 such example fields provided and they can be obtained by assigning the input l to an integer between 1 and 9. Some of the properties of the examples are summarized in the following table.  Example   degree over Q number of generators dim. of generators ExampleMatField(1) 4 4 4 ExampleMatField(2) 4 4 4 ExampleMatField(3) 4 4 4 ExampleMatField(4) 4 13 4 ExampleMatField(5) 4 13 4 ExampleMatField(6) 4 7 4 ExampleMatField(7) 4 18 4 ExampleMatField(8) 4 13 4 ExampleMatField(9) 4 7 4  alnuth-4.0.0/doc/chap2_mj.html0000644000000000000000000005743715201210200013051 0ustar00 GAP (Alnuth) - Chapter 2: Working with number fields
Goto Chapter: Top 1 2 3 4 Bib Ind

2 Working with number fields

An algebraic number field is a finite-dimensional extension of the rational numbers \(ℚ\). Such a number field has a primitive element and it can be defined by the minimal polynomial of this primitive element. Another important way to define an algebraic number field is by a set of rational matrices which generate a number field.

2.1 Creation of number fields

We provide functions to create number fields defined by rational matrices or by rational polynomials.

2.1-1 FieldByMatricesNC
‣ FieldByMatricesNC( matrices )( function )
‣ FieldByMatrices( matrices )( function )

Creates a field generated by the rational matrices matrices. In the faster NC version, the function assumes that the input generates a field and there are no checks on this performed.

2.1-2 FieldByMatrixBasisNC
‣ FieldByMatrixBasisNC( matrices )( function )
‣ FieldByMatrixBasis( matrices )( function )

Creates a field with basis matrices. The list matrices must consist of rational matrices which form a basis for a number field. In the faster NC version, the function assumes that the input is a matrix basis for a field and no checks are performed.

2.1-3 FieldByPolynomialNC
‣ FieldByPolynomialNC( polynomial )( function )
‣ FieldByPolynomial( polynomial )( function )

Creates a field defined by polynomial. The polynomial polynomial must be an irreducible rational polynomial. In the faster NC version, no checks on the input are performed.

2.2 Methods for number fields

We outline a number of functions for number fields.

2.2-1 PrimitiveElement
‣ PrimitiveElement( F )( function )
‣ DefiningPolynomial( F )( function )

Computes a primitive element and a defining polynomial for the given number field. The defining polynomial is the minimal polynomial of the primitive element. Since F contains various primitive elements, PrimitiveElement tries to find a primitive element which has a minimal polynomial with small coefficients. Via the user preference PrimitiveElementTrials the user can decide how many primitive elements will be compared. The default value is 20. (See SetUserPreference (Reference: SetUserPreference) for more information about user preferences.)

2.2-2 IsPrimitiveElementOfNumberField
‣ IsPrimitiveElementOfNumberField( F, a )( function )

Checks if the given element generates the field.

2.2-3 DegreeOverPrimeField
‣ DegreeOverPrimeField( F )( function )

Returns the degree of F over the rationals.

2.2-4 EquationOrderBasis
‣ EquationOrderBasis( F )( function )
‣ MaximalOrderBasis( F )( function )
‣ IsIntegerOfNumberField( F, k )( function )

These functions return bases for the equation order or the maximal order of the number field F. Also, they allow to check if a given element is an integer in the given number field.

2.2-5 UnitGroup
‣ UnitGroup( F )( function )

determines the unit group of F.

Recall that the unit group of F is a finitely generated abelian group. The function IsomorphismPcpGroup from the Polycyclic [EHN11] package gives an isomorphism to a pcp group which can be used for various computations with the unit group.

2.2-6 IsUnitOfNumberField
‣ IsUnitOfNumberField( F, k )( function )

checks whether the element k is a unit in F.

2.2-7 ExponentsOfUnits
‣ ExponentsOfUnits( F, elms )( function )

This function determines the exponent vectors of the elements in elms with respect to the generators of the unit group of F. If the unit group of F is not known, then the function computes this unit group also.

2.2-8 IsCyclotomicField
‣ IsCyclotomicField( F )( function )

Check whether F is cyclotomic.

2.2-9 NormCosetsOfNumberField
‣ NormCosetsOfNumberField( F, norm )( function )

Returns a description for the set of all elements of norm norm in F. These elements can be written as a finite union of cosets of the unit group of F. The function returns coset representatives for these cosets.

2.3 Presentations of multiplicative subgroups

Suppose that a finite number of invertible elements of a number field are given. Then these elements generate a finitely generated abelian group. However, it is a non-trivial task to provide a presentation for this abelian group. The most useful representation for such groups is as pcp group.

2.3-1 PcpPresentationOfMultiplicativeSubgroup
‣ PcpPresentationOfMultiplicativeSubgroup( F, elms )( function )
‣ IsomorphismPcpGroup( F, elms )( function )

Determine a pcp presentation for the multiplicative group of \(\textit{F}\backslash\{0\}\) generated by elms and an isomorphism on this presentation. Note, that the method IsomorphismPcpGroup is defined in the Polycyclic package [EHN11]. We refer to the manual of this package for further background.

In the determination of the Pcp-presentation of a multiplicative subgroup generated by elms the relations between the elements in elms play an important role. Let \(elms=\{e_1,\dots,e_l\}\) be a finite subset of a field F. The relation lattice for elms is

\[ rl(elms):=\left\{(h_1,\dots,h_l) \in ℤ^l | e_1^{h_1} \cdots e_l^{h_l} = 1\right\} . \]

2.3-2 RelationLattice
‣ RelationLattice( F, elms )( function )

Determines a generating set for the relation lattice of the field elements elms.

2.4 Methods to compute with subgroups of the unit group

2.4-1 RelationLatticeOfUnits
‣ RelationLatticeOfUnits( F, elms )( function )

Determines a basis for the relation lattice of the units elms in triangularized form. Note that this method is more efficient than the method RelationLattice.

2.4-2 IntersectionOfUnitSubgroups
‣ IntersectionOfUnitSubgroups( F, gen1, gen2 )( function )

The lists gen1 and gen2 are supposed to generate two subgroups \(U_1\) and \(U_2\) of the unit group of F. This function determines the intersection of \(U_1\) with \(U_2\). The result is returned as a list of vectors generating the lattice \(\{ e \in ℤ^n \mid g_1^{e_1} \cdots g_n^{e_n} \in U_2 \}\) for gen1 = \([g_1, \ldots, g_n]\).

For efficiency reasons this function does not check the input and it may return wrong results if the input generators do not fulfil the requirements.

2.5 Factorisation of polynomials over a number field

2.5-1 FactorsPolynomialAlgExt
‣ FactorsPolynomialAlgExt( F, pol )( function )

embeds the rational polynomial pol into the polynomial ring over the number field F, which has to be constructed by FieldByPolynomial or AlgebraicExtension, and returns the factorization of the embedded polynomial. By default a denotes the primitive element of the field one can obtain from PrimitiveElement(F), that is, a root of the defining polynomial of F.

2.5-2 FactorsPolynomialAlnuth
‣ FactorsPolynomialAlnuth( pol )( function )

takes a polynomial pol defined over an algebraic extension of the Rationals and factors it using the external CAS (PARI/GP or OSCAR).

The alias FactorsPolynomialPari is provided for backwards compatibility.

gap> x := Indeterminate( Rationals, "x" );;
gap> pol := 2*x^7+2*x^5+8*x^4+8*x^2;
2*x^7+2*x^5+8*x^4+8*x^2
gap> L := FieldByPolynomial( x^3-4 );
<algebraic extension over the Rationals of degree 3>
gap> y := Indeterminate( L, "y" );;
gap> FactorsPolynomialAlgExt( L, pol );
[ !2*y, y, y+a, y^2+!1, y^2+(-a)*y+a^2 ]
gap> FactorsPolynomialAlnuth( last[5] );
[ y^2+(-a)*y+a^2 ]

2.6 Examples

2.6-1 ExampleMatField
‣ ExampleMatField( l )( function )

This function returns some examples of fields generated by matrices. There are 9 such example fields provided and they can be obtained by assigning the input l to an integer between 1 and 9. Some of the properties of the examples are summarized in the following table.

                    degree over Q  number of generators  dim. of generators
ExampleMatField(1)              4                     4                   4
ExampleMatField(2)              4                     4                   4
ExampleMatField(3)              4                     4                   4
ExampleMatField(4)              4                    13                   4
ExampleMatField(5)              4                    13                   4
ExampleMatField(6)              4                     7                   4
ExampleMatField(7)              4                    18                   4
ExampleMatField(8)              4                    13                   4
ExampleMatField(9)              4                     7                   4
Goto Chapter: Top 1 2 3 4 Bib Ind

generated by GAPDoc2HTML

alnuth-4.0.0/doc/chap3.html0000644000000000000000000001734415201210200012355 0ustar00 GAP (Alnuth) - Chapter 3: An example application
Goto Chapter: Top 1 2 3 4 Bib Ind

3 An example application

In this section we outline two example computations with the functions of the previous chapter. The first example uses number fields defined by matrices and the second example considers number fields defined by a polynomial.

3.1 Number fields defined by matrices

gap> m1 := [ [ 1, 0, 0, -7 ], 
>            [ 7, 1, 0, -7 ], 
>            [ 0, 7, 1, -7 ], 
>            [ 0, 0, 7, -6 ] ];;

#
gap> m2 := [ [ 0, 0, -13, 14 ], 
>            [ -1, 0, -13, 1 ], 
>            [ 13, -1, -13, 1 ], 
>            [ 0, 13, -14, 1 ] ];;

#
gap> F := FieldByMatricesNC( [m1, m2] );
<rational matrix field of unknown degree>

#
gap> DegreeOverPrimeField(F);
4
gap> PrimitiveElement(F);
[ [ 0, -1, 1, 0 ], [ 0, -1, 0, 1 ], [ 0, -1, 0, 0 ], [ 1, -1, 0, 0 ] ]

#
gap> Basis(F);
Basis( <rational matrix field of degree 4>, 
[ [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ], 
  [ [ 0, 1, 0, 0 ], [ -1, 1, 1, 0 ], [ -1, 0, 1, 1 ], [ -1, 0, 0, 1 ] ], 
  [ [ 0, 0, 1, 0 ], [ -1, 0, 1, 1 ], [ -1, -1, 1, 1 ], [ 0, -1, 0, 1 ] ], 
  [ [ 0, 0, 0, 1 ], [ -1, 0, 0, 1 ], [ 0, -1, 0, 1 ], [ 0, 0, -1, 1 ] ] ] )

#
gap> MaximalOrderBasis(F);
Basis( <rational matrix field of degree 4>, 
[ [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ], 
  [ [ 0, -1, 1, 0 ], [ 0, -1, 0, 1 ], [ 0, -1, 0, 0 ], [ 1, -1, 0, 0 ] ], 
  [ [ 0, 0, 0, -1 ], [ 1, 0, 0, -1 ], [ 0, 1, 0, -1 ], [ 0, 0, 1, -1 ] ], 
  [ [ -1, 1, 0, 0 ], [ -1, 0, 1, 0 ], [ -1, 0, 0, 1 ], [ -1, 0, 0, 0 ] ] ] )

#
gap> U := UnitGroup(F);
<matrix group with 2 generators>

#
gap> u := GeneratorsOfGroup( U );;

#
gap> nat := IsomorphismPcpGroup(U);;
gap> H := Image(nat);
Pcp-group with orders [ 10, 0 ]
gap> ImageElm( nat, u[1] );
g1
gap> ImageElm( nat, u[2] );
g2
gap> ImageElm( nat, u[1]*u[2] );
g1*g2
gap> u[1] = PreImagesRepresentative(nat, GeneratorsOfGroup(H)[1] );
true

3.2 Number fields defined by a polynomial

gap> g := UnivariatePolynomial( Rationals, [ 16, 64, -28, -4, 1 ] );
x^4-4*x^3-28*x^2+64*x+16

#
gap> F := FieldByPolynomialNC(g);
<algebraic extension over the Rationals of degree 4>
gap> PrimitiveElement(F);
a
gap> MaximalOrderBasis(F);
Basis( <algebraic extension over the Rationals of degree 4>, 
[ !1, 1/2*a, 1/4*a^2, 1/56*a^3+1/14*a^2+1/14*a-2/7 ] )

#
gap> U := UnitGroup(F);
<group with 4 generators>

#
gap> natU := IsomorphismPcpGroup(U);;
gap> elms := List( [1..10], x-> Random(F) );;

#
gap>  PcpPresentationOfMultiplicativeSubgroup( F, elms );
Pcp-group with orders [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]

#
gap> isom := IsomorphismPcpGroup( F, elms );;
gap> y := RandomGroupElement( elms );;
gap> z := ImageElm( isom, y );;
gap> y = PreImagesRepresentative( isom, z );
true

#
gap> FactorsPolynomialAlgExt( F, g );
[ x_1+(-a), x_1+(a-2), x_1+(-1/7*a^3+3/7*a^2+31/7*a-40/7), 
  x_1+(1/7*a^3-3/7*a^2-31/7*a+26/7) ]
Goto Chapter: Top 1 2 3 4 Bib Ind

generated by GAPDoc2HTML

alnuth-4.0.0/doc/chap3.txt0000644000000000000000000001315515201210200012224 0ustar00 3 An example application In this section we outline two example computations with the functions of the previous chapter. The first example uses number fields defined by matrices and the second example considers number fields defined by a polynomial. 3.1 Number fields defined by matrices  Example  gap> m1 := [ [ 1, 0, 0, -7 ],  >  [ 7, 1, 0, -7 ],  >  [ 0, 7, 1, -7 ],  >  [ 0, 0, 7, -6 ] ];;  # gap> m2 := [ [ 0, 0, -13, 14 ],  >  [ -1, 0, -13, 1 ],  >  [ 13, -1, -13, 1 ],  >  [ 0, 13, -14, 1 ] ];;  # gap> F := FieldByMatricesNC( [m1, m2] );   # gap> DegreeOverPrimeField(F); 4 gap> PrimitiveElement(F); [ [ 0, -1, 1, 0 ], [ 0, -1, 0, 1 ], [ 0, -1, 0, 0 ], [ 1, -1, 0, 0 ] ]  # gap> Basis(F); Basis( ,  [ [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ],   [ [ 0, 1, 0, 0 ], [ -1, 1, 1, 0 ], [ -1, 0, 1, 1 ], [ -1, 0, 0, 1 ] ],   [ [ 0, 0, 1, 0 ], [ -1, 0, 1, 1 ], [ -1, -1, 1, 1 ], [ 0, -1, 0, 1 ] ],   [ [ 0, 0, 0, 1 ], [ -1, 0, 0, 1 ], [ 0, -1, 0, 1 ], [ 0, 0, -1, 1 ] ] ] )  # gap> MaximalOrderBasis(F); Basis( ,  [ [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ],   [ [ 0, -1, 1, 0 ], [ 0, -1, 0, 1 ], [ 0, -1, 0, 0 ], [ 1, -1, 0, 0 ] ],   [ [ 0, 0, 0, -1 ], [ 1, 0, 0, -1 ], [ 0, 1, 0, -1 ], [ 0, 0, 1, -1 ] ],   [ [ -1, 1, 0, 0 ], [ -1, 0, 1, 0 ], [ -1, 0, 0, 1 ], [ -1, 0, 0, 0 ] ] ] )  # gap> U := UnitGroup(F);   # gap> u := GeneratorsOfGroup( U );;  # gap> nat := IsomorphismPcpGroup(U);; gap> H := Image(nat); Pcp-group with orders [ 10, 0 ] gap> ImageElm( nat, u[1] ); g1 gap> ImageElm( nat, u[2] ); g2 gap> ImageElm( nat, u[1]*u[2] ); g1*g2 gap> u[1] = PreImagesRepresentative(nat, GeneratorsOfGroup(H)[1] ); true  3.2 Number fields defined by a polynomial  Example  gap> g := UnivariatePolynomial( Rationals, [ 16, 64, -28, -4, 1 ] ); x^4-4*x^3-28*x^2+64*x+16  # gap> F := FieldByPolynomialNC(g);  gap> PrimitiveElement(F); a gap> MaximalOrderBasis(F); Basis( ,  [ !1, 1/2*a, 1/4*a^2, 1/56*a^3+1/14*a^2+1/14*a-2/7 ] )  # gap> U := UnitGroup(F);   # gap> natU := IsomorphismPcpGroup(U);; gap> elms := List( [1..10], x-> Random(F) );;  # gap>  PcpPresentationOfMultiplicativeSubgroup( F, elms ); Pcp-group with orders [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]  # gap> isom := IsomorphismPcpGroup( F, elms );; gap> y := RandomGroupElement( elms );; gap> z := ImageElm( isom, y );; gap> y = PreImagesRepresentative( isom, z ); true  # gap> FactorsPolynomialAlgExt( F, g ); [ x_1+(-a), x_1+(a-2), x_1+(-1/7*a^3+3/7*a^2+31/7*a-40/7),   x_1+(1/7*a^3-3/7*a^2-31/7*a+26/7) ]  alnuth-4.0.0/doc/chap3_mj.html0000644000000000000000000001765615201210200013051 0ustar00 GAP (Alnuth) - Chapter 3: An example application
Goto Chapter: Top 1 2 3 4 Bib Ind

3 An example application

In this section we outline two example computations with the functions of the previous chapter. The first example uses number fields defined by matrices and the second example considers number fields defined by a polynomial.

3.1 Number fields defined by matrices

gap> m1 := [ [ 1, 0, 0, -7 ], 
>            [ 7, 1, 0, -7 ], 
>            [ 0, 7, 1, -7 ], 
>            [ 0, 0, 7, -6 ] ];;

#
gap> m2 := [ [ 0, 0, -13, 14 ], 
>            [ -1, 0, -13, 1 ], 
>            [ 13, -1, -13, 1 ], 
>            [ 0, 13, -14, 1 ] ];;

#
gap> F := FieldByMatricesNC( [m1, m2] );
<rational matrix field of unknown degree>

#
gap> DegreeOverPrimeField(F);
4
gap> PrimitiveElement(F);
[ [ 0, -1, 1, 0 ], [ 0, -1, 0, 1 ], [ 0, -1, 0, 0 ], [ 1, -1, 0, 0 ] ]

#
gap> Basis(F);
Basis( <rational matrix field of degree 4>, 
[ [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ], 
  [ [ 0, 1, 0, 0 ], [ -1, 1, 1, 0 ], [ -1, 0, 1, 1 ], [ -1, 0, 0, 1 ] ], 
  [ [ 0, 0, 1, 0 ], [ -1, 0, 1, 1 ], [ -1, -1, 1, 1 ], [ 0, -1, 0, 1 ] ], 
  [ [ 0, 0, 0, 1 ], [ -1, 0, 0, 1 ], [ 0, -1, 0, 1 ], [ 0, 0, -1, 1 ] ] ] )

#
gap> MaximalOrderBasis(F);
Basis( <rational matrix field of degree 4>, 
[ [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ], 
  [ [ 0, -1, 1, 0 ], [ 0, -1, 0, 1 ], [ 0, -1, 0, 0 ], [ 1, -1, 0, 0 ] ], 
  [ [ 0, 0, 0, -1 ], [ 1, 0, 0, -1 ], [ 0, 1, 0, -1 ], [ 0, 0, 1, -1 ] ], 
  [ [ -1, 1, 0, 0 ], [ -1, 0, 1, 0 ], [ -1, 0, 0, 1 ], [ -1, 0, 0, 0 ] ] ] )

#
gap> U := UnitGroup(F);
<matrix group with 2 generators>

#
gap> u := GeneratorsOfGroup( U );;

#
gap> nat := IsomorphismPcpGroup(U);;
gap> H := Image(nat);
Pcp-group with orders [ 10, 0 ]
gap> ImageElm( nat, u[1] );
g1
gap> ImageElm( nat, u[2] );
g2
gap> ImageElm( nat, u[1]*u[2] );
g1*g2
gap> u[1] = PreImagesRepresentative(nat, GeneratorsOfGroup(H)[1] );
true

3.2 Number fields defined by a polynomial

gap> g := UnivariatePolynomial( Rationals, [ 16, 64, -28, -4, 1 ] );
x^4-4*x^3-28*x^2+64*x+16

#
gap> F := FieldByPolynomialNC(g);
<algebraic extension over the Rationals of degree 4>
gap> PrimitiveElement(F);
a
gap> MaximalOrderBasis(F);
Basis( <algebraic extension over the Rationals of degree 4>, 
[ !1, 1/2*a, 1/4*a^2, 1/56*a^3+1/14*a^2+1/14*a-2/7 ] )

#
gap> U := UnitGroup(F);
<group with 4 generators>

#
gap> natU := IsomorphismPcpGroup(U);;
gap> elms := List( [1..10], x-> Random(F) );;

#
gap>  PcpPresentationOfMultiplicativeSubgroup( F, elms );
Pcp-group with orders [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]

#
gap> isom := IsomorphismPcpGroup( F, elms );;
gap> y := RandomGroupElement( elms );;
gap> z := ImageElm( isom, y );;
gap> y = PreImagesRepresentative( isom, z );
true

#
gap> FactorsPolynomialAlgExt( F, g );
[ x_1+(-a), x_1+(a-2), x_1+(-1/7*a^3+3/7*a^2+31/7*a-40/7), 
  x_1+(1/7*a^3-3/7*a^2-31/7*a+26/7) ]
Goto Chapter: Top 1 2 3 4 Bib Ind

generated by GAPDoc2HTML

alnuth-4.0.0/doc/chap4.html0000644000000000000000000004350315201210200012352 0ustar00 GAP (Alnuth) - Chapter 4: Installation
Goto Chapter: Top 1 2 3 4 Bib Ind

4 Installation

This package provides an interface between GAP and either PARI/GP or OSCAR. When Alnuth is loaded in GAP running inside OSCAR, it automatically uses OSCAR. Otherwise, Alnuth uses PARI/GP, which has to be obtained and installed independently of this package. Alnuth works with PARI/GP Version 2.5 or higher.

4.1 Installing Alnuth

The package Alnuth is part of the standard distribution of GAP so that in most cases there is no need to install it separately. If you are using GAP inside OSCAR, then Alnuth is already bundled and automatically uses OSCAR, so no further installation is required. Otherwise, to use Alnuth you need to have PARI/GP installed. See the following section for information on PARI/GP.

In case you want to update Alnuth independently of your main GAP installation or if you are interested in an old version of Alnuth interfacing to KANT/KASH you can find all released versions of Alnuth in the form of gzipped tar-archives at https://github.com/gap-packages/alnuth/releases

There are two ways of installing a GAP package. If you have permission to add files to the installation of GAP on your system you may install Alnuth into the pkg subdirectory of the GAP installation tree. Otherwise you may install Alnuth in a private pkg directory (for details see Subsections Reference: Installing a GAP Package and Reference: GAP Root Directories in the GAP reference manual).

To install the latest version of Alnuth download one of the archives alnuth.tar.gz, move it to the directory pkg in which you want to install, and unpack the archive. If you are using the command line you can unpack with the command tar xzf alnuth.tar.gz.

4.2 Getting PARI/GP

Using Alnuth outside OSCAR requires an installation of PARI/GP in Version 2.5 or higher. The software PARI/GP is freely available at https://pari.math.u-bordeaux.fr/

Note that the place where PARI/GP is located in your system is independent of the place where Alnuth is installed.

  1. Installing under Linux

    In many Linux distributions PARI/GP can be installed via the software package manager, but this might sometimes be an older version which cannot be used together with Alnuth. (Starting GP from the command line with the option --version-short will show you the version number.)

    If you install PARI/GP from source make sure you install with GMP support for better performance and complete the installation with make install so that you can start GP by just calling gp from the command line.

  2. Installing under Windows

    For Windows it is sufficient to get the basic GP binary which can be found at https://pari.math.u-bordeaux.fr/download.html

4.3 Adjust the path of the executable for GP

When Alnuth is used outside OSCAR, it needs to know where the executable for GP is. In the default setting Alnuth looks for an executable program named gp in the search paths of the system. More precisely, for a file gp inside one of the directories in the list returned by DirectoriesSystemPrograms() (called in a GAP session).

Under Linux the default setting should work with a standard installation of PARI/GP.

For the default setting to work under Windows the downloaded executable file, for example gp-2-5-0.exe has to be renamed to gp.exe and moved to one of the directories listed by DirectoriesSystemPrograms() (Ignore the leading cygdrive in each path name and note that the single letter specifies the drive, for example /cygdrive/c/Windows/ denotes the folder Windows on drive C:).

To check whether an executable of GP in Version 2.5 or higher is available with the default setting, you can use the function

4.3-1 PariVersion
‣ PariVersion( )( function )

which prints the version number, if the user preference PariGpPath refers to a usable GP executable.

If you cannot use the default setting for you purpose, you have several ways to configure Alnuth.

The recommended approach is to use the GAP user preference system:

gap> SetUserPreference("alnuth", "PariGpPath", "/home/my/pari-2.5.0/gp");
gap> SetUserPreference("alnuth", "PariStackSize", 256);
gap> WriteGapIniFile();

This changes the current session immediately. WriteGapIniFile() writes the current non-default settings to your personal gap.ini, so they are used again in future GAP sessions. See Reference: Configuring User preferences for background on the user preference system.

The user preferences relevant for Alnuth are shown by ShowUserPreferences("alnuth");. The most important ones are PariGpPath, PariGpOptions, PariStackSize, and PrimitiveElementTrials.

In older versions of Alnuth configuration was done via the global variables AL_EXECUTABLE, AL_PATH, AL_OPTIONS, AL_STACKSIZE, and PRIM_TEST. These globals are deprecated, and they trigger a warning when used. The globals except for AL_PATH still serve as a fallback if the corresponding user preference is unusable. Their replacements are as follows:

AL_EXECUTABLE

use the user preference PariGpPath

AL_OPTIONS

use the user preference PariGpOptions

AL_STACKSIZE

use the user preference PariStackSize

PRIM_TEST

use the user preference PrimitiveElementTrials

AL_PATH

has been removed; Alnuth now always uses the bundled GP helper files.

For backwards compatibility, the following functions still exist after loading the package (see Section 4.4), but they are deprecated wrappers around the user preference system.

4.3-2 SetAlnuthExternalExecutable
‣ SetAlnuthExternalExecutable( path )( function )

sets the user preference PariGpPath for the current GAP session. Depending on your installation of PARI/GP and your operating system the string path can be either the command to start GP in a terminal (for example gp) or the complete path to the executable of GP. The function is deprecated; new code should call SetUserPreference("alnuth", "PariGpPath", path); directly.

The function returns the stored preference value.

4.3-3 SetAlnuthExternalExecutablePermanently
‣ SetAlnuthExternalExecutablePermanently( path )( function )

does the same as SetAlnuthExternalExecutable and then calls WriteGapIniFile() to persist the current user preference settings in your personal gap.ini. The function is deprecated; new code should call SetUserPreference("alnuth", "PariGpPath", path); WriteGapIniFile(); instead.

4.3-4 RestoreAlnuthExternalExecutablePermanently
‣ RestoreAlnuthExternalExecutablePermanently( )( function )

restores the default value of PariGpPath and then calls WriteGapIniFile(). The function is deprecated; new code should set PariGpPath to the desired default command or path and then call WriteGapIniFile() directly.

4.4 Loading and testing the package

If Alnuth is not loaded when GAP is started you have to request it explicitly to use it. This is done by calling LoadPackage("alnuth"); in a GAP session. If Alnuth had not been loaded already a short banner will be displayed.

gap> LoadPackage("alnuth");
Loading Alnuth 4.0.0 (ALgebraic NUmber THeory and an interface to PARI/GP and OSCAR)
by Björn Assmann,
   Andreas Distler (a.distler@tu-bs.de), and
   Bettina Eick (http://www.iaa.tu-bs.de/beick).
maintained by:
   Max Horn (https://www.quendi.de/math) and
   The GAP Team (support@gap-system.org).
Homepage: https://gap-packages.github.io/alnuth
Report issues at https://github.com/gap-packages/alnuth/issues
true
gap>

To load a certain version of Alnuth you can specify the version number as second argument in the call to LoadPackage. (See LoadPackage (Reference: LoadPackage) in the GAP reference manual or type ?LoadPackage within a GAP session).

Once the package is loaded, it is possible to check the correct installation running a short test by calling ReadPackage("Alnuth", "tst/testinstall.tst");.

gap> ReadPackage("Alnuth", "tst/testinstall.g");
Architecture: aarch64-apple-darwin21.4.0-default64-kv8

testing: GAPROOT/pkg/alnuth/tst/ALNUTH.tst
      66 ms (33 ms GC) and 11.0MB allocated for GAPROOT/pkg/alnuth/tst/ALNUTH.tst
testing: GAPROOT/pkg/alnuth/tst/version.tst
      21 ms (21 ms GC) and 29.6KB allocated for GAPROOT/pkg/alnuth/tst/version.tst
-----------------------------------
total        87 ms (54 ms GC) and 11.0MB allocated
              0 failures in 2 files

#I  No errors detected while testing
gap>

The architecture, timings and memory usage will usually differ; other discrepancies in the output indicate some problem.

If the test suite runs into an error in the first part, which when running outside OSCAR verifies the availability of PARI/GP, check your installation of PARI/GP and consult the last chapter of the documentation of Alnuth for more information.

If you find any bugs or have any suggestions or comments, we would very much appreciate it if you would let us know by submitting an issue at the Alnuth issue tracker on GitHub https://github.com/gap-packages/alnuth/issues or by writing an mail to support@gap-system.org.

 

Goto Chapter: Top 1 2 3 4 Bib Ind

generated by GAPDoc2HTML

alnuth-4.0.0/doc/chap4.txt0000644000000000000000000003110015201210200012213 0ustar00 4 Installation This package provides an interface between GAP and either PARI/GP or OSCAR. When Alnuth is loaded in GAP running inside OSCAR, it automatically uses OSCAR. Otherwise, Alnuth uses PARI/GP, which has to be obtained and installed independently of this package. Alnuth works with PARI/GP Version 2.5 or higher. 4.1 Installing Alnuth The package Alnuth is part of the standard distribution of GAP so that in most cases there is no need to install it separately. If you are using GAP inside OSCAR, then Alnuth is already bundled and automatically uses OSCAR, so no further installation is required. Otherwise, to use Alnuth you need to have PARI/GP installed. See the following section for information on PARI/GP. In case you want to update Alnuth independently of your main GAP installation or if you are interested in an old version of Alnuth interfacing to KANT/KASH you can find all released versions of Alnuth in the form of gzipped tar-archives at https://github.com/gap-packages/alnuth/releases There are two ways of installing a GAP package. If you have permission to add files to the installation of GAP on your system you may install Alnuth into the pkg subdirectory of the GAP installation tree. Otherwise you may install Alnuth in a private pkg directory (for details see Subsections 'Reference: Installing a GAP Package' and 'Reference: GAP Root Directories' in the GAP reference manual). To install the latest version of Alnuth download one of the archives alnuth.tar.gz, move it to the directory pkg in which you want to install, and unpack the archive. If you are using the command line you can unpack with the command tar xzf alnuth.tar.gz. 4.2 Getting PARI/GP Using Alnuth outside OSCAR requires an installation of PARI/GP in Version 2.5 or higher. The software PARI/GP is freely available at https://pari.math.u-bordeaux.fr/ Note that the place where PARI/GP is located in your system is independent of the place where Alnuth is installed. 1 Installing under Linux In many Linux distributions PARI/GP can be installed via the software package manager, but this might sometimes be an older version which cannot be used together with Alnuth. (Starting GP from the command line with the option --version-short will show you the version number.) If you install PARI/GP from source make sure you install with GMP support for better performance and complete the installation with make install so that you can start GP by just calling gp from the command line. 2 Installing under Windows For Windows it is sufficient to get the basic GP binary which can be found at https://pari.math.u-bordeaux.fr/download.html 4.3 Adjust the path of the executable for GP When Alnuth is used outside OSCAR, it needs to know where the executable for GP is. In the default setting Alnuth looks for an executable program named gp in the search paths of the system. More precisely, for a file gp inside one of the directories in the list returned by DirectoriesSystemPrograms() (called in a GAP session). Under Linux the default setting should work with a standard installation of PARI/GP. For the default setting to work under Windows the downloaded executable file, for example gp-2-5-0.exe has to be renamed to gp.exe and moved to one of the directories listed by DirectoriesSystemPrograms() (Ignore the leading cygdrive in each path name and note that the single letter specifies the drive, for example /cygdrive/c/Windows/ denotes the folder Windows on drive C:). To check whether an executable of GP in Version 2.5 or higher is available with the default setting, you can use the function 4.3-1 PariVersion PariVersion( )  function which prints the version number, if the user preference PariGpPath refers to a usable GP executable. If you cannot use the default setting for you purpose, you have several ways to configure Alnuth. The recommended approach is to use the GAP user preference system:  Example  gap> SetUserPreference("alnuth", "PariGpPath", "/home/my/pari-2.5.0/gp"); gap> SetUserPreference("alnuth", "PariStackSize", 256); gap> WriteGapIniFile();  This changes the current session immediately. WriteGapIniFile() writes the current non-default settings to your personal gap.ini, so they are used again in future GAP sessions. See 'Reference: Configuring User preferences' for background on the user preference system. The user preferences relevant for Alnuth are shown by ShowUserPreferences("alnuth");. The most important ones are PariGpPath, PariGpOptions, PariStackSize, and PrimitiveElementTrials. In older versions of Alnuth configuration was done via the global variables AL_EXECUTABLE, AL_PATH, AL_OPTIONS, AL_STACKSIZE, and PRIM_TEST. These globals are deprecated, and they trigger a warning when used. The globals except for AL_PATH still serve as a fallback if the corresponding user preference is unusable. Their replacements are as follows: AL_EXECUTABLE use the user preference PariGpPath AL_OPTIONS use the user preference PariGpOptions AL_STACKSIZE use the user preference PariStackSize PRIM_TEST use the user preference PrimitiveElementTrials AL_PATH has been removed; Alnuth now always uses the bundled GP helper files. For backwards compatibility, the following functions still exist after loading the package (see Section 4.4), but they are deprecated wrappers around the user preference system. 4.3-2 SetAlnuthExternalExecutable SetAlnuthExternalExecutable( path )  function sets the user preference PariGpPath for the current GAP session. Depending on your installation of PARI/GP and your operating system the string path can be either the command to start GP in a terminal (for example gp) or the complete path to the executable of GP. The function is deprecated; new code should call SetUserPreference("alnuth", "PariGpPath", path); directly. The function returns the stored preference value. 4.3-3 SetAlnuthExternalExecutablePermanently SetAlnuthExternalExecutablePermanently( path )  function does the same as SetAlnuthExternalExecutable and then calls WriteGapIniFile() to persist the current user preference settings in your personal gap.ini. The function is deprecated; new code should call SetUserPreference("alnuth", "PariGpPath", path); WriteGapIniFile(); instead. 4.3-4 RestoreAlnuthExternalExecutablePermanently RestoreAlnuthExternalExecutablePermanently( )  function restores the default value of PariGpPath and then calls WriteGapIniFile(). The function is deprecated; new code should set PariGpPath to the desired default command or path and then call WriteGapIniFile() directly. 4.4 Loading and testing the package If Alnuth is not loaded when GAP is started you have to request it explicitly to use it. This is done by calling LoadPackage("alnuth"); in a GAP session. If Alnuth had not been loaded already a short banner will be displayed.  Example  gap> LoadPackage("alnuth"); Loading Alnuth 4.0.0 (ALgebraic NUmber THeory and an interface to PARI/GP and OSCAR) by Björn Assmann,  Andreas Distler (a.distler@tu-bs.de), and  Bettina Eick (http://www.iaa.tu-bs.de/beick). maintained by:  Max Horn (https://www.quendi.de/math) and  The GAP Team (support@gap-system.org). Homepage: https://gap-packages.github.io/alnuth Report issues at https://github.com/gap-packages/alnuth/issues true gap>  To load a certain version of Alnuth you can specify the version number as second argument in the call to LoadPackage. (See LoadPackage (Reference: LoadPackage) in the GAP reference manual or type ?LoadPackage within a GAP session). Once the package is loaded, it is possible to check the correct installation running a short test by calling ReadPackage("Alnuth", "tst/testinstall.tst");.  Example  gap> ReadPackage("Alnuth", "tst/testinstall.g"); Architecture: aarch64-apple-darwin21.4.0-default64-kv8  testing: GAPROOT/pkg/alnuth/tst/ALNUTH.tst  66 ms (33 ms GC) and 11.0MB allocated for GAPROOT/pkg/alnuth/tst/ALNUTH.tst testing: GAPROOT/pkg/alnuth/tst/version.tst  21 ms (21 ms GC) and 29.6KB allocated for GAPROOT/pkg/alnuth/tst/version.tst ----------------------------------- total 87 ms (54 ms GC) and 11.0MB allocated  0 failures in 2 files  #I No errors detected while testing gap>  The architecture, timings and memory usage will usually differ; other discrepancies in the output indicate some problem. If the test suite runs into an error in the first part, which when running outside OSCAR verifies the availability of PARI/GP, check your installation of PARI/GP and consult the last chapter of the documentation of Alnuth for more information. If you find any bugs or have any suggestions or comments, we would very much appreciate it if you would let us know by submitting an issue at the Alnuth issue tracker on GitHub https://github.com/gap-packages/alnuth/issues or by writing an mail to mailto:support@gap-system.org.   alnuth-4.0.0/doc/chap4_mj.html0000644000000000000000000004405615201210200013044 0ustar00 GAP (Alnuth) - Chapter 4: Installation
Goto Chapter: Top 1 2 3 4 Bib Ind

4 Installation

This package provides an interface between GAP and either PARI/GP or OSCAR. When Alnuth is loaded in GAP running inside OSCAR, it automatically uses OSCAR. Otherwise, Alnuth uses PARI/GP, which has to be obtained and installed independently of this package. Alnuth works with PARI/GP Version 2.5 or higher.

4.1 Installing Alnuth

The package Alnuth is part of the standard distribution of GAP so that in most cases there is no need to install it separately. If you are using GAP inside OSCAR, then Alnuth is already bundled and automatically uses OSCAR, so no further installation is required. Otherwise, to use Alnuth you need to have PARI/GP installed. See the following section for information on PARI/GP.

In case you want to update Alnuth independently of your main GAP installation or if you are interested in an old version of Alnuth interfacing to KANT/KASH you can find all released versions of Alnuth in the form of gzipped tar-archives at https://github.com/gap-packages/alnuth/releases

There are two ways of installing a GAP package. If you have permission to add files to the installation of GAP on your system you may install Alnuth into the pkg subdirectory of the GAP installation tree. Otherwise you may install Alnuth in a private pkg directory (for details see Subsections Reference: Installing a GAP Package and Reference: GAP Root Directories in the GAP reference manual).

To install the latest version of Alnuth download one of the archives alnuth.tar.gz, move it to the directory pkg in which you want to install, and unpack the archive. If you are using the command line you can unpack with the command tar xzf alnuth.tar.gz.

4.2 Getting PARI/GP

Using Alnuth outside OSCAR requires an installation of PARI/GP in Version 2.5 or higher. The software PARI/GP is freely available at https://pari.math.u-bordeaux.fr/

Note that the place where PARI/GP is located in your system is independent of the place where Alnuth is installed.

  1. Installing under Linux

    In many Linux distributions PARI/GP can be installed via the software package manager, but this might sometimes be an older version which cannot be used together with Alnuth. (Starting GP from the command line with the option --version-short will show you the version number.)

    If you install PARI/GP from source make sure you install with GMP support for better performance and complete the installation with make install so that you can start GP by just calling gp from the command line.

  2. Installing under Windows

    For Windows it is sufficient to get the basic GP binary which can be found at https://pari.math.u-bordeaux.fr/download.html

4.3 Adjust the path of the executable for GP

When Alnuth is used outside OSCAR, it needs to know where the executable for GP is. In the default setting Alnuth looks for an executable program named gp in the search paths of the system. More precisely, for a file gp inside one of the directories in the list returned by DirectoriesSystemPrograms() (called in a GAP session).

Under Linux the default setting should work with a standard installation of PARI/GP.

For the default setting to work under Windows the downloaded executable file, for example gp-2-5-0.exe has to be renamed to gp.exe and moved to one of the directories listed by DirectoriesSystemPrograms() (Ignore the leading cygdrive in each path name and note that the single letter specifies the drive, for example /cygdrive/c/Windows/ denotes the folder Windows on drive C:).

To check whether an executable of GP in Version 2.5 or higher is available with the default setting, you can use the function

4.3-1 PariVersion
‣ PariVersion( )( function )

which prints the version number, if the user preference PariGpPath refers to a usable GP executable.

If you cannot use the default setting for you purpose, you have several ways to configure Alnuth.

The recommended approach is to use the GAP user preference system:

gap> SetUserPreference("alnuth", "PariGpPath", "/home/my/pari-2.5.0/gp");
gap> SetUserPreference("alnuth", "PariStackSize", 256);
gap> WriteGapIniFile();

This changes the current session immediately. WriteGapIniFile() writes the current non-default settings to your personal gap.ini, so they are used again in future GAP sessions. See Reference: Configuring User preferences for background on the user preference system.

The user preferences relevant for Alnuth are shown by ShowUserPreferences("alnuth");. The most important ones are PariGpPath, PariGpOptions, PariStackSize, and PrimitiveElementTrials.

In older versions of Alnuth configuration was done via the global variables AL_EXECUTABLE, AL_PATH, AL_OPTIONS, AL_STACKSIZE, and PRIM_TEST. These globals are deprecated, and they trigger a warning when used. The globals except for AL_PATH still serve as a fallback if the corresponding user preference is unusable. Their replacements are as follows:

AL_EXECUTABLE

use the user preference PariGpPath

AL_OPTIONS

use the user preference PariGpOptions

AL_STACKSIZE

use the user preference PariStackSize

PRIM_TEST

use the user preference PrimitiveElementTrials

AL_PATH

has been removed; Alnuth now always uses the bundled GP helper files.

For backwards compatibility, the following functions still exist after loading the package (see Section 4.4), but they are deprecated wrappers around the user preference system.

4.3-2 SetAlnuthExternalExecutable
‣ SetAlnuthExternalExecutable( path )( function )

sets the user preference PariGpPath for the current GAP session. Depending on your installation of PARI/GP and your operating system the string path can be either the command to start GP in a terminal (for example gp) or the complete path to the executable of GP. The function is deprecated; new code should call SetUserPreference("alnuth", "PariGpPath", path); directly.

The function returns the stored preference value.

4.3-3 SetAlnuthExternalExecutablePermanently
‣ SetAlnuthExternalExecutablePermanently( path )( function )

does the same as SetAlnuthExternalExecutable and then calls WriteGapIniFile() to persist the current user preference settings in your personal gap.ini. The function is deprecated; new code should call SetUserPreference("alnuth", "PariGpPath", path); WriteGapIniFile(); instead.

4.3-4 RestoreAlnuthExternalExecutablePermanently
‣ RestoreAlnuthExternalExecutablePermanently( )( function )

restores the default value of PariGpPath and then calls WriteGapIniFile(). The function is deprecated; new code should set PariGpPath to the desired default command or path and then call WriteGapIniFile() directly.

4.4 Loading and testing the package

If Alnuth is not loaded when GAP is started you have to request it explicitly to use it. This is done by calling LoadPackage("alnuth"); in a GAP session. If Alnuth had not been loaded already a short banner will be displayed.

gap> LoadPackage("alnuth");
Loading Alnuth 4.0.0 (ALgebraic NUmber THeory and an interface to PARI/GP and OSCAR)
by Björn Assmann,
   Andreas Distler (a.distler@tu-bs.de), and
   Bettina Eick (http://www.iaa.tu-bs.de/beick).
maintained by:
   Max Horn (https://www.quendi.de/math) and
   The GAP Team (support@gap-system.org).
Homepage: https://gap-packages.github.io/alnuth
Report issues at https://github.com/gap-packages/alnuth/issues
true
gap>

To load a certain version of Alnuth you can specify the version number as second argument in the call to LoadPackage. (See LoadPackage (Reference: LoadPackage) in the GAP reference manual or type ?LoadPackage within a GAP session).

Once the package is loaded, it is possible to check the correct installation running a short test by calling ReadPackage("Alnuth", "tst/testinstall.tst");.

gap> ReadPackage("Alnuth", "tst/testinstall.g");
Architecture: aarch64-apple-darwin21.4.0-default64-kv8

testing: GAPROOT/pkg/alnuth/tst/ALNUTH.tst
      66 ms (33 ms GC) and 11.0MB allocated for GAPROOT/pkg/alnuth/tst/ALNUTH.tst
testing: GAPROOT/pkg/alnuth/tst/version.tst
      21 ms (21 ms GC) and 29.6KB allocated for GAPROOT/pkg/alnuth/tst/version.tst
-----------------------------------
total        87 ms (54 ms GC) and 11.0MB allocated
              0 failures in 2 files

#I  No errors detected while testing
gap>

The architecture, timings and memory usage will usually differ; other discrepancies in the output indicate some problem.

If the test suite runs into an error in the first part, which when running outside OSCAR verifies the availability of PARI/GP, check your installation of PARI/GP and consult the last chapter of the documentation of Alnuth for more information.

If you find any bugs or have any suggestions or comments, we would very much appreciate it if you would let us know by submitting an issue at the Alnuth issue tracker on GitHub https://github.com/gap-packages/alnuth/issues or by writing an mail to support@gap-system.org.

 

Goto Chapter: Top 1 2 3 4 Bib Ind

generated by GAPDoc2HTML

alnuth-4.0.0/doc/chapBib.html0000644000000000000000000001200015201210200012667 0ustar00 GAP (Alnuth) - References
Goto Chapter: Top 1 2 3 4 Bib Ind

References

[Coh93] Cohen, H., A course in computational algebraic number theory, Springer-Verlag, New York, Heidelberg, Berlin (1993).

[DEF+25] (Decker, W., Eder, C., Fieker, C., Horn, M. and Joswig, M., Eds.), The Computer Algebra System OSCAR: Algorithms and Examples, Springer, 1 edition, Algorithms and Computation in Mathematics, 32 (2025), (10.1007/978-3-031-62127-7).

[EHN11] Eick, B., Horn, M. and Nickel, W., Polycyclic - a GAP package (2011).

[OSC24] OSCAR -- Open Source Computer Algebra Research system, Version 1.0.0, The OSCAR Team (2024).

[PAR11] PARI/GP, version 2.5.0, {The PARI~Group}, Bordeaux (2011).

[Poh93] Pohst, M. E., Computational Algebraic Number Theory, Birkhäuser, DMV Seminar, 21 (1993).

[PZ89] Pohst, M. and Zassenhaus, H., Algorithmic algebraic number theory, Cambridge University Press (1989).

[ST79] Stuart, I. N. and Tall, D. O., Algebraic number theory, Chapman and Hall (1979).

Goto Chapter: Top 1 2 3 4 Bib Ind

generated by GAPDoc2HTML

alnuth-4.0.0/doc/chapBib.txt0000644000000000000000000000247115201210200012555 0ustar00 References [Coh93] Cohen, H., A course in computational algebraic number theory, Springer-Verlag, New York, Heidelberg, Berlin (1993). [DEF+25] (Decker, W., Eder, C., Fieker, C., Horn, M. and Joswig, M., Eds.), The Computer Algebra System OSCAR: Algorithms and Examples, Springer, 1 edition, Algorithms and Computation in Mathematics, 32 (2025) (https://doi.org/10.1007/978-3-031-62127-7). [EHN11] Eick, B., Horn, M. and Nickel, W., Polycyclic - a GAP package (2011). [OSC24] OSCAR -- Open Source Computer Algebra Research system, Version 1.0.0, The OSCAR Team (2024). [PAR11] PARI/GP, version 2.5.0, {The PARI~Group}, Bordeaux (2011). [Poh93] Pohst, M. E., Computational Algebraic Number Theory, Birkhäuser, DMV Seminar, 21 (1993). [PZ89] Pohst, M. and Zassenhaus, H., Algorithmic algebraic number theory, Cambridge University Press (1989). [ST79] Stuart, I. N. and Tall, D. O., Algebraic number theory, Chapman and Hall (1979).  alnuth-4.0.0/doc/chapBib_mj.html0000644000000000000000000001230115201210200013361 0ustar00 GAP (Alnuth) - References
Goto Chapter: Top 1 2 3 4 Bib Ind

References

[Coh93] Cohen, H., A course in computational algebraic number theory, Springer-Verlag, New York, Heidelberg, Berlin (1993).

[DEF+25] (Decker, W., Eder, C., Fieker, C., Horn, M. and Joswig, M., Eds.), The Computer Algebra System OSCAR: Algorithms and Examples, Springer, 1 edition, Algorithms and Computation in Mathematics, 32 (2025), (10.1007/978-3-031-62127-7).

[EHN11] Eick, B., Horn, M. and Nickel, W., Polycyclic - a GAP package (2011).

[OSC24] OSCAR -- Open Source Computer Algebra Research system, Version 1.0.0, The OSCAR Team (2024).

[PAR11] PARI/GP, version 2.5.0, {The PARI~Group}, Bordeaux (2011).

[Poh93] Pohst, M. E., Computational Algebraic Number Theory, Birkhäuser, DMV Seminar, 21 (1993).

[PZ89] Pohst, M. and Zassenhaus, H., Algorithmic algebraic number theory, Cambridge University Press (1989).

[ST79] Stuart, I. N. and Tall, D. O., Algebraic number theory, Chapman and Hall (1979).

Goto Chapter: Top 1 2 3 4 Bib Ind

generated by GAPDoc2HTML

alnuth-4.0.0/doc/chapInd.html0000644000000000000000000001174515201210200012724 0ustar00 GAP (Alnuth) - Index
Goto Chapter: Top 1 2 3 4 Bib Ind

Index

DefiningPolynomial 2.2-1
DegreeOverPrimeField 2.2-3
EquationOrderBasis 2.2-4
ExampleMatField 2.6-1
ExponentsOfUnits 2.2-7
FactorsPolynomialAlgExt 2.5-1
FactorsPolynomialAlnuth 2.5-2
FieldByMatrices 2.1-1
FieldByMatricesNC 2.1-1
FieldByMatrixBasis 2.1-2
FieldByMatrixBasisNC 2.1-2
FieldByPolynomial 2.1-3
FieldByPolynomialNC 2.1-3
IntersectionOfUnitSubgroups 2.4-2
IsCyclotomicField 2.2-8
IsIntegerOfNumberField 2.2-4
IsomorphismPcpGroup 2.3-1
IsPrimitiveElementOfNumberField 2.2-2
IsUnitOfNumberField 2.2-6
MaximalOrderBasis 2.2-4
NormCosetsOfNumberField 2.2-9
PariVersion 4.3-1
PcpPresentationOfMultiplicativeSubgroup 2.3-1
PrimitiveElement 2.2-1
RelationLattice 2.3-2
RelationLatticeOfUnits 2.4-1
RestoreAlnuthExternalExecutablePermanently 4.3-4
SetAlnuthExternalExecutable 4.3-2
SetAlnuthExternalExecutablePermanently 4.3-3
UnitGroup 2.2-5

Goto Chapter: Top 1 2 3 4 Bib Ind

generated by GAPDoc2HTML

alnuth-4.0.0/doc/chapInd.txt0000644000000000000000000000245415201210200012574 0ustar00 Index DefiningPolynomial 2.2-1 DegreeOverPrimeField 2.2-3 EquationOrderBasis 2.2-4 ExampleMatField 2.6-1 ExponentsOfUnits 2.2-7 FactorsPolynomialAlgExt 2.5-1 FactorsPolynomialAlnuth 2.5-2 FieldByMatrices 2.1-1 FieldByMatricesNC 2.1-1 FieldByMatrixBasis 2.1-2 FieldByMatrixBasisNC 2.1-2 FieldByPolynomial 2.1-3 FieldByPolynomialNC 2.1-3 IntersectionOfUnitSubgroups 2.4-2 IsCyclotomicField 2.2-8 IsIntegerOfNumberField 2.2-4 IsomorphismPcpGroup 2.3-1 IsPrimitiveElementOfNumberField 2.2-2 IsUnitOfNumberField 2.2-6 MaximalOrderBasis 2.2-4 NormCosetsOfNumberField 2.2-9 PariVersion 4.3-1 PcpPresentationOfMultiplicativeSubgroup 2.3-1 PrimitiveElement 2.2-1 RelationLattice 2.3-2 RelationLatticeOfUnits 2.4-1 RestoreAlnuthExternalExecutablePermanently 4.3-4 SetAlnuthExternalExecutable 4.3-2 SetAlnuthExternalExecutablePermanently 4.3-3 UnitGroup 2.2-5 ------------------------------------------------------- alnuth-4.0.0/doc/chapInd_mj.html0000644000000000000000000001237215201210200013407 0ustar00 GAP (Alnuth) - Index
Goto Chapter: Top 1 2 3 4 Bib Ind

Index

DefiningPolynomial 2.2-1
DegreeOverPrimeField 2.2-3
EquationOrderBasis 2.2-4
ExampleMatField 2.6-1
ExponentsOfUnits 2.2-7
FactorsPolynomialAlgExt 2.5-1
FactorsPolynomialAlnuth 2.5-2
FieldByMatrices 2.1-1
FieldByMatricesNC 2.1-1
FieldByMatrixBasis 2.1-2
FieldByMatrixBasisNC 2.1-2
FieldByPolynomial 2.1-3
FieldByPolynomialNC 2.1-3
IntersectionOfUnitSubgroups 2.4-2
IsCyclotomicField 2.2-8
IsIntegerOfNumberField 2.2-4
IsomorphismPcpGroup 2.3-1
IsPrimitiveElementOfNumberField 2.2-2
IsUnitOfNumberField 2.2-6
MaximalOrderBasis 2.2-4
NormCosetsOfNumberField 2.2-9
PariVersion 4.3-1
PcpPresentationOfMultiplicativeSubgroup 2.3-1
PrimitiveElement 2.2-1
RelationLattice 2.3-2
RelationLatticeOfUnits 2.4-1
RestoreAlnuthExternalExecutablePermanently 4.3-4
SetAlnuthExternalExecutable 4.3-2
SetAlnuthExternalExecutablePermanently 4.3-3
UnitGroup 2.2-5

Goto Chapter: Top 1 2 3 4 Bib Ind

generated by GAPDoc2HTML

alnuth-4.0.0/doc/chooser.html0000644000000000000000000001130415201210200013007 0ustar00 GAPDoc Style Chooser

Setting preferences for GAPDoc manuals

Unfold subsections in menus only by mouse clicks: no (default)     yes

Show GAP examples as in sessions with ColorPrompt(true): yes (default)     no

Display side of table of contents within chapters: right (default)     left

Main document font: Helvetica/sans serif (default)     Times/serif

Paragraph formatting: left-right justified (default)     ragged right

Appearance: system (default)     light dark

Apply settings to last page.

alnuth-4.0.0/doc/dark.css0000644000000000000000000000515115201210200012115 0ustar00/* dark.css Frank Luebeck */ /* Initial dark theme contributed by kiryph in issue #75. */ /* colors */ body { background: #121212; color: #eee; } a:link { color: #576cad; } a:visited { color: #576cad; } a:active { color: #eee; } a:hover { background: #eee; } pre { color: black; } tt, code { color: #eee; } /* layout for the definitions of functions, variables, ... */ div.func { background: #909090; } /* Example elements (for old converted manuals, now in div+pre */ table.example { background: #efefef; } /* becomes ... */ div.example { background: #efefef; color: black; } /* Links to chapters in all files at top and bottom. */ div.chlinktop { background: #22272e; border-color: #3a414a; color: #d7dde5; } div.chlinktop a:hover { background: #2f3742; } div.chlinkbot { background: #22272e; border-color: #3a414a; color: #d7dde5; } /* and this is for the "Top", "Prev", "Next" links */ div.chlinkprevnexttop { background: #22272e; border-color: #3a414a; color: #d7dde5; } div.chlinkprevnexttop a:hover { background: #2f3742; } div.chlinkprevnextbot { background: #22272e; border-color: #3a414a; color: #d7dde5; } div.chlinkprevnextbot a:hover { background: #2f3742; } div.ContChap div.ContSect:hover div.ContSSBlock { background: #eee; border-color: #666; color: #000; } div.ContSSBlock a:hover { background: #fff; } /* and here for the side menu of contents in the chapter files */ div.ChapSects a:hover { background: #eee; color: #000; } div.ChapSects div.ContSect:hover div.ContSSBlock { background: #b5b5b5; border-color: #666; color: #000; } div.ChapSects div.ContSect:hover div.ContSSBlock a:hover { background: #828282; } /* Table elements */ table.GAPDocTable { border-color: black; } table.GAPDocTable td, table.GAPDocTable th { border-color: #555; } table.GAPDocTablenoborder td, table.GAPDocTable th { border-color: #555; } /* Colors and fonts can be overwritten for some types of elements. */ /* Verb elements */ pre.normal { color: #eee; } /* Func-like elements and Ref to Func-like */ code.func { color: #eee; } /* K elements */ code.keyw { color: #983d3d; } /* F elements */ code.file { color: #8e4510; } /* Arg elements */ var.Arg { color: #060; } /* colors for ColorPrompt like examples */ span.GAPprompt { color: #000097; } span.GAPbrkprompt { color: #970000; } span.GAPinput { color: #970000; } /* Bib entries */ span.BibKey { color: #052; } /* for light and dark mode pictures */ .only-on-dark { display: block; } .only-on-light { display: none; } alnuth-4.0.0/doc/example.xml0000644000000000000000000000633015201210200012637 0ustar00 An example application In this section we outline two example computations with the functions of the previous chapter. The first example uses number fields defined by matrices and the second example considers number fields defined by a polynomial.
Number fields defined by matrices m1 := [ [ 1, 0, 0, -7 ], > [ 7, 1, 0, -7 ], > [ 0, 7, 1, -7 ], > [ 0, 0, 7, -6 ] ];; # gap> m2 := [ [ 0, 0, -13, 14 ], > [ -1, 0, -13, 1 ], > [ 13, -1, -13, 1 ], > [ 0, 13, -14, 1 ] ];; # gap> F := FieldByMatricesNC( [m1, m2] ); # gap> DegreeOverPrimeField(F); 4 gap> PrimitiveElement(F); [ [ 0, -1, 1, 0 ], [ 0, -1, 0, 1 ], [ 0, -1, 0, 0 ], [ 1, -1, 0, 0 ] ] # gap> Basis(F); Basis( , [ [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ], [ [ 0, 1, 0, 0 ], [ -1, 1, 1, 0 ], [ -1, 0, 1, 1 ], [ -1, 0, 0, 1 ] ], [ [ 0, 0, 1, 0 ], [ -1, 0, 1, 1 ], [ -1, -1, 1, 1 ], [ 0, -1, 0, 1 ] ], [ [ 0, 0, 0, 1 ], [ -1, 0, 0, 1 ], [ 0, -1, 0, 1 ], [ 0, 0, -1, 1 ] ] ] ) # gap> MaximalOrderBasis(F); Basis( , [ [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ], [ [ 0, -1, 1, 0 ], [ 0, -1, 0, 1 ], [ 0, -1, 0, 0 ], [ 1, -1, 0, 0 ] ], [ [ 0, 0, 0, -1 ], [ 1, 0, 0, -1 ], [ 0, 1, 0, -1 ], [ 0, 0, 1, -1 ] ], [ [ -1, 1, 0, 0 ], [ -1, 0, 1, 0 ], [ -1, 0, 0, 1 ], [ -1, 0, 0, 0 ] ] ] ) # gap> U := UnitGroup(F); # gap> u := GeneratorsOfGroup( U );; # gap> nat := IsomorphismPcpGroup(U);; gap> H := Image(nat); Pcp-group with orders [ 10, 0 ] gap> ImageElm( nat, u[1] ); g1 gap> ImageElm( nat, u[2] ); g2 gap> ImageElm( nat, u[1]*u[2] ); g1*g2 gap> u[1] = PreImagesRepresentative(nat, GeneratorsOfGroup(H)[1] ); true ]]>
Number fields defined by a polynomial g := UnivariatePolynomial( Rationals, [ 16, 64, -28, -4, 1 ] ); x^4-4*x^3-28*x^2+64*x+16 # gap> F := FieldByPolynomialNC(g); gap> PrimitiveElement(F); a gap> MaximalOrderBasis(F); Basis( , [ !1, 1/2*a, 1/4*a^2, 1/56*a^3+1/14*a^2+1/14*a-2/7 ] ) # gap> U := UnitGroup(F); # gap> natU := IsomorphismPcpGroup(U);; gap> elms := List( [1..10], x-> Random(F) );; # gap> PcpPresentationOfMultiplicativeSubgroup( F, elms ); Pcp-group with orders [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] # gap> isom := IsomorphismPcpGroup( F, elms );; gap> y := RandomGroupElement( elms );; gap> z := ImageElm( isom, y );; gap> y = PreImagesRepresentative( isom, z ); true # gap> FactorsPolynomialAlgExt( F, g ); [ x_1+(-a), x_1+(a-2), x_1+(-1/7*a^3+3/7*a^2+31/7*a-40/7), x_1+(1/7*a^3-3/7*a^2-31/7*a+26/7) ] ]]>
alnuth-4.0.0/doc/fields.xml0000644000000000000000000002430615201210200012455 0ustar00 Working with number fields An algebraic number field is a finite-dimensional extension of the rational numbers &QQ;. Such a number field has a primitive element and it can be defined by the minimal polynomial of this primitive element. Another important way to define an algebraic number field is by a set of rational matrices which generate a number field.
Creation of number fields We provide functions to create number fields defined by rational matrices or by rational polynomials. Creates a field generated by the rational matrices matrices. In the faster NC version, the function assumes that the input generates a field and there are no checks on this performed. Creates a field with basis matrices. The list matrices must consist of rational matrices which form a basis for a number field. In the faster NC version, the function assumes that the input is a matrix basis for a field and no checks are performed. Creates a field defined by polynomial. The polynomial polynomial must be an irreducible rational polynomial. In the faster NC version, no checks on the input are performed.
Methods for number fields We outline a number of functions for number fields. Computes a primitive element and a defining polynomial for the given number field. The defining polynomial is the minimal polynomial of the primitive element. Since F contains various primitive elements, PrimitiveElement tries to find a primitive element which has a minimal polynomial with small coefficients. Via the user preference PrimitiveElementTrials the user can decide how many primitive elements will be compared. The default value is 20. (See for more information about user preferences.) Checks if the given element generates the field. Returns the degree of F over the rationals. These functions return bases for the equation order or the maximal order of the number field F. Also, they allow to check if a given element is an integer in the given number field. determines the unit group of F.

Recall that the unit group of F is a finitely generated abelian group. The function IsomorphismPcpGroup from the &Polycyclic; package gives an isomorphism to a pcp group which can be used for various computations with the unit group. checks whether the element k is a unit in F. This function determines the exponent vectors of the elements in elms with respect to the generators of the unit group of F. If the unit group of F is not known, then the function computes this unit group also. Check whether F is cyclotomic. Returns a description for the set of all elements of norm norm in F. These elements can be written as a finite union of cosets of the unit group of F. The function returns coset representatives for these cosets.

Presentations of multiplicative subgroups Suppose that a finite number of invertible elements of a number field are given. Then these elements generate a finitely generated abelian group. However, it is a non-trivial task to provide a presentation for this abelian group. The most useful representation for such groups is as pcp group. Determine a pcp presentation for the multiplicative group of F\backslash\{0\} generated by elms and an isomorphism on this presentation. Note, that the method IsomorphismPcpGroup is defined in the &Polycyclic; package . We refer to the manual of this package for further background.

In the determination of the Pcp-presentation of a multiplicative subgroup generated by elms the relations between the elements in elms play an important role. Let elms=\{e_1,\dots,e_l\} be a finite subset of a field F. The relation lattice for elms is rl(elms):=\left\{(h_1,\dots,h_l) \in &ZZ;^l | e_1^{h_1} \cdots e_l^{h_l} = 1\right\} . Determines a generating set for the relation lattice of the field elements elms.

Methods to compute with subgroups of the unit group Determines a basis for the relation lattice of the units elms in triangularized form. Note that this method is more efficient than the method RelationLattice. The lists gen1 and gen2 are supposed to generate two subgroups U_1 and U_2 of the unit group of F. This function determines the intersection of U_1 with U_2. The result is returned as a list of vectors generating the lattice \{ e \in &ZZ;^n \mid g_1^{e_1} \cdots g_n^{e_n} \in U_2 \} for gen1 = [g_1, \ldots, g_n].

For efficiency reasons this function does not check the input and it may return wrong results if the input generators do not fulfil the requirements.

Factorisation of polynomials over a number field embeds the rational polynomial pol into the polynomial ring over the number field F, which has to be constructed by FieldByPolynomial or AlgebraicExtension, and returns the factorization of the embedded polynomial. By default a denotes the primitive element of the field one can obtain from PrimitiveElement(F), that is, a root of the defining polynomial of F. takes a polynomial pol defined over an algebraic extension of the Rationals and factors it using the external CAS (PARI/GP or OSCAR).

The alias FactorsPolynomialPari is provided for backwards compatibility. x := Indeterminate( Rationals, "x" );; gap> pol := 2*x^7+2*x^5+8*x^4+8*x^2; 2*x^7+2*x^5+8*x^4+8*x^2 gap> L := FieldByPolynomial( x^3-4 ); gap> y := Indeterminate( L, "y" );; gap> FactorsPolynomialAlgExt( L, pol ); [ !2*y, y, y+a, y^2+!1, y^2+(-a)*y+a^2 ] gap> FactorsPolynomialAlnuth( last[5] ); [ y^2+(-a)*y+a^2 ] ]]>

Examples This function returns some examples of fields generated by matrices. There are 9 such example fields provided and they can be obtained by assigning the input l to an integer between 1 and 9. Some of the properties of the examples are summarized in the following table.
alnuth-4.0.0/doc/install.xml0000644000000000000000000002455115201210200012657 0ustar00 Installation This package provides an interface between &GAP; and either PARI/GP or OSCAR. When &Alnuth; is loaded in &GAP; running inside OSCAR, it automatically uses OSCAR. Otherwise, &Alnuth; uses PARI/GP, which has to be obtained and installed independently of this package. &Alnuth; works with PARI/GP Version 2.5 or higher.
Installing Alnuth The package &Alnuth; is part of the standard distribution of &GAP; so that in most cases there is no need to install it separately. If you are using &GAP; inside OSCAR, then &Alnuth; is already bundled and automatically uses OSCAR, so no further installation is required. Otherwise, to use &Alnuth; you need to have PARI/GP installed. See the following section for information on PARI/GP.

In case you want to update &Alnuth; independently of your main &GAP; installation or if you are interested in an old version of &Alnuth; interfacing to KANT/KASH you can find all released versions of &Alnuth; in the form of gzipped tar-archives at https://github.com/gap-packages/alnuth/releases

There are two ways of installing a &GAP; package. If you have permission to add files to the installation of &GAP; on your system you may install &Alnuth; into the pkg subdirectory of the &GAP; installation tree. Otherwise you may install &Alnuth; in a private pkg directory (for details see Subsections and in the &GAP; reference manual).

To install the latest version of &Alnuth; download one of the archives alnuth.tar.gz, move it to the directory pkg in which you want to install, and unpack the archive. If you are using the command line you can unpack with the command tar xzf alnuth.tar.gz.

Getting PARI/GP Using &Alnuth; outside OSCAR requires an installation of PARI/GP in Version 2.5 or higher. The software PARI/GP is freely available at https://pari.math.u-bordeaux.fr/

Note that the place where PARI/GP is located in your system is independent of the place where &Alnuth; is installed.

Installing under Linux

In many Linux distributions PARI/GP can be installed via the software package manager, but this might sometimes be an older version which cannot be used together with &Alnuth;. (Starting GP from the command line with the option --version-short will show you the version number.)

If you install PARI/GP from source make sure you install with GMP support for better performance and complete the installation with make install so that you can start GP by just calling gp from the command line. Installing under Windows

For Windows it is sufficient to get the basic GP binary which can be found at https://pari.math.u-bordeaux.fr/download.html

Adjust the path of the executable for GP When &Alnuth; is used outside OSCAR, it needs to know where the executable for GP is. In the default setting &Alnuth; looks for an executable program named gp in the search paths of the system. More precisely, for a file gp inside one of the directories in the list returned by DirectoriesSystemPrograms() (called in a &GAP; session).

Under Linux the default setting should work with a standard installation of PARI/GP.

For the default setting to work under Windows the downloaded executable file, for example gp-2-5-0.exe has to be renamed to gp.exe and moved to one of the directories listed by DirectoriesSystemPrograms() (Ignore the leading cygdrive in each path name and note that the single letter specifies the drive, for example /cygdrive/c/Windows/ denotes the folder Windows on drive C:).

To check whether an executable of GP in Version 2.5 or higher is available with the default setting, you can use the function which prints the version number, if the user preference PariGpPath refers to a usable GP executable. If you cannot use the default setting for you purpose, you have several ways to configure Alnuth.

The recommended approach is to use the &GAP; user preference system: SetUserPreference("alnuth", "PariGpPath", "/home/my/pari-2.5.0/gp"); gap> SetUserPreference("alnuth", "PariStackSize", 256); gap> WriteGapIniFile(); ]]> This changes the current session immediately. WriteGapIniFile() writes the current non-default settings to your personal gap.ini, so they are used again in future &GAP; sessions. See for background on the user preference system.

The user preferences relevant for Alnuth are shown by ShowUserPreferences("alnuth");. The most important ones are PariGpPath, PariGpOptions, PariStackSize, and PrimitiveElementTrials.

In older versions of &Alnuth; configuration was done via the global variables AL_EXECUTABLE, AL_PATH, AL_OPTIONS, AL_STACKSIZE, and PRIM_TEST. These globals are deprecated, and they trigger a warning when used. The globals except for AL_PATH still serve as a fallback if the corresponding user preference is unusable. Their replacements are as follows: AL_EXECUTABLE use the user preference PariGpPath AL_OPTIONS use the user preference PariGpOptions AL_STACKSIZE use the user preference PariStackSize PRIM_TEST use the user preference PrimitiveElementTrials AL_PATH has been removed; Alnuth now always uses the bundled GP helper files.

For backwards compatibility, the following functions still exist after loading the package (see Section ), but they are deprecated wrappers around the user preference system. sets the user preference PariGpPath for the current &GAP; session. Depending on your installation of PARI/GP and your operating system the string path can be either the command to start GP in a terminal (for example gp) or the complete path to the executable of GP. The function is deprecated; new code should call SetUserPreference("alnuth", "PariGpPath", path); directly.

The function returns the stored preference value. does the same as SetAlnuthExternalExecutable and then calls WriteGapIniFile() to persist the current user preference settings in your personal gap.ini. The function is deprecated; new code should call SetUserPreference("alnuth", "PariGpPath", path); WriteGapIniFile(); instead. restores the default value of PariGpPath and then calls WriteGapIniFile(). The function is deprecated; new code should set PariGpPath to the desired default command or path and then call WriteGapIniFile() directly.

Loading and testing the package If &Alnuth; is not loaded when GAP is started you have to request it explicitly to use it. This is done by calling LoadPackage("alnuth"); in a GAP session. If &Alnuth; had not been loaded already a short banner will be displayed.

LoadPackage("alnuth"); Loading Alnuth 4.0.0 (ALgebraic NUmber THeory and an interface to PARI/GP and OSCAR) by Björn Assmann, Andreas Distler (a.distler@tu-bs.de), and Bettina Eick (http://www.iaa.tu-bs.de/beick). maintained by: Max Horn (https://www.quendi.de/math) and The GAP Team (support@gap-system.org). Homepage: https://gap-packages.github.io/alnuth Report issues at https://github.com/gap-packages/alnuth/issues true gap> ]]> To load a certain version of &Alnuth; you can specify the version number as second argument in the call to LoadPackage. (See in the &GAP; reference manual or type ?LoadPackage within a GAP session).

Once the package is loaded, it is possible to check the correct installation running a short test by calling ReadPackage("Alnuth", "tst/testinstall.tst");.

ReadPackage("Alnuth", "tst/testinstall.g"); Architecture: aarch64-apple-darwin21.4.0-default64-kv8 testing: GAPROOT/pkg/alnuth/tst/ALNUTH.tst 66 ms (33 ms GC) and 11.0MB allocated for GAPROOT/pkg/alnuth/tst/ALNUTH.tst testing: GAPROOT/pkg/alnuth/tst/version.tst 21 ms (21 ms GC) and 29.6KB allocated for GAPROOT/pkg/alnuth/tst/version.tst ----------------------------------- total 87 ms (54 ms GC) and 11.0MB allocated 0 failures in 2 files #I No errors detected while testing gap> ]]> The architecture, timings and memory usage will usually differ; other discrepancies in the output indicate some problem.

If the test suite runs into an error in the first part, which when running outside OSCAR verifies the availability of PARI/GP, check your installation of PARI/GP and consult the last chapter of the documentation of &Alnuth; for more information.

If you find any bugs or have any suggestions or comments, we would very much appreciate it if you would let us know by submitting an issue at the &Alnuth; issue tracker on GitHub https://github.com/gap-packages/alnuth/issues or by writing an mail to support@gap-system.org.

alnuth-4.0.0/doc/intro.xml0000644000000000000000000000337015201210200012340 0ustar00 Introduction A number field is a finite extension of the field of rational numbers. &Alnuth; provides various methods to compute with number fields which are given by a defining polynomial or by generators. For background on number fields we refer to .

Some of the methods provided in this package are written in &GAP; code. The other part of the methods is imported from the Computer Algebra Systems PARI/GP respectively OSCAR , . Hence this package contains some &GAP; functions and an interface to some functions to these computer algebra systems. Therefore one has to have PARI/GP or OSCAR installed to use the full functionality of &Alnuth;.

We note that only a very small part of the functions available in PARI/GP respectively OSCAR are linked to &GAP; and they provides many more methods for computations in number fields.

The main methods included in &Alnuth; are: creating a number field, computing its maximal order, computing its unit group and a presentation of this unit group, computing the elements of a given norm of the number field, determining a presentation for a finitely generated multiplicative subgroup, and factoring polynomials defined over number fields. For background on algorithms for number fields we refer to , and .

The functions provided by &Alnuth; are introduced in the following chapter. Then an example application is outlined. In the final chapter of this manual the installation of the package and configuration of the interface, including hints on the installation of PARI/GP respectively OSCAR, are described.

alnuth-4.0.0/doc/lefttoc.css0000644000000000000000000000047415201210200012637 0ustar00/* leftmenu.css Frank Lübeck */ /* Change default CSS to show section menu on left side */ body { padding-left: 28%; } body.chap0 { padding-left: 2%; } div.ChapSects div.ContSect:hover div.ContSSBlock { left: 15%; } div.ChapSects { left: 1%; width: 25%; } alnuth-4.0.0/doc/manual.bib0000644000000000000000000000522315201210200012415 0ustar00 @manual{GAP4, key = "GAP", organization = "The GAP~Group", title = "{GAP -- Groups, Algorithms, and Programming, Version 4.14.0}", year = 2024, url = {https://www.gap-system.org/}, keywords = "groups; *; gap; manual", } @article{Kant, author = {M. Daberkow and C.Fieker and J. Klüners and M. Pohst and K.Roegner and K. Wildanger}, title = {Kant {V4}}, journal = {J. Symb. Comput.}, volume = 24, year = {1997}, pages = {267 -- 283} } @manual{PARI2, key = "PARI", organization = "{The PARI~Group}", title = "{PARI/GP, version {2.5.0}}", year = 2011, address = "Bordeaux", url = {https://pari.math.u-bordeaux.fr/} } @book{Poh93, author = {Michael E. Pohst}, title = {Computational Algebraic Number Theory}, publisher = {Birkhäuser}, volume = {21}, series = {DMV Seminar}, year = 1993 } @manual{Polycyclic, author = {Bettina Eick and Max Horn and Werner Nickel}, title = {Polycyclic - a {GAP} package}, url = {https://gap-packages.github.io/polycyclic/}, year = {2011}, } @book{PZa89, author = {M. Pohst and H. Zassenhaus}, title = {Algorithmic algebraic number theory}, publisher = {Cambridge University Press}, year = 1989 } @book{Coh93, author = {Henri Cohen}, title = {A course in computational algebraic number theory}, publisher = {Springer-Verlag}, address = {New York, Heidelberg, Berlin}, year = 1993 } @book{Sta79, author = {I. N. Stuart and D. O. Tall}, title = {Algebraic number theory}, publisher = {Chapman and Hall}, year = {1979} } @misc{OSCAR, key = {OSCAR}, organization = {The OSCAR Team}, title = {OSCAR -- Open Source Computer Algebra Research system, Version 1.0.0}, year = {2024}, url = {https://www.oscar-system.org}, } @book{Oscar25, editor = {Decker, Wolfram and Eder, Christian and Fieker, Claus and Horn, Max and Joswig, Michael}, title = {The {C}omputer {A}lgebra {S}ystem {OSCAR}: {A}lgorithms and {E}xamples}, year = {2025}, publisher = {Springer}, series = {Algorithms and Computation in Mathematics}, volume = {32}, edition = {1}, url = {https://doi.org/10.1007/978-3-031-62127-7}, issn = {1431-1550}, doi = {10.1007/978-3-031-62127-7}, }alnuth-4.0.0/doc/manual.css0000644000000000000000000001606615201210200012460 0ustar00/* manual.css Frank Lübeck */ /* This is the default CSS style sheet for GAPDoc HTML manuals. */ /* basic settings, fonts, sizes, colors, ... */ body { position: relative; background: #ffffff; color: #000000; width: 70%; margin: 0pt; padding: 15pt; font-family: Helvetica,Verdana,Arial,sans-serif; text-align: justify; } /* no side toc on title page, bib and index */ body.chap0 { width: 95%; } body.chapBib { width: 95%; } body.chapInd { width: 95%; } h1 { font-size: 200%; } h2 { font-size: 160%; } h3 { font-size: 160%; } h4 { font-size: 130%; } h5 { font-size: 100%; } p.foot { font-size: 60%; font-style: normal; } a:link { color: #00008e; text-decoration: none; } a:visited { color: #00008e; text-decoration: none; } a:active { color: #000000; text-decoration: none; } a:hover { background: #eeeeee; } pre { font-family: "Courier New",Courier,monospace; font-size: 100%; color:#111111; } tt,code { font-family: "Courier New",Courier,monospace; font-size: 110%; color: #000000; } var { } /* general alignment classes */ .pcenter { text-align: center; } .pleft { text-align: left; } .pright { text-align: right; } /* layout for the definitions of functions, variables, ... */ div.func { background: #e0e0e0; margin: 0pt 0pt; } /* general and special table settings */ table { border-collapse: collapse; margin-left: auto; margin-right: auto; } td, th { border-style: none; } table.func { padding: 0pt 1ex; margin-left: 1ex; margin-right: 1ex; background: transparent; /* line-height: 1.1; */ width: 100%; } table.func td.tdright { padding-right: 2ex; } /* Example elements (for old converted manuals, now in div+pre */ table.example { background: #efefef; border-style: none; border-width: 0pt; padding: 0px; width: 100% } table.example td { border-style: none; border-width: 0pt; padding: 0ex 1ex; } /* becomes ... */ div.example { background: #efefef; padding: 0ex 1ex; /* overflow-x: auto; */ overflow: auto; } /* Links to chapters in all files at top and bottom. */ /* If there are too many chapters then use 'display: none' here. */ div.chlinktop { background: #dddddd; border-style: solid; border-width: thin; margin: 2px; text-align: center; } div.chlinktop a { margin: 3px; } div.chlinktop a:hover { background: #ffffff; } div.chlinkbot { background: #dddddd; border-style: solid; border-width: thin; margin: 2px; text-align: center; /* width: 100%; */ } div.chlinkbot a { margin: 3px; } span.chlink1 { } /* and this is for the "Top", "Prev", "Next" links */ div.chlinkprevnexttop { background: #dddddd; border-style: solid; border-width: thin; text-align: center; margin: 2px; } div.chlinkprevnexttop a:hover { background: #ffffff; } div.chlinkprevnextbot { background: #dddddd; border-style: solid; border-width: thin; text-align: center; margin: 2px; } div.chlinkprevnextbot a:hover { background: #ffffff; } /* table of contents, initially don't display subsections */ div.ContSSBlock { display: none; } div.ContSSBlock br { display: none; } /* format in separate lines */ span.tocline { display: block; width: 100%; } div.ContSSBlock a { display: block; } /* this is for the main table of contents */ div.ContChap { } div.ContChap div.ContSect:hover div.ContSSBlock { display: block; position: absolute; background: #eeeeee; border-style: solid; border-width: 1px 4px 4px 1px; border-color: #666666; padding-left: 0.5ex; color: #000000; left: 20%; width: 40%; z-index: 10000; } div.ContSSBlock a:hover { background: #ffffff; } /* and here for the side menu of contents in the chapter files */ div.ChapSects { } div.ChapSects a:hover { background: #eeeeee; } div.ChapSects a:hover { display: block; width: 100%; background: #eeeeee; color: #000000; } div.ChapSects div.ContSect:hover div.ContSSBlock { display: block; position: fixed; background: #eeeeee; border-style: solid; border-width: 1px 2px 2px 1px; border-color: #666666; padding-left: 0ex; padding-right: 0.5ex; color: #000000; left: 54%; width: 25%; z-index: 10000; } div.ChapSects div.ContSect:hover div.ContSSBlock a { display: block; margin-left: 3px; } div.ChapSects div.ContSect:hover div.ContSSBlock a:hover { display: block; background: #ffffff; } div.ContSect { text-align: left; margin-left: 1em; } div.ChapSects { position: fixed; left: 75%; font-size: 90%; overflow: auto; top: 10px; bottom: 0px; } /* Table elements */ table.GAPDocTable { border-collapse: collapse; border-style: none; border-color: black; } table.GAPDocTable td, table.GAPDocTable th { padding: 3pt; border-width: thin; border-style: solid; border-color: #555555; } caption.GAPDocTable { caption-side: bottom; width: 70%; margin-top: 1em; margin-left: auto; margin-right: auto; } td.tdleft { text-align: left; } table.GAPDocTablenoborder { border-collapse: collapse; border-style: none; border-color: black; } table.GAPDocTablenoborder td, table.GAPDocTable th { padding: 3pt; border-width: 0pt; border-style: solid; border-color: #555555; } caption.GAPDocTablenoborder { caption-side: bottom; width: 70%; margin-top: 1em; margin-left: auto; margin-right: auto; } td.tdleft { text-align: left; } td.tdright { text-align: right; } td.tdcenter { text-align: center; } /* Colors and fonts can be overwritten for some types of elements. */ /* Verb elements */ pre.normal { color: #000000; } /* Func-like elements and Ref to Func-like */ code.func { color: #000000; } /* K elements */ code.keyw { color: #770000; } /* F elements */ code.file { color: #8e4510; } /* C elements */ code.code { } /* Item elements */ code.i { } /* Button elements */ strong.button { } /* Headings */ span.Heading { } /* Arg elements */ var.Arg { color: #006600; } /* Example elements, is in tables, see above */ div.Example { } /* Package elements */ strong.pkg { } /* URL-like elements */ span.URL { } /* Mark elements */ strong.Mark { } /* Ref elements */ b.Ref { } span.Ref { } /* this contains the contents page */ div.contents { } /* this contains the index page */ div.index { } /* ignore some text for non-css layout */ span.nocss { display: none; } /* colors for ColorPrompt like examples */ span.GAPprompt { color: #000097; font-weight: normal; } span.GAPbrkprompt { color: #970000; font-weight: normal; } span.GAPinput { color: #970000; } /* Bib entries */ p.BibEntry { } span.BibKey { color: #005522; } span.BibKeyLink { } b.BibAuthor { } i.BibTitle { } i.BibBookTitle { } span.BibEditor { } span.BibJournal { } span.BibType { } span.BibPublisher { } span.BibSchool { } span.BibEdition { } span.BibVolume { } span.BibSeries { } span.BibNumber { } span.BibPages { } span.BibOrganization { } span.BibAddress { } span.BibYear { } span.BibPublisher { } span.BibNote { } span.BibHowpublished { } /* for light and dark mode pictures */ .only-on-dark { display: none; } alnuth-4.0.0/doc/manual.js0000644000000000000000000001132115201210200012271 0ustar00/* manual.js Frank Lübeck */ /* This file contains a few javascript functions which allow to switch between display styles for GAPDoc HTML manuals. If javascript is switched off in a browser or this file in not available in a manual directory, this is no problem. Users just cannot switch between several styles and don't see the corresponding button. A style with name mystyle can be added by providing two files (or only one of them). mystyle.js: Additional javascript code for the style, it is read in the HTML pages after this current file. The additional code may adjust the preprocessing function jscontent() with is called onload of a file. This is done by appending functions to jscontentfuncs (jscontentfuncs.push(newfunc);). Make sure, that your style is still usable without javascript. mystyle.css: CSS configuration, read after manual.css (so it can just reconfigure a few details, or overwrite everything). Then adjust chooser.html such that users can switch on and off mystyle. A user can change the preferred style permanently by using the [Style] link and choosing one. Or one can append '?GAPDocStyle=mystyle' to the URL when loading any file of the manual (so the style can be configured in the GAP user preferences). */ /* generic helper function */ function deleteCookie(nam) { document.cookie = nam+"=;Path=/;expires=Thu, 01 Jan 1970 00:00:00 GMT"; } /* read a value from a "nam1=val1;nam2=val2;..." string (e.g., the search part of an URL or a cookie */ function valueString(str,nam) { var cs = str.split(";"); for (var i=0; i < cs.length; i++) { var pos = cs[i].search(nam+"="); if (pos > -1) { pos = cs[i].indexOf("="); return cs[i].slice(pos+1); } } return 0; } /* load dark appearance either explicitly or via the OS preference */ function writeAppearanceStyle(mode) { if (mode == "dark") { document.writeln( '' ); } else if (mode != "light") { document.writeln( '' ); } } /* when a non-default style is chosen via URL or a cookie, then the cookie is reset and the styles .js and .css files are read */ function overwriteStyle() { /* style in URL? */ var style = valueString(window.location.search, "GAPDocStyle"); /* otherwise check cookie */ if (style == 0) style = valueString(document.cookie, "GAPDocStyle"); if (style == 0 || style == "default") writeAppearanceStyle(""); if (style == 0) return; if (style == "default") deleteCookie("GAPDocStyle"); else { /* ok, we set the cookie for path "/" */ var path = "/"; /* or better like this ??? var here = window.location.pathname.split("/"); for (var i=0; i+3 < here.length; i++) path = path+"/"+here[i]; */ document.cookie = "GAPDocStyle="+style+";Path="+path; /* split into names of style files */ var stlist = style.split(","); var appearance = ""; /* read style's css and js files */ for (var i=0; i < stlist.length; i++) { if (stlist[i] == "dark" || stlist[i] == "light") { appearance = stlist[i]; } else { document.writeln(''); document.writeln(''); } } writeAppearanceStyle(appearance); } } /* this adds a "[Style]" link next to the MathJax switcher */ function addStyleLink() { var line = document.getElementById("mathjaxlink"); var el = document.createElement("a"); var oncl = document.createAttribute("href"); var back = window.location.protocol+"//" if (window.location.protocol == "http:" || window.location.protocol == "https:") { back = back+window.location.host; if (window.location.port != "") { back = back+":"+window.location.port; } } back = back+window.location.pathname; oncl.nodeValue = "chooser.html?BACK="+back; el.setAttributeNode(oncl); var cont = document.createTextNode(" [Style]"); el.appendChild(cont); line.appendChild(el); } var jscontentfuncs = new Array(); jscontentfuncs.push(addStyleLink); /* the default jscontent() only adds the [Style] link to the page */ function jscontent () { for (var i=0; i < jscontentfuncs.length; i++) jscontentfuncs[i](); } alnuth-4.0.0/doc/manual.lab0000644000000000000000000000664315201210200012426 0ustar00\GAPDocLabFile{alnuth} \makelabel{alnuth:Title page}{}{X7D2C85EC87DD46E5} \makelabel{alnuth:Copyright}{}{X81488B807F2A1CF1} \makelabel{alnuth:Acknowledgements}{}{X82A988D47DFAFCFA} \makelabel{alnuth:Table of Contents}{}{X8537FEB07AF2BEC8} \makelabel{alnuth:Introduction}{1}{X7DFB63A97E67C0A1} \makelabel{alnuth:Working with number fields}{2}{X7DC995CB8412F8E2} \makelabel{alnuth:Creation of number fields}{2.1}{X86AD0C3F7D38C269} \makelabel{alnuth:Methods for number fields}{2.2}{X79007A477D53B572} \makelabel{alnuth:Presentations of multiplicative subgroups}{2.3}{X833A0296798E0463} \makelabel{alnuth:Methods to compute with subgroups of the unit group}{2.4}{X86F68B4883142B5A} \makelabel{alnuth:Factorisation of polynomials over a number field}{2.5}{X7F656B217EF114DA} \makelabel{alnuth:Examples}{2.6}{X7A489A5D79DA9E5C} \makelabel{alnuth:An example application}{3}{X81CAD2F27B2066C4} \makelabel{alnuth:Number fields defined by matrices}{3.1}{X7981DB6C79742C4C} \makelabel{alnuth:Number fields defined by a polynomial}{3.2}{X85ADC6A27B26C804} \makelabel{alnuth:Installation}{4}{X8360C04082558A12} \makelabel{alnuth:Installing Alnuth}{4.1}{X821B9C2D817C0BE7} \makelabel{alnuth:Adjust the path of the executable for GP}{4.3}{X815DF28A87D65A3A} \makelabel{alnuth:Loading and testing the package}{4.4}{X781C2F107F76F8A4} \makelabel{alnuth:Bibliography}{Bib}{X7A6F98FD85F02BFE} \makelabel{alnuth:References}{Bib}{X7A6F98FD85F02BFE} \makelabel{alnuth:Index}{Ind}{X83A0356F839C696F} \makelabel{alnuth:FieldByMatricesNC}{2.1.1}{X8085204B7DE2C8BA} \makelabel{alnuth:FieldByMatrices}{2.1.1}{X8085204B7DE2C8BA} \makelabel{alnuth:FieldByMatrixBasisNC}{2.1.2}{X805CFBEB877FCBA3} \makelabel{alnuth:FieldByMatrixBasis}{2.1.2}{X805CFBEB877FCBA3} \makelabel{alnuth:FieldByPolynomialNC}{2.1.3}{X7AD9823687E61ABC} \makelabel{alnuth:FieldByPolynomial}{2.1.3}{X7AD9823687E61ABC} \makelabel{alnuth:PrimitiveElement}{2.2.1}{X86DB31B57FB4F570} \makelabel{alnuth:DefiningPolynomial}{2.2.1}{X86DB31B57FB4F570} \makelabel{alnuth:IsPrimitiveElementOfNumberField}{2.2.2}{X843C2BE881A3576A} \makelabel{alnuth:DegreeOverPrimeField}{2.2.3}{X7845CECE86A83219} \makelabel{alnuth:EquationOrderBasis}{2.2.4}{X8185FEF1811EA43F} \makelabel{alnuth:MaximalOrderBasis}{2.2.4}{X8185FEF1811EA43F} \makelabel{alnuth:IsIntegerOfNumberField}{2.2.4}{X8185FEF1811EA43F} \makelabel{alnuth:UnitGroup}{2.2.5}{X7902A7877B65FDA1} \makelabel{alnuth:IsUnitOfNumberField}{2.2.6}{X7D9484BA7AF4201C} \makelabel{alnuth:ExponentsOfUnits}{2.2.7}{X80389D828474FC64} \makelabel{alnuth:IsCyclotomicField}{2.2.8}{X84CAE4627F0CD639} \makelabel{alnuth:NormCosetsOfNumberField}{2.2.9}{X7A43318584DB3756} \makelabel{alnuth:PcpPresentationOfMultiplicativeSubgroup}{2.3.1}{X7975303583E6058B} \makelabel{alnuth:IsomorphismPcpGroup}{2.3.1}{X7975303583E6058B} \makelabel{alnuth:RelationLattice}{2.3.2}{X7C6E88FE82BB9DE3} \makelabel{alnuth:RelationLatticeOfUnits}{2.4.1}{X82B056EC85CF150D} \makelabel{alnuth:IntersectionOfUnitSubgroups}{2.4.2}{X7B8C89C980CB15F7} \makelabel{alnuth:FactorsPolynomialAlgExt}{2.5.1}{X815A5FBE805119CC} \makelabel{alnuth:FactorsPolynomialAlnuth}{2.5.2}{X7CC3F0458523CB22} \makelabel{alnuth:ExampleMatField}{2.6.1}{X7B4AE27B7BB8A9ED} \makelabel{alnuth:PariVersion}{4.3.1}{X84E2E83F8251DC49} \makelabel{alnuth:SetAlnuthExternalExecutable}{4.3.2}{X7F2835FB7C5069DD} \makelabel{alnuth:SetAlnuthExternalExecutablePermanently}{4.3.3}{X81CD0C70812FC6F3} \makelabel{alnuth:RestoreAlnuthExternalExecutablePermanently}{4.3.4}{X7F648B427EB19552} alnuth-4.0.0/doc/manual.mst0000644000000000000000000000046415201210200012466 0ustar00preamble "" 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 alnuth-4.0.0/doc/manual.pdf0000644000000000000000000055511315201210200012442 0ustar00%PDF-1.5 % 78 0 obj << /Length 630 /Filter /FlateDecode >> stream xuTMs0+tgbOʍ II3)==ȶc3܆ߵ%HɁٕX}A+D|B>7>H(RbS2b.)ZG0ޮ_c98I!ByXEqD/+ÈI<fu4~@B"B1A4t]:]XִKw4bSK`80D"e( ery>\#fOmHe൘uV?|FwSqcmYkw+( dR@ ʪݫj>8s<H=lBJ?7<4^'l|UF#g]ƚK;4;N,Eݥ1ãv!||W`G_̸MfuY.f;@>R Ԯ~\" F)Ru)P-VېkGYFoxN]?_~`!8B#) M3.>$J W.kS;+pȞxу /s]UVt- 5e tR :!-&@zG endstream endobj 89 0 obj << /Length 1358 /Filter /FlateDecode >> stream xڝVKsHW82BGqulțrm Kh-44 oH@R{ϯawW7xFd%pc׊}߈BJH /6Nn̿dz3J=})Eulm-]T^hEcÀLД'V!ްZnj)[sy!5bd[T<.H::;Y~OϋEZK}B.W<ֳyuca%tѬˬ M/va[jUɰ>C*Xs^2b̋ʹr~{s䰽;K4뱞vSԆױ^[-0QklD%Y$Q)]/F 0CdPPyo9}FiT% sRqI\X#t9ur`jUja|@_0='\YF&U%l7B4qD\ru0PRؑI=qo~lxU]l頪]6|k:W1mëPC$`X[JZ>XFlQtt 8{Gk.5уt+Oo\UWjıCGj|sN[o\wX+: sO>Ǽ= 'rC2hC UI25iupmuV%bn'@OL'f{uռbhlr<UtNxc׶cs u^)9@zFf.\7 6|+_{P Itq" ~goHGgԌ|vM'L~Ug(@\*ALF}6ˇgla~Y ; vTcPJ{2jHzHQRP=NKg%CU/ΰmz/^V) endstream endobj 116 0 obj << /Length 796 /Filter /FlateDecode >> stream xMo0>1ڨ6UU8)+~9%MdS0?? 00]]OpL,U2U}q s9q3ȯD RףaPwLRس U{A;?.ǺS=y?p47@ r+tn;#Wn룴\Le^C$*L'6q[|&) L!g FsIx'YoT9շvKU5^qWi$w?kVUo > stream xڭWKo6WE-E$E=zsM/5 4́ ąq;á#71Ѓ@r8(^_Ene{.e$4 ^"Y(xm {R^g߯0Ư=z{'4 FyA$Cӷ}itcQGxV07@D QE\Wmה&0;-9Vr<3iV_ޅ,+ IЙ ?0lb=Zڙuå iS /qf ed c {Sk;,JP&Yk Tn?JDMz!FEC͑gS=7.`m屣n4Ԡ f˱5CS0r8fb4> ?H½4_hm=Hj>%$FR@Qp`1sAˑLVGw{f }wM? 2MPITltzL;<|\n"4ӈ"cW +V[|oА'|hX?.r' ֮pC՗ܫ$n؍/YM8@{IyCuRaQ"d9g'HLͪ囷VRC#?ƒFY>S.ֺ+W&2%7]U$y 岙,?dBpay6K6t-MNt3UeOf+ERB x%j~JU}ucITg2-6Ё =#] ]kӣ'&dXUuZj ѭ2bl@ѯeE/hG#TRʛΎ/Ս}ak}>=U}(ܡЅ"!CK^}b^ Ն endstream endobj 141 0 obj << /Length 1311 /Filter /FlateDecode >> stream xXo6~_GYK=ȶeCߑGʒ$N}0;ɏG6ه Żk2N\ehʴbDp͖ٗjUL9;_s ſ>A%10(ͦҒ Q[u+yZ/[ SE(Ԧ ~_'+r}[͛-hBWteעMy]WﮥbJ3Mf"Zdtnݶ.C%`WPєSo1PrX>؟),T 0baT.ٔ d\`LU*=`Tgw۸MʿUP岎CEYb=UZbՈ |l\6mvPV"UXϧH-}hODsmwF-)e`yu|G2Dh~G-i+KkܢjQ[9Xs +1=g "3f5IOqR(=ikJr<R¬>9$$hq| " )7)ᬄPՠ)K [%RGC'0*5X"&s5 d[2..,Qьl&nUv+wKд#=uo/:ժZ|MS'{56jy.Weٺ+!HQja;yVʟZzHZC-ioA11>Ň|<0aU> axwBHxP$P8,?fTك4'PMDE:TREx"}>`WySeMMo,xӛ{1o Cˀ71dHS7D mD%N-TuzPOgϬ/Lr4@שA$bSɉp:H2Yng&godD Nm8z@^[}_>?C ՋQ"F6. endstream endobj 157 0 obj << /Length 1660 /Filter /FlateDecode >> stream xXKsHW(Waz V`vADZ YJ2OHI `k=3=_z^\/~~ Qؒ J䰙! 愺݁yL!s)*ͅ"QN]Ek߽|}}3JF7rY\Q5/+)v+ڟ(:;ީ7.kwQ_ɳuۗ+wH,ZvB@" YxB N=@Uɚlƨi7h>3IzLX2ftOTQ*bP DR>\1QV튟\BGs&EJ"+/(7Y2c~~HNAw " Hs "YnF#4ց L @vPb9X{ۣKnRѬv׽ igE0F];n j H rjR{4l@u;KoQQ)q08gEt/[``)?-&ɊMՇ1VA8gS :`ҀfӘXv*3QoJ 6 Kg N@|[g6Im NYf>p]f;$C԰)j<4Ch)Y@ ʡw" m+ҕ; "GĸzR< *Vp6kOritNlzp Lz,YY#)x3B_(!$έCa+v%zzR`*X$1䟗DW9$hڨr8X ǁO.1S1@bVcUBv+il kZ`9TlDewW?W-ۂ.PMX2@dGDvMP ry]>ۻ9\+ϻ'KM1$#rrx9mvXݺ٬;O<H= ( n 2/_v5?#R7VƵ+9Ŏkv % 71tn:5l@Nl 6,[8l)RPv#qĞ``69]JCndJV9S͆?K(\[83 ۯ)1QgU|; }$Eb]6&ͳtjֱ8CВpآ[6D" ~mKrm)\l Le{1K}ҭ]`A`@Qv.Խ0(Wbt9bPfy8Lzo)樥q endstream endobj 2 0 obj << /Type /ObjStm /N 100 /First 823 /Length 2263 /Filter /FlateDecode >> stream xZn}Wm =@X@6vArdm=PbV"^hԈ!-,0OV!)W%3>*xUo>dH|C>eճ<&y9ZIm9ɬ+F65<<[kږ ( l>ojxUn59<{τq3PYf Yl `I}ju+|͸!y z*KnS~fYoW-8kW4)躔7>|PnUbo 5E4gLn[uV5moT7Ss*uvF66WTô% _3}vU*p3 *fKr &T|Ŵ?7WE,"/2.¹2 i{KhZE:}9"AۿsXADU{AC-Շ7v/ZۏUD'E˱kUGFTT{"!s۶-q14/sVi\ׅ u^WF`[Q*\tooyr~j6ZuO]z endstream endobj 175 0 obj << /Length 2184 /Filter /FlateDecode >> stream xY[s۸~#5S!dvMl:dgם44 ٬)RCQq{^@C>hDW+zw񷫋W_ikVW8ɤ\锑S׺9w߮R$9 JjKsA=w f+|x#EJbP$K~ ')~Gju.V6R?ݵ.+S~˫K4 ;&PZtNA'YRJos|8R _eQL'}8'JG6|Tv"cSU xk#rADʚNuoozm!r+!X3CD-GWwi Uqos>xo|>1evS]~HdE%F?T B[@ql,O0$J H0b1+ RA:0C`ۮ=G)F('ӗ~%aN2*nMwo5WCY!8stI",m2M8&43d/Go˺]U)h=KN"ʈl᷐"儜үX)T=H)m:)=Pv7<~6 @9N1eh/\4ͿbǮq(j<߶.0  k?k|3ד֋j!4#&'BL2^x&˃|MMs0(LrУ,CWi|ᡒY([tQmU8 A"+Iqmʅ}gQkwY~LruVsۥ4QE2nִMtӐ(؃jwhq_kT5Ox\Bn&Sa۵?f{q=>?˻Gո}9 %Vqh2 o9!BeNp|J>g{|3!Sgh#F2t];0; i8wcԄ+65^9އ!f4'A.Od-bQ[|vl,FBՈxY¶_?FJ2Aq:.ϲRPD kZ$h]})SA L YbsM{*#9秀8IaM?vc\C [GIh d9ѐw =IXT>:%"G+p}?|`a| :{lǃvq@+cQ}T=vQ5`inp^s]|#q6uhjU,l+ğ RΛ!x-.qct813iSIL=Ba0#ޝeGdZ=ݾkkKN~4[.$Vd<"s"}4#BXr-i"I?k6 " .T 3}@H^ .Dጰi7#ID-QGQ*Sn(2+9SF*Y>8 HX:䅃Qwru')I(Sb#0ا?VM n1pq&%?K՘^BǸɖ4~71FЩ~Fww(a(De*}G4w3p$IHu?^Yԩ9oΞO3ػa h130u@zׅXƁr&eap-Dӳ4b9_=av XM*h= XdDӶ~ECccm402&u_^]/ endstream endobj 193 0 obj << /Length 2417 /Filter /FlateDecode >> stream xYs۸_'g!uƹƙ\4m(E%]`~ Ml4NhѳӔ'd*)'ьdL&dYm釋_0J2!DJ9Q;>JqKuLgO.0Sم> R M)s-b,mq>Hp@b]68f[WηL_fk-Gy̸C"2 A٦e`umn".p[IZ.}cC"Mr4U$M[f#P#E쬧 %Q.Q0ߺf F .S61FQ I81?Qgh250`1{, 4F#C*&`. ʅ5|EzSFr,m ǔc;W6V^yoFYX]/KSz>Ĭ7МxJS2 %պsEYW4 I>Y ^oV6s_X4.~Serϥvv2'Z/|/*ܹ#c[Gt:n5ynsK]Ev֫2_~V\zTeX W꠾{s6 WdyC7O( {80 `h.H5I.nts|=ZJFQAV2`iFە}=&(8XgT:G/;P Ū*cܔ&58tlP9U\:ѓ9XSo+yg]J.ۖQ;f)QM!ܖcZmG:/+8m By{4,788@`3 <Ew2z g%.{`Y(GE\l? YՈfe rU65/#^%жt]ؕ&wwJxUhDkƌC mt|.^!7#29TŴ&Wr@lvQXTm{2j|!vE?f÷U&PO.AU$m]V 35"ߘ8rG\%,Hh׺ 2MrL;oKjc;}`eFd K a̾{08yqw<rք\RGB|.YM3>99$_}ɹ=cE/῵Gc sٵ/Іo=Q$µWPUEVՇ_,o_kh0wzQd/BāV(N endstream endobj 209 0 obj << /Length 1323 /Filter /FlateDecode >> stream xڽWmo6_ _m@$Ŋ X[KS@G,{$;R"[9B?<='ߧ ÐV׈H+-h@47dz %9B00V*Z3" iưP W+0̭AkR}} >j,)}Dذ/qt]m7AlͶQXZ=ĉW0R+澂0k{6^_pm 820 Ϡ:I)!$:Wm:MIb A&1/i=ĥ-]PhM84SB5uXRG\ȗDE1+k c GZz}{ThN j/3IDFbgvr^S1-|7ǯ0 t->ȓDh܅ln~ƖP-05EX>Θ6/,KUo*i$ya¸qիfZ&,ɖ6J!6X}x4Vź\~.}3,nf(=UTLˋҿqvZyo'uPoq~.oUg$e΢ERӃռbcSޙ3l*XL}I ^R^tR+@ ZV U(BQ[oYO4*^Qhߓ>Z=y5G&5C]0k8@ hY'  q/XO#fI5R0iDNE6RE1ؘSqtR@Ur 8 'D?ho?PA muwDH MĔYLXwLձ6RB(..hH3u @ )%ЅԜlAb9DŽGB{j^׽D{ ?p5g] endstream endobj 216 0 obj << /Length 1479 /Filter /FlateDecode >> stream xڽo6W؋ 7D[uk XuyKJj_G;kZ"u<;2fC’7W̗n0 *O2 JD+mr;I_>V|=rR1pT*!3TP yD_F,wj5GrF:, l%K No$t6QV نv6]Yt|*ݫA/j-O(n1 Gu>*<]GT d24b>(@I=c|LMqO3 II^5~hG tV%e26IoLMU!Sb}], KA Bj - *'K>!2ҷ{ Y ;ϡセ %X !(x~u%jy&y,{ns_f&`5xfAMd;kOР69C A EK8Xc P2*E|3"5/޽ilI!uhһQ]͑_8WR8(~r]kWrӞRģyȥąˬ4<:2ͮ L6KHVp _D"yLgXBH/D^jO/^B8OH(qjtbi32F83~J!C/1(ۢXPT{sO'B8B{A2!^ 5A=qr֔gMi?88d[.\e?eELSchȨ2:,47 4>fG u֊52KkS$d-]yvy^.b㉄PIPR-;b,n/RBFLG(L?N#| i@l/^ 8d{AlbYkwvuO)#Xŗ1:Ȩ` (-c!z@kN2;Z Vm~~Cirrg֐Ί24v24އٙKܳ|y}ڕgЖƛ'ҶKɢ6[vbݝ5 _hL' FXRiYhR~~%r5xBRaJ_Z@lc< Cf93M04tO+@dJ= ֭57Em1D4T+:ee]dTj0 Z^ ՏZ!ĉ[hDQf`Ȏ? endstream endobj 222 0 obj << /Length 1923 /Filter /FlateDecode >> stream x[mS7ίNBw)3M'$4 MMf.pn/l'wu/F| Y^=ڕd {qw|jXJt "9'׃OoO5OKm՜iF{|=*M%e#Bjw&}MB &^ع0%& Y}6%V1(`L*l 9+H).@eO26G}qЃ~VH*)_kai H[#!/z=(x^|2vPCJʇYVMlدg"˪89*![D(< EQE2&ejGUIUhuX]ߺ+}Vzs?Fi(%W8`Ihփ hz3 2},CςD g!Y_G5_&@0t>e"ـR6s|4G;a=q=m­- ?+b [XAF7DkcBjn^pHDPmvQߪb^M9F Qň˨8t@%lGKq ~1/k,g&EŨBG VC"`VF\ZZM0K_kmwc~0l5B~Uzhv0Ńec-M2M䣬4fEhԐ( (fhh΂c$wDRݒtJ?Ѥ;NGgW7 ^D$g0D>0)\.K_߃x2(m ,721F ԤD .Hӕ3W"ef{ V9Մ]* ܚK%y^Gw+Gi‹LdꗰLġW0DJAX8t)O_m ;"0X`LuC bn.}%B>8?Aq "V+%|Gۚ#Q*gEVf!)i6[-j-2#Q(UbǮxF1MN-f_1;Luq~f'ƩP~VVôǎu0A(§.25L H괄O=JSwxGr G"X F*qwQN/+KFM'"QC 441A WZ26^nӌkcfÇc,;YpbֿcȆ*]r @yy;iq2ZDto넣O3QG_AF(agܥ5Dh#SCYݨ8kNbJ0~;a~6%Ӛwvm1Z\SS" endstream endobj 227 0 obj << /Length 739 /Filter /FlateDecode >> stream xڽo0WX \Ih}:X;E%K];Ǧ- 2r{CPGAoR(B'b`JRbC9Mиsw'ף@ElqLan9RfG Ra.̓5AvFgnaq!P_]J#dҮj_CD&1-}y;ӲFE99 i')!vtԹ5\W TczA^!8 OC%yagn;Kֳ Ӥpa mP$X#WW?ƨ[Eh\h(r'3E9R.rЪ;^y/$˽=; dc>oN_q,9;}1cz_٤ȇB;,ɓ!WdXc]JzGy&,al u֍AY 8ۣ,*]& wN6zEG+%؎p$}ƎxzpьcXvAVy%Ycg eQ.. aȧqv?aAX `D+ CV^!cWk9-t}2BJH{}|u#+aݨ 9)wV 6/EPBӯ ת[MFU,tu͒P#|e'P(q;pXëc'V/[* endstream endobj 233 0 obj << /Length 2183 /Filter /FlateDecode >> stream xڝXKs6ϯБAH`n;n`X#ZӍ-%PэF?n-߿=}X,Zzf ̹)xW"k[603*%9)Cܦ0bik7X`Fr; !eo8DkJ>[ύ \XFV]gfO?,-@e2L'W_peY}\^rڴ,MUN#CE2Eǁ}CW*𲃫Q,놊 C qcJpPҐPGwN݅9, oavtxM/2Se+ʟxMs U_IŴP]̍'e)ǡ&{EFWcq&pI\.2:hy\Q0e5a?0Qti^ :fqo\W"ӡ{e<*1REz%E"*lJh<ؖC B\-jimU^h;.4'ؑJ Gn$oM/!~ϧ hτl!dI'rZ`yn&JB.kS[sqB.tvReHq2㚿@V H-JeE]n kz{+k_B~wm`a@L<޿ vZ=dA) zΫʬ9ejKJb|ןƵU#t=^< !@$8PJ<#J>@-rԣխ ɥ 3ƹ\M*R1T%NR1Žw 6$M8iS wbf2\}83' endstream endobj 243 0 obj << /Length 2968 /Filter /FlateDecode >> stream xڽZY~_!Z}t; ';DIRBR;;yi8{Àfuu_F. uH"wP*ZDw/ޫ9¸^{<] WZ)#?k2c?:EOVYn4jsx|Lߓ[s Q=&l>9H@|FU>k۬f yj̡9 buH(Td%:3qNDJu-A"P%F3* $ӖG,b0u 4d<97m(Ȏg]iJ*i;X'{ u  ԐNttJ; k:%r.m;2ּV%2!>E@O44 R-/9hW`g[m+^Er$ O|s;ic i*Ӯg<$E-KG[Tr·=5߭ק1%<꾪Yz(v+*݊C{,.UHG|6 qS]rʧ$.{u96Sjjw}66/ܻUE4^{yD ߨ/&PIM@(pQun|O߿zƾ)+l"羷2AF&q4mND=CFϼAS$Flz:΂sx g1$U-4 ӧ!3S]/ezm(1L LAQ\)0F,#<Ǧ͎V͟l7Y ]b .tkE7ԆX.\*Ebzu֍.=9 W7>Q6k7c~05#_չp[^[EmmGӺwe)e1p\Hcn9Io.IΜiPHe47g']$vGa㉹|FQ(XUd "2DR㢲‹cܱ41G/NJn|8.cºr/+JQ|M'a۽4,^f_g`b+t |6mR[T 4GWeXDĘ HLNZ* ?!͒iճ _\*,vj ֳެQ v=)bU><ݎk9 ~<^L%Ť΁Bv|mpdO]8цEn[Rj'6lCT%}@\(ųчm$G\=ŜX]vfq8҇|I,Qp b2Xq?*R's`΋;@]!C6{.Wn, ކB?MfZIu LוЙ > JC$9tBxVX I@5LܻΕmx iKG]ĵ|X(;}jB=94 Iקtn۱Z3NgӤkt0@ \}rD8`26U꛷O]WNT56lqtXTtc%=0Y(u1tYYizBbsElgLn>XUs_YلTnwW"r*`q~M.XMa> stream xX[o6~ϯ: /.͓^oAf둒6ۛw]MLEv^|o ho ieLvk7ov&g`4^)W̱65+gV 2󑖶uke3iLR ?eX]M<ߤjLJ*H탡#oEڙcK^N7b-F?`Ǧ͋vnLMto&6[.IUumcUfh(G,U>ߛڔ;C㼡<5XXaX;s0eR5U0>﫢:?6Nh2I>S?.bf&!?5N dB,mTlBqtJK%wjZ~dԾm!oϪ`Y:Vye. ,v T4Q _-[ "{KA%U@=̜rXYa2_HTW B$*N|D+YCSpˋ}\'XSrGm49oZcҬߠ {7kl YoK1cܣ{o:(`4> {lc(c!=V2{NFqش O@O8d-tLlSKSp [R]~B!eZ\~2S1qw|s%qڈ׮6ʔ FH:bqг1KnFgQ'WrwylUJ"~,:W}aKȥX.ړ-fq[ T}E.BHo/6 wV'E^Bm |ҮI!6b +߬_y*(' F蝠'Ӥ>j5}AO)qIKorUτ:z}۪$[zlfiA%%6c%G0 Lb1{8>%Gd'5aDIb´hA5Y)e9 ,|ۅ>Ѷ[Wd4uGr3pxrWef>TARoG~~ܸYyZPz EUY :r2 ,2caZap.ߴUݑ͜?]"iD D^H6Hi (͠9ybT/H1Y}D|&=trRRg]ڀ'Ra`"Eż_5̯rGbqɂ'e_6M:ž a;*Im䖆"T4\+Lū!]e%D8reFe:44;FŵxHD^)NУϢb>$ RG,l`atFx< 0}E![ D[#GzS;N  8դ2:^Y·tv*Z)ݭh%xĊ"T(<>i{_'&~4tjT:P oU *> stream xڽZYs6~P;PU 9ڍ'x&:SJ,PcF%sZW`/G#>zsw5>%HƜ "#X"n1=΋Ya}F']F,n: gHh{`21 YlBzI3Mo1>~?"+ -hlRc?X h"5%?ꓰ$V`Q*f5(j ]P{n?P_7itʖt,yi,)ZٿZg;ɳy^˴:D$[uwEYNTB&:!i-9dD-q!J"pq nק) Y>CsE2Hྶu*Oeat]WF!¸3k ;o5+.$WeՐdlTl!,ϩ5M>s_W#E &z4__'-0_Tz$~(Ɛ6Ҹ)%L)bP;"Ѿ;]orYIId#'as|`{L/~ '"zxRx؝EۣoR:1X7M;lI|,?XabQQs&w@*"eIjkz:n,KS)Bw4{Zb53QxXINa9{x}FB$C`wߤ۲y9 _uuڬ ,w_sYd˨n> V~u[m۠n7-7}NꇺkVV; 3rm7&-˨xzfvƲr*'*l_]y2TsA(`RLm]Cö9aA}lmԱpc*}k`$gS-e.v^:TiX}ECotJx"|@a# RNpJU#]_6r_=Y`S=wp%,!_qKb9Z)HB ? v{%3DTwS jFt4m :Wu2@P9iQp3&`vE;|,`#US7SBNiû櫬EuuK)Ѝ" !K,2m:|?g 7\Tm' xtb@(eo"H> ޕ鍊]y-gL>XоXafRr] fi7> `qȑuxx_ Z$IGp A!sN"2@0!GemաWj 5\z1fFEKxtbyy%#dw N _7[Ue卽Ou0vݗ:Kˊ/0`Zꠋ6i8aPm'./l^Ae@5w+ '+\¢qmڮݷ`lI1{,g: JY=&-8l&A6â>+m( vM)4؏E=H۬ԬڢVV ~ӂ(nfu=eۤUT͹+z@8p h[g /LNt#fȜVCŜ"ҩ'=>" ;?L.KTVqYl  +C8sZWe}I{̴yFc@G8[Tls/!ob(a6Me癛dFs%]x4#{wlk~,J - l5tqz9ʑ> stream xڽYn7}Wy3 #mhkAU[5tA%N( iÙv3Ɉ&G\!J: S5b2).W/2ԭ Rb3֥h2\ɘM!}^L:F0@B| ‡\TbOJ}PU2dB]]oy@EMGqSRn!"g?/ WǏ8c̊dhKJ$2*H 0a?;(dW@sP6-*9ǓyJcH`WA{QU%@p B+!XTQC+>ts1pN#vc;&u s8aRK>#QB$d#1R `|/t tQ2C W B&B+꣝!L.  g%[ XDթRC0? *%ã#^A֜94I(&` WFosQub<+lJXP1 Wa%ZmF@r-inQc2n_7cM-" \vt<^Ӽ{d/Ks/1 ǃ ϖ n0^h2^7l2|~1'C 5 \Nm8 d"w?ZP-'σu;?;y׼ p2!lW" %nhUrDcᎀP"{RvMkJ-\aDXƐGmgZ`QdXKx:oiIut=|_l΀ HYԇֻw=<7x-"D*~PeW{6 uha^f㹱(aZOZI j n@lAcKLȦn~=[`1ZJ}!q'0m0X]ڈN=cIo/4SP/RʲX>kÃ|s8ZNYs~X.?7dydGes>zy5}*p:[-/x:.Ƌ_9/v6V҃;t2W^v͋^OOjW}X'UaQ:,%K>Z)zY~o`~2+a9Ylrۥۥ;?J6D\ !VaUkbS }VAK%le37n]mj.%$Q-IJV\=s[;Gh.AyW(8XO6:z=9i,\e" pO߇ml>Cek#&{e^%j2ҳWCbO-t[[tJAbCJtBꪝ/Qa׋Ҷ[Dh endstream endobj 279 0 obj << /Length 1187 /Filter /FlateDecode >> stream xڵVs8~_G1we˺I7״Qc3iߕ%L n.}`$߮gįWL`:{dC0q0i A0[@zKS]&KԔ续cSV-)|Gr@@1tCFJrz>z>f{;rn浿I83Mkd@Yn bK,B?NkL`9$ƤNϠ폱]%^7:"r?x/eT&6}_buxkFB0}Ue%L'(ch6z VۡDN4>IGE#z*8S橝R(GBu݇vmj_8Mg:7Kyי}tgo2q<78'‚Dh+8ypʐ+@Sgv߳'/ endstream endobj 314 0 obj << /Length 825 /Filter /FlateDecode >> stream x͘]o0lI˕bZl7.`|0TwLҖD PH^9~%"h!s3p(2,-ccf2d;S=^9\}{f`وoA]F1% B"^Np'Uj{Pl${K&(0f!D?;k0redR3{E[J'/\N@pZ˃w lDO[?hPU|55jfcVIcN?c*=L&0S{/?PL E5\72m IbX5_VϟOL;X%UîiǮUjD 1)*ƽ+;qV=S> \5Yff(V\<؝K0hu:i)䘁 b47Fio$0ϪRޒb8p㓂#kLσ(gF`59mnoRm΄/H+\:`cav$̃$쀗'BZ^voDGE]adȨ\6VPS\A=;ԗ;vU8]t& d ]9<] @:TbqBt)ݴKi^k|xyVi8?V{43ظ;u?~*! .tq> stream x=1 @wn^Xbhi(m,-q#(|cYj9֌YJUT΢yךTN̖Y ƭx܎b*N7qDoRp, endstream endobj 320 0 obj << /Length 200 /Filter /FlateDecode >> stream xڅн 0+ ~`A, vtr'utPt5}4б&O Crɗ3)hX֮*ilEAl&Ws:.{dbB3D]$ p %X3'=íU6}C IB%:+Brm^CseB}]P8qOdz endstream endobj 321 0 obj << /Length 219 /Filter /FlateDecode >> stream xMϱJ1"0>Bt7BBGˣ#\yŒYC_„kJςƵƠoA{]VyfIc/ݝ]Íqh H<YNW͌!#|i~8-v:Q,b#X}n}Hْj`O:Aom"jAk1xp3YvG-m endstream endobj 322 0 obj << /Length 210 /Filter /FlateDecode >> stream xڅ1N048feH-AK|%G2amCEg[|w[>]r-;mzM[.NGxSӜpϟ_{ ۇv}a@ZJhD2Ȅ$2c4dvJuNͨ (p7Rij/M)vAm+uӿ@"S endstream endobj 323 0 obj << /Length 221 /Filter /FlateDecode >> stream xU1N1Ei|kBR[ AEQA h.SD;&O͟7+nykzeayH={ɏ#~@~  ,FI# $Hy!p9sP SlQ S]BS3O?9Cz 5I[lIݐ\N+*iD=ktSn'-o endstream endobj 324 0 obj << /Length 286 /Filter /FlateDecode >> stream xuJ@g"0y!SZYZZ(]-rvABs.ovI{F%t\tZSSc/ش\-iYqaqKM%ױ 9UXl订 d ybR.aa cX"`?5̆o,, ߫0Ȅg_RPg)$.z4/@ciJKJʓnyA u%>@+ +0@:ɝs<#Nz3b:%^txۺ endstream endobj 325 0 obj << /Length 207 /Filter /FlateDecode >> stream x}; @49 SZYZZ(f=Z"xSg7 ?2Aɥ ^H[]McajIj*UTNp>"՘VkQrtaQ d,ɹu|--"1^JBR̉*z&v:N{X5gS\Uo.Nb\ endstream endobj 326 0 obj << /Length 168 /Filter /FlateDecode >> stream xڕʱ 0+[| LBI Njh}x&A Ifz9mPkcaP,IkSע03:;|L EI+Er$ 4./ @'PE \b<<Iya9PpbpO)T< endstream endobj 327 0 obj << /Length 221 /Filter /FlateDecode >> stream x}Ͻ 0C>B Zt vtr'utPtS,GB1EAA1$$wKҬ`[43\%4}r`^jijD1w5ޤ l. 0Nߚ`gTj*YO8:uȱqJꂽSyXND!uаڻ7ԗ:1D&/e6 xE3~0)<|] endstream endobj 328 0 obj << /Length 159 /Filter /FlateDecode >> stream x31ӳP0P0b#S3CB.cS I$r9yr+r{E=}JJS ]  b<]``Q"? ?8 8{0u L?` .WO@.R_^ endstream endobj 329 0 obj << /Length 177 /Filter /FlateDecode >> stream x}ʱ 0J-}{B(u* ftr'utPt+G#t< pwxb1?p dsԍaw\XL@y B-r@) -=/4mVgu𤆚N-.Ѧt+.Jf{m?FN3w!ct1]a`/B' endstream endobj 330 0 obj << /Length 190 /Filter /FlateDecode >> stream xm1 P ,jEB`A'qRGE>֣<;B|?Ns42!Mgohu۶՞Lj-)tC*.G'}4!r8FJp-27sX;+YJ>!PDhxհ#qʩe#\Y.D*~ps endstream endobj 331 0 obj << /Length 217 /Filter /FlateDecode >> stream xe=n0 ^ !Ȕt"YkMG4z0R :]ށ"ħ=,\'7O>i:aAOtL}eÞܖ[V($FFUG"@'C;MBMIU (5[resKMSCЩAgC4jFV"j"kJh+bo endstream endobj 332 0 obj << /Length 247 /Filter /FlateDecode >> stream xuпN0/`<JUeTD$02G#d|P,'?.n\uۚPk^kozETkToj/ ׯԭ 6~9H$؀BzF{baIu=L1;> stream x}= 0 kI NEzbIJS$.(qfc.1xIjsq$Uj"ۯ1)Fy#ҜN&"Yy 2$P5sΚʮTz)z@=qQg5椳[o }6 dcq endstream endobj 334 0 obj << /Length 222 /Filter /FlateDecode >> stream xm=N0_4{2lXҲH@j D (GQr.L(4~sr>p>ܟq q<> stream xuϽ@ ^H.1::htG K6idP@ 5E5^0PጙAKaRݮzNi)أ F8/nO+y\җ1DgiP->Ձan,Oz౽R0ʞ^ endstream endobj 336 0 obj << /Length 232 /Filter /FlateDecode >> stream xMαn02 ݒG^:DSD$:u@LЪ:DGˣ=D1>$N}q2QDcMMtR1% '3̶{FܽBيԂ4570ze(mi_,h[i[s?v%| ϛ'a73UVWhvV۩~rk endstream endobj 337 0 obj << /Length 179 /Filter /FlateDecode >> stream xm; @YL#8'p+U F0XٛQr)$㬈k ?S`O'QD4>&)"fwļD$E3\|=ɗS)bY LTUB3K2Pmr/*qOrZv_Ծ~bnJ\ \T endstream endobj 338 0 obj << /Length 244 /Filter /FlateDecode >> stream x]N0 @qK?j`Jc N'q@p%~J>a)ODiVkh)Y5a}[mpaxfV;x|ŰÖj?D˃yp̓gYYC;@!&_@b˔?ճGefoT8g~цv@Q6tozazkz4Ut_)ΔQMEјw>7x@ endstream endobj 347 0 obj << /Length 201 /Filter /FlateDecode >> stream xڅN1@ 6<} +D ,ZZhvO so)^r̤"[RDe1]bc1% OQW[z>^WnEK:*IЁש/p3ي2ր'S#-X!ghr7o~FֵE.F44POA)RC I xZa endstream endobj 348 0 obj << /Length 137 /Filter /FlateDecode >> stream x%; 1F;]]hL!he!Vjih7eIY@5`NKnn;[.>Yʬz8nQuĥ>W#D*L"QCĶ5e" ьwO)B endstream endobj 349 0 obj << /Length 192 /Filter /FlateDecode >> stream xڅ1PDPl Ċ1D+ cmq@IA;WL0 v xlagnEt4'g'Ty!n{> stream xڅO; Pl {I*L!he!Vj)h-G,-$q̃T;LNuihuɗV'/2O4Ĭxq7 $$M | ,G\W{F9^ـ"J[|rY"ֱ4nT?pGrjݬc_e*[M* endstream endobj 351 0 obj << /Length 167 /Filter /FlateDecode >> stream x313T0P0U0Q0T01SH1*26(%s<=\ %E\N \. ц \. L@$AD=$? ?@P&VV̌...SG;&.WO@.n= endstream endobj 352 0 obj << /Length 162 /Filter /FlateDecode >> stream x] 0->KNZ N⤎>cbMN8>] y GGbO%T2[0YFK&pOdLSAZZFHW 2"L}Tߩoﻭ "Іֺ? endstream endobj 353 0 obj << /Length 114 /Filter /FlateDecode >> stream x313T0P04W5W01T0PH1*22(Bs<=\ %E\N \. ц \. a`?r 5ez endstream endobj 354 0 obj << /Length 116 /Filter /FlateDecode >> stream x313T0P0V5W02W0PH1*22 (Bds<=\ %E\N \. ц \. c``pzrrlI endstream endobj 355 0 obj << /Length 104 /Filter /FlateDecode >> stream x313T0P0UеP0T5RH1*26 (A$s<≠=}JJS ]  b<]'W * endstream endobj 356 0 obj << /Length 113 /Filter /FlateDecode >> stream x313T0P04F F )\\@ IrW04 s{*r;8+E]zb<] P\=AQ@ endstream endobj 357 0 obj << /Length 171 /Filter /FlateDecode >> stream x313T0P0S0W0P01VH1*26(%s< =\ %E\N @QhX.OXǏ?1 ɁԀԂ2} pzrrxS endstream endobj 358 0 obj << /Length 116 /Filter /FlateDecode >> stream x313T0P0V0S01T01QH1*26E-ɹ\N\ \@Q.}O_T.}gC.}hCX.O A-4v@ ù\=emH endstream endobj 359 0 obj << /Length 136 /Filter /FlateDecode >> stream x313T0P04U54R0 R M F0\.'O.pC.}BIQi*S!BA,???PP'W ,5 endstream endobj 360 0 obj << /Length 99 /Filter /FlateDecode >> stream x313T0P04F )\\@$lIr p{IO_T.}g E!'EA0XAՓ+ ; endstream endobj 361 0 obj << /Length 157 /Filter /FlateDecode >> stream x313T0P0U5W0T0PH1*26 (Bds<=\ %E\N \. ц \. @#HD؁:Q'@&> f0d82>3 df Dpzrr@: endstream endobj 362 0 obj << /Length 107 /Filter /FlateDecode >> stream x313T0P04F f )\\@ IrW04 s{*r;8+E]zb<]:\={-= endstream endobj 363 0 obj << /Length 155 /Filter /FlateDecode >> stream x313T0P04U54R06P06SH1*24 (Xs< M=\ %E\N \. ц \. A# ?0` @.WO@.8 endstream endobj 364 0 obj << /Length 110 /Filter /FlateDecode >> stream x313T0P0V04S01T06QH1*26 (Z@ds<͹=\ %E\N \. ц \.  \\\A endstream endobj 365 0 obj << /Length 103 /Filter /FlateDecode >> stream x313T0P0W04S06W02TH1*2 (B$s<,=L=}JJS ]  b<]0 szrr$~ endstream endobj 366 0 obj << /Length 117 /Filter /FlateDecode >> stream x313T0PT02W06U05RH1*22 ()Lr.'~8PKLz*r;8+r(D*ry(01l;cNJ l r \+ endstream endobj 367 0 obj << /Length 168 /Filter /FlateDecode >> stream x313T0P0bCSCCB.cs I$r9yr+s{E=}JJS|hCX.Ov;: PNF01`u@Qf f2J~ 񀿁;'W Ǟs endstream endobj 368 0 obj << /Length 239 /Filter /FlateDecode >> stream xڍ1N0Dg"o|$Q6ZZHPQ *!p!eU8i=opZ-uC玝|H?Я\~4wJ3޻MÍ?ε/2"P<> ufA@5ã`cO4s1d1gʮɧ:eP~Kٜ-˺QvOh9X܅H$% RM Zlmb dr)}A!> stream xm=` .߁1D'㤎]ċ8p n #~$(}L> stream x}0K:#pO`i1NI4 Kd0FMj\ijx@½%\PPGL2P[2;|=7P~K<Ls 9y|9#l K#vӜ_[ZCN _CF,a8[NXTQ endstream endobj 371 0 obj << /Length 218 /Filter /FlateDecode >> stream xڝ1N@4QY AT (Ar 3AzWJ_kN|y9H/vI'Zun8-)\ؙBwoVWg)6r}Gݚ3J~ ZTMa.)- o̤/`tR27V֯ifhh`+-RN]dvg9 endstream endobj 372 0 obj << /Length 183 /Filter /FlateDecode >> stream x313T0P0bCSCCB.c I$r9yr+[p{E=}JJS|hCX.OD|?b0 AD}&> f0H0b!On%rv?s?>  `szrrǁG endstream endobj 373 0 obj << /Length 147 /Filter /FlateDecode >> stream x313T0P0b#SCCB.c HrW0r{*r;8+. ц \.    `|$lthvb)،6 Q .WO@.̌r endstream endobj 374 0 obj << /Length 145 /Filter /FlateDecode >> stream x313T0P0bCSCCB.c I$r9yr+[p{E=}JJS|hCX.OH" $`@CLmQD !( ,x endstream endobj 375 0 obj << /Length 227 /Filter /FlateDecode >> stream xڍ=N@\4PY AT(PR$ގk 7eUI"Q|{;5袥aC]8> stream x313T0P0b#SCCB.c HrW0r{*r;8+. ц \. ?c4 N%'W  endstream endobj 377 0 obj << /Length 108 /Filter /FlateDecode >> stream x313T0P0bc SCCB.crAɹ\N\ \@Q.}O_T.}g E!P E >Փ+ HX~ endstream endobj 378 0 obj << /Length 218 /Filter /FlateDecode >> stream xE=n@E.,MvNm M,#EPR%)SB9QPr.]lȢOLt&c&FRf1K~|U.k9s endstream endobj 379 0 obj << /Length 123 /Filter /FlateDecode >> stream x313T0P0bCSCCB.cs I$r9yr+s{E=}JJS|hCX.OLŘN|? ?*f endstream endobj 380 0 obj << /Length 177 /Filter /FlateDecode >> stream x313T0P0b#SCCB.c HrW0r{*r;8+. ц \.  B`W${1y 01h͇q|Fa  l?`!'W , endstream endobj 381 0 obj << /Length 194 /Filter /FlateDecode >> stream xU-@%&c 迨 P$u[GEev K1h8&nL؃-;CFXA_>pi ?!&+R"c(ɉ(N+ƵGSroW\"Ϡ+tIߣmśh5| dXB]/qs| endstream endobj 382 0 obj << /Length 170 /Filter /FlateDecode >> stream xŐ1 @ERxt)R-n!he!VB9EqW7seϨxAƘxң3U5ݮr 쀾"h `,T'uID x/H 9 Zpqol endstream endobj 383 0 obj << /Length 174 /Filter /FlateDecode >> stream x313T0P0bSCCB.cs I$r9yr+s{E=}JJS|hCX.O0"370`H؃@`?#^^Q`Cƃ-Y  f $700 F"b\\\wN endstream endobj 384 0 obj << /Length 209 /Filter /FlateDecode >> stream x1n0/ʀ! &HYj کC @9j1CNjKޠ{iˊs.y^,V\.x_ЉۜWH[KEԯ|9_do\g ƃHLd pLi'Ai ?NI i&tZ0^gȅX{cY701<5  endstream endobj 385 0 obj << /Length 197 /Filter /FlateDecode >> stream xڕС0jrf{::"#a e0XvtmCOh)T^ aLiOvG ֤FscT,r0ʖSiNfEN`Y9Q3pqNN3O0n ZJ4&}5ty+A -ؼ+ԀW2>z endstream endobj 386 0 obj << /Length 236 /Filter /FlateDecode >> stream xu1N@ E"a|$H" * DH$*\!G2HQwmT 娔DJsՠg?x#Um<>r\Iq+wn˜24wC0MLNLtA 9a=tC68yF̛aO2/a<&E>oxv endstream endobj 387 0 obj << /Length 124 /Filter /FlateDecode >> stream x313T0P0b#SCCB.c HrW0r{*r;8+. ц \. @†H0 z(QՓ+ +T endstream endobj 388 0 obj << /Length 167 /Filter /FlateDecode >> stream x1@G(LtYY +D ,ZZhq@IaGhf'_Ϭgɂ#}SqblF.b27+e=Z3bÏB&.ْ`9:Rs)U*H]J^w¤%HRQC/~*hGo8 endstream endobj 389 0 obj << /Length 197 /Filter /FlateDecode >> stream xڍϯ P#)>tœ &5m.b_CYN wzto,NvE69Wh .-rZeD/@sL@56Mo%n} :}v%$@FTiXz[V!zyM-+_X=Ey>J3CN.{K endstream endobj 390 0 obj << /Length 191 /Filter /FlateDecode >> stream xm= @ x Ղ?` A+ RK E[)S,;h%Xfh< }:ex\T:8^pVQ>EmqF;)C}FE$ sXBט^Hȃ@?|bezYETZ_q-`R!a~K<.Kj/\ endstream endobj 391 0 obj << /Length 187 /Filter /FlateDecode >> stream xڝ= @g"#Xraˀ!N;GYg!BR@[]/w%ܔ|q&?,Lƹ+x"ҡ@yRx -0遍~*?umֽr!0e] EӐ`%Ж*sz endstream endobj 392 0 obj << /Length 182 /Filter /FlateDecode >> stream xڍ1 @EIk9 n!he!Vjihh%GL2Φօ}g?ofǜlS>'t#k5?;2{Zd܆L]rBC\"iJzD=[5/jLAOQ~ߏ@B_Zh4J5Ϋ^RMuZ9uEJ endstream endobj 393 0 obj << /Length 193 /Filter /FlateDecode >> stream xڕα@ .<} L &`qRG;[pqᾤ 5)+H+9s<^&|XLפ*L,r0S⺡MNMC $z11wx!"><Zi&N?>cH RaH'c ˁ:ѴmO, YK endstream endobj 394 0 obj << /Length 201 /Filter /FlateDecode >> stream xmPE4K BBrmM>}}V́;ܹiԥS=T'u9&a+NFF⻥OK+ VZ[( f#2;܃J>PDCv@Z }•cC 7'* 4u.7mp b2rcZI_ endstream endobj 395 0 obj << /Length 154 /Filter /FlateDecode >> stream x313T0P0asSCCB.c1s<=\ %E\N @BA,@Az H?*;&p4Aka[~ `1.WO@.^ endstream endobj 396 0 obj << /Length 253 /Filter /FlateDecode >> stream x}J@#E`}!k.p` A+ RK E#U(y[,gǰzqꜟJz`;볟 Z.(wk~x|ws%{/xv4lnfxYDdItSn\#7@efd=`El6X4jB*`f}E_h0bj1SL̀,x>v*!*:MƢ:?-y%ۧF@-7> endstream endobj 397 0 obj << /Length 161 /Filter /FlateDecode >> stream x313T0P0bcSCCB.1s<L =\ %E\N @B4Pe,B @d ?  B~oAd $?HzI8'W z endstream endobj 398 0 obj << /Length 132 /Filter /FlateDecode >> stream x313T0P0bcKS#CB.cC I$r9yr+r{E=}JJS. @-\.  @x@@?C1;}pA|.WO@.O) endstream endobj 399 0 obj << /Length 169 /Filter /FlateDecode >> stream x͏= @_#d.͟ B Fp !VbnxK q\`eW񊉣~2c!GOj .mO1dXV|-M -X endstream endobj 400 0 obj << /Length 198 /Filter /FlateDecode >> stream xڝ;@%$p.H)L0VjiVW(x[_~0E_cƃ=2b4gA ΄Sp)-8lsQy endstream endobj 401 0 obj << /Length 115 /Filter /FlateDecode >> stream x313T0P0b ebUel䃹 \.'O.pc.}(BIQi*Sm`Pz<7,{\W endstream endobj 402 0 obj << /Length 171 /Filter /FlateDecode >> stream xڽ= @[&G\@7!Q1#X^,7[n8ȃW3r9Al&]'-\,cx܎` s0 n ==Cbq1 SeKvI'mr/)T8R`5zf endstream endobj 403 0 obj << /Length 155 /Filter /FlateDecode >> stream x313T0P0bcc3CB.1s<L =\ %E\N @QhX.O$$PD2`$ȃ@H&?:7 q.WO@.ll endstream endobj 404 0 obj << /Length 183 /Filter /FlateDecode >> stream x}=@XLvNBLH0XF[٣Q8ab^2}KJ)*%Kw4 +@@)juE]VQzB[_P :9o.A@9(dq%7@'a/=ߵG.^Tyh p A!\\[>P: endstream endobj 405 0 obj << /Length 200 /Filter /FlateDecode >> stream xڥ= @g fI"SZYZZ(ښͣ[.(wS|7q4HRYs_8 LWCNv?$#(%p:lHj&5pGٌs V,S*7;(&A]t, -GT@8=F> $_ȥF<5ޯ endstream endobj 406 0 obj << /Length 211 /Filter /FlateDecode >> stream xڭ= @ 4 وVVb&7J{ Lig Z 6_B޼q;QH1.#ܡ$ )ѯO-3 # ƒcM?n0O$!Wɾb|31P_6rilxz+=Տ>jO=]quBVŴ~[)D\|kse8'vG endstream endobj 407 0 obj << /Length 158 /Filter /FlateDecode >> stream xڭ1 @ПJuj!Fp A+ RKAEh9JAqc![̃I`4-ØԈmjw쎜{Vky\Y\/|9êe_Hx+5C8#$RC\B"xo<Iw endstream endobj 408 0 obj << /Length 185 /Filter /FlateDecode >> stream xM1 @4!s7q5@T0XErr,,2ԎgDM&rv=pr^ًYMyaoY!RrGB7 }KD#"eZSW!("PB Ca}96A=> stream x313T0P0bc 3CB.cS I$r9yr+r{E=}JJS ]  b<] @AH2`h AA~[@ Lx:B endstream endobj 410 0 obj << /Length 148 /Filter /FlateDecode >> stream x313T0P0bcc3CB.1s<L =\ %E\N @QhX.O` $0()D? d=H2cģd> endstream endobj 411 0 obj << /Length 186 /Filter /FlateDecode >> stream x5= 0W:oN`B`A'qRGE7^̭ ء4ؔ? ,&Q@>0[}pb*Q)QzܟvI>>yG:J^]S |-,ZHZX:^<r[C准qzb&gaQ$L endstream endobj 412 0 obj << /Length 174 /Filter /FlateDecode >> stream x313T0P0bcc3CB.1s<L =\ %E\N @QhX.O `?aC00~ @2?Dv`N2~+ߎ #ȏߏ`` ?G#g``?A6 H@RՓ+ ɝm endstream endobj 413 0 obj << /Length 202 /Filter /FlateDecode >> stream xE; PEoH!LUBBBN!۲t @!L@,a̻{ې lfOÄܒZrɌOp>ܘW!kJ/LnRQ;H(+p{h/ O.ok> 44W&F&R$}xY& endstream endobj 414 0 obj << /Length 237 /Filter /FlateDecode >> stream xEαj@ dz)CB=ҩCɔdnvj:t&=$%p!:d-"zX!ZnhyxDQd}LKႲ)ֳ[{vȭ+OPy5 @U-G[;z[*lB;v\ɼHer;SHR Z88 ~Ka{ endstream endobj 415 0 obj << /Length 176 /Filter /FlateDecode >> stream x}1 P S2Y<9*BV N⤎G(Ϥc|?!?'S3>gt#͔+^wr~ÏB.9#W!H"Px+"B I / >i`$f_$hj(D{{-ӎ~b endstream endobj 416 0 obj << /Length 203 /Filter /FlateDecode >> stream xڝ= @_L#8MLRL!he!Vjih'({!q-6߲`}t!'<8 91 ũ piNfqJf)c2ot=̜w{@^m W÷x: dTLdO_'X`*w]!WҢqz9KU" }}d endstream endobj 417 0 obj << /Length 141 /Filter /FlateDecode >> stream x313T0Pac S#CB.# I$r9yr+Yp{E=}JJS ]  b<] X큸7001;j?0FJ endstream endobj 418 0 obj << /Length 222 /Filter /FlateDecode >> stream xe1N1E*i| .-V Ab $(UAݣ(>B,?kWEwk.i;O%/$=iI^>$nF6x0ڄʬ ͎X⌾T~fGvlgOȠ<|HTGǂ+ˇD5WTL3*=2,<8h endstream endobj 419 0 obj << /Length 226 /Filter /FlateDecode >> stream xEнN0 J^ @ZHHCL @>ZlDZTe}9W|Qps}ů}PYkP|N#5[ Sj~??ScNzDDFM&4=:4WL hLVښQ5A1;,wKi sęǐ dw;-y"ͧ\ۼ>[z3Vc4 endstream endobj 420 0 obj << /Length 181 /Filter /FlateDecode >> stream xڕ=@!$p. b&ZY+h pJLh$%^5Y (xTHN)74 U[QcL uMĄB9ƛG3a(if M( /#`cV2OZ˿Z;5t endstream endobj 421 0 obj << /Length 207 /Filter /FlateDecode >> stream xڥ= @4{t&)!BBB,xxqFE惝}ov)ZRGk;Sʱڬ)Nюe6aܠOi(Zb>$\Cǹ.5Tº)7 P \)'ߘ'-,e$9ґ i `AY ֚ G9-c endstream endobj 422 0 obj << /Length 241 /Filter /FlateDecode >> stream xm1N0E"4 @TE"Th+)S ͓=3uE5w|pWs/ 5gFGn{n5j+UknS=6@! `dHp糢0g0p \ύF<'"DMbLz[Zj6]*7DE??(jALP5ˠGԡ(OY*G@BR栛 5pI endstream endobj 423 0 obj << /Length 183 /Filter /FlateDecode >> stream xڕͽ 0+- h NB`A'qRGE(}zWEq _~3#)';#I~C"cQ8|Q iT5t] '`010%p1 iBt*Rt 2;nB)4_T+~Ѭ.:\M endstream endobj 424 0 obj << /Length 213 /Filter /FlateDecode >> stream x}O @`qM>!zI 0XɧSW؈p w3s3Y:'sÄ1P{~s8Ӵ$4'tcot=w {* (D`D:y#jAԠBQSQ]9h@9׆mƠ3/"-PIoәn ժ?|R3{6nR}Zn endstream endobj 425 0 obj << /Length 245 /Filter /FlateDecode >> stream xm1N@ Ema|HBbE"Tj`&GkH 4أnv+4rVISJ{!Orݢ~9^ꖋknR*.PI^((`)3Sژ1+-:%8p'?, \%ᔀ^ÊH"4)MP9%7Hi/! GdL!n&{| JMc_u|_!r endstream endobj 430 0 obj << /Length 197 /Filter /FlateDecode >> stream xڍ `4w/Pj)MPԚ>#46_Gth =(TWC# |=yrϭ3;/ft싳^l,N+=u-',]ƠBR"/ w]OJ Hѐ4MJ0?_9.6վэ-iN͋eVL endstream endobj 431 0 obj << /Length 196 /Filter /FlateDecode >> stream xڍ= @ GbVbh%GH"/Vef Ʃj?8$C(gbg(X]r;fwPL@ | ~nF <z/@:Mrp\3]8[FihHOҙAHVxuO endstream endobj 432 0 obj << /Length 106 /Filter /FlateDecode >> stream x31ӳP0P0UеT01R5RH1*26 (C$s<͸=̹=}JJS ]  b<]L!W51 endstream endobj 433 0 obj << /Length 142 /Filter /FlateDecode >> stream x31ӳP0P04S54V06R04TH1*24 (s< M=\ %E\N \. ц \. ?aC??@P`4,r endstream endobj 434 0 obj << /Length 96 /Filter /FlateDecode >> stream x31ӳP0P0@P!Ő H(`\.'O.pU()*Mw pV]zb<]\= endstream endobj 435 0 obj << /Length 162 /Filter /FlateDecode >> stream x31ӳP0P0UеP01R03VH1*26 (Bds<͸=\ %E\N @BA,<b@N ?8$D D`#2f2X3Iq,63 *@'W yK/ endstream endobj 436 0 obj << /Length 104 /Filter /FlateDecode >> stream x31ӳP0P0@dbUeh䃹`\.'O.pCC.}0BIQi*SPE!'EA0XA0Փ+ 9-I endstream endobj 437 0 obj << /Length 157 /Filter /FlateDecode >> stream xڅ0EkHO-DD'㤎]O:2bg'g/18ǂS WqY2˝jCHo mvx=7~ &ĈdDVvUr9+G^‹aUnF;~ZQ:?8 endstream endobj 438 0 obj << /Length 102 /Filter /FlateDecode >> stream x31ӳP0PP04W0T02VH1*26PA3Dr.'~BIQi*S!BA,B?ĸ\=E:( endstream endobj 439 0 obj << /Length 118 /Filter /FlateDecode >> stream x31ӳP0P04P0"sSsCB.#39T*9ɓK?\ȌK(ΥPRTʥ`ȥm``P !\`߀ Apzrr]7 endstream endobj 440 0 obj << /Length 254 /Filter /FlateDecode >> stream xڍ1N0E"49BD.!ҲH@Q V9#Xqabf4ҷoy5w|pw Raͫ~yzH==US53UKnC#[J  K(R( 4]7^/_2 (`\ <Lx\XgA7A:HÝְZjIKj)! "chI(QUJ{շ1Ge/]tG߹< endstream endobj 441 0 obj << /Length 201 /Filter /FlateDecode >> stream xڕ1 @E'l&GȜMFQVbIx--qFj%.̃^ )LKb> stream x31ӳP0P0bSSsCB.1s<L=\ %E\N \. ц \. P߀ J2~~d|"N`%값 hL F'y,$33oAYՓ+ H06 endstream endobj 443 0 obj << /Length 198 /Filter /FlateDecode >> stream x}ϱ 0 [|TkI Nj}>JcҘ 4蠄|4;.ˇ)Jq)+di#  3 bnA5o3bDTYk[z^DyÒ1 <§QSHhUsjD0N/QG<T]KDbh@C63K[xGj endstream endobj 444 0 obj << /Length 230 /Filter /FlateDecode >> stream xڥбJ@/L i +PysQ%o镶={[r\/䶷\C#;"L E(JdG)23!_#2C[{GE{ʐ :Z2 fFb֘9e)QSFO?V2C鎾?9ru endstream endobj 445 0 obj << /Length 197 /Filter /FlateDecode >> stream x31ӳP0P0bS3CB.C I$r9yr+r{E=}JJS. @-\. 700& @Y4$)&?H L2A :0Y&q RbbH.C _@|A! HC, !݈I endstream endobj 446 0 obj << /Length 149 /Filter /FlateDecode >> stream x31ӳP0P0bSS3CB.C I$r9yr+r{E=}JJS. @-\. $BփI uD6`D2JOĥj2|$(47Ae\=WD endstream endobj 447 0 obj << /Length 141 /Filter /FlateDecode >> stream x31ӳP0P0bS3CB.rAɹ\N\ &\@Q.}O_T.}gC.}hCX.O$3``'Lȁ|DAjD  \\\, endstream endobj 448 0 obj << /Length 230 /Filter /FlateDecode >> stream xڕN0/?BՅv`b@Lб $R_.jKŊ-}oﳻͦTИJr&7R+Ly?ocv~K*^d`dPɑaDZN{8;@Ά:0GdzT 3#'d!Q M4 >15Ȏ×t*ć5 endstream endobj 449 0 obj << /Length 114 /Filter /FlateDecode >> stream x31ӳP0P0bSS3CB.1s<L=\ %E\N \. ц \. p,~BĄ'W NP endstream endobj 450 0 obj << /Length 105 /Filter /FlateDecode >> stream x31ӳP0P0bS3CB.c# I$r9yr+q{E=}JJS ]  b<] 0 %\\\6Qg? endstream endobj 451 0 obj << /Length 231 /Filter /FlateDecode >> stream x]ϱn0` n#' v D$:1NClf1t#4Cd?Ka@?>ό/x7e`+/l2 .|w9be;U:.Jp΂Zг j@AR&B n ~x)[yF^}lEƪ# `"P0~? endstream endobj 452 0 obj << /Length 126 /Filter /FlateDecode >> stream x31ӳP0P0bS3CB.rAɹ\N\ &\@Q.}O_T.}gC.}hCX.O``'!P:'`b\=jo endstream endobj 453 0 obj << /Length 201 /Filter /FlateDecode >> stream xڭ1 @4 \kP1),J--!9D,,T]S[̃3nQ*9zK5.sWj9!!qSdaV o,cP$nPPBz@Q(>Zll/5.K=&Mإ(o9)[-_m0v`fs8 endstream endobj 454 0 obj << /Length 199 /Filter /FlateDecode >> stream xe1 0-wӖZtP*AAAQPPRo7iqpT I( 8{~B&6}\9Ol[L,7@g@GEq;>:@8w^@8@X&as!eV^zH4 6Q25> stream x͐=@XL #V &naRK (҂.C l}/N竌BJh&)^PF ] 厹Fq(Eu1 }C$QtQZۂgmJ9Հe 7Fд?oaF k ,|_F&h endstream endobj 456 0 obj << /Length 182 /Filter /FlateDecode >> stream xڭϱ 0H^{ӐZZ+AAA(}$]8N KM9&xg,\Od+ f.S0~ ,Ђ)qo19/"jB.P;UuDF 'aybhF4j-iMːO*"`a oƅt endstream endobj 457 0 obj << /Length 218 /Filter /FlateDecode >> stream xڝн 1 Y|;? N⤎磝"b/Y>Jڤu)&cjiɈZ=qYh>&xޡG*hɘR. eى/".Ҭt ҪwVhO/o2C xBbMn7ݥ| "Ԁ3ï>$$J endstream endobj 458 0 obj << /Length 250 /Filter /FlateDecode >> stream xu1N@E'rai=1IL,  DѶ. (ig?lncQiں'Tl=yE&lk\FZ,6KNZa| 9|t5iûH Jbz<rd'0 (9qp&8 %?cFi=H^Q #t)g/pxLkDυ3zA endstream endobj 459 0 obj << /Length 127 /Filter /FlateDecode >> stream x31ӳP0P0bSS3CB.1s<L=\ %E\N \. ц \. D?`OY$$ ;R?$XՓ+ VX endstream endobj 460 0 obj << /Length 174 /Filter /FlateDecode >> stream x1 @ ) fa n!he!Vjih-GL2 +7&.&RY S2sjOƠZKFe7?/4#ڂJ"nݯ;QO7ZB؈U$fMYD@ ϝf+;|WW endstream endobj 461 0 obj << /Length 197 /Filter /FlateDecode >> stream x} @\|jU$A:uNձCQWQ /mU%v?,Ŝlriz mgCsb ۓ"[YyAm }$E'}2FZ_V7W?Wei f )XP>V*5yMg9V/zVJAf9'*LCx8 endstream endobj 462 0 obj << /Length 210 /Filter /FlateDecode >> stream xڍϱj@_pK@{98Sj@-48 -rpnA0f#VX܏]і1ey8%dIL2~Ar<"9hM锳AitJweB# LX6vs`RaF$i4 ;QWytExݭ'{gk~϶,O*$=t %~ endstream endobj 463 0 obj << /Length 242 /Filter /FlateDecode >> stream xmбn@ P#$/ "L :vhծgO@@$2Dv."PtO h"+4}ih//hMм.tI?hfs ,hRtA אLZ5;: Gk?ޱR/R7ux;xl;3{gߺjmkxN|סuޔΚv:T-tjO;Q d,ŲZ8ݎ[+R endstream endobj 464 0 obj << /Length 186 /Filter /FlateDecode >> stream xڭ1 @ aM!L!he!Vji(Xͣ)ykk|x$ 0 S9|W> stream xu=N@ _b%79 H" * D[n&"ymafYy.\O:/wa\gVVOK{Ǵý~~|m]=(k}fϋ kEm&fhF hrá +'2ʉ3q4|PY؁0e齳s5\@e'XreSU4Q~MQd endstream endobj 466 0 obj << /Length 206 /Filter /FlateDecode >> stream xڥϽ 0+->Z+S*AAAѹ}>b$*.bBz:ԥVDJQܣmT;fiTTf3:; :Yc6\;lhkb⍹/N-Z6*p|ZX?4>usn tn N2\KKv endstream endobj 467 0 obj << /Length 205 /Filter /FlateDecode >> stream xڍn1 ]1%o )$n@S ZYG!i _ϲ=gzp;:٨T6{hh.DmyءQvF0`80cf̱b9)zA}T$"'S|_Q((M I +TPGey?4dѸYz1_ S endstream endobj 468 0 obj << /Length 220 /Filter /FlateDecode >> stream xڝ; @ )isJE"b=A aS~] endstream endobj 469 0 obj << /Length 216 /Filter /FlateDecode >> stream xu1N0E*ir ,-D $(VT@Iv(>–)VAaYO??V=ϝz`U6]oX?ݕvⷺ}qE XXͨ̎p[P0LhB M 4ESDiDf( DETHIc %)>/~Œ\r/_})oG endstream endobj 470 0 obj << /Length 164 /Filter /FlateDecode >> stream x31ӳP0P0bSsCB.c3 I$r9yr+q{E=}JJS ]  b<]300? C=`cf ?F%5Ƅ@.N%\=CSt endstream endobj 471 0 obj << /Length 275 /Filter /FlateDecode >> stream xڅ=N@ M_(E"T+*AD \%7!H9Ec{BHLid=RI'tT%=VjIM}h=<|ŕԱh UXiSQy :!1{.g t<A9Nt¿ɽ`n [Y'(3@ ~sPoi5E,b6y0ɬ1$V ٺ[Lz #h&;ij$^MR} ^x?m endstream endobj 472 0 obj << /Length 165 /Filter /FlateDecode >> stream xɱ @ : Y k 7:9utPt>ZpcҘ(@>?1t>C1I0IF*x܂ڡA ʮv@F G` t>'C/fH= b賚'b6l Q"Di endstream endobj 473 0 obj << /Length 137 /Filter /FlateDecode >> stream x31ӳP0P0bCSsCB.cc I$r9yr+s{E=}JJS ]  b<](B` D00 aDHpzrrȧYA endstream endobj 474 0 obj << /Length 217 /Filter /FlateDecode >> stream xڭνn0pH' Q" vP+ċekdUGk?>48^iƏ%Ii?1B4,Ⱦr'd Wwc'/kL8TEk%t:u=|?Q ;DN d~U7 S[v0ؼ?bjv? k1N\*7V*=4#S endstream endobj 475 0 obj << /Length 123 /Filter /FlateDecode >> stream x31ӳP0P0b#S3CB.c3 I$r9yr+q{E=}JJS ]  b<]``? ×0? 'W g endstream endobj 476 0 obj << /Length 161 /Filter /FlateDecode >> stream x31ӳP0C CB.sD"9ɓK?\ĜK(ʥPRTʥ`ȥm`C}?  Yo`*?!*9=g!@d\= endstream endobj 477 0 obj << /Length 159 /Filter /FlateDecode >> stream x1 @бa1[ZYZZ(ZoG 2΢]> stream xڍ1@E #0eV$&ZY+h+{4(- 㲘ڼOϛ$ͦ񄇚1'O6MvV6&U~{I7 ֤rkT dR" "/x"o"x Aā, Ң~~5oU9qNȩ9IR 3,hK` endstream endobj 479 0 obj << /Length 221 /Filter /FlateDecode >> stream xڭбn0bt @Y"QPNt@hycs U.ɺϿm˧ > stream xڭϱJA?lq0= %*#xE@+ I-SD5_,9 ,9nsckc_ťc?f5ySǣZhZ}dl5.dj0r DW@`D$  F]67@Hmtt9OYw억g߹٫e&ڥOM&7ۊ` endstream endobj 481 0 obj << /Length 172 /Filter /FlateDecode >> stream xڵ1 A i832VºSZYZZ(ZXYz#llXZO7荆d/9C;GtVibs0W,lQ9O=l1!洖}N)!0Z2-ygg"(.0P5tŷAUɲ+Y0\%-nYW endstream endobj 482 0 obj << /Length 218 /Filter /FlateDecode >> stream xM1J`b`w.~7hXW0VbZ * vnUra!,ǔK-tgQ ->Gy劲p3%WtpK-Ϗ kxzX 33䎅rCF40@:b #LɂY.dČ 曶AȺ lB{,Zxώ`1K{+orSN~o' endstream endobj 483 0 obj << /Length 160 /Filter /FlateDecode >> stream x31ӳP0P0R5T01P05PH1*26 \.'O.pcs.}0BIQi*Sm` $?` #$`'0   Sd.WO@.] endstream endobj 484 0 obj << /Length 159 /Filter /FlateDecode >> stream x31ӳP0P0R5T01U0TH1*21 (@es<L=\ %E\N \. ц \. `,dF }H<00g?`G"?\=kqt endstream endobj 485 0 obj << /Length 174 /Filter /FlateDecode >> stream x31ӳP0P0bScKCB.1s<L=\ %E\N \. ц \. 7P& eJ``$? @cg@%4*PFF2?F2~~F2?N7 H{ r V endstream endobj 486 0 obj << /Length 195 /Filter /FlateDecode >> stream xuν @ > stream xmν 0C(vAAAѵͣ7Q|AwݤGr6&آt&=>'|z zzBQvi z0b zoU YUX)է-ؽFF'{DžyVJtlH!r&u]Ŋ;7RCSQ񋦠iwH>ʳh endstream endobj 488 0 obj << /Length 237 /Filter /FlateDecode >> stream xeαN02D%{pҊ.TD$: &73Ea+RősƂ)eTQS9mr|IJҌ.kk* C秗{˫3Q&l [f۲cvӨh+켍 R PPÛLm55wۃQ?ڋ_"|v։&Ԋ*Z IM ]4O`9kb{0D>7k endstream endobj 489 0 obj << /Length 171 /Filter /FlateDecode >> stream xڍ1 @ aM@ Fp A+ RK EۉG(2E:/u ͧB"IIR9|c#ʅgݺ+Kٕr%:/%!ԕIDeoKhѰj#0#0?Y` ` `]ГnS^yi endstream endobj 490 0 obj << /Length 218 /Filter /FlateDecode >> stream xڥ1n@E?@#\ ^ c)ʅ*q"QQ8%Ŋ2[$r~y.9R3.#OcE_/T_ܙt_?g~)O)'o6`Pv*;k . , UPC< èzDNe{Υ]ɷ~+| 2%E_Iqhҁ x endstream endobj 491 0 obj << /Length 232 /Filter /FlateDecode >> stream xmN0Kxe' 0Y*E"L vd(~wH`O,+¯.wZt7j='(IB??v7ϭo^x# `0#,yB=:F0A.O= {řs2t 9FtJ:ZTTwHsͪTU!,)b")3t#}wo endstream endobj 492 0 obj << /Length 217 /Filter /FlateDecode >> stream xڭα@4;/@NYYZZ(ښWG#Lq:q5_1xD1 P)> stream xڍtT6 J 1twt2 0 C "4 ݈ t (9=Y׵~8X ;: ITt́B!!!!a"c!PABA*uCA<]@P\(!-$@JTA^0@Gzq |0GM_\`nPJJ;@Apu`\(CtxPC~ B&@0vy!Q $pcppO8dijܠ.+_` 0{ -A@p/"q\@v7ߥJM#an(˯f58D <~է CB7+gp7j&h{B5UpnLD9@Q1!)a qq; J` oz@!7m@`Л?" @!=y":D~cu? 7ApXPUK\ÀO>4(_XJ\HHHS8k꽹k#? g,]čt+ZHL|'_QWwE..qraHu:e7 @!0OF5QuP;"a0(D;&v#<`.~a7 vx7ٟT_&,&! _1ߜhFB> #P7.$ѯo"h.P{2A~oHVMi<N!2Num?kx}X3G"=ӸC'Jis+j\NJX.;- Q_eGNWk_'[LpLҳx(|nM|p1/QnH1rI8toX ]Kz&ccʛѥ 'Xݮ5NCPΞٜbz$a+*]eP0{SLoy;w+Tt Zؑ-^6<51$"V$Ezshy(>R\ywsQ~ƒxI'lɭ9_SbsO/goIKf#:ܛ0اU4S*]ZgcZya̡P,ZĿṆ(OZ [ ?{ #9sJU9*K3[V`nʶ3/QW4Ɲ;$̝o:$ROniTsn.+Ќ{.˚]ϑҺ[<}.^V| xɩI3zIYR˽`B)m ˁ O_Kb縠֯~eWh&n7q1j~DiNd^L RyMr}6[H>FwWO9GD_ :9Yɬ񦎆4~܏xY{7.ά`ӰH9e0?~e{|*Sv@^;c͗v>?N<ړmIȹL2>CH777Dm=}.ٳJRz4*C̻֚CíT2>qޗZwTXe;&I4@-_ /YȆ*ҭDpQ~ŒNȺ07E-|e-9|ȾIX״ٳ~<6aʝ% gnGY}Dλwl,)? kWqbZKyDWa%}}mZe/.V6Jqu@FG ܽcj\Rtn-_ۗZutB#U:-V0Wbگ]ҝz +fڿף.2 њwبyl<99mHNIY{)pH`h7M]L^US?HYL-n3BW }kE3 &%;= rl`6;o}4"hG'fj;0c,KѫEv<'U Ï1#Z8Ic3t]2j6w+yD`0uH׫İ#~ޛI+[8^;-?9xȉ6}X̗a2>OT)~XU3O2Q7rTDL:Z8<‡FKi{w˼4][ ߯wHlQbئT"h`#Pv>^1E7NuMFXSTÄJUB|9|"̂{I $ +:MHx^Wl]˚xD#%=;p&MT5sˊ>]W]H F{{7w%GFu&0)U(#wǃ0Mw^o ?`StR/"&py%W,Y䴇b60]Sy2%mOWnN5KVEY y.-~E͖;ͺBN/9Bk0g8J)S蠈wlUle5wן94f6gz2t.|t&kP.m .瓥r嬧^3_*b,/ulŠ|_Dz aPٚ)Ogu5[1*Mz\pPʏ6RHpf{XzQch2͗8%*{][6G-&BZm ..Y{c!8KE,7ɦ@\K4i_MGvDzHGo7kj>`Žo4K2,.a[c3X_mz9=;O`$++sYKcDʮ_ hke.AY9=\{,*+agub r;D,Z.f;m̈́p/eks'5ֱif̱n?%{Zm@1d1A={d/S$iF\_cD_Ňt) RFA40woǾaNӠX9 Mo#mfaZ}DhVJniLڢ:W=XcL2Ӛb58Wck%P,u1zFBIbS;#ߏW ӢҩE5LWJ%O$2S ͍֚صQ2H J2+X˘uAj&S} N$٦'D.Dz .v\g{5P#2:Rںj;E"%Lh{xě}=TzJEQ8G#NkD oo1Z}hńlRm9e:96l|0G_ikdz1bgV '*eؒ-q.i1!m\sos9rb>;eL2Q<񠽭S ,]C_?l~>Ze@XRy>1jM"q1iІF7>Lm*~jPPkq3b7ʽmh!VW#*lV!Ntog[ d",B:qRoc"h{pu~]Nba82.G3#;HONE7O(m[ |yH7s6q)dP5kól㖟{_EEt;=_㴂}i,K^M($$wɨ#Ae8%ɂHFU8uzq#'$/gXM|Fނ:əȍjXL)u35*+hXֶki; ^r|)zMr@׾k4#lIz2qbÐS9 $}Q^G|a)qyL^mG||ܔ⒈{+6'36_csU;榳-p6#?(oue[7sdM|6vI1PLd+1vqrKj9*v=届 ZB}p{2i>K<4B90E6":y|SHkstZ&@+.* BE 4k~xu#1'ބYؠ7^ؙ[D >Iy!Oy  c+j!y*RrNpL:mJ<{uEzUEW~Xa.?) $LP ]0[v CXDTXtn(؞*RC↉Vޞ`nƬ qBؿQ.*htX" Vvea(T[,>D +r8a;CDRiLFLOR6= k{DS'\J9$.1='u\;O)I{撾}%RdRΕvlcL@߶LhxS{ƈ׹ 4hhc8*1 l.U1FiRIw~TO%lvQX1%j-MKdB VLJ5ssV5J ,r!SDsS >dREֻMeTY'[伂Fqn;ɹ0;c\'I{ah4˽$WW}vV1ߪ b&Lďt.F` wn,}?gW8mrCלԩ[rG5'o3`**]=jq^#}#' f򵫒 ףY؅!/aGY1 fi9Qm(PZ.>A(/5~Z[kCs39r?Lc7aCL2ϩ͹ljݾpȝ-f:AG.UaW ϣ@PFkbAӷ"KͣjKao>V?czvBu%(B ԫ8KIrSU!JcNL"ǛO =ݡ<"jT]z>襴'EZp38k[7(\cN*u^nocb(B<)[(-u/~w0cD56qie_.Uf)(3:oXyp83h| -\Tݿ2t!M!# ˸y5F_t2GZ-?/ͿL |o٠^H"0[֔XhjHB9:\kJ9NG\_ysGnj2;b£ec!e@b~fɘ<}&CP=ʵ^3J){]Ӻ~f!=]P-pŻq&5ʇS@,4k6 e:B^ە:CكqfރZקi':n4;y0!zwihbcUY\Uɒ.d6sUHՙ9.`dN68va2U"9!zq]t^}{qOpВ3[ba$&rNߤ^vWޛVI98Lg}VFj~wΌ0N٣A G 7(%u}NVՃa/sJn?}8ëq\YIa-d3먟FDvTO(7LU˂/'s3ƙBբa ݒ*>/UG)5.,a endstream endobj 501 0 obj << /Length1 1442 /Length2 6098 /Length3 0 /Length 7078 /Filter /FlateDecode >> stream xڍwT6t*҉ H'{PJH&]zoҔ* JU*Eҋs=w<3{f微 Q|<@q D,,P o;1aP@B@hM0cOXODbHq"jaᅄ:81`ep ȹBP[ B;B\1;ڂ\p[(lh4BÃ#ٹP#@ !v WȟxXPoBB CaB Hfw&@kp_D_'~lm sC] eM' ]A.(8&Ae9=PH(AA]{N9f%CS"!s3\g n1u{ QSmsB@QQ! u 6czA{L?=CChc:"Am0 #wvb{? 0b^dao)hqi_Nyy'[/E"Aj0{8:uf?$`v?i1ԅt ͯL?~+Ch 1j]-{ `Js ۡ(e'NuMvk@a]8 z}`aTf댹FPnvPɡ z u(lvHf#S;/vxy`p4&`G]ZH +" E`IP!*cH$_וxBl>m%BC:Nj<$qwOLNJJˉ9ٳNr605z q3)o80gnL%?!izf*(^e&!s7`!}T!ɃLYD=C,[^g}txpMQgק+1iڙ4$N=jH^F}gC)I + W꾝IVݶXdO=s\۶ϖ#hl 1G)/\΄2(t2̀Z5;;Fہ6.Dկ~M,ajSV8ٷ ]rBLE; KBLnCӫ6}/6;,guŒx/5f=;}hQ|[l9 /p,..`}KJ_!c%vVv~A ՛x{Y`ٶ6v&@[{WxAx[#4uAW9腾@LOgU*r([UYG?nOlq(7t-EOM}Q&H#K~&.k+wyzų=LhWs^-6)tCXvw>0vƷ9>K6yIS=0x])=l^̜PSP?/9* 3tEtt.Qzx.Ю~s`Aa1G!q3wʇO9f$87! W7/ r Ūi@M'HElٷ5K~w7rb}lI!v9v4.ϻ@ ZJX~dtذs/*H͉mֈaᒥ㝦Ei@FC}eqp,H.adKj*owB볦D!Kg~=a7 'MSKfRt:IYzn=5i]򑞊ͯy _\T=C|gǑJP:< C,DNjg6n$$Coc3PanMDt OCT=E3xFc!=ĩsZ$T}Nlhjq٬ZN"ѡvaP.d wO5V/U5>Z|0h.hr)/+W@Hvb#O#cm\K5"(opH$pY>1beG#qtKYlMOwN UenY`lMΊz`DM־gUm#I<ӌņ+'9,pzB/#zB7' XbMVesh%2cԱHoաd:& WbyYko(;m@XǽifW9i(Ҕs}@}g FiGY+p3CU!ĥWVh`'*T\vuJ*'?{$1\܅/7%fS'u!;( H~W׷+&[<Yr%ƾWӀK3a:I [k1M^t('lZ]^>s iT?a֞W@d ;|ʘKx1L|VC׵Omm 00jA:V^"?HA$JʪXp+ыk,f /c/5e||u{DEϪsMVP5 z}\qO\nGC|};U]m?0vL "lj xlH.*{2BRʣxi:Dʬbi/Fl-G O;c;"Qġ6o.;FUX7d )lRrVdŢ-d5@ih$5h9^Iq+Ӯ&_?w ִtO&[]Pw=KpTj])A=gj P,Ơ*] ٘o90YI&&e1o *KiN]Q!ITzUhbqb-laf[2ql:]W}PqztI+w67"0ٲ.SPqn$_->>!(ōK; KIp>]YOgS<}3XT,1z{EdA6v`JYE%n=yxɐgU+ 1p^tc7DeRP5&wCXṈC\[k:qSy)1CY- gCHLJ;&mAa=yjN.u9o/-yTsT .(LD {n⟧~x8fV9amt 6#@%xIp$]śSݩ|~M-Wθ^m4GL[R,ŌQDbk wVΖ Kii3rnͭo7ptتPXcTs#5vk#++m&m+JJ48 -~T[;GQ24/5:$6I6"2g QK)5Iݣvqb㷜Іhl$ʔN R[ŦݡKfop$1%tAY`'d69lf-& x~,G\d$:0@nџV*>rq.8G%b`^ojB>61alBv9&7$1;NdKN[+vY>hu)Bf:3ܻsǗ(p. a֞fYT_GF`šIN:&2[?ŎBG77K dW,𘖀 (+}:DM=>Yu(c0R/Wt.%1̥j:" 7YnpIsN}pmUzFOx&4=MǂIB) V !AZ5!7Zez.GV=0K.>ʢo}D^n=̽h"7l/ş)mPk>:W3|{91|'j*ڶ~elkIirx+RMCQ˰ɰBYر)A+YZIC5d_ّsw-E<پ "uE;8yn 1Fq za]fo)9[d!<ܳɧ 44$7S  [sev*g:-\zno"n}QԆ!78vGO?\Ot㩎>aW~ox{%S0&؛l=( 6܃zhMGUUe6wf6YNk#y^c!f;'f)ȶxy,^8sz]KwϠ /5*ZM"Xќ -2]lLyČ|Iz:B&uKCj^  /U p5PC9jtH57Y,_nIeB%174qRד%h%+"Q #mଛQIrz&:Nԣq-+35>*6s^'Zx{/BLe^.kb045RiXJ~FFu, zՆ;^ͺrK5!k )^nGE}ϣ ^lN,:J<"J2Dv_k4qvһ endstream endobj 503 0 obj << /Length1 1478 /Length2 6403 /Length3 0 /Length 7390 /Filter /FlateDecode >> stream xڍtT>H( R3tww30 /!ҭ04ҡtҠt|ck}ߚ~sγgVc~E'D GRe]# B&P &0 =8(#!`S0~8@  @bR q)  J@JTP'@ xs(#PW昿nGHRRW8@ :]09 #?Rp˸PR>>>`7OEE 7 0@L` #Q>`$`PGw ƚ:}wo>@J'g"(W0A.g( W@`OG0{0W`!!#~Rs˪p'e$Y  q\>#|6PON^pDS "7AD@0: Loe1 g H#{C($(? @'# q‰C1GB}V@@߿V6y9!0ꯠ!o))!|"@()2q"i ?eG&]- B5PRS, 5/엙1ݠ0?z0]!Vro& E _TB (Gj21@xB>+~Lkˆ-LJ#_&fry*sĄD`$Gi2f' af KA8 `H`LJi bQ#e c? uyy F_/ q$G8J? o WnW)Iv! 4 l?"͸5#cm]SocXˬ`֯E:jҢq8DN։吴Y+ySŪiƊ.VO]&a +c^z<9KBlu<YKlhoDkbϳ}s %wbWϲX'uh+n_. asxLq;kYf2!e߈@X55_6ūAśZxSZXZ(4g{8S ⻡f-ccwc?TpaS}oX~0XxAB2dL&3XHz-mt2cuo>'|kau۷)4$v}9xVϛ%| dD@cL'XdbuAHm/W4Se, }Z֦%W4SJ0Wb Z7y;k3 kDASKSԠߍn2h =}Egg5`a}aN9ﰜSbG$i0dkYm8{^X1x30Ƃ{ȟ޴mv?U=Jwx=+J_I'[*+i^qw_z %ub9Qղٍdj lٺ/{_CIa5C; Y /C/ޝ)C9=`ު!bDCB/N= 5;/.Wnվf~?oeD⵻A+Y&SdbdgRI/vjxr2vR{\$5P/j4V-vΈt~˷dX7>da+l/NWoηJo],kz|2JRZ=LY>kbSoaZ! civX0;iېp㱁xO(l.Rf-޳­ϑjXH3l"8D|(a$kB滔>s][l)?S|e3 }fm=,Ԅf?~VpdkViaN^[<(u| Y~crX1HZ{SĄ'jD ~6#oJ_$dzO7jbԞ=&[8)V][E?v>1 шȡF`~Q%=T4U&ܘa}RL4~T`ǘȯ09v.A>Ae{@ o2z.MXebjE[U_7lIB']7g/JxͲ#R{;9z=bqf:ATf4>|Dz\4(.UpuTQkJR꫐󇒚ߓ3p?_RNPzrG֖v{Z37[- 7v̐1qO)nhEk .]i`by3te:/E^˧c}::n? Vu2S]~~Uh+X[QՎ{I>pb1"-={CwRAncD^/m3AC1=]&==$t7^'=3Ƌai>;hSsSzv4D:%@ź1רصaKLCi߻OXYnopԢ >_d0!C}m7,fVۄ2OqDͷsդoqqQBc+ [54FțHm+LҮ][+d4.68שԸ&L3ck7 #WJ=Ē$R6z'8lM~}ueE>V]ok|iV`,ERuwT-1Mk# ^3rc$ihF& wM{V2q "~,}Q}-A´0̇lυ2ǨԢӃuѮ$2:$bmue@kUA:cUƔ1R!1m» {$BVj&/2g028nMӅ\B5? u+#bZʮY">?74Eax켌i#yG# mY%cQȓw,w.&_Vl; g+|ߜlP%/GR"K- e #9i/4 F?`[]dh0槟3/4^5/SDsut̞ѾS0o-g޶\1T+mRjYt;&Ui9]W '+wb;#{|UqPv_h6.~/V IRwu:4P4lתjs^&\?u?F,RnѕPKJ Hħ>ÑGj؀ϣ}_O*F!|=]/b:t9M9hN64c'˅i^qKGcJnhT [Q5fB<b]iIM3A9]쁱Â5c{,m_^s[D.7[*\xcܒPrDC3_U/q_j;v4?Ī7|<l佷X=p7m0e_}2)wb\;ǦZ+-iChg@fi/snNN0cl'2*_ wtGrc M.FRF83T7.Ney,Ay RpJR9l0Grԥ +Vv4I@opw:-e.ҝgρʥX{օX6&ǝCZUFe> stream xڍxT[5"ŀ{ "` B$t^E:HGP: H"]z{P@X{}[Y+yΞ=sf9 'BbAB@E@bNN38 '洀(?P01X> @@ HRQ25'/A!hbNU; GPv!`$@qbwS+&#,%vE x^p{B?K]J"9ѿ ( `E.H;;T[`E&&$O?? #08 0xc`O"Fa`8l%J P6 qaBh8g?`Y頊ru"1hݡi k#`?pp6G{@pߘ#JKH7If>n__0?7-A~h'q1pC0{#Iwt, ^cX?_y*DMbaKuM=?%Ǩ H%$;'j#a(tWʞ4g@xe* [w@ /F_ix <  Ga`N> ; ކ]}0vXE Ąbq8Z u0c NU79o8jB0X/ l!`o4VLP {_u$sD%`ww1ؕ8J/1( Cl,a{0~~@?,@Pw± c?o.@ KC9` )cj X/aKkBID6Uhi2 BKTUW8k꩟a}{/MN>`=ۖ4QZRveu@1:K>ZK0f!go͝t{}L{h.NQu&ܺtTO>;F>[r]5s;+"]z%OiFUB|Rf^!'TM `>9.>'wP >xޤ<3Y ^~֔c-t޹4#|Hf`w]SŸpt07ǦL6&Z%rėhrd. 9\3Mv?RpK}@!O+}GJU1;Ԯv [E31^ܳQNYna^y9hҺȳ1 F糄Ef:j-\{V,0/pTcH8L؛~ۘqEHչNƄE('1ڏP;yBOAthg" "QGMr#VPm)YLdP '_bSlTK8~i\ud{j^,hg`@*Kq[Ȗ,Xh2:2{}D"ѻSW m!{oJ^30.=e#$D'Y1 ʜoSxw)+v ('bB}J5_,ܼ:n \rx7t^UôsvQ.[YBnNts++Z5n80D^N9`ڶڲӔ!78|L!Ntgy;A9ѱRo3RE̝eא׫'̚);? ͓llت/ erٟEپܘ3 '7q-بy} 13:_XcWYݔ*8SKf~ IK}2L !QOŘd-4F 3{AIZɌB']vu"P5JUAvcE4*G9i(ֳVؑh:Ve/gn+Q-45O~sܨX-a4k]K#k]GKMW?/Nm1Qk&e.Sh氐^t[4ӓ!U /`ltWn7 ytFH5(<%7+upi>ə}`5OiAKv}BUk4[ DU9,Rp2fAqsPa.Ơ3!EY&N<4*uY =n6'CHP''-;T3ury}]rAnlv-EM.sdj-\MS *|lSC<TUQ 78 l$eywފG}FoQKK)j1 0Jk4Nky I3S<͖S?DG^A3 B4 kNc_ }>{U۩JgOn"+&G/^=|ltEcT DŽ2eb+r=enDkA5\r`f+n>ڋfW9a"WޜaQCNb-{J(ؚY\y#ؚJ==kGC]8s9x*KqAIKa#ZʘJ9<ɧQ#l!j[3C%E%#Ek$$ ͂I>YTƋG |ު kCIw{rUίAW{y%Т+Or f(3Jݡp1$"'ĔW#B(Fc- U"-OXAIozBzLlF3rhOR9`Tt; }phSCMp{OJqSCz|>@U}3Z߹1صkr1AWaA:M M~[Hh |KAx-mI1]LUyӮ”+wNs{pB򌒸$1rcM_Y]GYe_{oT~dܿUabND v sJ']P {x٨VN7Jfam\pVQN f?@r?bu,%>k+}If1qObTնF=L,]yIWA2L) Y~G~ɴ2Mf8J&,54UkMdoeoȆLLC—喇F:Ft?o/Y#V2+OLp9u3nC-<+)+SJZb͚= ?@_W0 !}d`0t<&؎I'057t9Z|.3Trݥ ߲;.K!m9Myѫ)Rz()2Q[L_RG1ܖ)4UD1R~]61  ׻P伙)p`dxdN`zʍh#-]([RCE?lD.x=1I%:;fkh7HV8ΰ$I[+u"4bm :T UcU;?LN%L~.*Ce$uɻH<8Oo~0ށLCq53:?/#xzOx8'ź==Za43+UV5]VCBX& "z3V H-gELϱ :+$ľWgfo:μb38t`}+L/^me k>J] ߉~С%KݗQ,Aqy5_U*xB$萇cy.N *{Z n6gtMl'^&N 6k4.BaR^Cn}fqёHbӅśLRDlCU]mQn.$ڡ\o!:0',A;n&=s3oKEj=ԡ3;܌D7}^4~x_iu:30z2P.>kp#/:t|V}P` j!2F)O!\f|Fd^9.vË b|gBCgHraM-Id+w>y,R0ZƀoYc5`T:rNQތu3("kN = mͿ+ OMmrzR0XFo=0<6Cw6yֱuy+7S!h} qwrՏ5<;AdB7NsX0ɄQ Ӻ'R͢}<5k-grz$ ql^"ڲ#ZR_LH6,iDw.zgg5 Ӈ^g85%$&OsH;n1`ѥPf3ouf5o0ae5|Qrtjs]}Y34sijbVb%rOr\t.S.e 'zFSK>ZĞ/wCgx/|SX} EdGJ[gܧ3tT(┝l>qWqfZL7q䓘ĄB?PR>GJ寨w=s4׷Z pyN ln %0BN2c^ڜtRQz|^ zO?.OE9B;5HuxgW~c!gBNW#PXrV|[̼B[HIvJ' Zl8+;$ʼH^ΎӬJĝ2HS3Xe0~9prsl(eQ(|Rv<ñbƻɴ6 > stream xڍS 8MI*f_l 'kɖ'B,sp(-9ﻮ=s?HSQw"V(L?.8kniQ?qzO&>)4*^$uΈWsL>]5i^[Hy|x`)Ooa;{X؃ҕ[x9Ey9#K:jL%u?e4h֜4:[;J _RGK+ΪI|N`DE?<%_НkpY~l.5-xǣ3Ր_G[YtBط蛓Wm>E#jf́o0 k,5Nw$utt[%i_z&,+rYH ys5=^Dfɶmю+o,6K7peo+D+)ĄΔ#U7zK޶(DOX+NZ2]MGr\J@g""}۱'=i!U&pfpm유h-ΤXC 6T2F8;ѕIh49m%"Znb#P0_i9W0(6hxvԌk[M`c{"jԽ7J ~rs˷ʎ M`{n𪥆BJĎ_8Sѕ1kӋbJ/|,ӣ(IMc8s[pzQCq;HGyEaǞY}9yb OE.ϯ}q{R~`bL[LRβDd}zU0hd$gQAOɼt֔`]'qAg?{5A6.fLZ~Y{*Z!:㧞U\ްjEGl8#Rʹ/rZиJ +$.5Ot'Ȩz;K=N`E`yJnK|1| s 1_wtn>3%xoQ"r4cfJdN~ܣ~2{P@BU'AB!|},HSM $>:6?Cu{ҩ=oxt{t#K(^t$Iޠ|kQg6e6}ҚG%" MfO^>r,d8c e#h!Fz5= 7CkƜmUR $ۗ=|x|E;2R7E]:/ԐHpԒecS lk]U2cb[Kj0[vh]jz?c>zc2SЀz3C)$;4䤐,#r2.D?1oqͶ _ĉ_̛yȗ^Ⱦ];eR%N# Yߕ R+*VO-MikyíF_+v+ 72_ j+lC3\zK Frsҹcǡ8'WVENȅӈ֟Ht}4~"S?e1Q=fvL}'-3]p e4 {&hIwVW V՝>BrƉ9SU(b喭f|\lׁ UTѷ` i? v߽o"cdRs,sH endstream endobj 509 0 obj << /Length1 1144 /Length2 3230 /Length3 0 /Length 3979 /Filter /FlateDecode >> stream xuUyh صiGv9.fR@&pfCV6#ctyb47?&\,SMg%/VYV - E?,LBtj+ W+lN|wP}Y0s.}514og|G}0~:ٜ{rT$5L 93EFI)p?cR՛{"⯗3>`}'!uC(KG",숆si#oyou i`9 2$\xa_[5$w=~>cm{ؐ"4Cyb%siyMT4a  SWqkqQ Rc:I[2-ѐ4>dͤEIvGW 6Q3 _F$%Avk6!`}1{uN"BAQ5֖&Iȴuf[qsXZ |)y iEl4zK!|fY Yם]O#i߮cf<$׬tce򗃙>*bz5IH%v!ʹq~N+o!/ ]$_Ӿ֊Q7| Hqn"'3$B?j2:_tJ(-uZ3$(VDQ }w:dy]vW9iw fmcF_X7Q{s0rK+S-VZrcF`X~7.cBxI i> ?#-JwV)3iWV/ZR UT tn%v2tdlᴳNاx 8>ZO3\)Eo}G8:(q]k墸65X'|r JKE#:rfviEܕ2v T瀰m4Ry#35Zp_[ЀvVnk(aRn5#.X`=}G|#$_WdjM?a۟8R Ƃ:¸曌)J/uC GYOIroภI_~+sGIHw誟0^Oh2jQHK^T ɝn@ Z|3٭<pnMxmQ0N5BEBcr\H|VtcKz7PS^J0IC>*3н[EǕ4v=2(qdЮe]ѭ,Gȇ;Iȓ߶D}{yÚt(ɦSFVWޞ64 $ VS^=c9?fHsf?S8\O?Wdi 9IJRr/w)@-M4G@o{Xn|cn-jP! ۖc*4h|{ѬtnQ;#rz(ךx endstream endobj 511 0 obj << /Length1 1626 /Length2 14854 /Length3 0 /Length 15682 /Filter /FlateDecode >> stream xڭctf]&vضm;T;m۶*mUo>=ߟc55{S(1%\XyƮΪ< @SK_9N ā&VV @@ECGGLƞlinwڹ \,3K @LIYGFQ @-lʮ6&yK3`f`bogjOiΌc8@˿n@?*z;`dd.K;W _ ۿ]M,\*K?-f-MM\)_aj],.@r6Fs d/Ζv47r2:; 7?:[F6` 1ccaonsK;8fEo܀Nj?3C'hǤh7%e>(o!7r+G%5]2Fv{ gѸ\l-m<hEmLNoKDoT`fd_kؙl,yWK ,EnaibmVL+T <2aP{:?KQ7_ˆ{X8 l,_@<̾ g#'KߺYU|_Hؙ؛36j.Fv' Q:9%_oq@{ z켑)q݁>P&€Z^]*Pv3CYc}X6T_2B-N.ALeZ1K;85MꗾCt9\ s+ r@3IkBiA/:;L>D54>:2{ OKgrFՍDcciKGY ]6r]ӽBf^SkB#D2!HSB&IFBߟ'9.fzHYԑ}葧 r ^)Ł ~ƙa<:^k7cP%ڕ0ı͝8T鹼<^7cƣhP|I4q5Ƽc%OEy s'Vp3+S̫Vq'_@ J.?%ŀUAo*<]nd}G69~-\=KʢѴ˴S%~LFZ7v%M @Wna(2ǹf%'쨋#k.>>݁0ّꗌ3Xt ޖl[ 6s_zҞmC| VOx|U25R^7 ]r:`zחNv@>=$d'qILV1 5fF[І|19UOf>4=n]2蠴c7_ !02nBqs@N] 5J1$L,gsOwG.WTm9ס̿QӀ D &`6 n+;HG2TC|%`Wk7~_O3+Ev=|`ZdO)cx:aCKg H{/y+&}ES{1$ )9`u`_Adg=`& YNY'sm41;BԴ!^aSyH 4 w )ls_@*''[R1_#`Q օ\_4N^^[x Qn~:F-LĚ[?N=aŚ_'i_ 743ְ #r|s/H l Z 0&-.){J=#e]O5Fń0˖9Lka%6kRѦa%RbFDLZqŤVG-/4ᏡªŔ ~>V &g$'}@:/mbchvbWNNcwP\% oM2Di*hbN "I'D'\?˔Z*!T7'Sxۨ_!çHo -kWjD*Saj:O\|:}X<=A2=_.B5 DݹmƃtLZH}SyY ÓOYIs8̍E..rQ.(vR`\8al"̝)X$vCpm6k~Q h\:-RуoY3g6 -&ihqULAR4ۥk K̆( җV ~CλNl̃FU4Oo#%a2b+d9FȺ<=ʿgry!mlj5KMYfd!A p4<%]YLEߠ"VQŮLU+`]""GnFlqLhnkgFzN_Ku,duccѵj;=6dy-[XN;6Lܘopb*!d̸Xآi|hEa*EQaKs#Q˨왕دb(rv zMgnKRPRO!TDvQ%PC-] GpZ@ʎ*g9΅3ߡ6QYB3@RStLNHoHb)㡌MKGhć; #ۑqW@E]99/AIeb ظVnk-ҁ JpTR07޸uhu^53KK[kԼrO+ vqhqpx"7^ь 7XqaM>@eї>,|}cߜwI)$Ԏ*%Q^~ 2Yd/OXU$8A:ͺ'b!\4e*Ei8xP?m:X w)m $.!ȔOX 1P7z{%IJ%Rϫ XY uwE;@;wV['dI]ua(alZ m=Ip{3*1K5 )s?U)n5JS 2D+U#'$:+ ھmV\Y2݂VwБ璝iMe^+j)j:i.d8=*W 6R!U@I(AW!z[ɕ%NՖuuȮԮĵ+w+[?s]2žl)Qo. zRl"bxonsq24RS%G'|<eMܥ*[^'}b\BvUN1M-sΔ lYȔA2Pg%Y !7l?:C 6vq]\ طDi|g۹Z9PrQޢIV4|$? A-28wrz(kMF]C5BYa!.3ǫ̋{j`~NMd6ZsҸ洷orHei3ƫ.WWW}JEe|I̬ă×Ji#g'ryiQ7=JĆ|Rj8lIsMم"rG*&rB='A`[gzٌ vz \@H802^^.)VK‡ajv\$[zfm8=Y>WzeQq [wdïv8vGܧ=q"vx!qabہm_я"S1hj)Ct?8QgY`6 ^)̳9O,*ƝI!G Ͻ xڨj-JuQR+l K 1_~RlSCC0G+ x$l}J1̞;d*YhP 7*wrȩ6Mo-d<6AxqٰOfvS0##LxAmZ>kr>(VlC'RBK̓Gm22SS,9aDAHTt|r}SO -QBaYnfkKB exCBC&]jX}{ BDgo3/:_x$X2yuA6e=يRl5\o&b'n;3BWP|F௃9XM=?7naWO] Te9rl>ҍQa}2=uv]bk }T4 ӹm$ihQ&C{e6OOֳH{L2U '&ԙUCp?Bt6t!/t3@t Wٹ71T'g>cņPFuvUWS}$Y98 !Wy*?Kw dY= t]hY-'>7:a{'dhoL͍ܡ)UDr$_Eb_ҍfT1=5%=Lm;fXc B9mJTb䩦aه!D ]]xE_ȹVd`0ɆZo%t5൸~/Kw qoAAs,juDNDC}3Wrz)ɭr`WxDچWܐ0 fj<[7GK+2W&?VT#&P(94f+d =S}ÃPͻ_KǬ=s$9we;Odn˞BdgF w{ɟ?-#XDTOLa15 /PmqgpGߕL#/k9z/ mOAc$_]b2c*^_!\V\61J d:jU23pKZ:d<޿'')-0Ho(;}CU'Xs ۞wץ7_V^G5w[C<~^oUe>bVW{hrg'|0v; -VҴ3mVFA5x-ȻFK>GD {ҌfrSْh5T|?맥$qbrk '8@bH,2oT_܂Wezb֞^Ih2$ r>fcݬtCiiB4WXZo9^m(eǒxSt,D;A6bN,6粷>ޫ\dq_#Jj%DpiNlqӘ\ݳ#S5tNvDd(h6\1 Ht yw.g2O!0Ȑg^CIYk۰ɨ!uUdc%6Cmj+vm z/_zm>Uguho?Jyu-/ Qh=<^$TVJfBb4DB\r訥_* o}t݇]dǏУ*0D#,5ީ:nrZfCѲ#~_wuϼ%x׌y;-`2^ " x&K ䷧&*‡hݡu/ֳ J©e#E֣r Ԧyp "43; ]qk£,z]!Lv'\YMу6'ǢT-Em :ܭz4_ոڊ=%B Qn#||qrkU'"=rP?j_fcnQei$hU(J52ay צJ )S'hLlW}9 8F Q:N.I bbW?%!2]>wlO1lsu1O5^Ѐ2[!G)}ڮ%H}GցEJ;0DMt 7Tj9fcJ>{NY:zCS#Č'byyN8{.*1dFgn>ua#Suj 0SmM&'=hq^3Ӄx\-吱GAĐ^Уw{4V@.ٷ/޸ ylcJ!H'.PꡝUMڢ:v0sA75"6Fc?/E98Q6r ظ1__.ѡH cR+_GAZF1V_ԄLJ[r t;J!ڷJjZ3~bV [ErM'~p X1Gt '.i(VF>2{<#TٯF[rJ`i63zĭo#go ~gCN ,@~XI/,0G}\kiجe扜PMNgwSvMz#cƙFzm8Ki`@0DFr"EFsƘBT’R,[(ޙ zK5SOp~NpcmҊyNl0{Ƽ=z)^5!OYV>(+G뇻А!=oS.En!ƌG>n6!&eXU;ܕE&-qpP qvE E)[i1 1?x湍Uۑp98Ծ~Vd7;WS.~;ZzKȓ^ PIJ|G mfS$ьcw}$+rMM :>bɃ^,`@ŸL1r̹BlŧN$o|fdQ"yJȆl),+ P8J0%twP|㗘R`h& lzn%i 0\Z^n.Ժ3_WƎ U vwp|Sp5Q8R ^Z]/#hhi4ۇA XMEz=avҶ|' ܚG^~P|Q-v1=sI|Є5i?с>V]j$[gU\v(yΥIm KBgoZFky TuIi=XY!,+gl,jÇ K?g]-A}3i_ KŨ+[U=UN?&fa6r7(mgf6$Λ+b I˄(~ˎ_ 6wȺ &k0!ci'$eSgHnO9?zՕ_B5qѹ ,٧%+SSB%c QyQz8ԙ5Gu(K+'8泡e-@WD$ d#|Xta^*a*}s+z\Ɋ:zЈAW馞uvv8|+Uh%Ā]9?Q3$뼙Q=@oDtNam; QF:suE[$^9ĆFe}:&+}~vS /y#$B3Vu|I1̴:W¦3ͤ-%|W/- ȲIޯ0iA:E"9ͪ[Ɍd#dkߕZFփ#$?2~K9i><:X&1]=s<JH˓~N+L17m;< b t<"0]mbMl>ixÙ~##!B 8;G(0O_%1W&T6T @i&,qsNS<-My5f^Oa2ve!-j!S/D?Y2߹OU-@Œ %X -w0;ZwmUvj#DpSOOMԁfj\^\v|lܩhĪVu[ tSfބ{h{Ox+wS"ɼj/lZN~kj`9Phvu/S4/8|c( '~i,YMŭ9(G -g2xQ؎l(gmb/0׏IS=b6 9EK ؄GO+z;} -GNbLr\mswcČY`c!TW\aA$l#g*XjSƤ+غ8;Ɍ1`W-= zۉַRH|34W3OQO96G *>tғ@*Xn.6H}`\Z19D0vx݉e'mDTSLP6a WvNtZb_AK Gtnh䓝$L@~Rl/?\\3Vf䇷+6];3RC w2vz92XY%HR6o"&_7%#`-/T[i*0x/4ǷѡVB Tb?Jx*!F'9H6;B:Zf  .LwQkfTKs&8^{[AsEc$R1nB<Ȫ'y}ҕRvGzO1Os~9?}V :tCm>=8B)&_'AF/72I2ڒ:ZYmrjI^JU&"5B.? 1䪜?s*2j|M&h.1\h>ݴT`.lHcn@meozaGh6_?ˤ/J7?sFbR\k i !40YoQU2K""sj5*b7t[.7x,L΂p~Ȣqs~ PJL+xWb8ݡsl2h0:?sz`$'ERu\0"8fhf I7\r'u}QR*uD*O+J6T+T`D^ @̅5ŮXkHo!!P[?ǑX=×BvֿO#h'261zVغzpWBO3լB*xCBVt>^3(P2lΧ< 85y9([δ(2(h5bj2^a ӓ-!mwODcSϑ=NJlf3ًT_XP(",P:}"-K 2凷E͵Q[}ɃӤ)x}"!} K1VSTYjZ7n\_1+->b&yN J-i9(F23)~Z8{JϰUJyvNra4V/O/  [&xAc۹5YU%PZ j5#7xtV,Atz#[)4ʋP?߬N/P״Ǡa[ytM wr>NSڂA[MLwJ22 狨J#8>Y<)epNoRCӬiW"˗Ы>5C$g6=C&_!N SQ(E= !ұqXq3ddO)_(:ݣUboGwT z8ĸP7 6K =MV?:)^˓;h;F;zf6MQN&DohæRV @h6W#+WaZ)8p 6d߷$f,S$:@uO#/?,8U\m+{l绰/?JeTk Puyc ڑ(h96Qn򙛥r AЂ&h> FJ*{~Ƌ*2HXӾ4Wϳ&t.UkZ)mP1SAT!9s4I$2qޑm`- CZ+G#,ZiLsku!tD hXM-V+Kj[AR4(sdpa虼f߸ {Z&ɖ& 8t~0mJN቏E\;X)Gx+V6bo`fU;b}N`)+-JF c\~Cʊt {m.( Ѽ0;=i>@73#VPyYy!@BZُÓqzt:pDu%py֤~>#c;94/]ɦ_ڥ<>2Gd𳃍kSr#Z vHc!%2"ٙĽMJhk,!M{$2zF<6!W37=L5LN(̣PC!>QM~Jr%{ُ]]uY|3?IZE4q]%l+Z_m\ ?Z!a6zznP ~KP;܍ySVWD'O<xmM {YoLUxځsz´Қ,`Yqb_@8댦EXr˓kN[i(9;~csn;`ISMcRtL՚Rrdd܈axsOb@4MpLWga64G466UFt9B*M)tԂGO.?F)i!>)B-f=%b`vE.J(VFZR5;SJNZW { 5,U:XRkY.6i˼} ytyUV\C6@خD;xw 5.RMĵtuפMN0l_RS'=e1efRFBzf ',r U::NwzҺ  z^Ui!@0UhĘa/]`~{> stream xڬctem&;NŶ͊m;ٱm۶mVlUl۶}q?ck\{)X;0sdVN 6V26R4 ƦNr8!{c}G1'@ ll`d0pppll쁦freU **c0p_O5_cGEcc1hi S % elmlo s2{Ck#?9pl ݌] mQQl@8ֆNF$WnblmZXqpt0:FwfvUlLZ:SҿtajGcWbnc+ 'e@ 76շ74vp Wz}[[Ky?s::[10i7)Y60[nd:gc5NoH˴H@GC:YZ[%o gRG h֪N&-֦ t56:L-_rek#c{K_nV =) -!*ck^_?/łApTrF? ڸz5An #=dƗyx^D(lTt:%igWR[*; :PL0WODďHކ)1ȍ g OdC7T1$\XInz l -( .oN?.L@ b$].C yRЩX?[f]=LX6F,J%*dDQ!3SgGNWWbcG"‹_;Z_ER_u&G3b8t W7<|~U(cш)X>a^9; ͗݉R"yG"a3R<.I[+UqOoꨯQxƭaH]T7Z&כ9IiޠfZ3Xk7M09;u7 ?xŌĶ15i.zUbAΔDZ ծiR.bc#>-XᲞjAJb윱SAI>Seېf> kVh`1bX 4)$[d()?fc,E%I]ˈBmGH*K /T7ȵA5!_IDq,NP'd8H[70{W (Wfwc,MnՋ%5+y'R6f͔ל \Pkg7OĚ tTF;D*HanYrƼL+\zO;-f9u?͉&ܲզx_Sdą_SOj%{_W(a8j䧾VOovZjL_HTۤj(')*ͷ 3lX&*X>_c^]~e4OR80a0zKQO|_`ebLH^gLQ (ڝJ/R@~`ZIQmҧI}c8xF@rE4}NXQND6ԟ!w[ j9'ы TxEϓ$O×?VJsIxJC&17&YoAht>|fKea!i/뉵~<񂌵$~E#T6E]}n9Qg2]JuQ~@#\$:ķ|Z!|(>"=LF ~kl b6pMăǠ1 SW2Z|MT='Y^jH3mR6ߑ0A <&!ks8{K Q\Ú͹.H.,_ [-K ᏥNqrACENl۹$àWJ(3#9Y*WY;,K#[(~ݕ]mlz:&y$ؙ R]և?bjɟ]r^bFRPt^k:jዌU/rh0%3H1 ~K45ηXv q"E%A%8DHA>kz DO|rw]m ]^+|+w–|:N6 |\x\L\.4b R H!fZW+` -s#7.rV>PVQ/+VBMʩ91}rv5nE#V6seSՖ0Gw`Ds?3&!S)\iǺgtRY3yI/[*6~BmZA9|s9VJL+\)V4pՉoȈHžEsU$X>l@,J@n&O6%gxbХ@_5'ƁcjlKi/z9],b3N`ظϵC}btv$\Y\u4Ue<;1QES.8ҁgJķ23{UYOVa ghR@C\p6)4|UCD1=~0.$D@%>!߶[ò=6SsY|6$+z]:秉tfBajLx(oH?D>zť5F4 w_\ZxRhms\Fr%2?]g_sZ=Y=,5w)C;R0+orzY5=-E El׿I7V7'aJ,3 "a+xku0ɹX]U_K 18.X Ylھ}C(_xl+MdoK}{G⍰}L)XAHY@(Ld.Ut13Q89\RXbhY"49clLƣCA88#KA)NCf8 SZWE}bZk,9npdE1)XI43I |+y2PEXބvN?_!m'M_}ýB^ 2cihD"LO1j^}7<;nッz Eߜ|J~Z4P6?c?(5La/e& D=C攇 R PnRo<)y۫}L%˝W| kq`xN<{?JмhI3;\q ) ؼF}22|\x"T|R u:_P2%opa~FIOLd?S[pN7dROy8⺇$mέGd&NDQ J?)hX?]L8vMm *X}1y- wl9AsYb _6(ϳ!M9 uQR[n8Z b+0Sn ڧjX_;&T*uD6O5u2@)flc` `v}]2? MfA{x \#jU )/bB5w botךoQe$".6뎟S.?naQ%Xq䥼*s۝q{ݠZ}Z*#^]EGL_%Xw ؊X1IhRY:Iqmd3S#bc5a菂OjH}IԓLS"q&ᔮqPzrEu.|(v%ZuuKmx[i"!63ߦK\Ρ4_F" +q"xn:9ͨO{lūX.BԯEQR$IH\pRbDO*f m.B-\u2AQbʝv;9Cwf!GNYv|/޺\ ǵ쌌fPޘ>$eNT^< x ,E",$X1z|o;{1DJ#gzRjQ Y(ljlͪ)E R꺥58\$qZ1i-NNu5]HbPGb~PJ*~<,k_*eXF~*f񡊓g/5ӐhPHWMRi}EWW3D]/v J^N|&4{3{aZ{γu{fչ"#A' nEtƩ;DFƆL!imnOҩk4+dșCꐸ̡}^)\iBţ,a.D+o+H_Nڀ3$dw]$oFQVHtlБ`e"Xok{"-7" MB'j];t=wEVPoOZQ]Y@!̄((#5fZcňM-ecj~)>ЋLJ;)qa׶Vm gi!Ta/C'"T. Z=r)?p[ Fh uQ6wd #Wm6/ve8|$!CIsp4Rb`?.ZN6CJ+*q!&c'xAa4גs7:>5Z젤eg&?F;kHo+%ÒMQ!>nlNqnVi)Ro`Cs ]37e>)qeCljd4zzj_L % M ^׬+q&s;}~X};;V7#MnTj5l(qFGRU|I"1:UJH>-T3 . !vdI:m~ lL ǰd#"dv O w@-r/6)aTL0yzNELզ) &Iq0נv_Z= [ɀfn~.r˷DpƄe`Nq5rƠvnaɅKߥSD4oW#>EO-ߝ kIvQ)B#9y:wlΫ{S8&;(XTz6}7\(Sb!ŋʳ,Ĵ3zvyzwZIv\xo.X)ܢ/OJȄdԎ݌45j5ნ )f`YE}|MzoK ;Uu=⌏55- 49;?P"f Sh lF|JqNO Gi,h7{@vzfL:;P [n7KC~#8v҆z-$ gY55RW:ac 6c-dc^j Eo}3\9H"h]{NZKMn?&ݓSSv\z j7, d13s* VATwKpob:B7mJOwJ pcި"^wiS"$b`啤yXBh7TNSZ7h<`uEws3 }W)oiQ b}.c3WN-\yF&Kj^ne"PFNm1/#He% R ?kʟ6̶*QWLZ.)̘C 껻ulᚵxGZ ڐ=QK! ig$; Estp!Kܔ (LuI, W iMpzz ŦTS!o|3sU=ouMy‘O;8š'm2Ï3p$EҌro5# |R~W=4nv~ͩAEFܖiϦPf+[۝] %H g$>͝}rՉq:4b]0'L\[)(:"ZJ0pxJF5Y5O,8"D ,=nΖ1P4Rb^[݄֌ku3{CvFEI N%b)U(fĜOLfmRHp](כ KL1 5}'R99av¹NݴimΧ?k|2cW˾3%eIfFRc0i C h,[-i sIqwċ7//Pr4O[ 쟘6׷iIdD;Ԣ"EĬl~k5 cԘ%J r X 'ڍ6Rݹ`fsH @MMJ{ci1~ä$ꡢ>kS'D㹨LTfu#q!tnQWݹ%~m| *=Cew1|6\n7S"Gb+U#A x}X[QH׻EzUy^rb]$mAp: %q,4Q~eZҡg?b(eXfM4bdP]ֆrGnI+wBe'oj;-ѮLLVg4)P0jPY1ܕmki*2wŻ#} ,ûS٢duQ7yB/bp{e< 6S?1;q7oGsA*g6*biFx`BbjKkR h "lgZz-!roƠI]_F~a`-["W&obņ ^  wϑ 33.5 sXpܿnlG9%,sk]~؛X  tӁ=|E<f#ћʂEbq$d$V/#r4#[6uMv$7 Q mGi%උܪbLc9UQH̿9Z#%|.%r/sbx%d9Bܕ#NT;C&1(L~q'f; (r;qRp@3h;ϋ-J`.܎ΛOЄ9eb܍&⚘ЅSm0:Y1TdjKdpg$۶SK]Gw_X=mJ)GkŅ[yayz6[ך{ȥQd+ˆ얶%P,7]l>lzX{:ǚY݁u(F 3"ƃv.(ך'R(Am}ZNջw@v\h׾Y%nOc B0W+Ժʖ_Nu_*ŋFW p59=G(e-/>C$g=0L\6O\_jX;Ջ_,F U*"Fo &og$#4 \ 29>ve{'o/PnZ w1 M3QSv^i5ȕA79]U7TpN=tUd=D7&zoiWb{ր]?q{JL':-zL`agK?%̬Gtete0v{0p)^EeŘ-Tڂ9";j_|/\b 1/1Їj ೱ ;|ׁ. z`&9Aj C//NF'Cw2BmP8FQcW5 $H}^$ӁUV_Rq: k4Hɓ$39~6?d9T'xHf5jSE+qn2>wZ-3s1~.'UD~OdJ><1c]+ݏY._}g 2aPT MÆn_ǤjG/p !Jo8 Z ʅ24X9R0+/'l]*\p .iz AFO)3ήiGGD2/5@=uV}@^Њi(N_"د( IJBd7-%xh@U:ۏ6/O+u,5*a d6- `RaJL,!25۫2c.!.[:ޝ#.rE3A}ѵvX ۹0Ǿ0oZ7FѥcKwpюlk7)Kk;KooO0]pvgS ּ h>2&Ad#s tNؒZ@C saL'Tȸ6' 'x֣CRNKLM ~Hix>ѥ3ǖFo^Z >Ud!M"`+Tszl'jyiI uf2!8KP}W{r[eeRK`֫>cD1yM8ݘ@]ZeYKNBIFzC/ ,̻vyl=h̗u)dc >Z8w008X;Tr]׺=*HYڙr_evh1 Zŏwe.l"F6 { ,?kL7|C.6Je⳿#ѐē붆JBПKRc"S/JTq@>WN$8`a(b3EmQ]ZW^\|i$Gl'Yi4{e{6գBTn5֯b ]3"f.cZM9&kE^^^a`W[inQŠX׸7psk)*}pwM"HʗB_"ۂz JA9O< 89A- "Csh欔N{{9 r@,<[||a'0H'{Y'YEblXwjwGuc S?^Zx ܤTfy<X@rGYXK`D @Rlܸ(/MdqH;ҡ^o͔TS@5 N_ؤHwmPJO`tO-k,,40iΩ4Af-%QfJrgڸVpE O)nb ޾lÝHJsEH:o-]Nf;AMW)ɆFVaTs,~Cd(~f&,_`mAM!@Fa JV&ͻUt7_;W^j/R1k+3j#x@ !}. }LkWe~\3 ܸƿ.+vgN{4.qPT&Z o DLñRU_@pŝ>P~R|4V~]c{3uBI~*nGمŴP֯ufwM /,h05ÌBJ'z f 4`ZKۍ '.tgU{&iZUM," zǃ"A #̪V"?j\'0';7.h j<չ;3:R'Ƿ͞GB>@wPzbz$!Iz\wZl~H{)Js&[ 1~'^`3S#TXL w zӶFQ+;+1=tjۀ 4Tr 1̊WBe-}QrW}Org>2R Tj:D8]3LbaŮzZ Q^An|46=dNl%p (z`f/B6+nǤ?ɼI:ð%ЉiHAT/1IĦDabBbwM'w4(9aK3ӆs֨{MA\BKX+v/lĪƊ`^ɡ.5v}"8|lZ}B ^?Xi<+(twEhhO>ז h3PvƊ#Zӹ;[!s](HmIdUԓ) H m}SxPZmd! ʠ3x Dr_we)F{Xd׻Wʸ]ťqi2ayKHQvWpƋ"0Ws`ib^Sĥ4{1qk&8zJtL+ c@[oC5R~"YXtA4L1;#2咺E5HLtz%$bʶ&p/Q9o,I.B4`yE_Cu'u 0 !A9  5;Z1L2a!lIrKS.2 i@ F,JDWF`>A#)[}"]_D#v=E{e/t/V 0B f%{E z@Ugٹ pӢbm g" ,`fx %{W[Aclh?ᆺ6G[( P#rH;& w|j],]ʝ6άu * |v`)*D)!Ʒϭ0# n9wtj3CRԻԕCkdC14蒛H$*Bmu yX^u%q!̚U:]*Q1uH:xHkcu$XZ=?g91UoF#SߝG7~*Dc8a2F#qlZ^0˗Ydzi5`.geտk S&IdGt De`$~t$){~Iݎk,' W869+*`\N ߰yαP7uH{ ]Q gk)Ƃ\Qadw6U %ۢNX9f@Ԅkq:fj8*$ 1Wz$+e*{ ~mF=9n"2s$_I4 Js c%h1+OE1I^v≛-\iw>믗FSW4lC-|| 12$!] "еݰ~0NlG䙘藥ᾑٳ! u >Ҝpa+ǖ۸9Αt&M1K| *ʁ"?ʬ;'?S7j138(Usef͵.ׄ) ~Ff$Rmk6h:4*K@?^Wϖ 1,%;"tU##7̡LCjђzK4dz.O&EF+HBˮfIBc/wJR&qoj>)5O;*ι'9,fVY9gM?nUz~Kes% 8 Pm2W7 L,hx*wX CK2ʱ- d'_Bd:CU *~pۢw$~@^SIf常ʖ+P('\Yz93kF9c~. 6'4f+c>m;o%vJ|u5:*|c'^hCt`0E嵿7[p430y5Z9ә"b|k*7g^'g+x{Ң 99+M#gdž-".e:f5m,fl˯On.]QWK\{"6Gz!;2{: @J>0"59hHfY^/qݠFwu#QO7/ͨO\ZۏBok R"t`@!Ye`k14/FfPu$! k@i/+al{T+ڿsJ#C;h^ ^-oYQOdx9jɫk(iQA7Ԕ ȔQduY@Y8' wz^{jHi$:2e#!3 6ꌞtL[0~t&/CpPuHQw3$XѦ7JE?pkP!(Jz"^BR=Fi>I3'(xO E/>̱e;q^P"[)Es3,qdѶ)B哇}*',myqqDo\'*Dl[(ы?}7>(tEt ,ўXsPgEmm _bwb jTw*l4<(w[|}oWfq*y[FK(U|=)\6KuЁ۠c.E#'`q۷P]pbȮWN2JNUt(BxT2k_ݍ]C߱r <R nDt_r"Z!k ]JHV>V0IfM5vb_.Df|Di3ԛO?*Br2h.}Uo3f&`̾s+B)0JbKoQ6v^]))eJrpa?S_09<qvgP)Oy+d:{ ()W@37~Y +etdy)b]BTzuC(B1w%HԈ[uG;Y*9$A BA؁N0@Yf#Y) endstream endobj 515 0 obj << /Length1 1644 /Length2 5470 /Length3 0 /Length 6293 /Filter /FlateDecode >> stream xڭUgXݖt" ]zҥPB)RE{GEEDU7At{fueu聐  j"!Qa,B = 2zB&P/.Iť00$B,: &!!=(+kfb' /牆 ܸo(E`pgP( 8PW E@Q 8 9`NPpF'$* -RA@' s:A= A'Cq!0` JgwFIa82#$vB<1\T#uͿĸ0W0 @:nBN^W%p48! s @`hO8#Dᅆ!\ u p(q_u_uK OO87ϭàpgaRQ1\L' . A*r5+:g$@ ޫ% p,u&1@bp!7}"$o'5/N ]eM 1lM`QNνUIf>~,?8/ҊfqT'ٍ$+|(Z}mǔִԗ:EtixzCV:G/js^e큉,ȧms= c+XJ\5!ʒطcPVi_e$4#z"sPlɿwrܤT"^iY?u^[gJ>wWϙ<dtR웻m:5$?*9px~Jk$σ$R.)&Ճ 6,mY1RrY= eno%䑾1kht_}wq¿VYڭcm~hx'.^Wo\33s$;k2y^%JpF<EigR] #NUxo;uYJ}}MO z\qr+ 喃uEz9ꕒT/"|kT'޾f/B AD9g-I>N|ۛ{4~)^spNh׏=9 E|h㻥FY~lA%A-诩_hQ $.rS}/CUy/@|NGTeL:am=Q˜^abyY- |ba5J"ͥNb5hD "7 ˛B,[%Ϣ>n<{T% }7IBZEDq ֝S.~ +2ϛTl^~QC:0ݎj)>F)SZK{M x[ӺTă( B%_n~ ]СUj`KCtuCYM mΒnEC~lw^6gJj fyH@.zE55lskdꣁ@d?_dNxR/Rv*E#\&TԎTFAP-yyMj7A]*~鏹.x6"It5Kj6zT uU"<8k]CCOux;wҠ6;ӵBAR?l~jgYS R[X rdޕ0Pkp(1i(Ż?6,zAS6Lsf)R-Ñ>BۦYsF^@&u7X?%oEM̽ &<ōRfGifqT3$."< ;Rw_>p=}z=ii nF"Τ n̛w/vŒ4"^-_9վ{\5InQ?]?5|\&z{{| 2 X"".WZM?s}/~.`[m|ȲwFo)-A50YSo{}6pノ|MB9+#!g|.Tcؐ4Si8v=ld51uittSaYʾ ޡOtAG+dR$3{Z@K^T߀i..X~k% *řYh i^9A#sh ]P $FL7uiA\U?j8a0ϴr[呇£bi5ȳmQ|$%Oa?fyi,?k.j#m-wTV }k6W;.dbG #[/3Z :]&H]7 !7F$m<<&nɐ|9կ½}FnVZl@_yߵ܀ ''fAH⮕l-}F‡n\_;_5n׾!>t_j10SŦi !Qd`Dž#hk>:TΐrKj.Mo$:OJAYgNL5\D]jU}(Js\[)bkH^ *.KD qs#*"=ter[Df()iLD Nx<0(;-z(1nYUOrۚ]?}aH+W𸠄Nbf <P ^خ~XX_? iP13&>MW)q3c;ZK5X )z'RYS1XGz!7\u481T|,fg:;dH=o ցdy?#JКn?OdqFlmL(v4D` &if=_E1q߱Y%Ksqtu HK ON;2‹!ELh(uu fh2trl&'quJN\'oNθMg԰9[y` 9[)i}ַ}3,k_<愩Z:0jKK;vXs uhQ|F'zo5l*SsʜްSKCYSe\53%9Aisz!I3}ʋ$ Y+UK=l3*eW|x+?ÕOU؆9QkD=*+7[* pAC)b`X#u}^M4j˒9~؇-)][wK Ww~-}Yu[ݎ"b3Hn/r峄ӵ._HGZٙGoS mZ+C';'&2o?7BIks I- G#94AmkIqD|f8pKOYWhҾqd FYrm@}8'_0$X֙`妼hvt,1'e$_ړe~ zaⷽhW~1܂pO2:kg7{[i=ժ~sp}tXUv&y44k\L11|Q(A[ֲgR `OL BUX{R5>~-uŌi4bU&4xes@:Ih}j#ʢ]+ ,lKO )^'tR\y"shTN41@`ziQB2[bot;n#g՛,;H<]1K*Owh<0ėPVEC͙7 Mj ]nd0V/ 6CҖ^S#ʌs#Of?1׻SF3|MYKg3~M+\HyC 2AHq$M]""G=mފxP|,&?lC#8KHY>Ӷq֪^E<5鐂CtgQTuo)2 ؠ]]r蝂M#0]kh-,UF-̄-髩OAIFOKyGLNj`Soer@/(GORz'y$]£_u }H12IW`3YPF\07ԷNusai;1ʻx8+G2܌6T.VY۷R(U(G{mv-ܚ\xϣ>U6acMd7 xT qC2=hbW̐S) Y˽{g'1`6WI=!];#i^, ^pajxI$Ô-;x'XzX3>i5Uc»H?:>dS{ѬɺZRI<{bCq}B 6[/oZVbid2guҌ'oI4^YT7[Dc"] }i9[Hθ=K&pd-;@>-nuzvX_[!D!< 9JA)x!!6>u ׁITqK#fTANɄLٿ#op J=&#c]9\}~sKpY:&Րd턾t܁5O du$U%| LĞK՗ǔ'{PtZGJҳ5D,t%vd,kβ]H0"5V:$9A3 Bx e.Q $J]` P[3Kt/k?\5'hM^NNѶ6zxK>HKt/)A3g.GG*^+q]j~;,ono,nnNT16~^&YK;dvB=ß<K@,"B˹6Esk2?\r5*B#7;`tUA%'J?ξ竽$8n=Y%-#*q?#D endstream endobj 517 0 obj << /Length1 1647 /Length2 12452 /Length3 0 /Length 13305 /Filter /FlateDecode >> stream xڭweT]ݒ-ݝ.nA ][ݾ}{OqثYUk֪7*1P΅`ikbo`#Ǡ4wv1|bpbN@#K{;q# /@h XY,<<mlv.cGU bYbJZ ___v@"\m,Mr&@;g `Ҝ?DFgDp:Z:;>,NFv.gb3q5+O 98>ɔ]M,\Q%_-?aNS{׿JD],.@b6F?,N_FN6@gOON_uKF6{?stqژ1±~4qmniWHۙXa7uu't$Ll<@38&{ϐʌ{"/H"FtQ0l1|acckX_F6#w!D?b``Yhdbb03{|Vߗ,ڛXf` :׫TwFlV26Lz.:N^nPs1#ix_mAhs2k+BN9\>`?8 فVzFt@502<4} ٻO /介];+;7zڛ+YiXI]+ ^Cwbdpt.@8+>{dfM:N)>Ll7F?5[4IRf>*7a$f-NwWIP%$BlaKMڄPy%<>;T1 ֮1[xYpIM`tHW _3=64UvmvfrNVr]$e $+@h^U,t%j^OZ뱱맖g`Li[D*#jj#+]菥ӌɾ=Aۢ /l~ N1Yκ#1N8|TvUIŏ嶏N&޾[i" ,~NvmYCcλ^*(Iaު;%FIB4OywDP|]#Q]q""z [FMi}bi֍orLucҴApI8T&gSqߪ)lS^'Pb + (:e]3Wc.˱5^zwM񜏎^v^}/Tuqiρ-%5~<F+5Zޘ`z d! uWë *g"TW-200 0INJ3K#fK|^relj%\ݲ? n}g%[c~nM¯ok|"DGp'4Nq #}ρ%@3sz [hk]-Hdrc{^Sl\fLTźn5qFBjZ FKɮyӌA]FTe') n=EWC'eysBUp q,-1lF|ooxyAɎG9]ևIPJ+ ~Q4aB.6eVێwlk[)zRyv1.S{)6;Trߚwq"E f Lq|a7% n$:tuꓪRbqH~ҔǗ#=K}9g67Whl`Cy:]9f<(gdG#gO)Q=LÈ2BK80P^Dl'kroXmt.} jd[B.ffc7q?Ff|0Τld!n|@+;_ee၅3{j=zthf1gT)h 5]$XnNrihCHD)1(IuE 5j;4Lh(/_>v: oJPꉃOd~6Yx||{޲g+qo*D`''Zc׼߄c⻻4KA%;п88z1 "Χz?!w6c?$*HUPqşfCh]^2(,S&p}/5WgmXXe_WE@7%wΰD9<'G荊>d^8}P8>A]'"GJ!QV."іڤya,t!bV/j#b*(# j萞A2'ɼO cx4Cl ђ*`.L5.kqh*|ؐ{ LOšN.3d@)G3L]'{\G=ndkwAZ+@Imƞ:kF{<ͺDlbM"c8hL"yu; C .i>UT=+ys;" E@ً9: &vÆ0d~ڱWR7y[g VR%ހ3}!ixygK/xaWIօ_vnoX.6¨@d @s\5;#M" k\̽Ъ.7R<6@h&E4Mq8Cu~toP9s1|JqBOXA CٖDmy6D}guJ[)q3f$KK\FIi<%+?DbFѼs{r&ڳCq_d%z:q~ hD_jth`7>KrVasD(w.: "vX1[ÌU5iB:,rvTm/Бv`^N DKŊ)|8o h@؜)[/#Q7<{'ÐO+&ZkEn (Z0J/Rؑ锏7%7NalMZS@uņk`J~s6ZxdMRl2bVΎn"|?l-_+a>\l8G`Κ 'o^u̐ҡ16HL\ 4dN1ZۭU'?YOU,":p GV IVy&cb!GáiΣ y.MlḖXKŻ5@A k]^Q" }$Dꄳ|eRgc >2@sg I]$M,bP6N FJ[(hv>J2Exj^Cj[+ڭ\L>ίNu!g9yДx 7t AmϝMB }хt_xI!`[ iwpDqw/}?üd0&j@2Ņ3EtNqC SLLE87Xf|~6Xz0 FH70ޏ8sio)"${\eo [)WKgDTqИ&G/7q3Z%G[Kgh/5];ߣ~mwK9P`H=BVlEA{1 .cYS="i70XדW[3>~=Ki{WbDO",D߁1"݆{}&XzBv]EnHH'cth HЅ, &iGN<kK?lT#f#t9IzUY=5oe&.9ބX87l_F c/ȇakѦ^i+\4Ú&gh8,qܶV/Ñ#RzD<J0/5|z7GJ=~UtL;&L0sCΙ?m%Xׄtni6K!`1\F[2~RZ_ 'm" ֜Xt%rJ1,R?n;T5fuIRp:1&3TW] *CM>0g?q ݁ G0'x,_7K)3eao '9/^*E6}D;zW-+j~}#"FʓR UBRh"JL?>fxX<7z}$ X(xqHVE3b Gbzq⚛}A ^֑ ZT̐GF=^H#h΍yLۦ;J~2'B?$@$WEj: k@8ePZrWZק:_$h`u[`/тWiLz9%85i)5z2 "k^W@z)c+ S1fcvE,ܬ`rLS~ʶm}TPm7 yGT5Zr8־?E:Ký%$wjɞJ:Оc}ׄuKϽ1<,&>$^ M9͇`;X_-B*@L=քN&SrM`5DԌ-zJV^v\h¡p5 $D\9j"lyi'Gdf(սR;Ռ,okͣwjZ^{24)j%/ØQi:) RUxqcj )CwE WD*J}gS!H 03Ƒ{ E)5$֌oLJ Mj#첾`ƿg#˶ߛq@&i / ˧%anme%{]37I.hX~D;8uZj:r!- D}XBe99mߧ1G8dIBܷFL%:BWe L_KT=ӲrDu}wА+AQ<) J{Jn?x 2]FM;L<Һtf/\ ;9x/A= > SۘADA ӑ[+Ht'{͓1tSJCѲ(B={bXiF #{h$)i6bIz #~2ŢؑU08օz]࿃8p΅ׯSۖV Y[YЅO'aG6@O^C-!ʋ|?x0XJuvw)SjRǥRVwu .cv[}r\ѕvV^oM/7=mwi-x#®]̨.S Nػ_¹LM.&xc)H]*mALCga % 3S^4r$2|d܇TcbT3gLh0 V)//>ivOUM5;E )gz_Ɇw{8L_. @Vۄ }2Pi_"~"/~ݹYlF-[#e8 @g-~}VU3ƅ&WrgJf2qΘS7ŷƬճ0]!QuIh"Jp?"j\pҺR{=\P'wp iy T M tUII?ViU"kEvǜ4&v>#rOЫuXcU=h,ew}st?@MrБVJ :_i||*[P섞Kli:{;\q ~(^[򕸑 w2t~~]8Ojl{i'Qmm\*}&%+UV h0-U&jN8lvu:܆YڛtxX98z>oq.aʦ `3RJzH6ǟ m>{@|_/Nw(y;(:OCsAڟI3~jie LT²UkxS^K7x+(l S3~=E8 q!ssWl) F+oQǐm܍:M1d !%)bk)Lב* e讑G0d"Ʀ&Rwve|a7Z!:.siwDj|Ո]jK)c'@m[lt?8]ܯ 2Ea\Yͧ̆wokۮ*3d-h10Cd$$BE)3[^\YRlGThq뽈(5y3͐YDo݌6Kw~N^N:Ҿ1" Ëum)o޽.%|0>OBna LG't9x-5\kA)5AO~< LI/o?6mƎz5=N;iPaד ;Pd_N~_ ŋ 4:_ڵmƸ`JtW6Z%$85:_$c9K\u~U6÷ zk7WôמO28;2,-FHS—fj_ZKQt>Z8n8sMJ՜hL֬ JOͶ)$ ۤ?wexR/l9ի{U:7$ Gؤ{51t˲p~}{'|EYv)KuAW>|E*X3Iw'ˑ14H]8v,8@u\SַMEbP9=U k-AeSE{!P$ f#͖o_ NƷGkt5DF^wjq*ľ),gLfUP[|OUi}6MllW2>dؼ -B=Vvf s<&(]Xr شB 7x(iԳmSd=Bmua~ :MO7 }a.Lc u+u[ tySY 9RQl7C7zB$-mY_q~"ANɼ^fP p$|YM-П9OnDʖon+1qoM3 K˟$昴CWvw&_p4+GD>^}3w/z5y:_ʺ mslvP6; xiD_?^t+E*ֈdYBɛ* QXߚ2`9I/lNi&yeIݪ)LTnM JExʨL6$J?KCSh/<8i$%#~GBs­i6cHǪRRQjY;Ɗl|q^ׄRw|Q/Oa vtep*,VQx(VqAO1]BY:1:^z6z.C_Bʄ?T˸π2Pk>QsFQ`0?NPuFwD+tcsU0|Υ !,\ Ψ䡇(VZTAr>n$`CkfHNg7Iq? mR'uSJ5$9g."#QXTjd4];(*}&L؈|1aJ/Rܱcz !e=7Wh I-o%?=)Dgsj;a"~9bjqd \UbL }xNjd&>3JNU>o-G=ߺ,ՠFr+[R(ԩZmlx.[$vRyZy' B̴M=_1u|l+A<4\Y;Hxl$D{@e­_=2lÅd8L8Qb6&9hbG  h{m -PP]h$JK3⎁|`kL j;.]"NWt/N԰1[V)*㪕%;64ngL`12V2 }x1q]{RRD@drMC25ҳ-K ;=bk1 7E-|[ޝPXX={҉qT>'ޅߠV鳘VL8Ō}GALI:=pJ:ߨ^tnpnlԭKw5 bCӦ 09eIe}8W[R$\.p;GQU" )D'f$ᒛ}Ra:5Jǿ[jDGX dQ^]50ـ]J%n [Q ߛoU(k[t 6VC p2=IvvJnW؉Afr[o$Xe;bZ ehUWM~?~h5-X['. C~\bl= Kp SEϿ)%"}HtZob+* D_VF?  Fy><9OjX!@h!rzQ:u$AS\jofQz2f~YͦsG9pJC`|t7x]Jx]^[Z1O/I<=nC+tqg٨!mv@\q:?m~kӴO6aIzS f b6-$$M'vtx-(([Y~XPIw5'#h̰M3۸`K639 0HM/.^{8`lgvrs(z&JlNӦN|չIWժ%h;X]r+W)9P8gKu+I;eNAZTNt';y|:"e}U,_ݚ#}O<;푚&(*LQ!ON)Y^Sl83e91[tK\Qf 2[ Y@z:hCAv?;ܙ3c;sӉ00~{Q%P ?0|SkW!u\)<\Ӈ}֍ৃ:sF L4H J郢GHnVBHߚqP TsH^u oq 'bsŢ粅 4 !.9rXJ$ S 쩰;l.`%2VycGYì?zr`aq endstream endobj 519 0 obj << /Length 494 /Filter /FlateDecode >> stream xmMo0 !Rz|UAa۪V&$E 6~=HUAgɯ~uo$ƛLD- t @ZcNt=YNk`T=Ro æeCڕ(>Պ AiZsn[6uc^0Xah\je?0bprOY[AKS|dۙoF)MZ}4W@{YmG;<9`;K (EytbabisbgEjq(po$}Idon-p!J m-O[L endstream endobj 520 0 obj << /Length 696 /Filter /FlateDecode >> stream xmTMo0Wx$ ! 8l[jWHL7IPV=M̼ su;Uٛ=w]yil;<[[j<=?׾+v`&ߴț<^*;~&Q>MS >_P{=s@dkx;`VY`s4JaQܡn.Uu9\Y6><ٴ.Z.4>Dӗ}~r:-d0VWk,8yLһʮӮђ[*mLr?q 5F8@=@)& 8Rx uD\j2HV0CzL] bctI g$`htы0\F0s jd< I6zg W qȐ+#k .bsrbmXK7ǵH7Gnb>&jؐu1VljOu$՟qWS/%1{\xB!K(hHTЖ枃Jρϯv=k2UKς_:~$/ ~E+7ˢ/ l(/} -+ZXukoԝE?ZKq endstream endobj 521 0 obj << /Length 739 /Filter /FlateDecode >> stream xmUMo0WxvHUdCmU^!1H#x?gx]OTm$|͜s_Iss :L;<Sz==׾f`*_`ɫڟk3'iѴ}=M;7rfnj-eSӵOLg~8 )ok A8 $`I\3`Af<Z]! xNky"7 _㓧q H`nḱRONH=CpB:# =%888QA~!*zƜАT?!~> tw8y*sύ }nFE>7*QύR>7G];~<6OIyktg>O:yұϓN|I/|yIg>O:y҅ϓ.}2 L> stream xmUMo:W5?$R. d9M eCkmCp;;w~>|3E_?O]5߶w]Occ]=~?}Oyh9%?۹׬B|Ɯ>);vw%g43>\ 6 EJ78 1{~`W(-;]%=xe_,b+-O;q\L}UI--=BKE1p[! Mߊyu>.N5K)Wb٬8i[_uʕMzQ)V(Txޢjy!Z2P="Zd0\ÃGR\).2*Шa!U,H`+j.5Nα@VK-x%3%AYӀzΚ>kP#5m0Woþj.ZT$X/)n)#Wo(oRZ $Kp4Z-b\1ܰJ P"GXQi/8k^Zq:Zs9dB )sL-7xJ`aɽ)f$1 dъcCZC<73JgznHȰYɚTa,_-O87}KԴܗLloK+gJ.GZyVc48Wt]:P~`rZq.n1] S/Pu7Ue:?&?!d&1yHn5)yғBx#1ޞ]Go׏M?X endstream endobj 523 0 obj << /Length 833 /Filter /FlateDecode >> stream xmUMo0Wx8T·~h[ ۍT~3r#_)9۞c$_{t]P܂~ݣP_(&w(R|vp#P)->g_B?q8SG AC۽[ia߿{2ZE_cf/1/{/4G+)bUUwkuTO4[@ 0@`%! #P .w)úp%KcJe Rͤ(*1:bDDR@ ȓ2UR*N)KIΡԀ0CS,km:5Bͦ&[Y{Ł@꒩)NMvSpJs}irphS ᐙ2L9ΙV}yXi8'z Ԛxq1GyלNZ1fXt:s0>wpVR.խr)>1qҾKvHX1iS5rM yR6FBlH>]6b 5&5&0a'evb_dfQTtQ]zK/WБ^Zz&孯ӷrW.&_rUOz䢓n9)C]!􁠧r7dE?_;~T?m endstream endobj 524 0 obj << /Length 700 /Filter /FlateDecode >> stream xmTn0CƆ@LE"jD;oƤjgy_xN{qV'wC&]\]]u>t\qxں7ŦmN7isƬ'k~G]?ߓ` 4;RV_n86]{̭֚u[sfߴ L:?v>4|`0nhWu}QE KU=5Yw߇l?N6jwwv Z/բ,ko{&PaffIq XMJ0LfhrdĥP> stream x\i[7_=.4%vc;˝x1Pd[r]%s.Gm.T.w=\dAFhDȴPF d. ڣB\ ѺF(PɓPZEKV EA PNpEgA %.&PΠ_  Mn@2!j&hB*4h\Z *DtOx NN$ /g0j0hɔ ( 9MF%ר0InC: DG+H3=@(/*PW<8bZ#$eѪ4I'FZa-daY… `A@Ib5Ƅ֝FY WN8 B91J 4W"7e7}X{f3+F Ho n}P,"xAZc -F(JSB)!%hr1j2 0@`"  h")p$X;َ.({=(œ*VJG5P -D'PRPb(*uǝb`;*2{Tw /<轛|/^iXOEKKA//?^\oۋP*T KעFJxxyEYT5ߣl)^DlRaӷI.0':Yvzxv>].^Iv_r] MhP-JIbGr/srsnrN99w)_jŶ:tv/8Cvm G2K VG`; !~I}&+E$exuiahOY`*!,* 1ګ,xdYq(٫5p p݆pИcFOF}N\62ϋ˙VF0:rsC1 Wyn/2TaH>乽ۋC{ LJ\\rnsrsrS=n?;88I r@ώN{DDNZ;#S #|qhptCc4 -ӂ)OYh^"4$ b0MB}쾒qH<5,ڠmjz5SHZ"qhȖ'd$FV6'C@M`K`*EAI!^dDB6$&*1'ƶDZ, $3 q"Pht$Ͷ:V bD g>. }BU2v RF&XpY]V}4%0o:Xl8ڇ"Y&o(p>B7"l!^*ݠw ʛvt$} 6 B8aU<*h֮ErL?Nr ic]oㅽ(Kcf]) p,"*#4O" V00A>Pڜ_E -W%jJQvPve@.ZqRWnn^yCJדW' _yknyj{4.ߖ7M!|Z4m5#_D@X\%Pt6Dy^ }!SIK!WnhĀ.4+h DǃLFPP\I&61 ]A Av3n6,#I[&h:2wCf5n_IdE?jkɞE{= ʼn'e#ەEu=,xzy Ai5/]|~6m]7\N Da껛)|wZj<͛E썠7H[/1o@1oP#|z?MaMB|avg/%*%2ciM ~VGhJB3ؘ0X&8Vut^OcOiOJ]}&}}D=0>?SEܢҢ,4&ҢW6zS){a[z7/Jhk}m=_1άym$=L4ds[^MS<\θ+!çvwnnp$Xr||Dڽ-nxhs'SJZ 2CYOrZ/GAiߧ`9C[uCbggӬuɉ5rSm\fif=~3 ;|r1 >5P1||(u >rku_SWF|7}aSB1B}Jܤ m$wrH@ HAB9r,Y(gQ΢E9rtJPáC 9#G˘yJ5kKL,BPB(Xk|m-Ni/x(z>zTXŧQL9*$N (bBB3+P(@ `  PĄBA1> |Lۖ-Mh*uxNJ\Av4-Ə#Ѷ?G"8z ')OR5n?I ldhf$=Ć30Җ^7fA Uhl+(4YF eȢ-B|_,'FQhHyB,Ia9 2-贠iνߜrs+#ƃLdZ1a|2h]]1#h-z=֢ h bf*>|jM卫6]^4gr!|oiR"u`V#\J,0ƅ!iJDH l!9 HAq =!$fe~:l-p.8xGXEuXxy `%Ղ[L V`%TJő T JF»€}RHۚ}iQoH iK%][¤V)-eH9兵ڴ[]Ef(9ɫBYHa1:ђt5tHk(-q6בO8?Q9㜘Ψ%Cu} v&[R$J $"5BX]u Ɛ*Us!oUS"nPN[S"WyvLԈb=*yZ+#ٕxaW-ƕ\z1}+)M抵vu> -}R|6jbid٧ Bn\ f#$YWNneZu}G#d޲1|Zjf^vĆy\fӍZw\50,U3fa*S =%JY5ĄUXO5TPO.VĪoog}%ja:<W\I|Dh?:y9`]UM?}6n)'rz1?sbO?mMr5=],W\ O(z0GK+Dg/?1F8{(q.R;BL3F1(*z(O_^ͧ\7 Q~)A,sY⍂udQ4~Ӌ*/}LwçW`a<| 8}S8Iz{;r41}}1~Q=ȺͮfL0ӻw144 Liicru$$Ctq VvL V+cXòzeXwYeա=yO,]b}‡R>ƱZURTý0p>)?OL9[\,.;g}jӿfǫm l\ϡ~Aoz{?Բ_o?]-V߽çkAXJυ4jEjG% ŋ%1e?%9yp[ mbïJ|{OnA{ttON/t $%wɯ@?tg*3=<junu؄GmEA'9AR`Q4e%,آw%)7K Df2%k &fdJi0I F6Lc/m|ui+!q;qxC3g])0c I0?kPYƌdE&9]NW<[X'Iě"GCCP>qAkhڠk6Qӳ r2[l$6 ҇ T6Zijk vvׯ mnKp endstream endobj 525 0 obj << /Length 699 /Filter /FlateDecode >> stream xmTn0CƆ@LE"j.RC~8iZ)Ayo7?nkNy$냛G׎ծU[7|SlfM[kwʽ5g x=i6;RV׵_n85]֚̽u[OsE͡i P{ LՑ @4=tb/yVvL MnݞArjwf4P׏ީFT]Nrî}sBZ2pmmR?\rs<, X#.KIɌCH'hjmJIQ09da"2rG~\5hגQv]`n @v)(A'b}qHI($ux-JBJ!^I :ggM597F7FN}Y{}&Ff.pdk_ ΜN0VG9ʱwDK4X=CaCɁg2)4X(rb0/s4lƵǮb]ˌ[r> stream xmTn0CƆ@LE"h.RC~8iZ)Ayo7?^$ŝPIs77EW]}==硫nTشxGɛz?{k۝=` 4vN߷u8NM>(s&`ywS0jzQshz+&TuS~Hxqq`P<+ OC톦}SWUn}@`T;P3qtj}w*5UWSܰo\ze \[3. 9ff ؤdF@!i @F\ ` H sn4ȶ` $(Ng 2R0zd9#Cb.k(@.0[Czr aà8SuX$Q:\CAfpGR~m%^!N%$h&՚R #ƿp'XϾ>AI }3Nh25gNE'bkkؿs %|V !3?fc91ӊ9|u 6ZcWCab d1׮eF-9Ag깐3Z=I= 6-7p?)pegT> stream xmTn0CƆ@LE"j.RC~8M])A̼7W?^$PIsWWEW]}~{SCWmݨMi7mv9I+ڴg{ҏÄ~F )P ǦkZn;@1zz5= 7m=x Fgu P}?i]X<;k C톦}UYoO} A`TS7~wpjmS!詺]]ꂅK(ew&97\=̒5⒁yAa>:M1ȈK,x΍t,@F*&" C,zdWXPv-hakH/]d"btv"gg?|2JB^G5kdwt,uVT Jb9;kBX!00a0bw3W M";\88̿9Earʱs ށ?c>+q p~PrL  hi˜c>:q-+01~k2#Ϡ3\OLqRυ>¹M \)s9O \Y!O>\\/Au*[ӺkzT%C0t endstream endobj 529 0 obj << /Length 700 /Filter /FlateDecode >> stream xmTn0CƆ@LE"j.RC~8M])A̼7W?^$PIsWWEW]}~{SCWmݨMi7mv9I+ڴg{ҏÄ~F )P ǦkZn;@1zz5= 7m=x Fgu P}?i]X<;k C톦}UYoO} A`TS7~wpjmS!詺]]ꂅK(ew&97\=̒5⒁yAa>:M1ȈK,x΍t,@F*&" C,zdWXPv-hakH/]d"btv"gg?|2JB^G5kdwt,uVT Jb9;kBX!00a0bw3W M";\88̿9Earʱs ށ?c>+q p~PrL  hi˜c>:q-+01~k2#Ϡ3\OLqRυ>¹M \)s9O \Y!O>\\/Au*[ӺkzT%C2t endstream endobj 558 0 obj << /Producer (pdfTeX-1.40.25) /Author(\376\377\000\040\000G\000A\000P\000\040\000c\000o\000d\000e\000\040\000b\000y\000\040\000B\000j\000\366\000r\000n\000\040\000A\000s\000s\000m\000a\000n\000n\000,\000\040\000A\000n\000d\000r\000e\000a\000s\000\040\000D\000i\000s\000t\000l\000e\000r\000\040\000a\000n\000d\000\040\000B\000e\000t\000t\000i\000n\000a\000\040\000E\000i\000c\000k\000\040\000;\000\040\000P\000A\000R\000I\000/\000G\000P\000\040\000c\000o\000d\000e\000\040\000b\000y\000\040\000B\000i\000l\000l\000\040\000A\000l\000l\000o\000m\000b\000e\000r\000t\000\040\000;\000\040\000O\000S\000C\000A\000R\000\040\000c\000o\000d\000e\000\040\000b\000y\000\040\000C\000l\000a\000u\000s\000\040\000F\000i\000e\000k\000e\000r\000\040\000a\000n\000d\000\040\000M\000a\000x\000\040\000H\000o\000r\000n\000\040)/Title(\376\377\000\040\000A\000l\000n\000u\000t\000h\000\040)/Subject()/Creator(\376\377\000L\000a\000T\000e\000X\000\040\000w\000i\000t\000h\000\040\000h\000y\000p\000e\000r\000r\000e\000f\000\040\000p\000a\000c\000k\000a\000g\000e\000\040\000/\000\040\000G\000A\000P\000D\000o\000c)/Keywords() /CreationDate (D:19700101000000Z) /ModDate (D:19700101000000Z) /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.141592653-2.6-1.40.25 (TeX Live 2023/Debian) kpathsea version 6.3.5) >> endobj 526 0 obj << /Type /ObjStm /N 53 /First 443 /Length 2194 /Filter /FlateDecode >> stream xڭYnF}ࣕTMZQ^LHA3Z~Iv09usMBNbtQ^In%J{@TIo$X(,yK-Wѕ RU2JHA4%; 9(_g MvdPy) Evѕ!J  5"1O7PF2R9#V)*ShnxYaR$ H@ rIP-K](B2ZYLHcYEΓ8H0=(5?$!VXS'ҍ֫\rgn:{qPΪcMq^Woq^lݧ*as> EpIn> :;_O;"zjisw]hBv!aGE?p|x ew U.k~MCH0Sc$ͷ`vߏ2Oݬf9r)riӾ~ۭpR]?ttc'|1X"uZ)ј#? 4>=ZjXK)9\Jaj5_[CCP79๽qcXbF\Kq {eY؁HMҀT6p5WE4q$G 2'ecx&JdJ0s@31\&H:vFpǡ0[lL7L}W-Ctk a=fX3<S~jX=-CZLg5VA㎐`ԙnVcz:E$QXTKw4LӮ2ic%ʔ] لFGixH>F`z2NgSl̹̯O|hWI})OhҺDHo?At^ni]  Mh)C 'BQWh)aon7ϟs&*2֥e}uc&Z' aI[twPWڢa_HΗX[_+ikkPUې9,wxY{4u4FU'*Gjj]p>I$"L\8UUn4EICЭttHUi(&s Y,:xr Un%Hmet) "OV9me kN &Mp(T k}ES)iVJK&F)`E/gsĝVME҆亠LPETnTpUiyju'$ Š* ֔`DKH 퉖X9jרL s_zgP`:RrZuI(Yj'Uͬhhuf~)ByC`8Ap$:Ֆ4Yhj7-M};K\W@mBq@'AE%uh WD<]ҮШ閨:犻'-u0%W'*S!Z Gs Y,qC3Wo+h i SU!CZ>/̈́DL *ͱY@J<*qh@6f߽ ϞQ˻P^SjŐߖy j=HMhq-u o\}\x6:8֧ψESjt7r!O&Q2cTq0>CU/q<0RZN*MWqYb'Q[0M墙Dxii jU>#<ɘ dqѪڨ#nVN¾T\q.B.RcIi:?bD9%\Hܖg Q$1ӇGL-xPU_:#*h1BejjP d}dLV;ʸYU9>=sŋM'ɪ83؀һ*sr(W_4EϠfUYU<:g FK` WgJn7%ߌj_aᙉ÷? vŰ#da8lGR} ] /Length 1426 /Filter /FlateDecode >> stream x%wlVU\F E BKB-bA)eX*1F#фA5 .ԠxA\ 2Ec,E n}{7.$!$B޲@kBh$0Z{Z1LM 4+eJT3er SDiЂZ^-a:VI V~1āԸ#18wdq5yC͇&ScIGӒ5B'L-L@>|]@!t}틠x ^ BroYߙ\|^*>P}A􇋡@`PeR0p08I0Bڧ~xȘB662! |/ySWК3Z=f, s`.[Vo!_0["يH#=zڛ 7mlT^#WME2`bic%sJ:ctBEI]$kC B_O k R$%s~ i)HTbi~ E2 Ml攟 HDIDjaR%W EIN_/-ԝ;& NZ w+u@"9 Hb=8n0C^iތkz 4H@sHp6hZABGWK'JHWPEP ݡJ_ ʡT@_~Pa tpDP w~ŇĒ |qDqNq)c`SM*#>:#6?űF8~X`N2SJ|_*#lg__#6ߖ0ZzJ4S%0/įP}-٧p%qF endstream endobj startxref 185273 %%EOF alnuth-4.0.0/doc/manual.six0000644000000000000000000001651215201210200012467 0ustar00#SIXFORMAT GapDocGAP HELPBOOKINFOSIXTMP := rec( encoding := "UTF-8", bookname := "Alnuth", entries := [ [ "Title page", "0.0", [ 0, 0, 0 ], 1, 1, "title page", "X7D2C85EC87DD46E5" ], [ "Copyright", "0.0-1", [ 0, 0, 1 ], 32, 2, "copyright", "X81488B807F2A1CF1" ], [ "Acknowledgements", "0.0-2", [ 0, 0, 2 ], 48, 2, "acknowledgements", "X82A988D47DFAFCFA" ], [ "Table of Contents", "0.0-3", [ 0, 0, 3 ], 67, 3, "table of contents", "X8537FEB07AF2BEC8" ], [ "\033[1X\033[33X\033[0;-2YIntroduction\033[133X\033[101X", "1", [ 1, 0, 0 ], 1, 4, "introduction", "X7DFB63A97E67C0A1" ], [ "\033[1X\033[33X\033[0;-2YWorking with number fields\033[133X\033[101X", "2", [ 2, 0, 0 ], 1, 5, "working with number fields", "X7DC995CB8412F8E2" ], [ "\033[1X\033[33X\033[0;-2YCreation of number fields\033[133X\033[101X", "2.1", [ 2, 1, 0 ], 10, 5, "creation of number fields", "X86AD0C3F7D38C269" ], [ "\033[1X\033[33X\033[0;-2YMethods for number fields\033[133X\033[101X", "2.2", [ 2, 2, 0 ], 44, 6, "methods for number fields", "X79007A477D53B572" ], [ "\033[1X\033[33X\033[0;-2YPresentations of multiplicative subgroups\033[133\ X\033[101X", "2.3", [ 2, 3, 0 ], 124, 7, "presentations of multiplicative subgroups", "X833A0296798E0463" ], [ "\033[1X\033[33X\033[0;-2YMethods to compute with subgroups of the unit gro\ up\033[133X\033[101X", "2.4", [ 2, 4, 0 ], 160, 8, "methods to compute with subgroups of the unit group", "X86F68B4883142B5A" ], [ "\033[1X\033[33X\033[0;-2YFactorisation of polynomials over a number field\\ 033[133X\033[101X", "2.5", [ 2, 5, 0 ], 183, 8, "factorisation of polynomials over a number field", "X7F656B217EF114DA" ], [ "\033[1X\033[33X\033[0;-2YExamples\033[133X\033[101X", "2.6", [ 2, 6, 0 ], 219, 9, "examples", "X7A489A5D79DA9E5C" ], [ "\033[1X\033[33X\033[0;-2YAn example application\033[133X\033[101X", "3", [ 3, 0, 0 ], 1, 10, "an example application", "X81CAD2F27B2066C4" ], [ "\033[1X\033[33X\033[0;-2YNumber fields defined by matrices\033[133X\033[10\ 1X", "3.1", [ 3, 1, 0 ], 9, 10, "number fields defined by matrices", "X7981DB6C79742C4C" ], [ "\033[1X\033[33X\033[0;-2YNumber fields defined by a polynomial\033[133X\\ 033[101X", "3.2", [ 3, 2, 0 ], 71, 11, "number fields defined by a polynomial" , "X85ADC6A27B26C804" ], [ "\033[1X\033[33X\033[0;-2YInstallation\033[133X\033[101X", "4", [ 4, 0, 0 ], 1, 13, "installation", "X8360C04082558A12" ], [ "\033[1X\033[33X\033[0;-2YInstalling Alnuth\033[133X\033[101X", "4.1", [ 4, 1, 0 ], 10, 13, "installing alnuth", "X821B9C2D817C0BE7" ], [ "\033[1X\033[33X\033[0;-2YGetting PARI/GP\033[133X\033[101X", "4.2", [ 4, 2, 0 ], 38, 13, "getting pari/gp", "X83B28FDC7FACCE51" ], [ "\033[1X\033[33X\033[0;-2YAdjust the path of the executable for GP\033[133X\ \033[101X", "4.3", [ 4, 3, 0 ], 66, 14, "adjust the path of the executable for gp", "X815DF28A87D65A3A" ], [ "\033[1X\033[33X\033[0;-2YLoading and testing the package\033[133X\033[101X\ ", "4.4", [ 4, 4, 0 ], 169, 16, "loading and testing the package", "X781C2F107F76F8A4" ], [ "Bibliography", "bib", [ "Bib", 0, 0 ], 1, 17, "bibliography", "X7A6F98FD85F02BFE" ], [ "References", "bib", [ "Bib", 0, 0 ], 1, 17, "references", "X7A6F98FD85F02BFE" ], [ "Index", "ind", [ "Ind", 0, 0 ], 1, 18, "index", "X83A0356F839C696F" ], [ "\033[2XFieldByMatricesNC\033[102X", "2.1-1", [ 2, 1, 1 ], 16, 5, "fieldbymatricesnc", "X8085204B7DE2C8BA" ], [ "\033[2XFieldByMatrices\033[102X", "2.1-1", [ 2, 1, 1 ], 16, 5, "fieldbymatrices", "X8085204B7DE2C8BA" ], [ "\033[2XFieldByMatrixBasisNC\033[102X", "2.1-2", [ 2, 1, 2 ], 25, 5, "fieldbymatrixbasisnc", "X805CFBEB877FCBA3" ], [ "\033[2XFieldByMatrixBasis\033[102X", "2.1-2", [ 2, 1, 2 ], 25, 5, "fieldbymatrixbasis", "X805CFBEB877FCBA3" ], [ "\033[2XFieldByPolynomialNC\033[102X", "2.1-3", [ 2, 1, 3 ], 35, 5, "fieldbypolynomialnc", "X7AD9823687E61ABC" ], [ "\033[2XFieldByPolynomial\033[102X", "2.1-3", [ 2, 1, 3 ], 35, 5, "fieldbypolynomial", "X7AD9823687E61ABC" ], [ "\033[2XPrimitiveElement\033[102X", "2.2-1", [ 2, 2, 1 ], 49, 6, "primitiveelement", "X86DB31B57FB4F570" ], [ "\033[2XDefiningPolynomial\033[102X", "2.2-1", [ 2, 2, 1 ], 49, 6, "definingpolynomial", "X86DB31B57FB4F570" ], [ "\033[2XIsPrimitiveElementOfNumberField\033[102X", "2.2-2", [ 2, 2, 2 ], 63, 6, "isprimitiveelementofnumberfield", "X843C2BE881A3576A" ], [ "\033[2XDegreeOverPrimeField\033[102X", "2.2-3", [ 2, 2, 3 ], 69, 6, "degreeoverprimefield", "X7845CECE86A83219" ], [ "\033[2XEquationOrderBasis\033[102X", "2.2-4", [ 2, 2, 4 ], 75, 6, "equationorderbasis", "X8185FEF1811EA43F" ], [ "\033[2XMaximalOrderBasis\033[102X", "2.2-4", [ 2, 2, 4 ], 75, 6, "maximalorderbasis", "X8185FEF1811EA43F" ], [ "\033[2XIsIntegerOfNumberField\033[102X", "2.2-4", [ 2, 2, 4 ], 75, 6, "isintegerofnumberfield", "X8185FEF1811EA43F" ], [ "\033[2XUnitGroup\033[102X", "2.2-5", [ 2, 2, 5 ], 85, 6, "unitgroup", "X7902A7877B65FDA1" ], [ "\033[2XIsUnitOfNumberField\033[102X", "2.2-6", [ 2, 2, 6 ], 96, 7, "isunitofnumberfield", "X7D9484BA7AF4201C" ], [ "\033[2XExponentsOfUnits\033[102X", "2.2-7", [ 2, 2, 7 ], 102, 7, "exponentsofunits", "X80389D828474FC64" ], [ "\033[2XIsCyclotomicField\033[102X", "2.2-8", [ 2, 2, 8 ], 110, 7, "iscyclotomicfield", "X84CAE4627F0CD639" ], [ "\033[2XNormCosetsOfNumberField\033[102X", "2.2-9", [ 2, 2, 9 ], 116, 7, "normcosetsofnumberfield", "X7A43318584DB3756" ], [ "\033[2XPcpPresentationOfMultiplicativeSubgroup\033[102X", "2.3-1", [ 2, 3, 1 ], 132, 7, "pcppresentationofmultiplicativesubgroup", "X7975303583E6058B" ], [ "\033[2XIsomorphismPcpGroup\033[102X", "2.3-1", [ 2, 3, 1 ], 132, 7, "isomorphismpcpgroup", "X7975303583E6058B" ], [ "\033[2XRelationLattice\033[102X", "2.3-2", [ 2, 3, 2 ], 153, 8, "relationlattice", "X7C6E88FE82BB9DE3" ], [ "\033[2XRelationLatticeOfUnits\033[102X", "2.4-1", [ 2, 4, 1 ], 163, 8, "relationlatticeofunits", "X82B056EC85CF150D" ], [ "\033[2XIntersectionOfUnitSubgroups\033[102X", "2.4-2", [ 2, 4, 2 ], 171, 8, "intersectionofunitsubgroups", "X7B8C89C980CB15F7" ], [ "\033[2XFactorsPolynomialAlgExt\033[102X", "2.5-1", [ 2, 5, 1 ], 186, 8, "factorspolynomialalgext", "X815A5FBE805119CC" ], [ "\033[2XFactorsPolynomialAlnuth\033[102X", "2.5-2", [ 2, 5, 2 ], 197, 8, "factorspolynomialalnuth", "X7CC3F0458523CB22" ], [ "\033[2XExampleMatField\033[102X", "2.6-1", [ 2, 6, 1 ], 222, 9, "examplematfield", "X7B4AE27B7BB8A9ED" ], [ "\033[2XPariVersion\033[102X", "4.3-1", [ 4, 3, 1 ], 88, 14, "pariversion", "X84E2E83F8251DC49" ], [ "\033[2XSetAlnuthExternalExecutable\033[102X", "4.3-2", [ 4, 3, 2 ], 140, 15, "setalnuthexternalexecutable", "X7F2835FB7C5069DD" ], [ "\033[2XSetAlnuthExternalExecutablePermanently\033[102X", "4.3-3", [ 4, 3, 3 ], 152, 15, "setalnuthexternalexecutablepermanently", "X81CD0C70812FC6F3" ], [ "\033[2XRestoreAlnuthExternalExecutablePermanently\033[102X", "4.3-4", [ 4, 3, 4 ], 161, 15, "restorealnuthexternalexecutablepermanently", "X7F648B427EB19552" ] ] ); alnuth-4.0.0/doc/nocolorprompt.css0000644000000000000000000000031315201210200014104 0ustar00 /* colors for ColorPrompt like examples */ span.GAPprompt { color: #000000; font-weight: normal; } span.GAPbrkprompt { color: #000000; font-weight: normal; } span.GAPinput { color: #000000; } alnuth-4.0.0/doc/ragged.css0000644000000000000000000000023115201210200012417 0ustar00/* times.css Frank Lübeck */ /* Change default CSS to use Times font. */ body { text-align: left; } alnuth-4.0.0/doc/rainbow.js0000644000000000000000000000533615201210200012466 0ustar00 function randchar(str) { var i = Math.floor(Math.random() * str.length); while (i == str.length) i = Math.floor(Math.random() * str.length); return str[i]; } hexdigits = "0123456789abcdef"; function randlight() { return randchar("cdef")+randchar(hexdigits)+ randchar("cdef")+randchar(hexdigits)+ randchar("cdef")+randchar(hexdigits) } function randdark() { return randchar("012345789")+randchar(hexdigits)+ randchar("012345789")+randchar(hexdigits)+ randchar("102345789")+randchar(hexdigits) } document.write('\n'); alnuth-4.0.0/doc/times.css0000644000000000000000000000026115201210200012312 0ustar00/* times.css Frank Lübeck */ /* Change default CSS to use Times font. */ body { font-family: Times,Times New Roman,serif; } alnuth-4.0.0/doc/title.xml0000644000000000000000000000434315201210200012327 0ustar00 Alnuth ALgebraic NUmber THeory
and an interface to
PARI/GP and OSCAR
&VERSION; Note: PARI/GP is not part of this package. It can be obtained from https://pari.math.u-bordeaux.fr/. If you use GAP via OSCAR, then OSCAR will automatically be used instead of PARI/GP. GAP code by Björn Assmann, Andreas Distler and Bettina Eick PARI/GP code by Bill Allombert OSCAR code by Claus Fieker and Max Horn &RELEASEDATE; 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, see https://www.gnu.org/licenses/

To begin with we are very grateful for all the feedback by users of former versions of &Alnuth;.

We thank Bill Allombert who wrote the GP code for the interface to PARI/GP and who was extremely helpful in the transition from KANT to PARI/GP.

For feedback on the development version, including a code patch, we are much obliged to Max Horn.

The second author acknowledges the financial support at CAUL within the projects PTDC/MAT/101993/2008 and ISFL-1-143, financed by FEDER and FCT, in the development of Version 3 of &Alnuth;.

Support for using OSCAR instead of PARI/GP was added by Claus Fieker and Max Horn.

alnuth-4.0.0/doc/toggless.css0000644000000000000000000000167215201210200013027 0ustar00/* toggless.css Frank Lübeck */ /* Using javascript we change all div.ContSect to div.ContSectOpen or div.ContSectClosed. This way the config for div.ContSect in manual.css is no longer relevant. Here we add the CSS for the new elements. */ /* This layout is based on an idea by Burkhard Höfling. */ div.ContSectClosed { text-align: left; margin-left: 1em; } div.ContSectOpen { text-align: left; margin-left: 1em; } div.ContSectOpen div.ContSSBlock { display: block; text-align: left; margin-left: 1em; } div.ContSectOpen div.ContSSBlock a { display: block; width: 100%; margin-left: 1em; } span.tocline a:hover { display: inline; background: #eeeeee; } span.ContSS a:hover { display: inline; background: #eeeeee; } span.toctoggle { font-size: 80%; display: inline-block; width: 1.2em; } span.toctoggle:hover { background-color: #aaaaaa; } alnuth-4.0.0/doc/toggless.js0000644000000000000000000000420515201210200012646 0ustar00/* toggless.js Frank Lübeck */ /* this file contains two functions: mergeSideTOCHooks: this changes div.ContSect elements to the class ContSectClosed and includes a hook to toggle between ContSectClosed and ContSectOpen. openclosetoc: this function does the toggling, the rest is done by CSS */ closedTOCMarker = "▶ "; openTOCMarker = "▼ "; noTOCMarker = " "; /* merge hooks into side toc for opening/closing subsections with openclosetoc */ function mergeSideTOCHooks() { var hlist = document.getElementsByTagName("div"); for (var i = 0; i < hlist.length; i++) { if (hlist[i].className == "ContSect") { var chlds = hlist[i].childNodes; var el = document.createElement("span"); var oncl = document.createAttribute("class"); oncl.nodeValue = "toctoggle"; el.setAttributeNode(oncl); var cont; if (chlds.length > 2) { var oncl = document.createAttribute("onclick"); oncl.nodeValue = "openclosetoc(event)"; el.setAttributeNode(oncl); cont = document.createTextNode(closedTOCMarker); } else { cont = document.createTextNode(noTOCMarker); } el.appendChild(cont); hlist[i].firstChild.insertBefore(el, hlist[i].firstChild.firstChild); hlist[i].className = "ContSectClosed"; } } } function openclosetoc (event) { /* first two steps to make it work in most browsers */ var evt=window.event || event; if (!evt.target) evt.target=evt.srcElement; var markClosed = document.createTextNode(closedTOCMarker); var markOpen = document.createTextNode(openTOCMarker); var par = evt.target.parentNode.parentNode; if (par.className == "ContSectOpen") { par.className = "ContSectClosed"; evt.target.replaceChild(markClosed, evt.target.firstChild); } else if (par.className == "ContSectClosed") { par.className = "ContSectOpen"; evt.target.replaceChild(markOpen, evt.target.firstChild); } } /* adjust jscontent which is called onload */ jscontentfuncs.push(mergeSideTOCHooks); alnuth-4.0.0/exam/0000755000000000000000000000000015201210200010645 5ustar00alnuth-4.0.0/exam/fields.gi0000644000000000000000000000207015201210200012433 0ustar00############################################################################# ## #W fields.gi Alnuth - ALgebraic NUmber THeory Bjoern Assmann ## ############################################################################# ## ## ExampleMatField provides somes examples of fields which are generated ## by matrices in GL(d,Z) or GL(d,Q) ## BindGlobal( "ExampleMatField", function(n) if n = 1 then return FieldByMatricesNC(ExamUnimod(1){[1..4]}); elif n = 2 then return FieldByMatricesNC(ExamUnimod(2){[1..4]}); elif n = 3 then return FieldByMatricesNC(ExamUnimod(3){[1..4]}); elif n = 4 then return FieldByMatricesNC(ExamUnimod(1)); elif n = 5 then return FieldByMatricesNC(ExamUnimod(2)); elif n = 6 then return FieldByMatricesNC(ExamUnimod(3)); elif n = 7 then return FieldByMatricesNC(ExamRationals(1)); elif n = 8 then return FieldByMatricesNC(ExamRationals(2)); elif n = 9 then return FieldByMatricesNC(ExamRationals(3)); else return fail; fi; end ); alnuth-4.0.0/exam/rationals.gi0000644000000000000000000003420415201210200013165 0ustar00############################################################################# ## #W rationals.gi Alnuth - ALgebraic NUmber THeory Bjoern Assmann ## ############################################################################# ## ## ExamRationals contains 3 lists of ## matrices in GL(d,Q) which generated a free-ablian group ## such that the associated algebra over Q is simple over ## BindGlobal( "ExamRationals", function(n) local matrixlist; matrixlist:= [ [ [ [ -260689/5, -2887416/25, 1206744/125, 1448433/25 ], [ 236502/5, 2619208/25, -1081647/125, -1314054/25 ], [ -420105/4, -232680, 19657, 233415/2 ], [ 222054/5, 2458876/25, -1001784/125, -1233788/25 ] ], [ [ -151553/25, -2649108/25, -363216/25, 1720341/25 ], [ 654381/100, 4794304/25, 719523/25, -6309891/50 ], [ -9870, 0, 5545, -14805/4 ], [ 181608/25, 7064288/25, 1093596/25, -4671026/25 ] ], [ [ -116112/25, -29429764/75, -7979888/125, 6537587/25 ], [ 892899/100, 18795319/25, 15287769/125, -25050837/50 ], [ 1120, 278320/3, 15086, -247275/4 ], [ 335832/25, 28253568/25, 22980468/125, -18828407/25 ] ], [ [ 62523793214089/25, 5339768524608, 2430717299136/125, -67628119554576/25 ], [ -124713368896032/25, -10836657663551, -8719832238768/125, 138007269305388/25 ], [ -613170403020, -1330061172720, -8251382159, 677232982440 ], [ -189793628149104/25, -16575734835072, -15023590053696/125, 211434513536761/25 ] ], [ [ 206728/25, 2649108/25, 363216/25, -1720341/25 ], [ -654381/100, -4739129/25, -719523/25, 6309891/50 ], [ 9870, 0, -3338, 14805/4 ], [ -181608/25, -7064288/25, -1093596/25, 4726201/25 ] ], [ [ 62523793214089/25, 5339768524608, 2430717299136/125, -67628119554576/25 ], [ -124713368896032/25, -10836657663551, -8719832238768/125, 138007269305388/25 ], [ -613170403020, -1330061172720, -8251382159, 677232982440 ], [ -189793628149104/25, -16575734835072, -15023590053696/125, 211434513536761/25 ] ], [ [ 262548367/25, 22422624, 10207008/125, -283982328/25 ], [ -523693296/25, -45505025, -36616104/125, 579516714/25 ], [ -2574810, -5585160, -34649, 2843820 ], [ -796976712/25, -69604416, -63086688/125, 887850583/25 ] ], [ [ 62523793214089/25, 5339768524608, 2430717299136/125, -67628119554576/25 ], [ -124713368896032/25, -10836657663551, -8719832238768/125, 138007269305388/25 ], [ -613170403020, -1330061172720, -8251382159, 677232982440 ], [ -189793628149104/25, -16575734835072, -15023590053696/125, 211434513536761/25 ] ], [ [ -61106002910039/25, -5339768524608, -2430717299136/125, 67628119554576/25 ], [ 124713368896032/25, 10893369275713, 8719832238768/125, -138007269305388/25 ], [ 613170403020, 1330061172720, 64962994321, -677232982440 ], [ 189793628149104/25, 16575734835072, 15023590053696/125, -210016723232711/25 ] ], [ [ -29146612742563984/25, -38742944058068404/15, 27229938402618896/125, 32388330250096051/25 ], [ 104624553390591843/100, 11589291802956299/5, -24436109013984423/125, -58130504103186501/50 ], [ -2371390466258800, -15760776275028400/3, 443089804313262, 10540556233557525/4 ], [ 24257889033477624/25, 10748213265061888/5, -22662680336012556/125, -26955877378349111/25 ] ], [ [ -29146612742563984/25, -38742944058068404/15, 27229938402618896/125, 32388330250096051/25 ], [ 104624553390591843/100, 11589291802956299/5, -24436109013984423/125, -58130504103186501/50 ], [ -2371390466258800, -15760776275028400/3, 443089804313262, 10540556233557525/4 ], [ 24257889033477624/25, 10748213265061888/5, -22662680336012556/125, -26955877378349111/25 ] ], [ [ -61106002910039/25, -5339768524608, -2430717299136/125, 67628119554576/25 ], [ 124713368896032/25, 10893369275713, 8719832238768/125, -138007269305388/25 ], [ 613170403020, 1330061172720, 64962994321, -677232982440 ], [ 189793628149104/25, 16575734835072, 15023590053696/125, -210016723232711/25 ] ], [ [ -61106002910039/25, -5339768524608, -2430717299136/125, 67628119554576/25 ], [ 124713368896032/25, 10893369275713, 8719832238768/125, -138007269305388/25 ], [ 613170403020, 1330061172720, 64962994321, -677232982440 ], [ 189793628149104/25, 16575734835072, 15023590053696/125, -210016723232711/25 ] ], [ [ -61106002910039/25, -5339768524608, -2430717299136/125, 67628119554576/25 ], [ 124713368896032/25, 10893369275713, 8719832238768/125, -138007269305388/25 ], [ 613170403020, 1330061172720, 64962994321, -677232982440 ], [ 189793628149104/25, 16575734835072, 15023590053696/125, -210016723232711/25 ] ], [ [ -151553/25, -2649108/25, -363216/25, 1720341/25 ], [ 654381/100, 4794304/25, 719523/25, -6309891/50 ], [ -9870, 0, 5545, -14805/4 ], [ 181608/25, 7064288/25, 1093596/25, -4671026/25 ] ], [ [ -64265363669/25, -5862628307256/25, -4777859393832/125, 3908821093569/25 ], [ 122902951122/25, 11230823634328/25, 9153133403841/125, -7488059052222/25 ], [ 2425896375/4, 55411113240, 9031991977, -73889742465/2 ], [ 184645147134/25, 16881759134716/25, 13758822703752/125, -11255808020684/25 ] ], [ [ 206728/25, 2649108/25, 363216/25, -1720341/25 ], [ -654381/100, -4739129/25, -719523/25, 6309891/50 ], [ 9870, 0, -3338, 14805/4 ], [ -181608/25, -7064288/25, -1093596/25, 4726201/25 ] ], [ [ 262548367/25, 22422624, 10207008/125, -283982328/25 ], [ -523693296/25, -45505025, -36616104/125, 579516714/25 ], [ -2574810, -5585160, -34649, 2843820 ], [ -796976712/25, -69604416, -63086688/125, 887850583/25 ] ] ] , [ [ [ -89939/294, -4125/14, -5500/49, -24475/196 ], [ 99187/147, 3813/7, 25355/98, 24805/98 ], [ 832018/441, 8580/7, 110983/147, 94765/147 ], [ -46981/21, -1375, -6325/7, -10469/14 ] ], [ [ 132835851/49, 80954060/49, 50501715/49, 48421120/49 ], [ -1762982716/735, -80519709/49, -43049402/49, -45621774/49 ], [ -870974896/147, -706948352/147, -99585525/49, -372539992/147 ], [ 440026928/105, 28750040/7, 9154618/7, 14091205/7 ] ], [ [ -806482346573543/42, -905842109848225/98, -626379490638550/49, -2144706530156025/196 ], [ -12425559834787/7, -41869219439471/49, -115808351295615/98, -99131170555945/98 ], [ 1930036159182010/63, 2167819326809180/147, 2998044696051277/147, 855435365367165/49 ], [ 23693456413429, 79837571678645/7, 110413540939845/7, 189026498103369/14 ] ], [ [ 19836237149488559/294, 4155371221888975/98, 1245337416741550/49, 4899069301314375/196 ], [ -3633783494270325/49, -2283656809965471/49, -2737587688039215/98, -2692369076168585/98 ], [ -107143732343431498/441, -22444880985943460/147, -13453166328964963/147, -4410317054285395/49 ], [ 1596525340029939/7, 1003338799001605/7, 601388074078605/7, 1182909070374089/14 ] ], [ [ -107151325/49, -80954060/49, -50501715/49, -48421120/49 ], [ 1762982716/735, 106204235/49, 43049402/49, 45621774/49 ], [ 870974896/147, 706948352/147, 125270051/49, 372539992/147 ], [ -440026928/105, -28750040/7, -9154618/7, -10421987/7 ] ], [ [ 3860325842315/294, 16503589795/2, 242354846635/49, 136200974635/28 ], [ -3535849123213/245, -9069835950, -532761351441/98, -74851623891/14 ], [ -20851218686122/441, -89142723692/3, -2618117803132/147, -367838936839/21 ], [ 4660491792407/105, 27894221135, 117036003667/7, 32886525663/2 ] ], [ [ -11330001475788361/294, -3369189059461775/98, -707070652125200/49 , -2969349448083975/196 ], [ 3190305283555709/49, 2846091857668944/49, 2389166047872615/98, 2508330979054945/98 ], [ 55481558317169930/441, 16498484993766820/147, 6924867874711142/147, 2423420316514835/49 ], [ -940420589931603/7, -838955255948645/7, -352132593036345/7, -739391967144091/14 ] ], [ [ 172599265990897/42, 119659947421025/98, 88112726022200/49, 214986676925625/196 ], [ 75779589936875/7, 157609856672944/49, 464229991462215/98, 283169267669585/98 ], [ 5450274415998214/63, 3778576665367460/147, 5564780813013382/147, 1131461372403395/49 ], [ -117422706427477, -244221114731605/7, -359669021982105/7, -438779119922811/14 ] ], [ [ 132835851/49, 80954060/49, 50501715/49, 48421120/49 ], [ -1762982716/735, -80519709/49, -43049402/49, -45621774/49 ], [ -870974896/147, -706948352/147, -99585525/49, -372539992/147 ], [ 440026928/105, 28750040/7, 9154618/7, 14091205/7 ] ], [ [ -399170579173615/147, -118700879964040/49, -49822023826135/49, -52307007239630/49 ], [ 3371957206966084/735, 200542980144655/49, 84173404089038/49, 88371738418986/49 ], [ 3909373856970208/441, 1162525850203168/147, 487944071054917/147, 512281358666528/147 ], [ -993966944133592/105, -59114953395520/7, -24812171716442/7, -26049733550163/7 ] ], [ [ 3860325842315/294, 16503589795/2, 242354846635/49, 136200974635/28 ], [ -3535849123213/245, -9069835950, -532761351441/98, -74851623891/14 ], [ -20851218686122/441, -89142723692/3, -2618117803132/147, -367838936839/21 ], [ 4660491792407/105, 27894221135, 117036003667/7, 32886525663/2 ] ], [ [ -36734315/42, -5891765/14, -8160185/14, -97783345/196 ], [ -8595653/105, -279305/7, -758747/14, -4567453/98 ], [ 88301158/63, 14113924/21, 19590031/21, 117194473/147 ], [ 16134019/15, 520905, 717134, 8616589/14 ] ], [ [ 3860325842315/294, 16503589795/2, 242354846635/49, 136200974635/28 ], [ -3535849123213/245, -9069835950, -532761351441/98, -74851623891/14 ], [ -20851218686122/441, -89142723692/3, -2618117803132/147, -367838936839/21 ], [ 4660491792407/105, 27894221135, 117036003667/7, 32886525663/2 ] ] ] , [ [ [ -6264153250196389416903240923/229, 32298639086108555190545138052/229, 6250050153899910196592931288/229, -17062528604518090575374454108/229 ], [ -31828949487280183133780637174/229, 164113442139592040994066347761/229, 31757289883546699739121527862/229, -86696851016768019463271091168/229 ], [ 10706305822230402790227171324/229, -55202849273663798845585812684/229, -10682201676632474178149363807/229, 29162225450789804731984637796/229 ], [ -31630873935512564569306687014/229, 163092143569330601229006182316/229, 31559660278496695307183104530/229, -86157325619974009272661504835/229 ] ], [ [ -32922740572311041966823464707818129930409331/229, 169753145077879383397309722705981485900163876/229, 32848618410529519585754676836021522433280506/229, -89676158982313211602360836468734114418152304/229 ], [ -167284580182655189842874359703358730654824807/229, 862537052365596961509145685227392451967278339/229, 166907956168362736093277019723482684077697700/229, -455655827764409867117421029606966266278026982/229 ], [ 56269525184758861487331252988208249131583094/229, -290131644756973897407392677387760533570749882/229, -56142840140421394598033623641159798843012641/229, 153268980607634202422715921838991026204863618/229 ], [ -166243547221918122310167837625294921493119821/229, 857169375916344158272836981518015370204924276/229, 165869266986187060467986580374823273478628004/229, -452820224297929303195372763004426259134893423/229 ] ], [ [ 15249919019557/229, -10501382066448/229, -688215138912/229, 7314116210352/229 ], [ 6402597223176/229, -20493339577979/229, -7017597985608/229, 16978413905712/229 ], [ -7519116464496/229, 32192361338256/229, 11640450259093/229, -26964854857584/229 ], [ 3766879669896/229, -23145504884544/229, -8767421583480/229, 19576888669525/229 ] ], [ [ 80555126206508585287903316821/229, -183335834990114612065968727812/229, -57125319139708944868540766808/229, 149195252972813686479801033948/229 ], [ 27897137130063091461241343094/229, -63491240972825988770606150903/229, -19783134068385556918206404982/229, 51667977288833930017011925728/229 ], [ -29769638463282968475266172924/229, 67752876595690071254903155404/229, 21111010285418575004268784345/229, -55136016174223925477850277476/229 ], [ 12329249636446841813204697894/229, -28060204028541594293313254316/229, -8743234023736905752902049490/229, 22834866073687996604786287933/229 ] ], [ [ 31249965280/229, -21519315909/229, -1410282846/229, 14988005991/229 ], [ 26240262741/458, -41994724658/229, -28760768253/458, 34791977871/229 ], [ -15408090243/229, 65968230573/229, 23853481843/229, -55256082147/229 ], [ 15438096261/458, -47429512452/229, -35932206555/458, 40116743599/229 ] ], [ [ 15327076463725/229, -34882860138228/229, -10869082372854/229, 28387009458072/229 ], [ 5307942503781/229, -12080402052989/229, -3764116093752/229, 9830805308370/229 ], [ -5664223486098/229, 12891306835806/229, 4016789208679/229, -10490706552294/229 ], [ 2345870499615/229, -5339047456092/229, -1663592552064/229, 4344819846889/229 ] ], [ [ 1420434424899105493/229, -3232774170942360564/229, -1007294925359913336/229, 2630770794283255596/229 ], [ 491912256883196718/229, -1119545690071021655/229, -348837448172916654/229, 911065217849276976/229 ], [ -524930209668704268/229, 1194691422286793148/229, 372251986514043241/229, -972217400820933492/229 ], [ 217402559487699678/229, -494787627432359532/229, -154170084225283290/229, 402648861567049357/229 ] ] ] ]; return matrixlist[n]; end ); alnuth-4.0.0/exam/unimod.gi0000644000000000000000000001654515201210200012474 0ustar00############################################################################# ## #W unithom.gi Alnuth - ALgebraic NUmber THeory Bjoern Assmann ## ############################################################################# ## ## ExamUnimod contains 3 lists of matrices in GL(d,Z). Each of them ## generates a torsion-free abelian group with semisimple matrix algebra. ## ## Remark: These exemples were generated as normalsubgroupsgenerators ## of the kernel of the p-congruence homomorphism applied to ## MatExamples. The order is changes ## MatExamples(2) corresponds to ExamUnimod[1] ## MatExamples(3) corresponds to ExamUnimod[2] ## MatExamples(4) corresponds to ExamUnimod[3] ############################################################################# ## #F ExamUnimod(n) ## BindGlobal( "ExamUnimod", function(n) local matrixlist; matrixlist:= [ [ [ [ 2093340575128, 6213435078921, 17560570361343, -28693642181391 ], [ -3625838403333, -10761656507462, -30415567443933, 49698063067818 ], [ 1293798337794, 3839901865707, 10852879181962, -17733140676042 ] , [ -1314714587787, -3902311263375, -11028829922394, 18020890988656 ] ], [ [ 398946457, -197870628, -271469520, 913773168 ], [ 690995412, -342721799, -470198736, 1582701120 ], [ 246562392, -122290656, -167777219, 564742596 ], [ 329632680, -163492104, -224303736, 755012245 ] ], [ [ 57641556673, -51250063536, -73214376480, 161071628256 ], [ 21964312944, 28355806081, 43928625888, 0 ], [ -14642875296, 43928625888, 64962994321, -80535814128 ], [ 0, 29285750592, 43928625888, -37537132751 ] ], [ [ 13, 0, -21, 0 ], [ -42, 97, 105, -231 ], [ -21, 0, 34, 0 ], [ -21, 21, 42, -50 ] ], [ [ 6113341760402965, -3032143586011050, -4159967272068153, 14002438585824810 ], [ 10588511869480164, -5251666322974043, -7205040811308855, 24252552936374367 ], [ 3778184141734557, -1873864241780610, -2570850209123252, 8653736311352880 ], [ 5051133104082267, -2505235179386847, -3437063756709534, 11569395035183716 ] ], [ [ -929944511, 51250063536, 73214376480, -161071628256 ], [ -21964312944, 28355806081, -43928625888, 0 ], [ 14642875296, -43928625888, -8251382159, 80535814128 ], [ 0, -29285750592, -43928625888, 94248744913 ] ], [ [ 66665305, 197870628, 559233360, -913773168 ], [ -115467732, -342721799, -968620464, 1582701120 ], [ 41201448, 122290656, 345625141, -564742596 ], [ -41868840, -124271736, -351223944, 573891037 ] ], [ [ -929944511, 51250063536, 73214376480, -161071628256 ], [ -21964312944, 28355806081, -43928625888, 0 ], [ 14642875296, -43928625888, -8251382159, 80535814128 ], [ 0, -29285750592, -43928625888, 94248744913 ] ], [ [ -929944511, 51250063536, 73214376480, -161071628256 ], [ -21964312944, 28355806081, -43928625888, 0 ], [ 14642875296, -43928625888, -8251382159, 80535814128 ], [ 0, -29285750592, -43928625888, 94248744913 ] ], [ [ 34, 0, 21, 0 ], [ 42, -50, -105, 231 ], [ 21, 0, 13, 0 ], [ 21, -21, -42, 97 ] ], [ [ 3385900582, -1680337008, -2305472631, 7756555653 ], [ 5861155020, -2905320200, -3985748151, 13422579324 ], [ 2090409006, -1035207621, -1420053053, 4785959871 ], [ 2795550429, -1385267583, -1900360644, 6401474647 ] ], [ [ 13, 0, -21, 0 ], [ -42, 97, 105, -231 ], [ -21, 0, 34, 0 ], [ -21, 21, 42, -50 ] ], [ [ 242047, -215208, -307440, 676368 ], [ 92232, 119071, 184464, 0 ], [ -61488, 184464, 272791, -338184 ], [ 0, 122976, 184464, -157625 ] ] ] , [ [ [ -17555, -25515, -19929, 32571 ], [ 30387, 44164, 34503, -56364 ], [ 28392, 41265, 32236, -52668 ], [ 19362, 28140, 21987, -35909 ] ], [ [ 1351, -780, 0, 0 ], [ -2340, 1351, 0, 0 ], [ 5460, 6240, 5251, -8580 ], [ 780, 2340, 1560, -2549 ] ], [ [ 5044200094, 3284045655, 3464193024, -5660403408 ], [ -8736810795, -5688133874, -6000158304, 9804106224 ], [ 3117487071, 2029651800, 2140989019, -3498321651 ], [ -2217936039, -1443995685, -1523206542, 2488880785 ] ], [ [ 1351, 780, 0, 0 ], [ 2340, 1351, 0, 0 ], [ -5460, -6240, -2549, 8580 ], [ -780, -2340, -1560, 5251 ] ], [ [ 445, 285, 303, -495 ], [ -771, -494, -525, 858 ], [ 288, 195, 202, -330 ], [ -192, -120, -129, 211 ] ], [ [ 5044200094, 3284045655, 3464193024, -5660403408 ], [ -8736810795, -5688133874, -6000158304, 9804106224 ], [ 3117487071, 2029651800, 2140989019, -3498321651 ], [ -2217936039, -1443995685, -1523206542, 2488880785 ] ], [ [ -64949609, -94398330, -73739913, 120489633 ], [ 112494768, 163500796, 127720299, -208690878 ], [ 105089865, 152738475, 119313055, -194954199 ], [ 71703495, 104214405, 81408309, -133017998 ] ], [ [ -3051232082, -4434686265, -3464193024, 5660403408 ], [ 5284888965, 7681101886, 6000158304, -9804106224 ], [ 4936997199, 7175473080, 5605182043, -9158725059 ], [ 3368576649, 4895917515, 3824487762, -6249115823 ] ], [ [ -3051232082, -4434686265, -3464193024, 5660403408 ], [ 5284888965, 7681101886, 6000158304, -9804106224 ], [ 4936997199, 7175473080, 5605182043, -9158725059 ], [ 3368576649, 4895917515, 3824487762, -6249115823 ] ], [ [ 1351, -780, 0, 0 ], [ -2340, 1351, 0, 0 ], [ 5460, 6240, 5251, -8580 ], [ 780, 2340, 1560, -2549 ] ], [ [ 181150, 193440, 73353, -246906 ], [ 313755, 335044, 127047, -427647 ], [ -293103, -312990, -118685, 399498 ], [ 164082, 175215, 66441, -223643 ] ], [ [ 1351, -780, 0, 0 ], [ -2340, 1351, 0, 0 ], [ 5460, 6240, 5251, -8580 ], [ 780, 2340, 1560, -2549 ] ], [ [ 220027, 143250, 151107, -246906 ], [ -381093, -248111, -261723, 427647 ], [ 135981, 88530, 93388, -152592 ], [ -96744, -62985, -66441, 108562 ] ] ] , [ [ [ -492568055, -715902540, -559233360, 913773168 ], [ 853152732, 1239979321, 968620464, -1582701120 ], [ 796991748, 1158354480, 904858501, -1478515764 ], [ 543797628, 790360020, 617396520, -1008810083 ] ], [ [ -348686135, -530151780, -271469520, 913773168 ], [ -603941868, -918249479, -470198736, 1582701120 ], [ -215499732, -327651600, -167777219, 564742596 ], [ -793008492, -1205711460, -617396520, 2078172517 ] ], [ [ -151935722, -225045135, -150030090, 330066198 ], [ 45009027, 58106404, 90018054, 0 ], [ 105021063, 150030090, 133121449, -165033099 ], [ -45009027, -75015045, 0, 193133485 ] ], [ [ 13, 0, -21, 0 ], [ 147, 181, 105, -231 ], [ -21, 0, 34, 0 ], [ 84, 105, 63, -134 ] ], [ [ 670415977, 715902540, 271469520, -913773168 ], [ 1161194148, 1239979321, 470198736, -1582701120 ], [ -1084755588, -1158354480, -439246739, 1478515764 ], [ 607257732, 648459180, 245895000, -827688875 ] ], [ [ 814297897, 530151780, 559233360, -913773168 ], [ -1410405012, -918249479, -968620464, 1582701120 ], [ 503263572, 327651600, 345625141, -564742596 ], [ -358046868, -233107740, -245895000, 401786125 ] ], [ [ 141577573978831, 92174617804950, 97230886083807, -158872797828558 ], [ -245219551343241, -159651121205951, -168408834761919, 275175757779087 ], [ 87499752763389, 56967046703190, 60091992355948, -98188788945456 ], [ -62251695137616, -40529202794985, -42752445237981, 69856409444878 ] ] ] ]; return matrixlist[n]; end ); alnuth-4.0.0/gap/0000755000000000000000000000000015201210200010462 5ustar00alnuth-4.0.0/gap/factors.gd0000644000000000000000000000274315201210200012445 0ustar00############################################################################# ## #W factors.gd Alnuth - ALgebraic NUmber THeory Andreas Distler ## ############################################################################# ## #F FactorsPolynomialAlnuth, function( ) ## ## Factorizes the polynomial defined over an algebraic extension of ## the rationals using PARI/GP ## ## As a method of 'Factors' ? AD ## DeclareGlobalFunction("FactorsPolynomialAlnuth"); DeclareObsoleteSynonym( "FactorsPolynomialPari", "FactorsPolynomialAlnuth" ); ############################################################################# ## #F FactorsPolynomialAlgExt, function( , ) ## ## Factorizes the rational polynomial over the field , a proper ## algebraic extension of the rationals, using PARI/GP ## DeclareGlobalFunction( "FactorsPolynomialAlgExt" ); ############################################################################# ## #M IrrFacsAlgExtPol() . . . . . lists of irreducible factors of rational ## polynomial over algebraic extensions, initialize default ## DeclareAttribute( "IrrFacsAlgExtPol", IsUnivariatePolynomial, "mutable" ); ############################################################################# ## #F StoreFactorsAlgExtPol( , , ) . store factors list ## DeclareGlobalFunction( "StoreFactorsAlgExtPol" ); ############################################################################# ## #E alnuth-4.0.0/gap/factors.gi0000644000000000000000000000660615201210200012454 0ustar00############################################################################ ## #W factors.gi Alnuth - ALgebraic NUmber THeory Andreas Distler ## ############################################################################# ## #M IrrFacsAlgExtPol() . . . . . lists of irreducible factors of rational ## polynomial over algebraic extensions, initialize default ## InstallOtherMethod(IrrFacsAlgExtPol,true,[IsPolynomial],0,f -> []); ############################################################################# ## #F StoreFactorsAlgExtPol( , , ) . store factors list ## InstallGlobalFunction(StoreFactorsAlgExtPol,function(R,f,fact) local irf; irf:=IrrFacsAlgExtPol(f); if not ForAny(irf,i->i[1]=R) then Add(irf,[R,fact]); fi; end); ############################################################################# ## #F FactorsPolynomialAlgExt, function( , ) ## ## Factorizes the rational polynomial over the field , a proper ## algebraic extension of the rationals, using PARI/GP ## InstallGlobalFunction( FactorsPolynomialAlgExt, function( H, poly ) local faktoren, irf, i; if not ForAll( CoefficientsOfUnivariatePolynomial( poly ), IsRat ) then Error( "polynomial has to be defined over the Rationals" ); fi; if H = Rationals then return Factors( poly ); fi; irf := IrrFacsAlgExtPol( poly ); i := PositionProperty( irf, k -> k[1] = H ); if i <> fail then return irf[i][2]; fi; faktoren := FactorsPolynomialAlnuth( AlgExtEmbeddedPol( H, poly )); StoreFactorsAlgExtPol( H, poly, faktoren ); return faktoren; end ); ############################################################################# ## #F FactorsPolynomialAlnuth, function( ) ## ## Factorizes the polynomial defined over an algebraic extension of ## the rationals using PARI/GP ## ## As a method of 'Factors' ? AD ## InstallGlobalFunction(FactorsPolynomialAlnuth, function( poly ) local faktoren, fak, coeff, c, lcoeff, irf, i, coeffs, H; H := CoefficientsRing( DefaultRing( poly )); irf := IrrFacsAlgExtPol( poly ); i := PositionProperty( irf, k -> k[1] = H ); if i <> fail then return irf[i][2]; fi; if DegreeOfLaurentPolynomial( poly ) < 2 then faktoren := [ poly ]; StoreFactorsPol( H, poly, faktoren ); return faktoren; fi; faktoren := [ ]; lcoeff := LeadingCoefficient( poly ); coeffs := CoefficientsOfUnivariatePolynomial( poly / lcoeff ); coeffs := List( Reversed( coeffs ), ExtRepOfObj ); for fak in AL_FUNCS.PolynomialFactorsDescription( H, coeffs ) do coeff := [ ]; for c in Reversed( fak ) do if ( c in Rationals ) then Add( coeff, c ); else Add( coeff, LinearCombination( EquationOrderBasis(H), c ) ); fi; od; Add( faktoren, UnivariatePolynomial( H, One(H)*coeff ) ); od; faktoren[1] := lcoeff * faktoren[1]; StoreFactorsPol( H, poly, faktoren ); return faktoren; end ); ############################################################################# ## #E alnuth-4.0.0/gap/field.gd0000644000000000000000000000426715201210200012072 0ustar00############################################################################# ## #W field.gd Alnuth - ALgebraic NUmber THeory Bettina Eick #W Bjoern Assmann ## DeclareInfoClass( "InfoAlnuth" ); DeclareRepresentation( "IsBasisOfMatrixField", IsBasis and IsAttributeStoringRep, [] ); DeclareOperation( "ExponentsOfUnits", [IsNumberField, IsCollection] ); DeclareOperation( "IsPrimitiveElementOfNumberField", [ IsNumberField, IsObject ] ); DeclareOperation( "RelationLattice", [IsNumberField, IsCollection] ); DeclareProperty( "IsUnitGroup", IsGroup ); InstallTrueMethod( IsGroup, IsUnitGroup ); DeclareProperty( "IsUnitGroupIsomorphism", IsMapping); DeclareProperty( "IsNumberFieldByMatrices", IsNumberField ); InstallTrueMethod( IsNumberField, IsNumberFieldByMatrices ); DeclareProperty( "IsMultGroupByFieldElemsIsomorphism", IsMapping); DeclareAttribute( "IntegerDefiningPolynomial", IsNumberField ); DeclareAttribute( "IntegerPrimitiveElement", IsNumberField ); DeclareAttribute( "EquationOrderBasis", IsNumberField ); DeclareAttribute( "MaximalOrderBasis", IsNumberField ); DeclareAttribute( "UnitGroup", IsNumberField ); DeclareAttribute( "DefiningPolynomial", IsNumberFieldByMatrices ); DeclareAttribute( "FieldOfUnitGroup", IsGroup ); DeclareGlobalFunction( "FieldOfPolynomial" ); DeclareGlobalFunction( "FieldByMatricesNC" ); DeclareGlobalFunction( "FieldByMatrixBasisNC" ); DeclareGlobalFunction( "FieldByPolynomialNC" ); DeclareGlobalFunction( "FieldByMatrices" ); DeclareGlobalFunction( "FieldByMatrixBasis" ); DeclareGlobalFunction( "FieldByPolynomial" ); DeclareGlobalFunction( "IntersectionOfUnitSubgroups" ); DeclareGlobalFunction( "IntersectionOfTFUnitsByCosets" ); DeclareGlobalFunction( "NormCosetsOfNumberField" ); DeclareGlobalFunction( "IsUnitOfNumberField" ); DeclareGlobalFunction( "RelationLatticeOfTFUnits"); DeclareGlobalFunction( "RelationLatticeModUnits"); DeclareGlobalFunction( "RelationLatticeTF"); DeclareGlobalFunction( "RelationLatticeOfUnits"); DeclareGlobalFunction( "PcpPresentationMultGroupByFieldEl"); DeclareGlobalFunction( "PcpPresentationOfMultiplicativeSubgroup"); alnuth-4.0.0/gap/field.gi0000644000000000000000000001776115201210200012102 0ustar00############################################################################ ## #W field.gi Alnuth - ALgebraic NUmber THeory Bettina Eick #W Bjoern Assmann #W Andreas Distler ## ############################################################################# ## #F ListElmPower( range, elm ) #M EquationOrderBasis( F ) ## BindGlobal( "ListElmPower", function( range, elm ) local list, i; if not IsRange( range ) then Error( " has to be a range" ); fi; # trivial cases if IsEmpty( range ) then return [ ]; elif Length( range ) = 1 then return [ elm ^ range[1] ]; fi; list := [ elm ^ range[1] ]; elm := elm ^ (range[2] - range[1]); for i in [ 1..Length( range ) - 1 ] do Add( list, list[i] * elm ); od; return list; end ); InstallMethod( EquationOrderBasis, "for number field", true, [IsNumberField], 0, function( F ) return RelativeBasisNC( Basis( F ), ListElmPower( [ 0..DegreeOverPrimeField( F )-1 ], IntegerPrimitiveElement( F ) ) ) ; end ); InstallMethod( IsPrimitiveElementOfNumberField, "for number field and algebraic element", true, [ IsNumberField, IsObject ], 0, function( F, elm ) local d, g; if not elm in F then Info( InfoAlnuth, 1, "Element does not lie in the field." ); return false; fi; d := DegreeOverPrimeField( F ); g := MinimalPolynomial( Rationals, elm ); return Degree(g) = d; end ); InstallOtherMethod( EquationOrderBasis, "for number field and primitive element", true, [IsNumberField, IsObject ], 0, function( F , elm ) if not IsPrimitiveElementOfNumberField( F, elm ) then return fail; fi; return RelativeBasisNC(Basis( F ), ListElmPower([0..DegreeOverPrimeField(F)-1],elm)); end ); ############################################################################# ## #M MaximalOrderBasis( F ) ## InstallMethod(MaximalOrderBasis, "for number field", true,[IsNumberField], 0, function( F ) local e, T, b, B; if DegreeOverPrimeField(F)=1 then return EquationOrderBasis(F); fi; e := EquationOrderBasis(F); T := AL_FUNCS.MaximalOrderDescription(F); b := List( T, x -> LinearCombination( e, x ) ); B := Objectify(NewType(FamilyObj(F), IsFiniteBasisDefault and IsRelativeBasisDefaultRep), rec()); SetUnderlyingLeftModule( B, F ); SetBasisVectors( B, b ); B!.basis := e; B!.basechangeMatrix := Immutable( T^-1 ); return B; end ); ############################################################################# ## #F IsIntegerOfNumberField( F, k ) ## BindGlobal( "IsIntegerOfNumberField", function( F, k ) local c; c := Coefficients( MaximalOrderBasis(F), k ); return ForAll( c, IsInt ); end ); ############################################################################# ## #M UnitGroup( F ) ## BindGlobal( "AddNaturalHomomorphismOfUnitGroup", function( G ) local gens, rels, H, nat; # the generators of G are independent and the first one is torsion gens := GeneratorsOfGroup(G); rels := List( gens, x -> 0 ); rels[1] := Order( gens[1] ); H := AbelianPcpGroup( Length(rels), rels ); nat := GroupHomomorphismByImagesNC( G, H, gens, AsList(Pcp(H)) ); # add infos SetIsBijective( nat, true ); SetIsUnitGroupIsomorphism( nat, true ); SetIsomorphismPcpGroup( G, nat ); end ); BindGlobal( "AddUnitGroupOfNumberField", function( F, units ) local gens, G; # check if units are known if HasUnitGroup(F) then gens := GeneratorsOfGroup(UnitGroup(F)); if not gens = units then Error("wrong units"); fi; fi; # otherwise add them G := GroupByGenerators( units ); SetIsUnitGroup( G, true ); SetFieldOfUnitGroup( G, F ); AddNaturalHomomorphismOfUnitGroup( G ); SetUnitGroup( F, G ); end ); BindGlobal( "UnitGroupOfNumberField", function( F ) local eqn, uni, gen, G, r, H, nat; # determine generators eqn := EquationOrderBasis(F); uni := AL_FUNCS.UnitGroupDescription(F); if uni=[-1] then G:=GroupByGenerators([-1*eqn[1]]); else gen := List( uni, x -> LinearCombination( eqn, x ) ); G := GroupByGenerators(gen); fi; # add info SetIsUnitGroup( G, true ); SetFieldOfUnitGroup( G, F ); AddNaturalHomomorphismOfUnitGroup( G ); # return return G; end ); InstallMethod( UnitGroup, "for number field", true, [IsNumberField], 0, function( F ) return UnitGroupOfNumberField( F ); end); ############################################################################# ## #F IsUnitOfNumberField( F, k ) ## InstallGlobalFunction( IsUnitOfNumberField, function( F, k ) if not IsIntegerOfNumberField( F, k ) then return false; fi; return AbsInt(Norm( F, k )) = 1; end ); ############################################################################# ## #F AL_ExponentsTrivialUnits( unit, one ) #F ExponentsOfUnitsOfNumberField( F, elms ) #M ExponentsOfUnits( F, elms ) ## BindGlobal( "AL_ExponentsTrivialUnits", function( unit, one ) if unit = one then return [ 0 ]; else return [ 1 ]; fi; end ); BindGlobal( "ExponentsOfUnitsOfNumberField", function( F, elms ) local base, coef, exps, gens; # catch a trivial case if IsPrimeField(F) then # check whether all elements are units if ForAny( elms, x -> not x in [ One( F ), -One( F ) ] ) then return fail; fi; # return [ 0 ] for One( F ) and [ 1 ] for -One( F ) return List( elms, x -> AL_ExponentsTrivialUnits( x, One( F ))); fi; # determine exponents base := EquationOrderBasis( F ); coef := List( elms, x -> Coefficients( base, x ) ); exps := AL_FUNCS.ExponentsOfUnitsDescriptionWithRank( F, coef ); # add unit group if this is not yet known gens := List( exps.units, x -> LinearCombination( base, x ) ); AddUnitGroupOfNumberField( F, gens ); # return exponents if exps.expns = [ ] then return fail; else return exps.expns; fi; end ); InstallMethod( ExponentsOfUnits, "for number fields", true, [IsNumberField, IsCollection], 0, function( F, elms ) return ExponentsOfUnitsOfNumberField( F, elms ); end); ############################################################################# ## #F ExponentsOfUnitsWithRank( F, elms ) ## BindGlobal( "ExponentsOfUnitsWithRank", function( F, elms ) local base, flat, coef, exps, gens; # determine exponents base := EquationOrderBasis( F ); coef := List( elms, x -> Coefficients( base, x ) ); exps := AL_FUNCS.ExponentsOfUnitsDescriptionWithRank( F, coef ); # add unit group if this is not yet known gens := List( exps.units, x -> LinearCombination( base, x ) ); AddUnitGroupOfNumberField( F, gens ); # return exponents return rec(exps:=exps.expns, rank:=exps.rank); end ); ############################################################################# ## #F NormCosetsOfNumberField( F, norm ) ## InstallGlobalFunction( NormCosetsOfNumberField, function( F, norm ) local base, reps, gens; # catch a trivial case if IsPrimeField(F) then return [norm*One(F)]; fi; # get representatives mod unit group base := EquationOrderBasis( F ); reps := AL_FUNCS.NormCosetsDescription( F, norm ); # add unit group if this is not yet known gens := List( reps.units, x -> LinearCombination( base, x ) ); AddUnitGroupOfNumberField( F, gens ); # translate coset reps return List( reps.creps, x -> LinearCombination( base, x ) ); end ); ############################################################################# ## #M IsCyclotomicField( F ) ## InstallMethod( IsCyclotomicField, "for number fields", true, [IsNumberField], 0, function( F ) local U, t, o; U := UnitGroup(F); t := GeneratorsOfGroup(U)[1]; o := Order(t); return Phi(o) = DegreeOverPrimeField(F); end); alnuth-4.0.0/gap/isom.gi0000644000000000000000000000366215201210200011761 0ustar00############################################################################# ## #W isom.gi Alnuth - ALgebraic NUmber THeory Bjoern Assmann ## ############################################################################# ## #F IsomorphismOfMultGroupByFieldEl( F, elms ) ## BindGlobal( "IsomorphismOfMultGroupByFieldEl", function( F, elms ) local gens, rels, H, nat,CPCS,G; # calculate a constructive pc-sequence CPCS := CPCSOfGroupByFieldElements( F, elms ); H := PCPOfGroupByFieldElementsByCPCS( F, CPCS ); # new generating set for G := GroupByGenerators(CPCS.gens); nat := GroupHomomorphismByImagesNC( G, H, CPCS.gens, AsList(Pcp(H)) ); # add infos SetIsBijective( nat, true ); SetIsMultGroupByFieldElemsIsomorphism( nat, true ); nat!.CPCS := CPCS; nat!.field := F; return nat; end ); ############################################################################# ## #M Create isom to pcp group ## InstallOtherMethod( IsomorphismPcpGroup, "for matrix fields", true, [IsNumberFieldByMatrices, IsCollection], 0, function( F, elms ) return IsomorphismOfMultGroupByFieldEl( F, elms ); end); InstallOtherMethod( IsomorphismPcpGroup, "for fields def. by polynomial", true, [IsNumberField and IsAlgebraicExtension, IsCollection], 0, function( F, elms ) return IsomorphismOfMultGroupByFieldEl( F, elms ); end); ############################################################################# ## #M Images under group by field elems isom ## InstallMethod( ImagesRepresentative, "for group by field elems isom", FamSourceEqFamElm, [IsGroupGeneralMappingByImages and IsMultGroupByFieldElemsIsomorphism, IsMultiplicativeElementWithInverse], 0, function( nat, h ) local F, H, e, CPCS; F := nat!.field; CPCS := nat!.CPCS; H := Range( nat ); e := ExpVectorOfGroupByFieldElements( F, CPCS,h ); if e=fail then return fail; fi; return MappedVector( e, Pcp(H) ); end); alnuth-4.0.0/gap/matfield.gi0000644000000000000000000003330315201210200012572 0ustar00############################################################################# ## #W matfield.gi Alnuth - ALgebraic NUmber THeory Bettina Eick #W Bjoern Assmann #W Andreas Distler ## ############################################################################# ## #P IsNumberFieldByMatrices( ) ## InstallSubsetMaintenance( IsNumberFieldByMatrices, IsField and IsNumberFieldByMatrices, IsField ); ############################################################################# ## #F AL_SplitSemisimple( base ) ## BindGlobal( "AL_SplitSemisimple", function( base ) local d, b, f, s, i; d := Length( base ); b := PrimitiveAlgebraElement( [ ], base ); f := Factors( b.poly ); if Length( f ) = 1 then return [ rec( basis := IdentityMat( Length( b.elem ) ), poly := f ) ]; fi; s := List( f, function ( x ) return NullspaceRatMat( Value( x, b.elem ) ); end ); s := List( [ 1 .. Length( f ) ], function ( x ) return rec( basis := s[x], poly := f[x] ); end ); return s; end ); ############################################################################# ## #F AL_RadicalOfAbelianRMGroup( mats, d ) ## ## is an abelian rational matrix group ## BindGlobal( "AL_RadicalOfAbelianRMGroup", function( mats, d ) local coms, i, j, new, base, full, nath, indm, l, algb, newv, tmpb, subb, f, g, h, mat; base := []; full := IdentityMat( d ); # nath is the natural hom. from V to V/W nath := NaturalHomomorphismBySemiEchelonBases( full, base ); # indm for induced matrices indm := mats; # start spinning up basis and look for nilpotent elements i := 1; algb := []; while i <= Length( indm ) do # add next element to algebra basis l := Length( algb ); newv := Flat( indm[i] ); tmpb := SpinnUpEchelonBase(algb, [newv], indm{[1..i]},OnMatVector ); # check whether we have added a non-semi-simple element subb := []; for j in [l+1..Length(tmpb)] do mat := MatByVector( tmpb[j], Length(indm[i]) ); f := MinimalPolynomial( Rationals, mat ); g := Collected( Factors( f ) ); if ForAny( g, x -> x[2] > 1 ) then h := Product( List( g, x -> Value( x[1], mat ) ) ); Append( subb, List( h, x -> ShallowCopy(x) ) ); fi; od; #Print("found nilpotent submodule of dimension ", Length(subb),"\n"); # spinn up new subspace of radical subb := SpinnUpEchelonBase( [], subb, indm, OnRight ); if Length( subb ) > 0 then base := PreimageByNHSEB( subb, nath ); if Length( base ) = d then # radical cannot be so big return fail; fi; nath := NaturalHomomorphismBySemiEchelonBases( full, base ); indm := List( mats, x -> InducedActionFactorByNHSEB( x, nath ) ); algb := []; i := 1; else i := i + 1; fi; od; return rec( radical := base, nathom := nath, algebra := algb ); end ); ############################################################################# ## #F AL_HomogeneousSeriesAbelianRMGroup( mats, d ) ## ## is an abelian rational matrix group ## DeclareGlobalFunction( "AL_HomogeneousSeriesAbelianRMGroup" ); InstallGlobalFunction( "AL_HomogeneousSeriesAbelianRMGroup", function( mats, d ) local radb, splt, nath,inducedgens, l, sers, i, sub, full, acts, rads; # catch the trivial case and set up if d = 0 then return []; fi; full := IdentityMat( d ); if Length( mats ) = 0 then return [full, []]; fi; sers := [full]; # get the radical radb := AL_RadicalOfAbelianRMGroup( mats, d ); if radb = fail then return fail; fi; splt := AL_SplitSemisimple( radb.algebra ); nath := radb.nathom; # refine radical factor and initialize series l := Length( splt ); for i in [2..l] do sub := Concatenation( List( [i..l], x -> splt[x].basis ) ); TriangulizeMat( sub ); Add( sers, PreimageByNHSEB( sub, nath ) ); od; Add( sers, radb.radical ); # induce action to radical nath := NaturalHomomorphismBySemiEchelonBases( full, radb.radical); acts := List( mats, x -> InducedActionSubspaceByNHSEB( x, nath )); # use recursive call to refine radical rads := AL_HomogeneousSeriesAbelianRMGroup( acts, Length(radb.radical) ); if rads = fail then return fail; fi; rads := List( rads, function(x) if x=[] then return []; else return x * radb.radical; fi;end ); Append( sers, rads{[2..Length(rads)]} ); return sers; end ); ############################################################################# ## #F AL_MatricesGeneratingNumberField( gens ) ## BindGlobal( "AL_MatricesGeneratingNumberField", function( gens ) local d, series, G; d := Length(gens[1]); if ForAny( gens, x -> Length(x) <> d ) then Print("matrices must have same dimensions\n"); return false; elif not ForAll( Flat( gens ), IsRat ) then Print("matrices must be rational\n"); return false; elif ForAny( gens, x -> RankMat(x) <> d ) then Print("matrices must be invertible \n"); return false; fi; G := Group( gens ); if not IsAbelian( G ) then Print( "The algebra generated by the matrices is not abelian\n" ); return false; fi; series := AL_HomogeneousSeriesAbelianRMGroup( gens, d ); if Length( series ) > 2 then Print( "Matrices do not generate a field.\n" ); Print( "The natural module Q^",d," is not homogeneous.\n" ); return false; fi; return true; end ); ############################################################################# ## #F FieldByMatrices( gens ) ## InstallGlobalFunction( FieldByMatricesNC, function( gens ) local F; F := FieldByGenerators( gens); SetIsNumberField( F, true ); SetIsNumberFieldByMatrices( F, true ); SetIsFinite( F, false ); return F; end ); InstallGlobalFunction( FieldByMatrices, function( gens ) local F; if not AL_MatricesGeneratingNumberField( gens ) then return fail; fi; F := FieldByMatricesNC( gens ); DegreeOverPrimeField( F ); return F; end ); ############################################################################# ## #F FieldByMatrixBasisNC( gens ) . . . MatFieldByAlgebraBasis ## InstallGlobalFunction( FieldByMatrixBasisNC, function( gens ) local F, B; F := FieldByMatricesNC( gens ); B := Objectify(NewType(FamilyObj(F), IsBasisOfMatrixField), rec()); SetUnderlyingLeftModule( B, F ); SetBasisVectors( B, gens ); SetBasis( F, B ); DegreeOverPrimeField( F ); return F; end ); InstallGlobalFunction( FieldByMatrixBasis, function( gens ) local V; if not AL_MatricesGeneratingNumberField( gens ) then return fail; fi; V := VectorSpace( Rationals, gens ); # test linear independence if Length( Basis( V )) < Length( gens ) then Print("matrices must be linearly independent\n"); return fail; fi; # test whether V = Field( gens ) if Length( AlgebraBase( gens )) > Length( gens ) then Print("dimension of generated field is greater than vector space dimension\n"); return fail; fi; return FieldByMatrixBasisNC( gens ); end ); ############################################################################# ## #F BasisVectorsOfMatrixField( F ) #M CanonicalBasis( F ) #M Basis( F ) ## BindGlobal( "BasisVectorsOfMatrixField", function( F ) return AlgebraBase( GeneratorsOfField(F) ); end ); InstallMethod( CanonicalBasis, "for matrix field", true, [IsNumberFieldByMatrices], 0, function( F ) local B, b; B := Objectify(NewType(FamilyObj(F), IsBasisOfMatrixField), rec()); b := BasisVectorsOfMatrixField( F ); SetUnderlyingLeftModule( B, F ); SetBasisVectors( B, b ); return B; end ); InstallMethod( Basis, "for matrix field", true, [IsNumberFieldByMatrices], 0, function( F ) return CanonicalBasis( F ); end ); ############################################################################# ## #M Coefficients( B, a ) ## InstallMethod( Coefficients, "for basis of matrix field", true, [IsBasisOfMatrixField, IsVector ], 15, function( B, a ) local b; b := BasisVectors( B ); b := List( b, Flat ); return SolutionMat( b, Flat(a) ); end ); ############################################################################# ## #M DegreeOverPrimeField( F ) ## InstallMethod( DegreeOverPrimeField, "for matrix field", true, [IsNumberFieldByMatrices], 0, function( F ) return Length( Basis( F ) ); end); ############################################################################# ## #F IntegralMatrix #F SuitablePrimitiveElementCheck( F, k ) ## BindGlobal( "IntegralMatrix", function( mat ) local l,n,i,j,a; l := []; n := Length( mat ); for i in [1..n] do for j in [1..n] do Add( l, DenominatorRat( mat[i][j]) ); od; od; a := Lcm( l ); return a*mat; end ); BindGlobal( "SuitablePrimitiveElementCheck", function( F, k ) local d, g, sumCoef; d := DegreeOverPrimeField( F ); g := MinimalPolynomial( Rationals, k ); if not Degree(g) = d then return false; elif ForAll( CoefficientsOfUnivariatePolynomial(g), IsInt ) then sumCoef := Sum( List(CoefficientsOfUnivariatePolynomial(g),x->AbsInt(x)) ); Info( InfoAlnuth, 3, "sum of the coefficients is"); Info( InfoAlnuth, 3, sumCoef ); return rec( prim := k, min := g, sumCoef := sumCoef); else k := IntegralMatrix( k ); g := MinimalPolynomial( Rationals, k ); sumCoef := Sum( List(CoefficientsOfUnivariatePolynomial(g),x->AbsInt(x)) ); Info( InfoAlnuth, 3, "sum of the coefficients is"); Info( InfoAlnuth, 3, sumCoef ); return rec( prim := k, min := g, sumCoef := sumCoef); fi; end ); ############################################################################# ## #F SuitablePrimitiveElementOfMatrixField( F ) #M IntegerPrimitiveElement( F ) #M PrimitiveElement( F ) ## BindGlobal( "SuitablePrimitiveElementOfMatrixField", function( F ) local k, d, b, l, i, c, primtmp,prim, poss; # try to find a primitive element wiht small coeff in the minpol prim := rec( prim := [], min := [], sumCoef := infinity); poss := 0; #catch the trivial case if DegreeOverPrimeField(F)=1 then return One(F); fi; # first try the generators of F for k in GeneratorsOfField(F) do primtmp := SuitablePrimitiveElementCheck( F, k ); if not IsBool( primtmp ) then poss := poss + 1; if primtmp.sumCoef < prim.sumCoef then prim := primtmp; fi; fi; od; # otherwise try random elements d := DegreeOverPrimeField( F ); b := Basis(F); l := List( [1..d], x -> 0 ); Append( l, [1,1,-1] ); i := 1; while poss < AL_CurrentPrimitiveElementTrials() do Info( InfoAlnuth, 3, "another try to calculate primitive element"); Info( InfoAlnuth, 3, i ); c := List( [1..d], x -> RandomList( l ) ); k := LinearCombination( b, c ); primtmp := SuitablePrimitiveElementCheck( F, k ); if not IsBool( primtmp ) then poss := poss + 1; if primtmp.sumCoef < prim.sumCoef then prim := primtmp; fi; fi; i := i + 1; Append( l, [i,i,-i] ); od; SetDefiningPolynomial( F, prim.min ); SetIntegerDefiningPolynomial( F, prim.min ); Info( InfoAlnuth, 2, "prim is ", prim); return prim.prim; end ); InstallMethod( IntegerPrimitiveElement, "for matrix field", true, [IsNumberFieldByMatrices], 0, function( F ) return SuitablePrimitiveElementOfMatrixField(F); end); InstallMethod( PrimitiveElement, "for matrix field", true, [IsNumberFieldByMatrices], 0, function( F ) return IntegerPrimitiveElement(F); end); InstallOtherMethod( DefiningPolynomial, "for matrix field", true, [IsNumberFieldByMatrices], 0, function( F ) return MinimalPolynomial( Rationals, PrimitiveElement(F) ); end); ############################################################################# ## #M IntegerDefiningPolynomial( F ) ## InstallMethod( IntegerDefiningPolynomial, "for matrix field", true, [IsNumberFieldByMatrices], 0, function( F ) return MinimalPolynomial( Rationals, IntegerPrimitiveElement( F ) ); end ); ############################################################################# ## #F Norm(F,k) ## InstallOtherMethod( Norm, "for matrix fields", true, [IsNumberFieldByMatrices, IsMultiplicativeElement], SUM_FLAGS, function( F, k ) local l, d; l := Length(k); d := DegreeOverPrimeField(F); return Root( Determinant(k), l/d ); end ); ############################################################################# ## #M PrintObj( F ) #M ViewObj( F ) ## InstallMethod( PrintObj, "for a matrix field", true, [IsNumberFieldByMatrices], 0, function( F ) if HasDegreeOverPrimeField( F ) then Print( "" ); else Print(""); fi; end ); InstallMethod( ViewObj, "for a matrix field", true, [IsNumberFieldByMatrices], 0, function( F ) if HasDegreeOverPrimeField( F ) then Print( "" ); else Print(""); fi; end ); alnuth-4.0.0/gap/matunits.gi0000644000000000000000000000522215201210200012650 0ustar00############################################################################# ## #W matunits.gi Alnuth - ALgebraic NUmber THeory Bettina Eick ## ############################################################################# ## #F IntersectionOfUnitSubgroups( F, gen1, gen2 ) ## ## Let and be two subgroups of U(F). ## This function computes the intersection of and as exponents ## in the generators of . ## InstallGlobalFunction( IntersectionOfUnitSubgroups, function(F,gen1,gen2) local add, ad1, ad2, U, u, l, m, t, int, i; # get an additive description of both unit groups add := ExponentsOfUnits( F, Concatenation( gen1, gen2 ) ); ad1 := add{[1..Length(gen1)]}; ad2 := add{[Length(gen1)+1..Length(gen1)+Length(gen2)]}; # extract units U := UnitGroupOfNumberField( F ); u := GeneratorsOfGroup(U); l := Length(u)-1; m := Order(u[1]); t := List( [1..l+1], x -> 0 ); t[1] := m; # compute intersection int := NullspaceIntMat( Concatenation( ad1, ad2, [t] ) ); int := int{[1..Length(int)]}{[1..Length(ad1)]}; # reduce torsion if int[1][1] <> 0 then int[1][1] := int[1][1] mod m; fi; if int[1] = 0*int[1] then int := int{[2..Length(int)]}; fi; return int; end ); ############################################################################# ## #F IntersectionOfTFUnitsByCosets( F, mats, C ) ## ## is a torsion free subgroup of U(F) und C are some cosets in U(F). ## InstallGlobalFunction( IntersectionOfTFUnitsByCosets, function( F, mats, C ) local a, b, c, d, all, add, rep, s, i, r, fr1, fr2, int; # set up a := Length( mats ); b := Length( C.units ); c := Length( C.reprs ); # determine additive description all := Concatenation( mats, C.units, C.reprs ); add := ExponentsOfUnits( F, all ); # mod out torsion d := Length( GeneratorsOfGroup(UnitGroup(F)) ) - 1; add := add{[1..Length(add)]}{[2..d+1]}; # cut into pieces rep := add{[ a+b+1..a+b+c ]}; add := add{[ 1..a+b ]}; # loop over reps s := false; i := 1; while IsBool(s) and i <= Length(rep) do r := SolutionIntMat( add, rep[i] ); i := i+1; if not IsBool(r) then s := r{[1..a]}; fi; od; # if we cannot find a representative, then return if IsBool(s) then return false; fi; # otherwise add intersection of mats with C.units fr1 := add{[1..a]}; fr2 := add{[a+1..a+b]}; # find linear combinations of mgrp in unit int := NullspaceIntMat( Concatenation( fr1, fr2 ) ); int := int{[1..Length(int)]}{[1..a]}; return rec( repr := s, ints := int ); end ); alnuth-4.0.0/gap/oscar.gi0000644000000000000000000001047015201210200012114 0ustar00############################################################################# ## #W oscar.gi Alnuth - ALgebraic NUmber THeory Max Horn #W Claus Fieker ## ## ## This file is a drop-in replacement for pari.gi, thus alls functions are ## also made available with "Pari" in their name. BindGlobal("OSCAR_AL_FUNCS", rec()); # store isomorphism between GAP and OSCAR univariate polynomial ring over the # rationals as we need it again and again, for each new number field OSCAR_AL_FUNCS.PolyRingIso := Oscar.iso_gap_oscar(PolynomialRing(Rationals)); # Given a GAP number field, return an isomorphic Oscar number field. # This field is also cached OSCAR_AL_FUNCS.OscarField := function(F) local f; if not IsBound(F!.oscarField) then f := OSCAR_AL_FUNCS.PolyRingIso(IntegerDefiningPolynomial(F)); F!.oscarField := Oscar.number_field(f)[1]; fi; return F!.oscarField; end; OSCAR_AL_FUNCS.MaximalOrderDescription := function(F) local K, O, basis; K := OSCAR_AL_FUNCS.OscarField(F); O := Oscar.maximal_order(K); basis := Julia.map(Oscar.coordinates,Oscar.basis(O,K)); return JuliaToGAP(IsList, basis, true); end; OSCAR_AL_FUNCS.UnitGroupDescription := function(F) local K, O, U_m, U, m, basis; K := OSCAR_AL_FUNCS.OscarField(F); O := Oscar.maximal_order(K); U_m := Oscar.unit_group(O); U := U_m[1]; m := U_m[2]; basis := Julia.map(Oscar.coordinates, Julia.map(K, Julia.map(m, Oscar.gens(U)))); return JuliaToGAP(IsList, basis, true); end; OSCAR_AL_FUNCS.ExponentsOfUnitsDescriptionWithRank := function(F, elms) local K, O, U_m, U, m, basis, units, rank, expns, x; K := OSCAR_AL_FUNCS.OscarField(F); O := Oscar.maximal_order(K); U_m := Oscar.unit_group(O); U := U_m[1]; m := U_m[2]; basis := Julia.map(Oscar.coordinates, Julia.map(K, Julia.map(m, Oscar.gens(U)))); units := JuliaToGAP(IsList, basis, true); # the order of the torsion part of the full unit group rank := Oscar.GAP.julia_to_gap(Oscar.order(U_m[1][1])); expns := []; for x in elms do # map GAP int vector to Oscar element Add(expns, Oscar.GAP.julia_to_gap(Oscar.preimage(m, K(GAPToJulia(x))).coeff)[1]); od; # return result return rec(units := units, expns := expns, rank := rank); end; OSCAR_AL_FUNCS.ExponentsOfFractionalIdealDescription := function(F, elms) local K, O, tmp, ideals, result, blah, vec, I; K := OSCAR_AL_FUNCS.OscarField(F); O := Oscar.maximal_order(K); tmp := Julia.map(x -> Oscar.factor(K(GAPToJulia(x)) * O), elms); # take the union of the keys ideals := Julia.collect(Julia.reduce(Oscar.union, Julia.map(Oscar.Set, Julia.map(Oscar.keys, tmp)))); if Julia.isempty(ideals) then return []; fi; result := []; for blah in JuliaToGAP(IsList, tmp) do vec := []; for I in JuliaToGAP(IsList, ideals) do Add(vec, Julia.get(blah, I, 0)); od; Add(result, vec); od; return result; end; OSCAR_AL_FUNCS.NormCosetsDescription := function(F, norm) local K, O, U_m, U, m, basis, units, eqn, creps; K := OSCAR_AL_FUNCS.OscarField(F); O := Oscar.maximal_order(K); U_m := Oscar.unit_group(O); U := U_m[1]; m := U_m[2]; basis := Julia.map(Oscar.coordinates, Julia.map(K, Julia.map(m, Oscar.gens(U)))); units := JuliaToGAP(IsList, basis, true); eqn := Oscar.norm_equation(O, norm); creps := JuliaToGAP(IsList, Julia.map(Oscar.coordinates, Julia.map(K, eqn)), true); # return result return rec(units := units, creps := creps); end; OSCAR_AL_FUNCS.Vector_nf_elem := JuliaType( Julia.Vector, [ Oscar_jl.nf_elem ] ); OSCAR_AL_FUNCS.PolynomialFactorsDescription := function(F, coeffs) local K, cf, poly, facs, result, f, g, i; K := OSCAR_AL_FUNCS.OscarField(F); cf := OSCAR_AL_FUNCS.Vector_nf_elem(Reversed(List(coeffs, x -> K(GAPToJulia(x))))); poly := Oscar.polynomial(K, cf); facs := Oscar.factor(poly); Assert(0, Oscar.is_one(facs.unit)); result := []; for f in JuliaToGAP(IsList, Oscar.collect(facs.fac)) do # Convert factor to GAP g := Julia.map(Oscar.coordinates, f[1].coeffs); g := JuliaToGAP(IsList, g, true); g := Reversed(g); # add as many copies as necessary for i in [1..f[2]] do Add(result, g); od; od; # Sort result by ascending degrees SortBy(result, Length); return result; end; AL_FUNCS := OSCAR_AL_FUNCS; alnuth-4.0.0/gap/pari.gi0000644000000000000000000001650615201210200011746 0ustar00############################################################################# ## #W pari.gi Alnuth - ALgebraic NUmber THeory Bettina Eick #W Bjoern Assmann #W Andreas Distler ## ############################################################################# ## #F PolynomialWithNameToStringList( f[, name] ) ## BindGlobal("PolynomialWithNameToStringList", function( arg ) local c, f, stringlist, i; # get input f := arg[1]; # print identifier of polynomial, default 'f', or given as second argument if Length( arg ) = 1 then stringlist := ["f = "]; else stringlist := Concatenation(arg[2], " = "); fi; # print polynomial using 'x' as variable c := CoefficientsOfUnivariatePolynomial( f ); for i in [1..Length(c)] do if c[i] >= 0 and i > 1 then Add(stringlist, "+"); fi; Add(stringlist, Concatenation(String(c[i]), "*x^", String(i-1))); od; Add(stringlist,";\n"); return stringlist; end); ############################################################################# ## #F CoefficientsToStringList(name, coeffs) ## BindGlobal("CoefficientsToStringList", function(name, coeffs) local stringlist, c; stringlist := ["{"]; Add(stringlist, name); Add(stringlist, "= [ \n"); for c in coeffs do Add(stringlist, String(c)); Add(stringlist, ", \n"); od; Add(stringlist, "0]; }\n"); return stringlist; end); ############################################################################# ## #F ProcessPariGP(input, codefile) ## BindGlobal("ProcessPariGP", function(input, codefile) local exe, output, paricode, memopt; exe := AL_CurrentPariGpPath(); if exe = fail then Error("Alnuth couldn't locate a usable PARI/GP executable.\n", "You may the `PariGpPath` user preference to point to one."); fi; # add the prepared code fragments for the calculations in PARI/GP paricode := InputTextFile( Filename(DirectoriesPackageLibrary("alnuth", "gp"), codefile) ); # execute PARI/GP Info(InfoAlnuth, 1, "executing PARI/GP with ", codefile); output := ""; memopt := Concatenation("-s", String(AL_CurrentPariStackSize()), "M"); Process(DirectoryCurrent(), exe, InputTextString(Concatenation(input, ReadAll(paricode))), OutputTextString(output,false), Concatenation(AL_CurrentPariGpOptions(), [memopt]) ); # close open input stream from file with GP code CloseStream(paricode); return EvalString(output); end); ############################################################################# ## #F MaximalOrderDescriptionPari( F ) ## BindGlobal("MaximalOrderDescriptionPari", function( F ) local input, result; if IsPrimeField(F) then return [1]; fi; # initialize list of input strings with the defining polynomial input := PolynomialWithNameToStringList(IntegerDefiningPolynomial(F)); # execute PARI/GP result := ProcessPariGP(Concatenation(input), "maxord.gp"); # return result return result; end); ############################################################################# ## #F UnitGroupDescriptionPari( F ) ## BindGlobal("UnitGroupDescriptionPari", function( F ) local input, result; if IsPrimeField( F ) then return [-1]; fi; # initialize list of input strings with the defining polynomial input := PolynomialWithNameToStringList(IntegerDefiningPolynomial(F)); # execute PARI/GP result := ProcessPariGP(Concatenation(input), "units.gp"); # return result return result; end); ############################################################################# ## #F ExponentsOfUnitsDescriptionWithRankPari( F, elms ) ## BindGlobal("ExponentsOfUnitsDescriptionWithRankPari", function( F, elms ) local input, e, result; if IsPrimeField( F ) then return fail; fi; # initialize list of input strings with the defining polynomial input := PolynomialWithNameToStringList(IntegerDefiningPolynomial(F)); # add coefficients of input := Concatenation(input, CoefficientsToStringList("elms", elms)); # execute PARI/GP result := ProcessPariGP(Concatenation(input), "decompra.gp"); # return result return rec(units := result[1], expns := result[2], rank := result[3]); end); ############################################################################# ## #F ExponentsOfFractionalIdealDescriptionPari( F, elms ) ## ## are arbitrary elements of F (or rather their coefficients). ## Returns the exponents vectors of the fractional ideals ## generated by elms corresponding to the underlying prime ideals. ## BindGlobal( "ExponentsOfFractionalIdealDescriptionPari", function( F, elms ) local input, e, result; if IsPrimeField( F ) then return fail; fi; # initialize list of input strings with the defining polynomial input := PolynomialWithNameToStringList(IntegerDefiningPolynomial(F)); # add coefficients of input := Concatenation(input, CoefficientsToStringList("elms", elms)); # execute PARI/GP result := ProcessPariGP(Concatenation(input), "fracidea.gp"); # return result return result; end); ############################################################################# ## #F NormCosetsDescriptionPari( F, norm ) ## BindGlobal( "NormCosetsDescriptionPari", function( F, norm ) local input, result; if IsPrimeField(F) then return fail; fi; # initialize list of input strings with the defining polynomial input := PolynomialWithNameToStringList(IntegerDefiningPolynomial(F)); # add norm information Add(input, "nrm = "); Add(input, String(norm)); Add(input, "; \n"); # execute PARI/GP result := ProcessPariGP(Concatenation(input), "norm.gp"); # return result return rec(units := result[1], creps := result[2]); end); ############################################################################# ## #F PolynomialFactorsDescriptionPari, function( , ) ## ## Factorizes the polynomial defined by over the field ## using PARI/GP ## BindGlobal( "PolynomialFactorsDescriptionPari", function( F, coeffs ) local input, c, result, runtime; # initialize list of input strings with the defining polynomial input := PolynomialWithNameToStringList(IntegerDefiningPolynomial(F)); # add the coefficients of the polynomial to be factorised input := Concatenation(input, CoefficientsToStringList("coeffs", coeffs)); # execute PARI/GP result := ProcessPariGP(Concatenation(input), "polyfactors.gp"); # print runtime runtime := Remove(result); Info(InfoAlnuth, 1, "Runtime: ", runtime); # return result return result; end ); BindGlobal("PARI_AL_FUNCS", rec( MaximalOrderDescription := MaximalOrderDescriptionPari, UnitGroupDescription := UnitGroupDescriptionPari, ExponentsOfUnitsDescriptionWithRank := ExponentsOfUnitsDescriptionWithRankPari, ExponentsOfFractionalIdealDescription := ExponentsOfFractionalIdealDescriptionPari, NormCosetsDescription := NormCosetsDescriptionPari, PolynomialFactorsDescription := PolynomialFactorsDescriptionPari, )); AL_FUNCS := PARI_AL_FUNCS; alnuth-4.0.0/gap/polfield.gi0000644000000000000000000000434715201210200012611 0ustar00############################################################################# ## #W polfield.gi Alnuth - ALgebraic NUmber THeory Bettina Eick #W Bjoern Assmann ## ############################################################################# ## #F FieldOfPolynomial(f) ## InstallGlobalFunction( FieldOfPolynomial, function( f ) local c; c := CoefficientsOfUnivariatePolynomial(f); return Field(c); end ); ############################################################################# ## #F FieldByPolynomial( f ) ## InstallGlobalFunction( FieldByPolynomialNC, function( f ) return AlgebraicExtension( Rationals, f ); end ); InstallGlobalFunction( FieldByPolynomial, function( f ) if DegreeOfUnivariateLaurentPolynomial(f) <= 0 then Print("polynomial must have degree at least 1\n"); return fail; fi; if not IsIrreducible( f ) then Print("polynomial must be irreducible\n"); return fail; fi; if not ForAll( CoefficientsOfUnivariatePolynomial( f ), IsRat ) then Print("polynomial must be defined over Q \n"); return fail; fi; return FieldByPolynomialNC(f); end ); ############################################################################# ## #M IntegerPrimitiveElement( F ) ## InstallMethod( IntegerPrimitiveElement, "for algebraic extension", true, [IsNumberField and IsAlgebraicExtension], 0, function( F ) local coeff; coeff := CoefficientsOfUnivariatePolynomial( DefiningPolynomial( F )); # AD improvement possible, e.g. x^5 - 1/32 return Lcm( List( coeff, DenominatorRat ) ) * PrimitiveElement( F ); end ); ############################################################################# ## #M IntegerDefiningPolynomial( F ) ## InstallMethod( IntegerDefiningPolynomial, "for algebraic extension", true, [IsNumberField and IsAlgebraicExtension], 0, function( F ) local f, c, k, n; c := CoefficientsOfUnivariatePolynomial(DefiningPolynomial(F)); k := ExtRepOfObj( IntegerPrimitiveElement(F)/PrimitiveElement(F) )[1]; n := Degree( DefiningPolynomial(F) ); c := List( [0..n], i -> c[i+1] * k^(n-i) ); return UnivariatePolynomial( Rationals, c ); end ); alnuth-4.0.0/gap/present.gi0000644000000000000000000002177615201210200012500 0ustar00############################################################################# ## #W present.gi Alnuth - ALgebraic NUmber THeory Bjoern Assmann ## ############################################################################# ## #F GeneratorLatticeTF( rels ) ## ## rels is a sublattice of Z^n. ## this function compute a minimal generatorset of Z^n/rels ## which is torsion-free ## BindGlobal( "GeneratorLatticeTF", function( rels ) local n, normal,i,gens; n := Length( rels[1] ); normal:=NormalFormIntMat(rels,13); for i in [1..Length( normal.normal )] do if normal.normal[i][i] <> 1 then break; fi; od; if i = Length( normal.normal ) then i := i+1; fi; #gens := IdentityMat( n ); #gens := gens{[i..n]}; #gens := gens * normal.coltrans^-1; gens := (normal.coltrans^-1); gens := gens{[i..n]}; return gens; end ); ############################################################################# ## #F CPCSOfTFGroupByFieldElements( F, gens ) ## ## computes a constructive polycyclic sequence for gens ## BindGlobal( "CPCSOfTFGroupByFieldElements", function( F, gens ) local rels, exps, newGens, e, newRels; rels := RelationLatticeTF( F, gens ); if rels = [] then return rec( gens:=gens, relord:=List([1..Length(gens)], x -> 0)); fi; exps := GeneratorLatticeTF(rels); newGens := []; for e in exps do Add( newGens, MappedVector( e, gens )); od; newRels := List( [1..Length(newGens)], x -> 0); return rec( gens:=newGens, relord:=newRels); end ); ############################################################################# ## #F ExpVectorOfTFGroupByFieldElements( F, CPCS, elm ) ## ## torsion free group !! ## BindGlobal( "ExpVectorOfTFGroupByFieldElements", function( F, CPCS, elm ) local elms, rels, v, m, exp, i; m := Length( CPCS.gens ); elms := StructuralCopy( CPCS.gens ); Add( elms, elm ); rels:= RelationLatticeTF( F, elms ); v := rels[1]; exp:=[]; for i in [1..m] do exp[i]:=-v[i]/v[m+1]; od; Assert( 2, MappedVector( exp, CPCS.gens ) = elm ); return exp; end ); ############################################################################# ## #F Exp2genList(exp); ## BindGlobal( "Exp2GenList", function(exp) local n, genList,i; n:=Length(exp); genList:=[]; for i in [1..n] do if exp[i] <> 0 then Append(genList,[i,exp[i]]); fi; od; return genList; end ); ############################################################################# ## #F PCPOfTFGroupByFieldElementsByCPCS( F, CPCS ) ## BindGlobal( "PCPOfTFGroupByFieldElementsByCPCS", function( F, CPCS ) local ro, n; # Setup ro := CPCS.relord; n := Length( CPCS.gens ); return AbelianPcpGroup( n, ro ); end ); ############################################################################# ## #F PcpPresentationOfTFGroupByFieldElements( F, elms ) ## ## given a field F and elms in F. ## this function computes a polycyclic presentation for the group ## generated by elms ## BindGlobal( "PcpPresentationOfTFGroupByFieldElements", function( F, elms ) local CPCS, pcp; CPCS := CPCSOfTFGroupByFieldElements( F, elms ); pcp := PCPOfTFGroupByFieldElementsByCPCS( F, CPCS ); return pcp; end ); ############################################################################# # generalization to groups with torsion ############################################################################# ## #F GeneratorLattice( rels ) ## ## rels is a sublattice of Z^n. ## this function compute a minimal generatorset of Z^n/rels ## and the orders of the generators. ## BindGlobal( "GeneratorLattice", function( rels ) local n, normal,i,gens, torsion, relord, j; torsion := false; n := Length( rels[1] ); normal:=NormalFormIntMat(rels,13); for i in [1..Length( normal.normal )] do if normal.normal[i][i] <> 1 then torsion := true; break; fi; od; if not torsion then i := i+1; fi; #gens := IdentityMat( n ); #gens := gens{[i..n]}; #gens := gens * normal.coltrans^-1; gens := (normal.coltrans^-1); gens := gens{[i..n]}; # set relative orders of gens relord := []; for j in [i..n] do if IsBound(normal.normal[j]) then Add( relord, normal.normal[j][j] ); else Add( relord, 0 ); fi; od; return rec(exps := gens, relord:=relord ); end ); ############################################################################# ## #F CPCSOfGroupByFieldElements( F, gens ) ## ## computes a constructive polycyclic sequence for gens ## BindGlobal( "CPCSOfGroupByFieldElements", function( F, gens ) local rels, exps, newGens, e, newRels; rels := RelationLattice( F, gens ); if rels = [] then return rec( gens:=gens, relord:=List([1..Length(gens)], x -> 0)); fi; exps := GeneratorLattice(rels); newGens := []; for e in exps.exps do Add( newGens, MappedVector( e, gens )); od; return rec( gens:=newGens, relord:=exps.relord); end ); ############################################################################# ## #F ExpVectorOfGroupByFieldElements( F, CPCS, elm ) ## BindGlobal( "ExpVectorOfGroupByFieldElements", function( F, CPCS, elm ) local elms, rels, l, m, exp, i; if IsList(CPCS.gens[1]) then if Length(elm) <> Length(CPCS.gens[1]) then return fail; fi; fi; m := Length( CPCS.gens ); if elm=elm^0 then return List([1..m], x-> 0); fi; elms := StructuralCopy( CPCS.gens ); l :=Concatenation([elm],elms); rels := RelationLattice( F, l ); if rels=[] then return fail; fi; rels := NormalFormIntMat(rels,0).normal; if not rels[1][1]=1 then return fail; fi; exp := -rels[1]{[2..(m+1)]}; Assert( 2, MappedVector( exp, CPCS.gens ) = elm, "failure in ExpVectorOfGroupByFieldElements" ); return exp; end ); ############################################################################# ## #F PCPOfGroupByFieldElementsByCPCS( F, CPCS ) ## BindGlobal( "PCPOfGroupByFieldElementsByCPCS", function( F, CPCS ) local ro, n; # Setup ro := CPCS.relord; n := Length( CPCS.gens ); return AbelianPcpGroup( n, ro ); end ); ############################################################################# ## #F PcpPresentationOfGroupByFieldElements( F, elms ) ## ## given a field F and elms in F. ## this function computes a polycyclic presentation for the group ## generated by elms ## BindGlobal( "PcpPresentationOfGroupByFieldElements", function( F, elms ) local CPCS, pcp; CPCS := CPCSOfGroupByFieldElements( F, elms ); pcp := PCPOfGroupByFieldElementsByCPCS( F, CPCS ); return pcp; end ); InstallGlobalFunction( PcpPresentationMultGroupByFieldEl, function( F, elms ) local CPCS, pcp; CPCS := CPCSOfGroupByFieldElements( F, elms ); pcp := PCPOfGroupByFieldElementsByCPCS( F, CPCS ); return pcp; end); InstallGlobalFunction( PcpPresentationOfMultiplicativeSubgroup, function( F, elms ) local CPCS, pcp; CPCS := CPCSOfGroupByFieldElements( F, elms ); pcp := PCPOfGroupByFieldElementsByCPCS( F, CPCS ); return pcp; end); ############################################################################# # test functions BindGlobal( "RandomGroupElement", function(gens) local d,k,g,i,length,x,n; k:=Length(gens); g:=gens[1]^0; length:=Random(5,30); for i in [1..length] do x:=Random(1,k); n:=Random(Integers); g:=g*(gens[x]^n); od; return g; end ); BindGlobal( "TestExpVectorOfGroupByFieldElements", function( F, CPCS, gens,numberOfTests) local i,g,exp; SetAssertionLevel(2); for i in [1..numberOfTests] do Print(i); g:=RandomGroupElement(gens); #Print("g ist gleich ",g,"\n"); exp:=ExpVectorOfGroupByFieldElements( F, CPCS, g ); #Print("exp ist gleich ",exp,"\n"); od; SetAssertionLevel(0); end ); BindGlobal( "TestCPCSOfGroupByFieldElements", function( mats ) local F,j, CPCS; F := FieldByMatricesNC( mats ); #j := Random([1..Length(mats)]); j := Length(mats); CPCS:=CPCSOfGroupByFieldElements( F, mats{[1..j]} ); TestExpVectorOfGroupByFieldElements( F, CPCS, mats{[1..j]},10); end ); # faster BindGlobal( "TestCPCSOfGroupByFieldElements2", function( mats ) local F,j, CPCS,b; F := FieldByMatricesNC( mats ); b := Basis( F ); F := FieldByMatrixBasisNC( b ); #j := Random([1..Length(mats)]); j := Length(mats); CPCS:=CPCSOfGroupByFieldElements( F, mats{[1..j]} ); TestExpVectorOfGroupByFieldElements( F, CPCS, mats{[1..j]},10); end ); BindGlobal( "TestCPCSOfGroupByFieldElementsPol", function( pol ) local elms,F,j, CPCS; F := FieldByPolynomialNC( pol ); elms := List( [1..10], x-> Random(F) ); CPCS:=CPCSOfGroupByFieldElements( F, elms ); TestExpVectorOfGroupByFieldElements( F, CPCS, elms,10); end ); alnuth-4.0.0/gap/rationals.gi0000644000000000000000000000133315201210200012777 0ustar00############################################################################# ## #W rationals.gi Alnuth - ALgebraic NUmber THeory Andreas Distler ## ############################################################################# ## #M IntegerPrimitiveElement( Rationals ) ## InstallMethod( IntegerPrimitiveElement, "for the rationals", true, [IsRationals], 0, One ); ############################################################################# ## #M EquationOrderBasis( Rationals ) #M MaximalOrderBasis( Rationals ) ## InstallMethod( EquationOrderBasis, "for the rationals", true, [IsRationals], 15, CanonicalBasis ); InstallMethod( MaximalOrderBasis, "for the rationals", true, [IsRationals], 15, CanonicalBasis ); alnuth-4.0.0/gap/rels.gi0000644000000000000000000001664615201210200011765 0ustar00############################################################################# ## #W rels.gi Alnuth - ALgebraic NUmber THeory Bjoern Assmann ## ############################################################################# ## #F RelationLatticeOfTFUnits( F, elms ) ## ## The input is a list of elements which generate a free abelian subgroup ## of the unit group of F. The function computes the relation lattice of ## . ## InstallGlobalFunction( RelationLatticeOfTFUnits, function( F, elms ) local exps,rels,l; # do a simple check if ForAll( elms, x -> x = x^0 ) then return IdentityMat( Length(elms) ); fi; # now compute an additive description exps := ExponentsOfUnits( F, elms ); Info(InfoAlnuth,2,exps); Info(InfoAlnuth,2,"exps"); # the first entry in the vectors of exps corresponds to torsion - # mod out l := Length( exps[1] ); exps := exps{[1..Length(exps)]}{[2..l]}; # compute the relations rels := NullspaceIntMat( exps ); # format results if Length(rels) = 0 then return rels; fi; return NormalFormIntMat( rels, 2 ).normal; end ); ############################################################################# ## #F NullspaceModRank( M, n) ## BindGlobal( "NullspaceModRank", function( M, n ) local snf, null, nullM, i, gcdex; snf := NormalFormIntMat( M, 1 + 4 ); null := IdentityMat( Length( M ) ); for i in [ 1 .. snf.rank ] do null[i][i] := n / GcdInt( n, snf.normal[i][i] ); od; nullM := null * snf.rowtrans; Assert( 1, ForAll( nullM, function ( v ) return v * M mod n = 0 * M[1]; end ) ); return nullM; end ); ############################################################################# ## #F RelationLatticeOfUnits( F, elms ) ## ## The input is a list of elements which generate a subgroup ## of the unit group of F. The function computes the relation lattice of ## . ## InstallGlobalFunction( RelationLatticeOfUnits, function( F, elms ) local exps,rels,l,record,rank,expsTorsion,rels1,rels2; # do a simple check if ForAll( elms, x -> x = x^0 ) then return IdentityMat( Length(elms) ); fi; # now compute an additive description record := ExponentsOfUnitsWithRank( F, elms ); exps := record.exps; rank := record.rank; # the first entry in the vectors of exps corresponds to # the torsion unit l := Length( exps[1] ); expsTorsion :=exps{[1..Length(exps)]}{[1]}; exps := exps{[1..Length(exps)]}{[2..l]}; # solve the first system mod rank rels1 := NullspaceModRank( expsTorsion, rank ); #if there are fundamental units solve second if l > 1 then rels2 := NullspaceIntMat( exps ); # get rels as the intersection of rels1 and rels2 rels := LatticeIntersection( rels1, rels2 ); else rels := rels1; fi; # format results if Length(rels) = 0 then return rels; fi; return NormalFormIntMat( rels, 2 ).normal; end ); ############################################################################# ## #F ExponentsOfFractionalIdealDescription( F, elms ) ## BindGlobal( "ExponentsOfFractionalIdealDescription", function( F, elms ) local base, flat, coef, exps, gens; # catch a trivial case if IsPrimeField(F) then return List( elms, x -> Norm( F, x ) ); fi; # determine exponents base := EquationOrderBasis( F ); coef := List( elms, x -> Coefficients( base, x ) ); exps := AL_FUNCS.ExponentsOfFractionalIdealDescription( F, coef ); # return exponents return exps; end ); ############################################################################# ## #F RelationLatticeModUnits( F, elms ) ## ## The function determines the relation lattice for modulo the unit ## group of F, i.e. relations rels between elms such that elms^rels is in ## the unitgroup of F. ## InstallGlobalFunction( RelationLatticeModUnits, function( F, elms ) local exps,rels,l; # do a simple check if ForAll( elms, x -> x = x^0 ) then return IdentityMat( Length(elms) ); fi; # now compute an additive description exps := ExponentsOfFractionalIdealDescription( F, elms ); # catch trivial case if Length(exps) = 0 then return IdentityMat(Length(elms)); fi; # compute the relations rels := NullspaceIntMat( exps ); # format results if Length(rels) = 0 then return rels; fi; return NormalFormIntMat( rels, 2 ).normal; end ); ############################################################################# ## #F RelationLatticeTF( F, elms ) ## ## The input is a list of elements which generate a free abelian subgroup ## of F. The function determines the relation lattice for , i.e. ## relations rels between such that elms^rels=1 ## InstallGlobalFunction( RelationLatticeTF, function( F, elms ) local rul,units,i,rl; # calculate the relation unit lattice rul := RelationLatticeModUnits( F, elms ); # calculate corresponding units units := []; for i in [1..Length(rul)] do Add( units, MappedVector( rul[i], elms )); od; # calculate the relations between the units rl := RelationLatticeOfTFUnits( F, units ); # catch trivial case if Length( rl ) = 0 then return []; fi; return NormalFormIntMat( rl * rul, 2).normal; end ); ############################################################################# ## #F RelationLatticePol( F, elms ) #M RelationLattice( F, elms ) ## ## The input is a list of elements in F. ## The function determines the relation lattice for , i.e. ## relations rels between such that elms^rels=1 ## BindGlobal( "RelationLatticePol", function( F, elms ) local rul,units,i,rl,F2,x; if DegreeOverPrimeField(F)=1 then x:=Indeterminate(Rationals); F2:=FieldByPolynomial(x^2-2); else F2:=F; fi; # calculate the relation unit lattice rul := RelationLatticeModUnits( F2, elms ); # calculate corresponding units units := []; for i in [1..Length(rul)] do Add( units, MappedVector( rul[i], elms )); od; # calculate the relations between the units rl := RelationLatticeOfUnits( F2, units ); # catch trivial case if Length( rl ) = 0 then return []; fi; return NormalFormIntMat( rl * rul, 2).normal; end ); BindGlobal( "RelationLatticeMat", function( F, elms ) local rul,units,i,rl,F2,x,c,elms2; if DegreeOverPrimeField(F)=1 then x:=Indeterminate(Rationals); c:=x^2-2; F2:=FieldByPolynomial(c); elms2 := List( elms, x-> x[1][1]*One(F2) ); return RelationLatticePol( F2, elms2 ); else F2:=F; fi; # calculate the relation unit lattice rul := RelationLatticeModUnits( F2, elms ); # calculate corresponding units units := []; for i in [1..Length(rul)] do Add( units, MappedVector( rul[i], elms )); od; # calculate the relations between the units rl := RelationLatticeOfUnits( F2, units ); # catch trivial case if Length( rl ) = 0 then return []; fi; return NormalFormIntMat( rl * rul, 2).normal; end ); InstallMethod( RelationLattice, "for fields by polynomial", true, [IsNumberField and IsAlgebraicExtension, IsCollection], 0, function( F, elms ) return RelationLatticePol( F, elms ); end); InstallMethod( RelationLattice, "for matrix fields", true, [IsNumberFieldByMatrices, IsCollection], 0, function( F, elms ) return RelationLatticeMat( F, elms ); end); alnuth-4.0.0/gap/setup.gd0000644000000000000000000000264615201210200012146 0ustar00############################################################################# ## #W setup.gd Alnuth - ALgebraic NUmber THeory Andreas Distler ## ############################################################################# ## #F SetPariStackSize(size) ## DeclareGlobalFunction("SetPariStackSize"); ############################################################################# ## #F SetAlnuthExternalExecutable(path) ## DeclareGlobalFunction("SetAlnuthExternalExecutable"); ############################################################################# ## #F AL_SuitablePariExecutable(path) ## DeclareGlobalFunction("AL_SuitablePariExecutable"); ############################################################################# ## #F PariVersion(path) ## DeclareGlobalFunction("PariVersion"); ############################################################################# ## #F SetAlnuthExternalExecutablePermanently(path) ## ## Deprecated wrapper around setting the persistent executable preference. ## DeclareGlobalFunction("SetAlnuthExternalExecutablePermanently"); ############################################################################# ## #F RestoreAlnuthExternalExecutablePermanently() ## ## Deprecated wrapper around restoring the default executable preference. ## DeclareGlobalFunction("RestoreAlnuthExternalExecutablePermanently"); ############################################################################# ## #E alnuth-4.0.0/gap/setup.gi0000644000000000000000000001021115201210200012136 0ustar00############################################################################# ## #W setup.gi Alnuth - ALgebraic NUmber THeory Andreas Distler ## BindGlobal("AL_InfoDeprecatedWrapper", function(name, replacement) Info(InfoObsolete, 1, "The function `", name, "` is deprecated. Use ", replacement, " instead."); end); ############################################################################# ## #F SetPariStackSize( size ) ## InstallGlobalFunction( SetPariStackSize, function( size ) if not IsPosInt( size ) then ErrorNoReturn(", the amount of memory in MB, must be a positive integer"); fi; SetUserPreference("alnuth", "PariStackSize", size); end ); ############################################################################# ## #F SetAlnuthExternalExecutable( path ) ## InstallGlobalFunction( SetAlnuthExternalExecutable, function( path ) AL_InfoDeprecatedWrapper( "SetAlnuthExternalExecutable", "SetUserPreference(\"alnuth\", \"PariGpPath\", path)" ); if not AL_SuitablePariExecutable(path) then ErrorNoReturn( " must name a usable PARI/GP executable in version 2.5 or higher" ); fi; SetUserPreference("alnuth", "PariGpPath", path); return UserPreference("alnuth", "PariGpPath"); end ); ############################################################################# ## #F AL_SuitablePariExecutable( path ) ## InstallGlobalFunction( AL_SuitablePariExecutable, function( path ) local resolved, version; if path = "" then return true; fi; resolved := AL_ResolvePariGpPath(path); if resolved = fail then Info(InfoWarning, 1, path, " is not an executable file."); return false; fi; version := ""; Process(DirectoryCurrent(), resolved, InputTextNone(), OutputTextString(version, false), [ "--version-short" ]); version := Chomp(version); if version = "" then Info(InfoWarning, 1, path, " does not seem to be an executable for PARI/GP."); return false; fi; if not CompareVersionNumbers(version, "2.5") then Info( InfoWarning, 1, path, " seems to be an executable for PARI/GP Version ", version, ", but Alnuth needs PARI/GP Version 2.5 or higher." ); return false; fi; return true; end ); ############################################################################# ## #F PariVersion( ) ## InstallGlobalFunction( PariVersion, function( ) local exe, str; exe := AL_CurrentPariGpPath(); if exe <> fail then # use the command line option to obtain version number of PARI/GP str := ""; Process( DirectoryCurrent( ), exe, InputTextNone( ), OutputTextString( str, false ), [ "--version-short" ] ); Print( str ); fi; end ); ############################################################################# ## #F SetAlnuthExternalExecutablePermanently( path ) ## InstallGlobalFunction( SetAlnuthExternalExecutablePermanently, function( path ) AL_InfoDeprecatedWrapper( "SetAlnuthExternalExecutablePermanently", "SetUserPreference(\"alnuth\", \"PariGpPath\", path); WriteGapIniFile()" ); if not AL_SuitablePariExecutable(path) then ErrorNoReturn( " must name a usable PARI/GP executable in version 2.5 or higher" ); fi; SetUserPreference("alnuth", "PariGpPath", path); WriteGapIniFile(); return UserPreference("alnuth", "PariGpPath"); end ); ############################################################################# ## #F RestoreAlnuthExternalExecutablePermanently( ) ## InstallGlobalFunction( RestoreAlnuthExternalExecutablePermanently, function( ) AL_InfoDeprecatedWrapper( "RestoreAlnuthExternalExecutablePermanently", "SetUserPreference(\"alnuth\", \"PariGpPath\", AL_DefaultPariGpPath()); WriteGapIniFile()" ); SetUserPreference("alnuth", "PariGpPath", AL_DefaultPariGpPath()); WriteGapIniFile(); return UserPreference("alnuth", "PariGpPath"); end ); ############################################################################# ## #E alnuth-4.0.0/gap/unithom.gi0000644000000000000000000000131515201210200012466 0ustar00############################################################################# ## #W unithom.gi Alnuth - ALgebraic NUmber THeory Bettina Eick #W Andreas Distler ## ############################################################################# ## #F Images under unit group homs ## InstallMethod( ImagesRepresentative, "for unit groups", FamSourceEqFamElm, [IsGroupGeneralMappingByImages and IsUnitGroupIsomorphism, IsMultiplicativeElementWithInverse], 0, function( nat, h ) local F, H, e; F := FieldOfUnitGroup( Source( nat ) ); H := Range( nat ); e := ExponentsOfUnits( F, [h] )[1]; return MappedVector( e, Pcp(H) ); end); alnuth-4.0.0/gap/userpref.gi0000644000000000000000000001265115201210200012643 0ustar00############################################################################# ## #W userpref.gi Alnuth - ALgebraic NUmber THeory ## BindGlobal("AL_DefaultPariGpPath", function() local f; f := Filename(DirectoriesSystemPrograms(), "gp"); if f = fail then return ""; fi; return f; end); BindGlobal("AL_ResolvePariGpPath", function(path) local resolved; if not IsString(path) or path = "" then return fail; fi; resolved := Filename(DirectoriesSystemPrograms(), path); if resolved <> fail and IsExecutableFile(resolved) then return resolved; fi; if IsExecutableFile(path) then return path; fi; return fail; end); BindGlobal("AL_SuitablePariGpPath", function(path) local resolved, str, version; if path = "" then return true; fi; resolved := AL_ResolvePariGpPath(path); if resolved = fail then return false; fi; str := ""; Process(DirectoryCurrent(), resolved, InputTextNone(), OutputTextString(str, false), [ "--version-short" ]); if str = "" then return false; fi; version := Chomp(str); return CompareVersionNumbers(version, "2.5"); end); BindGlobal("AL_WarnAboutObsoleteGlobals", function() local obsolete, names, name; names := [ "AL_EXECUTABLE", "AL_PATH", "AL_OPTIONS", "AL_STACKSIZE", "PRIM_TEST" ]; obsolete := []; for name in names do if IsBoundGlobal(name) then Add(obsolete, name); fi; od; if Length(obsolete) > 0 then Info(InfoWarning, 1, "Alnuth no longer supports the global variables ", JoinStringsWithSeparator(obsolete, ", "), ". Use SetUserPreference(\"alnuth\", ...) instead; see the manual ", "for the new preference names."); fi; return obsolete; end); BindGlobal("AL_CurrentPariGpPath", function() local path; path := AL_ResolvePariGpPath(UserPreference("alnuth", "PariGpPath")); if path <> fail then return path; fi; if IsBoundGlobal("AL_EXECUTABLE") and AL_SuitablePariGpPath(VALUE_GLOBAL("AL_EXECUTABLE")) then return AL_ResolvePariGpPath(VALUE_GLOBAL("AL_EXECUTABLE")); fi; return fail; end); BindGlobal("AL_CurrentPariGpOptions", function() local options; options := UserPreference("alnuth", "PariGpOptions"); if IsList(options) and ForAll(options, IsString) then return options; fi; if IsBoundGlobal("AL_OPTIONS") and IsList(VALUE_GLOBAL("AL_OPTIONS")) and ForAll(VALUE_GLOBAL("AL_OPTIONS"), IsString) then return VALUE_GLOBAL("AL_OPTIONS"); fi; return [ "-f", "-q" ]; end); BindGlobal("AL_LegacyStackSize", function() local val, digits; if not IsBoundGlobal("AL_STACKSIZE") then return fail; fi; val := VALUE_GLOBAL("AL_STACKSIZE"); if IsPosInt(val) then return val; fi; if IsString(val) and Length(val) >= 4 and val[1] = '-' and val[2] = 's' and val[Length(val)] = 'M' then digits := val{[3 .. Length(val) - 1]}; if ForAll(digits, ch -> ch in "0123456789") then return Int(digits); fi; fi; return fail; end); BindGlobal("AL_CurrentPariStackSize", function() local size; size := UserPreference("alnuth", "PariStackSize"); if IsPosInt(size) then return size; fi; size := AL_LegacyStackSize(); if size <> fail then return size; fi; return 128; end); BindGlobal("AL_CurrentPrimitiveElementTrials", function() local trials; trials := UserPreference("alnuth", "PrimitiveElementTrials"); if IsPosInt(trials) then return trials; fi; if IsBoundGlobal("PRIM_TEST") and IsPosInt(VALUE_GLOBAL("PRIM_TEST")) then return VALUE_GLOBAL("PRIM_TEST"); fi; return 20; end); DeclareUserPreference(rec( package := "alnuth", name := "PariGpPath", description := [ """is the command or path for the PARI/GP executable used by Alnuth. The default searches for a program named gp in DirectoriesSystemPrograms(). Set this preference if PARI/GP is installed elsewhere or should be invoked with a different executable name. An empty string disables the PARI/GP backend until a usable executable is configured. """], default := AL_DefaultPariGpPath, check := x -> IsString(x) and AL_SuitablePariGpPath(x) )); DeclareUserPreference(rec( package := "alnuth", name := "PariGpOptions", description := [ """are the command line options passed to PARI/GP for every Alnuth call. The default disables user startup files and the interactive prompt. In normal use there is no need to change this preference. """], default := ["-f", "-q"], check := x -> IsList(x) and ForAll(x, IsString) )); DeclareUserPreference(rec( package := "alnuth", name := "PariStackSize", description := [ """is the stack size in megabytes requested from PARI/GP. The value is translated into a -s... command line argument when Alnuth starts PARI/GP. It must be a positive integer. """], default := 128, check := IsPosInt )); DeclareUserPreference(rec( package := "alnuth", name := "PrimitiveElementTrials", description := [ """is the number of random trials used when Alnuth searches for a primitive element with a small defining polynomial. Larger values may produce nicer defining polynomials at the cost of more work. """], default := 20, check := IsPosInt )); alnuth-4.0.0/gp/0000755000000000000000000000000015201210200010321 5ustar00alnuth-4.0.0/gp/decompra.gp0000644000000000000000000000077215201210200012451 0ustar00bnf = bnfinit(f,1); n = poldegree(f); un = lift(concat([bnf.tu[2]],bnf.fu)); r = #un; p2v(n,b) = vector(n,j,polcoeff(b,j-1)); \\print units print("[[ "); for(i=1,#un, print(p2v(n,un[i]),",")); print("],\n"); \\print exponents print("[ "); { for(i=1,#elms-1, c = bnfisunit(bnf, Polrev(elms[i])); if (#c==0, error("element must be a unit")); c = vector(r,j,if(j==1,lift(c[r]),c[j-1])); print(c,","); ); } print("],\n"); \\ get the rank of the group rank=bnf.tu[1]; print(rank,"];"); alnuth-4.0.0/gp/fracidea.gp0000644000000000000000000000117615201210200012414 0ustar00\\ calculates the exponentsvectors of the fractional ideals \\ generated by elms corresponding to the prime ideals \\ arrissing in the factorization nf = nfinit(f); \\ factorize all ideals generated by the elements of a and collect all \\ primideals which occur primId=eval(Set(concat(vector(#elms-1,i,idealfactor(nf,Polrev(elms[i]))[,1])))); \\ write for every element in a the exponentfactor corresponding to the \\ ideals in primId in a row \\ so we will have a matrix mat = matrix(#elms-1,#primId,i,j,idealval(nf,Polrev(elms[i]),primId[j])); print("[ "); { for(i=1,matsize(mat)[1], print(mat[i,],","); ); print("];"); } alnuth-4.0.0/gp/maxord.gp0000644000000000000000000000025615201210200012146 0ustar00\\ compute basis of maximal order b = nfbasis( f ); p2v(n,b)=vector(n,j,polcoeff(b,j-1)); \\ print result print("[ "); for(i=1,#b, print(p2v(#b,b[i]),",")); print("];"); alnuth-4.0.0/gp/norm.gp0000644000000000000000000000051015201210200011620 0ustar00bnf = bnfinit(f,1); n = poldegree(f); un = lift(concat([bnf.tu[2]],bnf.fu)); nr = bnfisintnorm( bnf, nrm); p2v(n,b) = vector(n,j,polcoeff(b,j-1)); \\ print units print("[[ "); for(i=1,#un, print(p2v(n,un[i]),",")); print("],\n"); \\ print norm elements print(" [ "); for (i=1, #nr, print(p2v(n,nr[i]),",\n")); print("]];"); alnuth-4.0.0/gp/polyfactors.gp0000644000000000000000000000070315201210200013216 0ustar00\\ compute factors of poly defined by coeffs over Q_f f = subst(f,variable(f),'varA); pol = Pol(vector(#coeffs-1,i,Polrev(coeffs[i],'varA))); n = poldegree(f); gettime(); fac = lift(nffactor(f, pol )); zeit = gettime(); p2v(n,b)=vector(n,j,polcoeff(b,j-1)); f2v(n,v)=vector(#v,i,p2v(n,v[i])); \\ print result print("[ "); { for(i=1,#fac[,1], for(j=1,fac[i,2], print(f2v(n, Vec(fac[i,1]) ),","); ) ); } print1(zeit); print("];"); alnuth-4.0.0/gp/units.gp0000644000000000000000000000031115201210200012006 0ustar00bnf = bnfinit(f,1); n = poldegree(f); un = lift(concat([bnf.tu[2]],bnf.fu)); p2v(n,b) = vector(n,j,polcoeff(b,j-1)); \\ print units print("[ "); for(i=1,#un, print(p2v(n,un[i]),",")); print("];\n"); alnuth-4.0.0/init.g0000644000000000000000000000071315201210200011027 0ustar00############################################################################# ## #W init.g Alnuth - ALgebraic NUmber THeory Bettina Eick #W Andreas Distler ## ############################################################################# ## #R read .gd files ## ReadPackage("alnuth", "gap/setup.gd"); ReadPackage("alnuth", "gap/factors.gd"); ReadPackage("alnuth", "gap/field.gd"); alnuth-4.0.0/makedoc.g0000644000000000000000000000104715201210200011470 0ustar00## this creates the documentation, needs: GAPDoc and AutoDoc packages, pdflatex ## ## Call this with GAP from within the package directory. ## if fail = LoadPackage("AutoDoc", ">= 2022.07.10") then Error("AutoDoc 2022.07.10 or newer is required"); fi; AutoDoc(rec( autodoc := true, extract_examples := true, scaffold := rec( TitlePage := false, includes := [ "intro.xml", "fields.xml", "example.xml", "install.xml", ], bib := "manual.bib", ), )); alnuth-4.0.0/read.g0000644000000000000000000000200015201210200010766 0ustar00############################################################################# ## #W read.g Alnuth - ALgebraic NUmber THeory Bettina Eick ## Andreas Distler ## ############################################################################# ## #R read files ## ReadPackage("alnuth", "gap/userpref.gi"); AL_WarnAboutObsoleteGlobals(); ReadPackage("alnuth", "gap/setup.gi"); ReadPackage("alnuth", "gap/pari.gi"); ReadPackage("alnuth", "gap/factors.gi"); ReadPackage("alnuth", "gap/matfield.gi"); ReadPackage("alnuth", "gap/polfield.gi"); ReadPackage("alnuth", "gap/field.gi"); ReadPackage("alnuth", "gap/unithom.gi"); ReadPackage("alnuth", "gap/matunits.gi"); ReadPackage("alnuth", "gap/rels.gi"); ReadPackage("alnuth", "gap/present.gi"); ReadPackage("alnuth", "gap/isom.gi"); ReadPackage("alnuth", "gap/rationals.gi"); ReadPackage("alnuth", "exam/unimod.gi"); ReadPackage("alnuth", "exam/rationals.gi"); ReadPackage("alnuth", "exam/fields.gi"); alnuth-4.0.0/tst/0000755000000000000000000000000015201210200010525 5ustar00alnuth-4.0.0/tst/ALNUTH.tst0000644000000000000000000000661715201210200012266 0ustar00gap> START_TEST("Installation test of Alnuth package"); gap> mats := ExamUnimod( 1 );; gap> F := FieldByMatrices( mats ); gap> DegreeOverPrimeField( F ); 4 gap> IsFinite( F ); false gap> EquationOrderBasis( F ); Basis( , [ [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ], [ [ 11, 11, 22, -22 ], [ 33, -33, -66, 132 ], [ 22, -22, -22, 55 ], [ 20, -24, -38, 80 ] ], [ [ 528, -198, -132, 660 ], [ 462, -264, -660, 1848 ], [ 132, 132, 330, -198 ], [ 192, -72, -180, 702 ] ], [ [ 9570, -594, 2508, 7788 ], [ 18810, -16038, -28116, 66528 ], [ 9108, -5412, -5544, 16830 ], [ 9816, -8400, -13740, 32532 ] ] ] ) # testing maxord.gp gap> IsIntegerOfNumberField( F, mats[1] ); true gap> MaximalOrderBasis( F );; # testing units.gp gap> UnitGroup( F ); gap> IsCyclotomicField( F ); false # testing fracidea.gp and decompra.gp gap> IsomorphismPcpGroup( F, mats{[2..5]} ); [ [ [ 57641556673, -51250063536, -73214376480, 161071628256 ], [ 21964312944, 28355806081, 43928625888, 0 ], [ -14642875296, 43928625888, 64962994321, -80535814128 ], [ 0, 29285750592, 43928625888, -37537132751 ] ], [ [ 13, 0, -21, 0 ], [ -42, 97, 105, -231 ], [ -21, 0, 34, 0 ], [ -21, 21, 42, -50 ] ], [ [ 6113341760402965, -3032143586011050, -4159967272068153, 14002438585824810 ], [ 10588511869480164, -5251666322974043, -7205040811308855, 24252552936374367 ], [ 3778184141734557, -1873864241780610, -2570850209123252, 8653736311352880 ], [ 5051133104082267, -2505235179386847, -3437063756709534, 11569395035183716 ] ] ] -> [ g1, g2, g3 ] gap> RelationLatticeOfUnits( F, mats ); [ [ 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 2, -2 ], [ 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2 ], [ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 1, -4 ], [ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2 ], [ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2 ], [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2 ], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0 ], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, -3 ] ] # testing polyfactors.gp gap> pol := UnivariatePolynomial( Rationals, [0,0,8,0,8,2,0,2] ); 2*x^7+2*x^5+8*x^4+8*x^2 gap> f := UnivariatePolynomial( Rationals, [-4,0,0,1] ); x^3-4 gap> L := FieldByPolynomial( f ); gap> FactorsPolynomialAlgExt( L, pol ); [ !2*x_1, x_1, x_1+a, x_1^2+!1, x_1^2+(-a)*x_1+a^2 ] gap> pol := UnivariatePolynomial( Rationals, [ 1, 3, 2, -1, 2, 3, 1 ] ); x^6+3*x^5+2*x^4-x^3+2*x^2+3*x+1 gap> f := UnivariatePolynomial( Rationals,[ 11/64, 59/16, -7/4, 1 ] ); x^3-7/4*x^2+59/16*x+11/64 gap> L := FieldByPolynomial( f ); gap> FactorsPolynomialAlgExt( L, pol ); [ x_1^2+x_1+(-a+1/4), x_1^2+(-a^2+3/2*a-21/16)*x_1+!1, x_1^2+(a^2-3/2*a+53/16)*x_1+(a^2-3/2*a+53/16) ] # testing norm.gp and fracidea.gp gap> pol := UnivariatePolynomial( Rationals, [ 1, 0, -1, 1 ] ); x^3-x^2+1 gap> L := FieldByPolynomial( pol ); gap> cosets := NormCosetsOfNumberField( L, 5 );; gap> [Norm(cosets[1]), Length(cosets)]; [ 5, 1 ] gap> ExponentsOfFractionalIdealDescription( L, cosets ); [ [ 1 ] ] gap> STOP_TEST( "ALNUTH.tst", 100000); alnuth-4.0.0/tst/alnuth01.tst0000644000000000000000000000157615201210200012726 0ustar00# Alnuth, chapter 2 # # DO NOT EDIT THIS FILE - EDIT EXAMPLES IN THE SOURCE INSTEAD! # # This file has been generated by AutoDoc. It contains examples extracted from # the package documentation. Each example is preceded by a comment which gives # the name of a GAPDoc XML file and a line range from which the example were # taken. Note that the XML file in turn may have been generated by AutoDoc # from some other input. # gap> START_TEST("alnuth01.tst"); # doc/fields.xml:251-262 gap> x := Indeterminate( Rationals, "x" );; gap> pol := 2*x^7+2*x^5+8*x^4+8*x^2; 2*x^7+2*x^5+8*x^4+8*x^2 gap> L := FieldByPolynomial( x^3-4 ); gap> y := Indeterminate( L, "y" );; gap> FactorsPolynomialAlgExt( L, pol ); [ !2*y, y, y+a, y^2+!1, y^2+(-a)*y+a^2 ] gap> FactorsPolynomialAlnuth( last[5] ); [ y^2+(-a)*y+a^2 ] # gap> STOP_TEST("alnuth01.tst", 1); alnuth-4.0.0/tst/alnuth02.tst0000644000000000000000000000574715201210200012733 0ustar00# Alnuth, chapter 3 # # DO NOT EDIT THIS FILE - EDIT EXAMPLES IN THE SOURCE INSTEAD! # # This file has been generated by AutoDoc. It contains examples extracted from # the package documentation. Each example is preceded by a comment which gives # the name of a GAPDoc XML file and a line range from which the example were # taken. Note that the XML file in turn may have been generated by AutoDoc # from some other input. # gap> START_TEST("alnuth02.tst"); # doc/example.xml:13-70 gap> m1 := [ [ 1, 0, 0, -7 ], > [ 7, 1, 0, -7 ], > [ 0, 7, 1, -7 ], > [ 0, 0, 7, -6 ] ];; # gap> m2 := [ [ 0, 0, -13, 14 ], > [ -1, 0, -13, 1 ], > [ 13, -1, -13, 1 ], > [ 0, 13, -14, 1 ] ];; # gap> F := FieldByMatricesNC( [m1, m2] ); # gap> DegreeOverPrimeField(F); 4 gap> PrimitiveElement(F); [ [ 0, -1, 1, 0 ], [ 0, -1, 0, 1 ], [ 0, -1, 0, 0 ], [ 1, -1, 0, 0 ] ] # gap> Basis(F); Basis( , [ [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ], [ [ 0, 1, 0, 0 ], [ -1, 1, 1, 0 ], [ -1, 0, 1, 1 ], [ -1, 0, 0, 1 ] ], [ [ 0, 0, 1, 0 ], [ -1, 0, 1, 1 ], [ -1, -1, 1, 1 ], [ 0, -1, 0, 1 ] ], [ [ 0, 0, 0, 1 ], [ -1, 0, 0, 1 ], [ 0, -1, 0, 1 ], [ 0, 0, -1, 1 ] ] ] ) # gap> MaximalOrderBasis(F); Basis( , [ [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ], [ [ 0, -1, 1, 0 ], [ 0, -1, 0, 1 ], [ 0, -1, 0, 0 ], [ 1, -1, 0, 0 ] ], [ [ 0, 0, 0, -1 ], [ 1, 0, 0, -1 ], [ 0, 1, 0, -1 ], [ 0, 0, 1, -1 ] ], [ [ -1, 1, 0, 0 ], [ -1, 0, 1, 0 ], [ -1, 0, 0, 1 ], [ -1, 0, 0, 0 ] ] ] ) # gap> U := UnitGroup(F); # gap> u := GeneratorsOfGroup( U );; # gap> nat := IsomorphismPcpGroup(U);; gap> H := Image(nat); Pcp-group with orders [ 10, 0 ] gap> ImageElm( nat, u[1] ); g1 gap> ImageElm( nat, u[2] ); g2 gap> ImageElm( nat, u[1]*u[2] ); g1*g2 gap> u[1] = PreImagesRepresentative(nat, GeneratorsOfGroup(H)[1] ); true # doc/example.xml:78-114 gap> g := UnivariatePolynomial( Rationals, [ 16, 64, -28, -4, 1 ] ); x^4-4*x^3-28*x^2+64*x+16 # gap> F := FieldByPolynomialNC(g); gap> PrimitiveElement(F); a gap> MaximalOrderBasis(F); Basis( , [ !1, 1/2*a, 1/4*a^2, 1/56*a^3+1/14*a^2+1/14*a-2/7 ] ) # gap> U := UnitGroup(F); # gap> natU := IsomorphismPcpGroup(U);; gap> elms := List( [1..10], x-> Random(F) );; # gap> PcpPresentationOfMultiplicativeSubgroup( F, elms ); Pcp-group with orders [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] # gap> isom := IsomorphismPcpGroup( F, elms );; gap> y := RandomGroupElement( elms );; gap> z := ImageElm( isom, y );; gap> y = PreImagesRepresentative( isom, z ); true # gap> FactorsPolynomialAlgExt( F, g ); [ x_1+(-a), x_1+(a-2), x_1+(-1/7*a^3+3/7*a^2+31/7*a-40/7), x_1+(1/7*a^3-3/7*a^2-31/7*a+26/7) ] # gap> STOP_TEST("alnuth02.tst", 1); alnuth-4.0.0/tst/examples.tst0000644000000000000000000002450115201210200013101 0ustar00gap> START_TEST("Testing examples from Alnuth"); # example 1 gap> F := ExampleMatField(1); gap> DegreeOverPrimeField(F); 4 gap> DefiningPolynomial(F); x^4+4*x^3-394*x^2-796*x+2101 gap> basis := Basis(F, > [ [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ], > [ [ -1, 1, 1, 0 ], [ 5, -5, -5, 11 ], [ 3, -4, -7, 11 ], [ 3, -3, -4, 7 ] ], > [ [ 9, -10, -13, 22 ], [ -12, 17, 21, -33 ], [ -11, 18, 28, -44 ], > [ -9, 13, 18, -28 ] ], > [ [ -3, 5, 7, -11 ], [ 7, -9, -13, 22 ], [ 6, -9, -13, 22 ], > [ 5, -7, -10, 17 ] ] ]);; gap> ForAll(BasisVectors(basis), mat-> IsIntegerOfNumberField(F, mat)); true gap> ForAll(BasisVectors(MaximalOrderBasis(F)), > mat-> ForAll( Coefficients( basis, mat ), IsInt)); true gap> ug := UnitGroup(F); gap> RelationLatticeOfUnits(F,GeneratorsOfGroup(ug)); [ [ 2, 0, 0, 0 ] ] # example 2 gap> F := ExampleMatField(2); gap> DegreeOverPrimeField(F); 4 gap> DefiningPolynomial(F); x^4-18*x^3-286*x^2+2178*x+14641 gap> basis := Basis(F, > [ [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ], > [ [ -1, 1, 1, 0 ], [ -4, -9, -5, 11 ], [ -6, -8, -7, 11 ], > [ -5, -8, -5, 11 ] ], > [ [ -9, -18, -13, 22 ], [ 15, 29, 21, -33 ], [ 25, 34, 28, -44 ], > [ 12, 19, 15, -22 ] ], > [ [ 6, 9, 7, -11 ], [ -11, -17, -13, 22 ], [ -12, -17, -13, 22 ], > [ -8, -12, -9, 16 ] ] ] );; gap> ForAll(BasisVectors(basis), mat-> IsIntegerOfNumberField(F, mat)); true gap> ForAll(BasisVectors(MaximalOrderBasis(F)), > mat-> ForAll( Coefficients( basis, mat ), IsInt)); true gap> ug := UnitGroup(F); gap> Size(ug); infinity # example 3 gap> F := ExampleMatField(3); gap> DegreeOverPrimeField(F); 4 gap> DefiningPolynomial(F); x^4+4*x^3-90*x^2-188*x+1669 gap> basis := Basis( F, > [ [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ], > [ [ -4, 6, 7, 0 ], [ -31, -60, -35, 77 ], [ -35, -48, -41, 66 ], > [ -34, -53, -33, 75 ] ], > [ [ -11, -15, -10, 22 ], [ 3, 3, 6, 0 ], [ 7, 10, 8, -11 ], > [ -3, -5, 0, 12 ] ], > [ [ 4, 10, 8, -11 ], [ -15, -27, -18, 33 ], [ -18, -25, -21, 33 ], > [ -13, -20, -14, 26 ] ] ] );; gap> ForAll(BasisVectors(basis), mat-> IsIntegerOfNumberField(F, mat)); true gap> ForAll(BasisVectors(MaximalOrderBasis(F)), > mat-> ForAll( Coefficients( basis, mat ), IsInt)); true gap> ug := UnitGroup(F); gap> Size(ug); infinity # example 4 gap> F := ExampleMatField(4); gap> DegreeOverPrimeField(F); 4 gap> DefiningPolynomial(F); x^4-8*x^3-550*x^2-1936*x-1331 gap> basis := Basis( F, > [ [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ], > [ [ 0, -1, 1, 0 ], [ -1, -4, -5, 11 ], [ -1, 4, 4, -11 ], [ -1, 1, 0, -2 ] ] > , > [ [ 0, 8, 9, -22 ], [ -2, 8, -1, -11 ], [ 3, -10, -5, 22 ], > [ 1, -5, -6, 15 ] ], > [ [ 1, -5, -3, 11 ], [ 1, -9, -7, 22 ], [ -2, 9, 7, -22 ], [ -1, 3, 2, -7 ] > ] ] );; gap> ForAll(BasisVectors(basis), mat-> IsIntegerOfNumberField(F, mat)); true gap> ForAll(BasisVectors(MaximalOrderBasis(F)), > mat-> ForAll( Coefficients( basis, mat ), IsInt)); true gap> ug := UnitGroup(F); gap> Size(ug); infinity # example 5 gap> F := ExampleMatField(5); gap> DegreeOverPrimeField(F); 4 gap> DefiningPolynomial(F); x^4+4*x^3-40*x^2-88*x+244 gap> basis := Basis( F, > [ [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ], > [ [ 148, 95, 101, -165 ], [ -257, -165, -175, 286 ], [ 96, 65, 67, -110 ], > [ -64, -40, -43, 70 ] ], > [ [ 3549, 2310, 2437, -3982 ], [ -6147, -4001, -4221, 6897 ], > [ 2195, 1430, 1508, -2464 ], [ -1560, -1015, -1071, 1750 ] ], > [ [ 2999, 1953, 2060, -3366 ], [ -5195, -3383, -3568, 5830 ], > [ 1853, 1206, 1272, -2079 ], [ -1319, -859, -906, 1480 ] ] ] );; gap> ForAll(BasisVectors(basis), mat-> IsIntegerOfNumberField(F, mat)); true gap> ForAll(BasisVectors(MaximalOrderBasis(F)), > mat-> ForAll( Coefficients( basis, mat ), IsInt)); true gap> ug := UnitGroup(F); gap> Size(ug); infinity # example 6 gap> F := ExampleMatField(6); gap> DegreeOverPrimeField(F); 4 gap> DefiningPolynomial(F); x^4-34*x^2+49 gap> basis := Basis( F, > [ [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ], > [ [ -6, -2, -3, 0 ], [ 15, 18, 15, -33 ], [ 11, 16, 7, -22 ], > [ 14, 21, 13, -37 ] ], > [ [ -2, -11, -4, 22 ], [ -27, -36, -24, 66 ], [ -15, -22, -9, 33 ], > [ -31, -47, -26, 83 ] ], > [ [ 29, 55, 26, -99 ], [ 82, 118, 68, -209 ], [ 37, 55, 25, -88 ], > [ 102, 155, 82, -270 ] ] ] );; gap> ForAll(BasisVectors(basis), mat-> IsIntegerOfNumberField(F, mat)); true gap> ForAll(BasisVectors(MaximalOrderBasis(F)), > mat-> ForAll( Coefficients( basis, mat ), IsInt)); true gap> ug := UnitGroup(F); gap> Size(ug); infinity # example 7 gap> F := ExampleMatField(7); gap> DegreeOverPrimeField(F); 4 gap> DefiningPolynomial(F); x^4-9118*x^3+39843*x^2-9118*x+1 gap> basis := Basis( F, > [ [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ], > [ [ -16591/25, -4204252/75, -1139984/125, 933941/25 ], > [ 127557/100, 2685042/25, 2183967/125, -3578691/50 ], > [ 160, 39760/3, 2155, -35325/4 ], > [ 47976/25, 4036224/25, 3282924/125, -2689776/25 ] ], > [ [ -172958/5, -227281196/75, -61682584/125, 50500116/25 ], > [ 1325391/20, 145139966/25, 118170042/125, -193493841/50 ], > [ 32695/4, 2148280/3, 116606, -1909325/4 ], > [ 498078/5, 218173052/25, 177632124/125, -145429076/25 ] ], > [ [ -1572318/25, -137719084/25, -22425524/25, 91800234/25 ], > [ 3012234/25, 263839042/25, 42962292/25, -703475043/100 ], > [ 29725/2, 1301735, 211968, -867705 ], > [ 4527973/25, 1189801372/75, 64580524/25, -264364324/25 ] ] ] );; gap> ForAll(BasisVectors(basis), mat-> IsIntegerOfNumberField(F, mat)); true gap> ForAll(BasisVectors(MaximalOrderBasis(F)), > mat-> ForAll( Coefficients( basis, mat ), IsInt)); true gap> ug := UnitGroup(F); gap> Size(ug); infinity # example 8 gap> F := ExampleMatField(8); gap> DegreeOverPrimeField(F); 4 gap> DefiningPolynomial(F); x^4-2693461698*x^3+915480803*x^2-183198*x+1 gap> basis := Basis( F, > [ [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ], > [ [ 350938712911/294, 1500326345/2, 22032258785/49, 12381906785/28 ], > [ -321440829383/245, -824530541, -48432850131/98, -6804693081/14 ], > [ -1895565335102/441, -8103883972/3, -238010709389/147, -33439903349/21 > ], [ 423681072037/105, 2535838285, 10639636697/7, 2989684151/2 ] ], > [ [ 4296545420323143572/147, 1800113708794452685/98, 539482234887109565/49, > 1061142474502207065/98 ], > [ -23612415601847672819/735, -989283921486886210/49, > -592963764782450491/49, -1166338752161250809/98 ], > [ -232074212936617048906/2205, -9723159685193494472/147, > -5827933970510514158/147, -1910556664266896923/49 ], > [ 3458087129618678238/35, 434648032727934931/7, 260522311384860087/7, > 256219085901701948/7 ] ], > [ [ -359040394192145849/98, -225639486739431445/98, > -270490678428289125/196, -266022798598028295/196 ], > [ 2959753770581068096/735, 124004119958269647/49, 74326437761644025/49, > 73098737073176767/49 ], > [ 3232209784961308454/245, 1218772319845216676/147, > 243505363658010411/49, 239483218757603493/49 ], > [ -433462064765870443/35, -54481979964874243/7, -65311563750512469/14, > -64232767911560593/14 ] ] ] );; gap> ForAll(BasisVectors(basis), mat-> IsIntegerOfNumberField(F, mat)); true gap> ForAll(BasisVectors(MaximalOrderBasis(F)), > mat-> ForAll( Coefficients( basis, mat ), IsInt)); true gap> ug := UnitGroup(F); gap> Size(ug); infinity # example 9 gap> F := ExampleMatField(9); gap> DegreeOverPrimeField(F); 4 gap> DefiningPolynomial(F); x^4-50691194176*x^3+13505436470112846*x^2-5255736770373376*x+1 gap> basis := Basis( F, > [ [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ], > [ > [ 851504247972/229, -1937936674346/229, -603837909603/229, > 1577056081004/229 ], > [ 589771389309/458, -671133447401/229, -209117560764/229, > 546155850465/229 ], > [ -314679082561/229, 2148551139301/687, 223154956025/229, > -582817030683/229 ], > [ 260652277735/458, -889841242682/687, -92421808448/229, > 241378880370/229 ] ], > [ > [ 479595170949875358661/229, -3274539508376250773645/687, > -340102839979551252617/229, 888252880017494540431/229 ], > [ 166089147656173639110/229, -378003163829060810519/229, > -235562800592787808287/458, 307611862433136447321/229 ], > [ -177237322072221156244/229, 1210126057694719416842/687, > 125687079941754647751/229, -328259272238145784528/229 ], > [ 73403753002708619935/229, -167059987151745488349/229, > -104107907570323308205/458, 135950274239559405325/229 ] ], > [ > [ -168577244280151879851/229, 1150997507992512356939/687, > 119545823245159623469/229, -312220038497649730859/229 ], > [ -116760353367458396067/458, 265735501720229196779/458, > 41400049650414034161/229, -216250551372975665307/458 ], > [ 62298749337598187302/229, -425358152864100770527/687, > -44178888490966125184/229, 115382820501957885815/229 ], > [ -51602698069330099209/458, 352328555032045040059/1374, > 18296915011903387616/229, -95572782957948415617/458 ] ] ] );; gap> ForAll(BasisVectors(basis), mat-> IsIntegerOfNumberField(F, mat)); true gap> ForAll(BasisVectors(MaximalOrderBasis(F)), > mat-> ForAll( Coefficients( basis, mat ), IsInt)); true gap> ug := UnitGroup(F); gap> Size(ug); infinity # no more examples gap> F := ExampleMatField(10); fail gap> STOP_TEST( "examples.tst", 10000000); alnuth-4.0.0/tst/polynome.tst0000644000000000000000000000366115201210200013131 0ustar00# this needs RadiRoot to be loaded gap> START_TEST("Factorisation of polynomials using Alnuth"); # some splitting fields gap> pol := UnivariatePolynomial( Rationals, [ -1, 0, 0, 0, 1, 0, 1 ] );; gap> SplittingField( pol ); gap> pol := UnivariatePolynomial( Rationals, [ 4, -1, 0, 6, -1, -2, 2, 1 ] );; gap> SplittingField( pol ); gap> pol := UnivariatePolynomial( Rationals, [ 4, 0, 4, 0, -3, 0, -1, 0, 1 ] );; gap> SplittingField( pol ); gap> pol := UnivariatePolynomial(Rationals, > [ -3, 1, -1, 2, 1, 3, -2, -1, 0, 1 ]);; gap> SplittingField( pol ); gap> pol := UnivariatePolynomial(Rationals, > [ 47, 0, 103, 0, 41, 0, 7, 0, -2, 0, 1 ]);; gap> SplittingField( pol ); # example from email to Bill Allombert (10/05/11) gap> pol := UnivariatePolynomial( Rationals, [ 1, 2, 2, 2, 2, 1, 1 ] ); x^6+x^5+2*x^4+2*x^3+2*x^2+2*x+1 gap> f := UnivariatePolynomial( Rationals, [ 1, 1, 1 ] ); x^2+x+1 gap> K := SplittingField( pol ); gap> FactorsPolynomialAlgExt( K, f ); [ x_1^2+x_1+!1 ] # example from Bill Allombert (10/05/11) gap> pol := UnivariatePolynomial( Rationals, [ 20736, 0, 4147200, 0, 60632064, > 0, 347286528, 0, 1078555392, 0, 2069549568, 0, 2613917952, 0, 2241209088, 0, > 1318874976, 0, 530669952, 0, 143684928, 0, 25510464, 0, 2872752, 0, 195936, 0, > 7536, 0, 144, 0, 1 ] );; gap> L := FieldByPolynomial( pol ); gap> facs := FactorsPolynomialAlgExt( L, pol );; gap> Collected(List(facs, Degree)); [ [ 1, 32 ] ] gap> Product(facs) = AlgExtEmbeddedPol(L, pol); true # gap> STOP_TEST( "polynome.tst", 10000000); alnuth-4.0.0/tst/testall.g0000644000000000000000000000044415201210200012347 0ustar00LoadPackage("alnuth"); LoadPackage("radiroot"); # ensure name of indeterminate matches the manual x := Indeterminate(Rationals, "x"); dirs := DirectoriesPackageLibrary( "alnuth", "tst" ); TestDirectory(dirs, rec(exitGAP := true, testOptions:=rec(compareFunction := "uptowhitespace"))); alnuth-4.0.0/tst/testinstall.g0000644000000000000000000000046415201210200013247 0ustar00LoadPackage("alnuth"); # ensure name of indeterminate matches the manual x := Indeterminate(Rationals, "x"); dirs := DirectoriesPackageLibrary( "alnuth", "tst" ); tests := [ "ALNUTH.tst", "userprefs.tst", ]; tests := List(tests, f -> Filename(dirs,f)); TestDirectory(tests, rec(exitGAP := false)); alnuth-4.0.0/tst/userprefs.tst0000644000000000000000000000472515201210200013307 0ustar00gap> START_TEST("userprefs.tst"); gap> pari_path:=UserPreference("alnuth", "PariGpPath");; gap> IsString(pari_path); true gap> UserPreference("alnuth", "PariGpOptions"); [ "-f", "-q" ] gap> UserPreference("alnuth", "PariStackSize"); 128 gap> UserPreference("alnuth", "PrimitiveElementTrials"); 20 gap> tmpdir := DirectoryTemporary();; gap> oldroot := GAPInfo.UserGapRoot;; gap> oldobsolete := InfoLevel(InfoObsolete);; gap> oldinfo := InfoLevel(InfoWarning);; gap> GAPInfo.UserGapRoot := tmpdir![1];; gap> SetInfoLevel(InfoObsolete, 1);; gap> SetInfoLevel(InfoWarning, 0);; gap> path := SetAlnuthExternalExecutable("gp");; #I The function `SetAlnuthExternalExecutable` is deprecated. Use SetUserPreference("alnuth", "PariGpPath", path) instead. gap> IsString(path); true gap> path := SetAlnuthExternalExecutablePermanently("gp");; #I The function `SetAlnuthExternalExecutablePermanently` is deprecated. Use SetUserPreference("alnuth", "PariGpPath", path); WriteGapIniFile() instead. gap> IsString(path); true gap> IsExistingFile(Filename(tmpdir, "gap.ini")); true gap> oldparipath := UserPreference("alnuth", "PariGpPath");; gap> oldpariopts := UserPreference("alnuth", "PariGpOptions");; gap> oldparistack := UserPreference("alnuth", "PariStackSize");; gap> oldprimtrials := UserPreference("alnuth", "PrimitiveElementTrials");; gap> SetUserPreference("alnuth", "PariGpPath", "");; gap> AL_EXECUTABLE := "gp";; gap> IsString(AL_CurrentPariGpPath()); true gap> SetUserPreference("alnuth", "PariGpOptions", 1);; gap> AL_OPTIONS := [ "-f" ];; gap> AL_CurrentPariGpOptions(); [ "-f" ] gap> SetUserPreference("alnuth", "PariStackSize", 0);; gap> AL_STACKSIZE := "-s256M";; gap> AL_CurrentPariStackSize(); 256 gap> SetUserPreference("alnuth", "PrimitiveElementTrials", 0);; gap> PRIM_TEST := 7;; gap> AL_CurrentPrimitiveElementTrials(); 7 gap> AL_OPTIONS := [ "-f" ];; gap> AL_STACKSIZE := "-s128M";; gap> AL_WarnAboutObsoleteGlobals(); [ "AL_EXECUTABLE", "AL_OPTIONS", "AL_STACKSIZE", "PRIM_TEST" ] gap> SetUserPreference("alnuth", "PariGpPath", oldparipath);; gap> SetUserPreference("alnuth", "PariGpOptions", oldpariopts);; gap> SetUserPreference("alnuth", "PariStackSize", oldparistack);; gap> SetUserPreference("alnuth", "PrimitiveElementTrials", oldprimtrials);; gap> SetInfoLevel(InfoObsolete, oldobsolete);; gap> SetInfoLevel(InfoWarning, oldinfo);; gap> GAPInfo.UserGapRoot := oldroot;; gap> Unbind(AL_EXECUTABLE); Unbind(AL_OPTIONS); Unbind(AL_STACKSIZE); Unbind(PRIM_TEST); gap> STOP_TEST("userprefs.tst", 1);