radiroot-2.9/0000755000175000017500000000000014207520027011634 5ustar billbillradiroot-2.9/README0000644000175000017500000000167114207520017012520 0ustar billbill The GAP 4 package 'RadiRoot' ============================ Abilities: --------- The package can compute and display an expression by radicals for the roots of a solvable, rational polynomial. Related to this it is possible to create the Galois group and the splitting field of a rational polynomial. Requirements: ------------ The package is written for GAP version 4.7 or higher. It requires the package 'Alnuth' in version 3.0 or higher. License: -------- The 'RadiRoot' package is free software and can be redistributed and/or modified under the terms of the GNU General Public License version 2 or (at your option) any later version. For details see the file LICENSE or https://www.gnu.org/copyleft/gpl.html. Installation: ------------ The installation follows standard GAP rules. So the normal way to install is to unpack the archive in the `pkg' directory, which will create a subdirectory `radiroot'. radiroot-2.9/htm/0000755000175000017500000000000014211721314012421 5ustar billbillradiroot-2.9/htm/indxL.htm0000644000175000017500000000136114207520027014215 0ustar billbillRadiroot : a GAP 4 package - Index L

Radiroot : a GAP 4 package - Index L

_ A F G I L M R S T

License 1.1
Loading and Testing the Package 4.2

[Up]

Radiroot manual
March 2022
radiroot-2.9/htm/CHAP003.htm0000644000175000017500000000355614207520027014105 0ustar billbill[Radiroot] 3 The Info Class of the Package [Up] [Previous] [Next] [Index]

3 The Info Class of the Package

The info mechanism in GAP allows functions to print information during the computation (see Section Info Functions in the GAP reference manual for general information).

  • InfoRadiroot V

    is the info class of this package.

  • SetInfoLevel( InfoRadiroot, level )

    sets the info level for InfoRadiroot to level, where level has to be an integer in the range 0-4.

    The default value for InfoRadiroot is 1. Information why a function returns fail will be given with this setting.

    gap> InfoLevel(InfoRadiroot);
    1
    gap> RootsOfPolynomialAsRadicals(x^5-4*x+2);
    #I  Polynomial is not solvable.
    fail
    

    Setting the info level to a higher value will cause messages to show up during single steps of the computation. On level 2 one gets a rough overview. Those who want to go into the details of the algorithm described in Distler05 and of the implementation itself will find the information on level 3-4 helpful.

    To use the package in silent mode the info level can be given the value 0.

    [Up] [Previous] [Next] [Index]

    Radiroot manual
    March 2022
    radiroot-2.9/htm/CHAP004.htm0000644000175000017500000000655014207520027014103 0ustar billbill[Radiroot] 4 Installation [Up] [Previous] [Index]

    4 Installation

    Sections

    1. Getting and Installing this Package
    2. Loading and Testing the Package
    3. Additional Requirements

    4.1 Getting and Installing this Package

    This package is available at

    https://gap-packages.github.io/radiroot/
    

    in form of a gzipped tar-archive. For installation instructions see Chapter Installing a GAP Package in the GAP reference manual. Normally you will unpack the archive in the pkg directory of your GAP version by typing:

        bash> tar xfz radiroot-2.9.tar.gz        # for the gzipped tar-archive
    

    4.2 Loading and Testing the Package

    To use the Radiroot package you have to request it explicitly. This is done by calling

    gap> LoadPackage("radiroot");
    -----------------------------------------------------------------------------
    Loading  RadiRoot 2.9 (Roots of a Polynomial as Radicals)
    by Andreas Distler (a.distler@tu-bs.de).
    Homepage: https://gap-packages.github.io/radiroot/
    -----------------------------------------------------------------------------
    true
    

    The LoadPackage command is described in Section LoadPackage in the GAP reference manual.

    If you want to load the Radiroot package by default, you can put the LoadPackage command into your gaprc file (see Section The gaprc file in the GAP reference manual).

    Once the package is loaded, it is possible to check the correct installation by running the test suite of the package with the command

        gap> ReadPackage( "radiroot", "tst/testall.g" );
    

    4.3 Additional Requirements

    To use Radiroot the package Alnuth in version 3.0 or higher has to be loaded with its interface fully functional.

    In the standard mode a dvi file is created to display the roots of a polynomial. As default the package uses the command latex searched for in your system programs to create the dvi file and the command xdvi to start the dvi viewer. If you can not use this settings you will have to change the function RR_Display in the file Strings.gi in the subdirectory lib of the package.

    [Up] [Previous] [Index]

    Radiroot manual
    March 2022
    radiroot-2.9/htm/indxF.htm0000644000175000017500000000126314207520027014210 0ustar billbillRadiroot : a GAP 4 package - Index F

    Radiroot : a GAP 4 package - Index F

    _ A F G I L M R S T

    Functionality of the Package 2.0

    [Up]

    Radiroot manual
    March 2022
    radiroot-2.9/htm/CHAP002.htm0000644000175000017500000002001614207520027014072 0ustar billbill[Radiroot] 2 Functionality of the Package [Up] [Previous] [Next] [Index]

    2 Functionality of the Package

    Sections

    1. Methods for Rational Polynomials
    2. Solving a Polynomial by Radicals

    2.1 Methods for Rational Polynomials

  • IsSeparablePolynomial( f )

    returns true if the rational polynomial f has simple roots only and false otherwise.

  • IsSolvable( f )
  • IsSolvablePolynomial( f )

    returns true if the rational polynomial f has a solvable Galois group and false otherwise. It signals an error if there exists an irreducible factor with degree greater than 15.

  • SplittingField( f )
  • IsomorphicMatrixField( F )
  • RootsAsMatrices( f )
  • IsomorphismMatrixField( F )

    For a normed, rational polynomial f, SplittingField(f) returns the smallest algebraic extension field L of the rationals containing all roots of f. The field is constructed with FieldByPolynomial (see Creation of number fields in Alnuth). The primitive element of L is denoted by a. A matrix field K isomorphic to L is known after the computation and can be accessed using IsomorphicMatrixField(L. The matrices, one for each distinct root of f, in the list produced by RootsOfMatrices(f) lie in K. IsomorphismMatrixField( L ) returns an isomorphism of L onto K.

    gap> x := Indeterminate( Rationals, "x" );;
    gap> f := UnivariatePolynomial( Rationals, [1,3,4,1] );
    x^3+4*x^2+3*x+1
    gap> L := SplittingField( f );
    <algebraic extension over the Rationals of degree 6>
    gap> y := Indeterminate( L, "y" );;
    gap> FactorsPolynomialAlgExt( L, f );
    [ y+(-3/94*a^4-24/47*a^3-253/94*a^2-535/94*a-168/47), 
      y+(-3/94*a^4-24/47*a^3-253/94*a^2-441/94*a+20/47), 
      y+(3/47*a^4+48/47*a^3+253/47*a^2+488/47*a+336/47) ]
    gap> IsomorphicMatrixField( L );
    <rational matrix field of degree 6>
    gap> Display(RootsAsMatrices(f)[1]);
    [ [   0,   1,   0,   0,   0,   0 ],
      [   0,   0,   1,   0,   0,   0 ],
      [  -1,  -3,  -4,   0,   0,   0 ],
      [   0,   0,   0,   0,   1,   0 ],
      [   0,   0,   0,   0,   0,   1 ],
      [   0,   0,   0,  -1,  -3,  -4 ] ]
    gap> MinimalPolynomial( Rationals, RootsAsMatrices(f)[1]);
    x^3+4*x^2+3*x+1
    gap> iso := IsomorphismMatrixField( L );
    MappingByFunction( <algebraic extension over the Rationals of degree
    6>, <rational matrix field of degree
    6>, function( x ) ... end, function( mat ) ... end )
    gap> PreImages( iso, RootsAsMatrices( f ) );
    [ -3/47*a^4-48/47*a^3-253/47*a^2-488/47*a-336/47, 
      3/94*a^4+24/47*a^3+253/94*a^2+441/94*a-20/47, 
      3/94*a^4+24/47*a^3+253/94*a^2+535/94*a+168/47 ]
    
    To factorise a polynomial over its splitting field one has to use FactorsPolynomialAlgExt (see Alnuth) instead of Factors.

  • GaloisGroupOnRoots( f )

    calculates the Galois group G of the rational polynomial f, which has to be separable, as a permutation group with respect to the ordering of the roots of f given as matrices by RootsAsMatrices.

    gap> GaloisGroupOnRoots(f);
    Group([ (2,3), (1,2) ])
    

    If you only want to get the Galois group abstractly, and if f is irreducible of degree at most 15, it is often better to use the function GaloisType (see Chapter Polynomials over the Rationals in the GAP reference manual).

    2.2 Solving a Polynomial by Radicals

  • RootsOfPolynomialAsRadicals( f [, mode [, file ] ] )

    computes a solution by radicals for the irreducible, rational polynomial f up to degree 15 if the Galois group of f is solvable, and returns fail otherwise. If it succeeds and mode is not off, the function returns the path to a file containing the description of the roots of f and generators of cyclic radical extensions to produce its splitting field.

    The user has several options to specify what happens with the results of the computation. Therefore the optional second argument mode, a string, can be set to one of the following values:

    "dvi"
    
    Provided latex and the dvi viewer xdvi are available, this option will display the irreducible radical expression for the roots and cyclic extension generators in a new window. The package uses this option as the default.

    "latex"
    
    A LaTeX file is generated which contains the encoding for the expression by radicals. This gives the user the opportunity to adjust the layout of the individual example before displaying the expression.

    "maple"
    
    The generated file can be read into Maple Maple10 which makes a root of f available as variable a.

    "off"
    
    In this mode the function does not actually compute a radical expression but is only called for its side effects. Namely, the attributes SplittingField, RootsAsMatrices and GaloisGroupOnRoots are known for f afterwards. This is slightly more effective than calling the corresponding operations one by one.

    With the optional third argument file the user can specify a file name under which the description files will be stored in the directory from which GAP was called. Depending on the option for mode an extension like .tex might be added automatically. If file is not given, the function places description files in a new directory /tmp/tmp.string with names such as Nst and Nst.tex; the temporary directory is removed at the end of the GAP session.

    The computation may take a very long time and can get unfeasible if the degree of f is greater than 7.

    
    

  • RootsOfPolynomialAsRadicalsNC( f [, mode [, file ] ] )

    does essentially the same as RootsOfPolynomialAsRadicals except that it runs no test on the input before starting the actual computation. Therefore it can be used for polynomials with arbitrary degree, but it may run for a very long time until a non-solvable polynomial is recognized as such.

    Detailed examples for these two functions can be found in the next section.

    [Up] [Previous] [Next] [Index]

    Radiroot manual
    March 2022
    radiroot-2.9/htm/chapters.htm0000644000175000017500000000124114207520027014745 0ustar billbillRadiroot : a GAP 4 package - Chapters

    Radiroot : a GAP 4 package - Chapters

    1. Introduction
    2. Functionality of the Package
    3. The Info Class of the Package
    4. Installation

    Radiroot manual
    March 2022
    radiroot-2.9/htm/biblio.htm0000644000175000017500000000267314207520027014406 0ustar billbillRadiroot : a GAP 4 package - References

    Radiroot : a GAP 4 package - References

    [Abel26]
    Niels Henrik Abel.
    Beweis der Unmöglichkeit, algebraische Gleichungen von höheren Graden als dem vierten allgemein aufzulösen.
    J. für die reine und angewandte Math. (Crelle's Journal), 1:65--84, 1826.
    [Distler05]
    Andreas Distler.
    Ein Algorithmus zum Lösen einer Polynomgleichung durch Radikale.
    Diplomarbeit, TU Braunschweig, 2005.
    http://www.icm.tu-bs.de/ag_algebra/software/distler/Diplom.pdf.
    [Galois97]
    Évariste Galois.
    Oeuvres Mathématiques d'Évariste Galois.
    Gauthier-Villars, Paris, 1897.
    [Maple10]
    Michael B. Monagan, Keith O. Geddes, K. Michael Heal, George Labahn, Stefan M. Vorkoetter, James McCarron, and Paul DeMarco.
    Maple 10 Programming Guide.
    Maplesoft, Waterloo ON, Canada, 2005.

    [Up]

    Radiroot manual
    March 2022
    radiroot-2.9/htm/indxM.htm0000644000175000017500000000127714207520027014224 0ustar billbillRadiroot : a GAP 4 package - Index M

    Radiroot : a GAP 4 package - Index M

    _ A F G I L M R S T

    Methods for Rational Polynomials 2.1

    [Up]

    Radiroot manual
    March 2022
    radiroot-2.9/htm/indxI.htm0000644000175000017500000000212214207520027014206 0ustar billbillRadiroot : a GAP 4 package - Index I

    Radiroot : a GAP 4 package - Index I

    _ A F G I L M R S T

    InfoRadiroot 3.0
    Installation 4.0
    Introduction 1.0
    IsomorphicMatrixField 2.1.3
    IsomorphismMatrixField 2.1.3
    IsSeparablePolynomial 2.1.1
    IsSolvable 2.1.2
    IsSolvablePolynomial 2.1.2

    [Up]

    Radiroot manual
    March 2022
    radiroot-2.9/htm/theindex.htm0000644000175000017500000000116314207520027014747 0ustar billbillRadiroot : a GAP 4 package - Index _

    Radiroot : a GAP 4 package - Index _

    _ A F G I L M R S T

    [Up]

    Radiroot manual
    March 2022
    radiroot-2.9/htm/indxS.htm0000644000175000017500000000145614207520027014231 0ustar billbillRadiroot : a GAP 4 package - Index S

    Radiroot : a GAP 4 package - Index S

    _ A F G I L M R S T

    SetInfoLevel 3.0
    Solving a Polynomial by Radicals 2.2
    SplittingField 2.1.3

    [Up]

    Radiroot manual
    March 2022
    radiroot-2.9/htm/indxT.htm0000644000175000017500000000126414207520027014227 0ustar billbillRadiroot : a GAP 4 package - Index T

    Radiroot : a GAP 4 package - Index T

    _ A F G I L M R S T

    The Info Class of the Package 3.0

    [Up]

    Radiroot manual
    March 2022
    radiroot-2.9/htm/CHAP001.htm0000644000175000017500000001410014207520027014066 0ustar billbill[Radiroot] 1 Introduction [Up] [Next] [Index]

    1 Introduction

    Sections

    1. License

    This package provides functionality to deal with one of the fundamental problems in algebra. The roots of a rational polynomial shall be expressed by radicals. This means one is only allowed to use the four basic operations (+, −, · ,÷) and to extract roots. For example, a radical expression for the roots of the polynomial x4x3x2 + x + 1 is
    1

    4
    + 1

    4


     

    −3
     
    + 1

    2
      ⎛


    7

    2
    + 1

    2


     

    −3
     
     
    ·

    There are formulas to solve the general equation xn+ an−1xn−1+ ... + a1x+a0 = 0 up to degree 4. For higher degrees such formulae do not exist (Abel26). It was Évariste Galois (1811 -- 1832) who discovered that there exists a radical expression for the roots if and only if the Galois group of the polynomial - initially a permutation group on the roots - is solvable Galois97. But the task itself was impractical in his days. This package is the first public tool which provides a practical method for solving a polynomial algebraically. The implementation is based on Galois' ideas and the algorithm is described in Distler05.

    The package can provide the result in various forms. As a default an expression is given in a similar way as in the example above. Alternatively, a file containing the roots might be created which is readable by Maple Maple10. In GAP itself some information deduced during the computation is available.

    The user should be aware that radical expressions can get very complicated even for polynomials of small degree. Especially because the algorithm will find an irreducible radical expression. That means one gets a root of the given polynomial for every choice of a value of the radicals in the expression. Moreover it is not the aim of this package to give a simplest expression, in any sense.

    In Chapter 2 the methods provided by this package are listed and explained.

    Chapter 3 gives details about the info class of this package. See Section Info Functions in the GAP reference manual for general information about info classes.

    While the installation of the package follows standard GAP rules the Chapter 4 contains information about external programs required by Radiroot in its default setup.

    This package uses the interface in the package Alnuth, to factorise polynomials over algebraic number fields. This functionality must be available to use the functions in Radiroot.

    1.1 License

    This package 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.

    [Up] [Next] [Index]

    Radiroot manual
    March 2022
    radiroot-2.9/htm/indxG.htm0000644000175000017500000000140414207520027014206 0ustar billbillRadiroot : a GAP 4 package - Index G

    Radiroot : a GAP 4 package - Index G

    _ A F G I L M R S T

    GaloisGroupOnRoots 2.1.4
    Getting and Installing this Package 4.1

    [Up]

    Radiroot manual
    March 2022
    radiroot-2.9/htm/indxA.htm0000644000175000017500000000126614207520027014206 0ustar billbillRadiroot : a GAP 4 package - Index A

    Radiroot : a GAP 4 package - Index A

    _ A F G I L M R S T

    Additional Requirements 4.3

    [Up]

    Radiroot manual
    March 2022
    radiroot-2.9/htm/indxR.htm0000644000175000017500000000137514207520027014230 0ustar billbillRadiroot : a GAP 4 package - Index R

    Radiroot : a GAP 4 package - Index R

    _ A F G I L M R S T

    RootsAsMatrices 2.1.3
    RootsOfPolynomialAsRadicals 2.2.1

    [Up]

    Radiroot manual
    March 2022
    radiroot-2.9/read.g0000644000175000017500000000146514207520017012724 0ustar billbill############################################################################# ## #W read.g RADIROOT package Andreas Distler ## ## The read file for the RADIROOT package ## #Y 2005 ## ############################################################################# ## #R radiroot global variables ## DeclareInfoClass( "InfoRadiroot" ); SetInfoLevel( InfoRadiroot, 1 ); ############################################################################# ## #R read files ## ReadPackage( "RADIROOT", "lib/Radicals.gi" ); ReadPackage( "RADIROOT", "lib/SplittField.gi" ); ReadPackage( "RADIROOT", "lib/Manipulations.gi" ); ReadPackage( "RADIROOT", "lib/Strings.gi" ); ReadPackage( "RADIROOT", "lib/Maple.gi" ); ############################################################################# ## #E radiroot-2.9/PackageInfo.g0000644000175000017500000000442214207520017014154 0ustar billbill############################################################################# ## #W PackageInfo.g RadiRoot package Andreas Distler ## ## The package info file for the RadiRoot package ## SetPackageInfo( rec( PackageName := "RadiRoot", Subtitle := "Roots of a Polynomial as Radicals", Version := "2.9", Date := "01/03/2022", # dd/mm/yyyy format License := "GPL-2.0-or-later", PackageWWWHome := "https://gap-packages.github.io/radiroot/", README_URL := Concatenation( ~.PackageWWWHome, "README" ), PackageInfoURL := Concatenation( ~.PackageWWWHome, "PackageInfo.g" ), SourceRepository := rec( Type := "git", URL := "https://github.com/gap-packages/radiroot", ), IssueTrackerURL := Concatenation( ~.SourceRepository.URL, "/issues" ), ArchiveURL := Concatenation( ~.SourceRepository.URL, "/releases/download/v", ~.Version, "/radiroot-", ~.Version ), ArchiveFormats := ".tar.gz", Persons := [ rec( LastName := "Distler", FirstNames := "Andreas", IsAuthor := true, IsMaintainer := false, Email := "a.distler@tu-bs.de", ), rec( LastName := "GAP Team", FirstNames := "The", IsAuthor := false, IsMaintainer := true, Email := "support@gap-system.org", ), ], Status := "accepted", CommunicatedBy := "Edmund Robertson (St Andrews)", AcceptDate := "02/2007", AbstractHTML := "The RadiRoot package installs a method to \ display the roots of a rational polynomial as radicals if it is solvable.", PackageDoc := rec( BookName := "RadiRoot", ArchiveURLSubset := ["doc", "htm"], HTMLStart := "htm/chapters.htm", PDFFile := "doc/manual.pdf", SixFile := "doc/manual.six", LongTitle := "Roots of a Polynomial as Radicals", Autoload := true ), Dependencies := rec( GAP := ">=4.7", NeededOtherPackages := [[ "Alnuth", ">=3.0" ]], SuggestedOtherPackages := [], ExternalConditions := ["latex and the dvi-viewer xdvi are recommended"] ), AvailabilityTest := ReturnTrue, Autoload := false, TestFile := "tst/testall.g", Keywords := ["roots", "radicals"] )); ############################################################################# ## #E radiroot-2.9/tst/0000755000175000017500000000000014211721314012443 5ustar billbillradiroot-2.9/tst/docexmpl.tst0000644000175000017500000000334614207520017015022 0ustar billbillgap> START_TEST("Test of documentation examples in package RadiRoot"); gap> f := UnivariatePolynomial( Rationals, [1,3,4,1] ); x_1^3+4*x_1^2+3*x_1+1 gap> L := SplittingField( f ); gap> FactorsPolynomialAlgExt( L, f ); [ x_1+(-3/94*a^4-24/47*a^3-253/94*a^2-535/94*a-168/47), x_1+(-3/94*a^4-24/47*a^3-253/94*a^2-441/94*a+20/47), x_1+(3/47*a^4+48/47*a^3+253/47*a^2+488/47*a+336/47) ] gap> IsomorphicMatrixField( L ); gap> Display(RootsAsMatrices(f)[1]); [ [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ -1, -3, -4, 0, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ], [ 0, 0, 0, 0, 0, 1 ], [ 0, 0, 0, -1, -3, -4 ] ] gap> MinimalPolynomial( Rationals, RootsAsMatrices(f)[1]); x_1^3+4*x_1^2+3*x_1+1 gap> iso := IsomorphismMatrixField( L ); MappingByFunction( , , function( x ) ... end, function( mat ) ... end ) gap> PreImages( iso, RootsAsMatrices( f ) ); [ -3/47*a^4-48/47*a^3-253/47*a^2-488/47*a-336/47, 3/94*a^4+24/47*a^3+253/94*a^2+441/94*a-20/47, 3/94*a^4+24/47*a^3+253/94*a^2+535/94*a+168/47 ] gap> GaloisGroupOnRoots(f); Group([ (2,3), (1,2) ]) gap> g := UnivariatePolynomial( Rationals, [1,1,-1,-1,1] ); x_1^4-x_1^3-x_1^2+x_1+1 gap> RootsOfPolynomialAsRadicalsNC( g, "off" ); gap> SplittingField( g ); gap> GaloisGroupOnRoots( g ); Group([ (2,4), (1,2)(3,4) ]) gap> poly := UnivariatePolynomial( Rationals, [2,-4,0,0,0,1] ); x_1^5-4*x_1+2 gap> RootsOfPolynomialAsRadicals( poly ); #I Polynomial is not solvable. fail gap> STOP_TEST( "docexmpl.tst", 100000); radiroot-2.9/tst/testall.g0000644000175000017500000000022114207520017014260 0ustar billbillLoadPackage("radiroot"); dirs := DirectoriesPackageLibrary( "radiroot", "tst" ); TestDirectory(dirs, rec(exitGAP := true, rewriteToFile:=true)); radiroot-2.9/tst/trivial.tst0000644000175000017500000000216114207520017014653 0ustar billbillgap> START_TEST("Test handling of easy polynomials by RadiRoot"); gap> # special case f = x, does output work gap> f := UnivariatePolynomial( Rationals, [0,1] );; gap> RootsOfPolynomialAsRadicals(f, "off");; gap> RootsAsMatrices(f); [ [ [ 0 ] ] ] gap> SplittingField(f); Rationals gap> GaloisGroupOnRoots(f); Group(()) gap> # f = x - 1 gap> f := UnivariatePolynomial( Rationals, [-1,1] );; gap> RootsAsMatrices(f); [ [ [ 1 ] ] ] gap> SplittingField(f); Rationals gap> GaloisGroupOnRoots(f); Group(()) gap> # f = x^2 + x + 2 gap> f := UnivariatePolynomial( Rationals, [2,1,1] );; gap> GaloisGroupOnRoots(f); Group([ (1,2) ]) gap> SplittingField(f); gap> RootsAsMatrices(f); [ [ [ 0, 1 ], [ -2, -1 ] ], [ [ -1, -1 ], [ 2, 0 ] ] ] gap> RootsOfPolynomialAsRadicals(f,"latex");; gap> # f = x^3 - 3*x^2 + 3*x -3 gap> f := UnivariatePolynomial( Rationals, [-3,3,-3,1] );; gap> RootsOfPolynomialAsRadicals(f,"maple");; gap> GaloisGroupOnRoots(f); Group([ (2,3), (1,2) ]) gap> SplittingField(f); gap> STOP_TEST( "docexmpl.tst", 100000); radiroot-2.9/LICENSE0000644000175000017500000004311014207520017012637 0ustar billbill 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. radiroot-2.9/lib/0000755000175000017500000000000014211721314012377 5ustar billbillradiroot-2.9/lib/Manipulations.gd0000644000175000017500000000166114207520017015544 0ustar billbill############################################################################# #### ## #W Manipulations.gd RADIROOT package Andreas Distler ## ## Declaration file for the functions that do various manipulations ## to special elements of a splitting field and to the permutations ## in its Galois-group ## #Y 2006 ## DeclareAttribute( "GaloisGroupOnRoots", IsUnivariatePolynomial ); DeclareGlobalFunction( "RR_DegreeConclusion" ); DeclareGlobalFunction( "RR_PrimElImg" ); DeclareGlobalFunction( "RR_Produkt" ); DeclareGlobalFunction( "RR_Resolvent" ); DeclareGlobalFunction( "RR_CyclicElements" ); DeclareGlobalFunction( "RR_IsInGalGrp" ); DeclareGlobalFunction( "RR_ConstructGaloisGroup" ); DeclareGlobalFunction( "RR_FindGaloisGroup" ); DeclareGlobalFunction( "RR_Potfree" ); DeclareGlobalFunction( "RR_CompositionSeries" ); ############################################################################# ## #E radiroot-2.9/lib/SplittField.gd0000644000175000017500000000132514207520017015141 0ustar billbill############################################################################# #### ## #W SplittField.gd RADIROOT package Andreas Distler ## ## Declares the functions to compute the splitting field of a polynomial ## #Y 2006 ## DeclareAttribute( "IsomorphismMatrixField", IsNumberField ); DeclareGlobalFunction( "IsomorphicMatrixField" ); DeclareGlobalFunction( "RR_BegleitMatrix" ); DeclareGlobalFunction( "RR_BlowUpMat" ); DeclareGlobalFunction( "RR_MatrixField" ); DeclareGlobalFunction( "RR_RootInH" ); DeclareGlobalFunction( "RR_RootInK" ); DeclareGlobalFunction( "RR_Zerfaellungskoerper" ); ############################################################################# ## #E radiroot-2.9/lib/Radicals.gd0000644000175000017500000000147514207520017014446 0ustar billbill############################################################################# #### ## #W Radicals.gd RADIROOT package Andreas Distler ## ## Declaration file for main function of the RADIROOT package ## #Y 2006 ## DeclareGlobalFunction( "RR_SplittField" ); DeclareGlobalFunction( "RR_SimplifiedPolynomial" ); DeclareGlobalFunction( "RR_RootOfUnity" ); DeclareGlobalFunction( "RR_Roots" ); DeclareGlobalFunction( "RootsOfPolynomialAsRadicals" ); DeclareGlobalFunction( "RootsOfPolynomialAsRadicalsNC" ); DeclareAttribute( "RootsAsMatrices", IsUnivariatePolynomial ); DeclareProperty( "IsSolvablePolynomial", IsUnivariatePolynomial ); DeclareProperty( "IsSeparablePolynomial", IsUnivariatePolynomial ); ############################################################################# ## #E radiroot-2.9/lib/SplittField.gi0000644000175000017500000002573414207520017015160 0ustar billbill############################################################################# #### ## #W SplittField.gi RADIROOT package Andreas Distler ## ## Installs the functions to compute the splitting field of a polynomial ## #Y 2006 ## ############################################################################# ## #M SplittingField( ) ## ## Returns the smallest field, that contains the roots of the irreducible, ## rational polynomial as algebraic extension of the Rationals ## InstallMethod( SplittingField, "rational polynomials", [ IsUnivariateRationalFunction and IsPolynomial ], function( f ) local splitt; if not ForAll( CoefficientsOfUnivariatePolynomial( f ), IsRat ) then TryNextMethod( ); fi; if not IsSeparablePolynomial( f ) then # make polynomial separable f := f / Gcd( f, Derivative( f ) ); fi; splitt := RR_Zerfaellungskoerper( f, rec( roots := [ ], degs := [ ], coeffs := [ ], K := FieldByMatrices([ [[ 1 ]] ]), H := Rationals ) ); if Length( splitt.roots[1] ) >= Length( splitt.roots[2] ) then # roots as matrices, otherwise linear factors known Add( splitt.roots[1], -CoefficientsOfUnivariatePolynomial(f)[Degree(f)]*One(splitt.K) -Sum( splitt.roots[1] ) ); SetRootsAsMatrices( f, splitt.roots[1] ); fi; return splitt.H; end ); ############################################################################# ## #F IsomorphicMatrixField( ) ## ## returns a matrix field which is isomorphic to the field ## InstallGlobalFunction( IsomorphicMatrixField, function( L ) return Range( IsomorphismMatrixField( L ) ); end ); ############################################################################# ## #O IsomorphismMatrixField( Rationals ) ## ## installs the value for 'IsomorphismMatrixField' of the Rationals ## SetIsomorphismMatrixField( Rationals, MappingByFunction( Rationals, FieldByMatrices([[[ 1 ]]]), x -> [[ x ]], mat -> mat[1][1] )); ############################################################################# ## #F RR_BegleitMatrix( , ) ## ## Computes the companion matrix of the polynomial with respect to ## the field generated by the matrix ## InstallGlobalFunction( RR_BegleitMatrix, function( f, A ) local matrix, coeff, blockmat, deg, i, k, l; deg := Degree(f); coeff := CoefficientsOfUnivariatePolynomial(f); matrix := NullMat( deg*Size(A), deg*Size(A), Rationals); # create last row for i in [ 1..deg ] do # matrix, representing the i-th coefficient blockmat := -RR_RootInK( A, coeff[i] ); for k in [1..Size(A)] do for l in [1..Size(A)] do matrix[(deg-1)*Size(A)+k][(i-1)*Size(A)+l] := blockmat[k][l]; od; od; od; # fill the secondary diagonal with 1 for i in [1..(deg-1)] do for k in [1..Size(A)] do matrix[(i-1)*Size(A)+k][i*Size(A)+k] := 1; od; od; return matrix; end ); ############################################################################# ## #F RR_BlowUpMat, function( , ) ## ## Computes a matrix that is -times bigger than and has ## on the blocks with size of at the diagonal ## InstallGlobalFunction( RR_BlowUpMat, function( mat, n ) local i, j, k, Mat; Mat := NullMat( n * Size(mat), n * Size(mat), Rationals ); for i in [ 1..n ] do for j in [ 1..Size( mat ) ] do for k in [ 1..Size( mat ) ] do Mat[ (i-1)*Size(mat)+j ][ (i-1)*Size(mat)+k ] := mat[j][k]; od; od; od; return Mat; end ); ############################################################################# ## #F RR_MatrixField( , ) ## ## Returns the matrixfield that arises from adjoining a root of the ## polynomial to the matrixfield generated by ## InstallGlobalFunction( RR_MatrixField, function( f, mat ) local A, B; # mat as matrix in the supfield # mat is deg(f) times on the diagonal A := RR_BlowUpMat( mat, Degree(f) ); # companion matrix of f with respect to the field generated by mat B := RR_BegleitMatrix( f, mat ); return FieldByMatricesNC( [A, B] ); end ); ############################################################################# ## #F RR_RootInH( , ) ## ## The record contains two isomorphic fields. One generated ## with AlgebraicExtension and the other as matrixfield. Both are ## defined by a primitive element. This function transfers the ## matrix to it's isomorphic symbolic represenation ## InstallGlobalFunction( RR_RootInH, function( erw, a ) local coeff, bas; # basis {1, primEl, ... , primEl^(n-1)} as matrices bas := EquationOrderBasis( erw.K, PrimitiveElement( erw.K )); return LinearCombination( Basis( erw.H ), Coefficients( bas, a) ); end ); ############################################################################# ## #F RR_RootInK( , ) ## ## Does the inverse of RR_RootInH; the fieldelement given symbolic ## by it's external representation is transfered in a matrix ## of the field generated by ## InstallGlobalFunction( RR_RootInK, function( primEl, elm ) local i, mat; mat := NullMat( Size(primEl), Size(primEl), Rationals ); for i in [1..Size(primEl)] do mat := mat + ExtRepOfObj(elm)[i] * primEl^(i-1); od; return mat; end ); ############################################################################# ## #F RR_Zerfaellungskoerper( , ) ## ## Computes the splitting field of the polynomial . In the ## record the field is stored as matrix field as well as in a ## symbolic represenation generated by ## AlgebraicExtension. The roots of are also stored. ## InstallGlobalFunction( RR_Zerfaellungskoerper, function( poly, erw ) local matA,matB,faktoren,i,f,minpol,roots,primEl, map; # catch trivial case if Degree( poly ) = 1 then erw.roots := [ [ ], [ ] ]; return erw; fi; # Splitting field already known if not IsBound( erw.unity ) and HasSplittingField( poly ) then erw.H := SplittingField( poly ); erw.K := IsomorphicMatrixField( erw.H ); # roots will be needed in any further computation erw.roots := [ ShallowCopy( RootsAsMatrices( poly ) ), [] ]; erw.degs := RR_DegreeConclusion( Basis(erw.K), erw.roots[1] ); Remove( erw.roots[1] ); erw.coeffs := Filtered(Coefficients(Basis(erw.K), PrimitiveElement(erw.K)), i -> i <> 0 ); return erw; fi; roots := [ ]; # repeat until factors in linear polynomials while Length(erw.roots) + Length(roots) + 1 < Degree(poly) do # factors over the latest faktoren := FactorsPolynomialAlgExt( erw.H, poly );; Info( InfoRadiroot, 4, " Factorization of polynomial:\n", faktoren ); f := faktoren[ Length( faktoren ) ]; if Degree( f ) = 1 then break; fi; roots := RR_Roots( [ erw.roots, roots, List( Filtered( faktoren, f -> Degree( f ) = 1 ), f -> -CoefficientsOfUnivariatePolynomial(f)[1])], erw ); erw.K := RR_MatrixField( f, PrimitiveElement( erw.K ) ); Add( erw.degs, Degree(f) ); SetDegreeOverPrimeField( erw.K, Product( erw.degs )); Info( InfoRadiroot, 3," Degree of the extension: ", Degree(f) ); matA := GeneratorsOfField( erw.K )[ 1 ];; matB := GeneratorsOfField( erw.K )[ 2 ];; # bring the list of roots up-to-date for i in [ 1..Length(erw.roots) ] do erw.roots[i] := RR_BlowUpMat( erw.roots[i], Degree( f ) ); od; for i in [ 1..Length(roots) ] do roots[i] := RR_BlowUpMat( roots[i], Degree( f ) ); od; if IsBound( erw.unity ) then erw.unity := RR_BlowUpMat( erw.unity, Degree( f ) ); fi; Info( InfoRadiroot, 4, " Adjoined root:\n", matB ); Add( erw.roots, matB ); Info( InfoRadiroot, 3, " Searching for a primitive element" ); primEl := Sum([1..Length(erw.roots)], i -> i * erw.roots[i]); if IsBound( erw.unity ) then primEl := primEl+erw.unity; fi; minpol := MinimalPolynomial( Rationals, primEl ); if Degree( minpol ) = Product( erw.degs ) then SetPrimitiveElement( erw.K, primEl ); SetDefiningPolynomial( erw.K, minpol ); Add( erw.coeffs, Length( erw.roots ) ); else for i in [ Minimum( 2 * [ Length( erw.degs )-1, 1 ] )..99 ] do minpol := MinimalPolynomial( Rationals, i * matA + matB ); if Degree( minpol ) = Product( erw.degs ) then SetPrimitiveElement( erw.K, i * matA + matB ); SetDefiningPolynomial( erw.K, minpol ); erw.coeffs := Flat( [ i * erw.coeffs, 1 ] ); break; fi; od; fi; erw.H := AlgebraicExtension( Rationals, minpol ); Info( InfoRadiroot, 3, " ", minpol, " is defining polynomial."); od; erw.roots := [ Concatenation( erw.roots, roots ), List( faktoren, f -> -Value( f, 0 ) ) ]; if IsBound( erw.unity ) then erw.degs := erw.degs{[ 2..Length(erw.degs) ]}; fi; Info( InfoRadiroot, 3, " Composition of the primitive element: ", erw.coeffs ); map := MappingByFunction( erw.H, erw.K, x -> RR_RootInK( PrimitiveElement( erw.K ) ,x ), mat -> RR_RootInH( rec( K := erw.K, H := erw.H), mat )); SetIsomorphismMatrixField( erw.H, map ); SetSplittingField( poly, erw.H ); return erw; end ); ############################################################################# ## #F RR_SplittField( , ) ## ## Calls the function RR_Zerfaellungskoerper for the polynomial with ## special initial values. The splitting field is constructed over a ## cyclotomic field. ## InstallGlobalFunction( RR_SplittField, function( poly, m ) local erw, cyclopol; cyclopol := CyclotomicPolynomial(Rationals, m); erw := rec( roots := [ ], degs := [ Degree(cyclopol) ], coeffs := [ ], K := RR_MatrixField( cyclopol, [[ 1 ]]), H := AlgebraicExtension( Rationals, cyclopol )); erw.unity := PrimitiveElement( erw.K ); erw := RR_Zerfaellungskoerper( poly, erw );; return erw; end ); ############################################################################# ## #E radiroot-2.9/lib/Manipulations.gi0000644000175000017500000003347314207520017015557 0ustar billbill############################################################################# #### ## #W Manipulations.gi RADIROOT package Andreas Distler ## ## Installation file for the functions that do various manipulations ## to special elements of a splitting field and to the permutations ## in its Galois group ## #Y 2006 ## ############################################################################# ## #M GaloisGroupOnRoots( ) #M GaloisType( ) ## ## Computes the Galois group of the rational polynomial with respect to ## its roots, created as matrices ## InstallMethod( GaloisGroupOnRoots, "for rational polynomial", [ IsUnivariateRationalFunction and IsPolynomial ], function( f ) local erw, galgrp; if not ForAll( CoefficientsOfUnivariatePolynomial( f ), IsRat ) then TryNextMethod( ); fi; if not IsSeparablePolynomial( f ) then Error("f must be separable"); fi; erw := RR_Zerfaellungskoerper( f, rec( roots := [ ], degs := [ ], coeffs := [ ], K:=FieldByMatrices([ [[ 1 ]] ]), H:=Rationals ));; erw.roots := RR_Roots( [ [], erw.roots[1], erw.roots[2] ], erw );; Add( erw.roots, -CoefficientsOfUnivariatePolynomial(f)[Degree(f)]*One(erw.K) -Sum( erw.roots ) ); # neccessary to use RR_Produkt in the computation of the Galois group erw.unity := 1; galgrp := RR_ConstructGaloisGroup( erw ); return galgrp; end ); InstallMethod(GaloisType,"for polynomials",true,[IsUnivariateRationalFunction and IsPolynomial and HasGaloisGroupOnRoots],0, function( f ) if not(IsIrreducibleRingElement(f)) then Error("f must be irreducible"); fi; return TransitiveIdentification( GaloisGroupOnRoots( f )); end ); ############################################################################# ## #F RR_DegreeConclusion( , ) ## InstallGlobalFunction( RR_DegreeConclusion, function( B, roots ) local i, degs; degs := [ ]; roots := Filtered( roots, root -> root in B ); for i in [ 1..Length( roots )-1 ] do degs[i] := (Position( B, roots[i+1] ) - 1) / Product(degs); od; degs[ Length( roots ) ] := Length( B ) / Product(degs); return degs; end ); ############################################################################# ## #F RR_PrimElImg( , ) ## ## Calculates the result for apllying the permutation to the ## primitive element of the field in the record ## InstallGlobalFunction( RR_PrimElImg, function( erw, perm ) # basefield = rationals if Length(erw.degs) = Length(erw.coeffs) then return Sum( [ 1..Length(erw.coeffs) ], i -> erw.coeffs[i] * erw.roots[i^perm] );; # basefield = cyclotomic field else return Sum( [ 2..Length(erw.coeffs) ], i -> erw.coeffs[i] * erw.roots[(i-1)^perm] ) + erw.coeffs[1] * erw.unity;; fi; end ); ############################################################################# ## #F RR_Produkt( , , ) ## ## Calculates the result for apllying the permutation to the ## field element ## InstallGlobalFunction( RR_Produkt, function( erw, elm, perm ) local i, k, mat, coeff, degprod, prod; mat := 0*One(erw.K); coeff := Coefficients( Basis(erw.K), elm ); # computation with respect to the known order of the basis for i in [ 1..Length(coeff) ] do if coeff[i] <> 0 then # Einheitswurzel bleibt erhalten # Size(elm)/Product(erw.degs) ist 1, wenn keine # Einheitswurzel adjungiert wurde degprod := Length( coeff ) / Product( erw.degs ); prod := erw.unity^RemInt( i-1, degprod ); # One( erw.K ); # the roots that built the basis are permuted for k in [ 1..Length(erw.degs) ] do prod := prod * erw.roots[ k^perm ]^QuoInt( RemInt( i-1, degprod * erw.degs[k] ), degprod ); degprod := degprod * erw.degs[k]; od; mat := mat + coeff[i] * prod; fi; od; return mat; end ); ############################################################################# ## #F RR_CompositionSeries( , ) ## ## Computes a composition series of through its normal subgroup ## InstallGlobalFunction( RR_CompositionSeries, function( G, N ) local hom, genN, grps, gens; if G = N then return CompositionSeries( G ); elif Order( G ) / Order( N ) in Primes then return Concatenation([ G ], CompositionSeries( N )); else Info( InfoRadiroot, 3, " computation of compositon series" ); hom := NaturalHomomorphismByNormalSubgroupNC( G, N ); # Generators of Composition Series G/N as free group gens := List( CompositionSeries(Range(hom)), GeneratorsOfGroup ); Unbind( gens[ Length( gens ) ] ); # Preimages of the Generators in G gens := List(gens, ll->List(ll, x->PreImagesRepresentative(hom, x))); genN := GeneratorsOfGroup( N ); grps := List( gens, x -> Group( Concatenation( genN, x ))); fi; return Concatenation( grps, CompositionSeries( N ) ); end ); ############################################################################# ## #F RR_Potfree( , ) ## ## Computes / where and are the largest integers such ## that ^ resp. )^ occur as factor the nominator resp. ## denominator of every rational number in the list ## InstallGlobalFunction( RR_Potfree, function( rats, exp ) local num, den; num := Gcd(List(rats, NumeratorRat)); den := Gcd(List(Filtered(rats, x-> x<>0), DenominatorRat)); num := Product( Collected( Factors( num )), pe -> pe[1]^( exp * (QuoInt( pe[2], exp ) ) ) ); den := Product( Collected( Factors( den )), pe -> pe[1]^( exp * (QuoInt( pe[2], exp ) ) ) ); return Root( num, exp ) / Root( den, exp ); end ); ############################################################################# ## #F RR_Resolvent( , , , ) ## ## Computes the Lagrange resolvent for the element and a ## generator of the factor group of and ## InstallGlobalFunction( RR_Resolvent, function( G, N, elm, erw ) local unity, gen, p; p := Order( G ) / Order( N ); # determine gen with G/N = gen := First( Elements( G ), x -> not x in N ); # p-th root of unity if IsInt( Order( erw.unity ) / p ) then unity := erw.unity^( Order( erw.unity ) / p ); else # if RR_SplittField has been used this distinction is necessary unity := E( p ) * One( erw.K ); fi; return Sum([ 0..p-1 ], k -> unity^k * RR_Produkt( erw, elm, gen^k ) )/p; end ); ############################################################################# ## #F RR_CyclicElements( , ) ## ## It is a composition series for the Galois group of the ## field in the record . The function returns a list of elements ## that generate the corresponding tower of fields. Each element is ## cyclic in the direct subfield. ## InstallGlobalFunction( RR_CyclicElements, function( erw, compser ) local i, k, elements, elm, primEllist, L, n, potelm, primEl; if erw.H = Rationals then return [ ]; fi; elements := [ ]; if Length(erw.degs) = Length(erw.coeffs) then L := FieldByMatricesNC( [ One( erw.K ) ] ); else L := FieldByMatricesNC( [ erw.unity ] ); fi; for i in [ 2..Length(compser)-1 ] do primEllist := List( AsList( compser[i] ), perm -> RR_PrimElImg( erw, perm ));; for k in Flat(List([ 1..Length(primEllist) ], i -> [i, Length(primEllist) + 1 - i ])) do elm := Sum( Combinations( [ 1..Length(primEllist) ], k), subset -> Product( subset, x -> primEllist[x]));; if not (elm in L) then Info( InfoRadiroot, 3, " found element of field with degree ", DegreeOverPrimeField( erw.K ) / Order( compser[i] ) ); break; fi; od; n := Order( compser[i-1] ) / Order( compser[i] ); for k in [ 1..n ] do elements[i-1]:=RR_Resolvent(compser[i-1],compser[i],elm^k,erw); if elements[i-1] <> 0 * One( erw.K ) then break; fi; od; potelm := elements[i-1]^n;; if IsDiagonalMat( potelm ) and IsRat( potelm[1][1] ) then elements[i-1] := elements[i-1] / RR_Potfree( [ potelm[1][1] ], n ); fi; elements[i-1] := [elements[i-1], n]; if i <> Length(compser)-1 then L := FieldByMatricesNC( Concatenation( GeneratorsOfField(L), [ elements[i-1][1] ])); fi; od; i := Length( compser ); n := Order( compser[i-1] ) / Order( compser[i] ); for k in [ 1..n ] do elements[i-1]:=RR_Resolvent(compser[i-1],compser[i], PrimitiveElement(erw.K)^k,erw); if elements[i-1] <> 0 * One( erw.K ) then break; fi; od; if i = 2 then potelm := elements[i-1]^n; if IsDiagonalMat( potelm ) and IsRat( potelm[1][1] ) then elements[i-1] := elements[i-1] / RR_Potfree( [ potelm[1][1] ], n ); fi; fi; elements[i-1] := [elements[i-1], n]; return elements; end ); ############################################################################# ## #F RR_IsInGalGrp( , ) ## ## Tests if the permutation is in the Galois group that ## belongs to the roots in the record ## InstallGlobalFunction( RR_IsInGalGrp, function( erw, perm ) local i; for i in [ 1..Length(erw.roots) ] do if RR_Produkt( erw, erw.roots[i], perm ) <> erw.roots[ i^perm ] then return false; fi; od; return true; end ); ############################################################################# ## #F RR_ConstructGaloisGroup( ) ## ## Constructs the Galois group for the roots in the record with ## respect to their order ## InstallGlobalFunction( RR_ConstructGaloisGroup, function( erw ) local Sn, rt, ggelm, p, B, imgs, oldgroup; Info( InfoRadiroot, 2, " Construction of the Galoisgroup" ); ggelm := [ () ]; oldgroup := [ ]; if erw.H = Rationals then return Group( ggelm ); fi; Sn := SymmetricGroup( Length( erw.roots ) ); rt := RightTransversal( Sn, Stabilizer( Sn, [ 1..Length(erw.degs) ], OnTuples ) ); imgs := List( rt, perm -> RR_PrimElImg( erw, perm ));; if IsDuplicateFreeList( imgs ) then Info( InfoRadiroot, 3, " using fast Galoisgroup computation" ); repeat # sort out already known permutations rt := Difference(rt, List(Difference(AsList(Group(ggelm)),oldgroup), p -> First(rt, prm->ForAll([1..Length(erw.degs)], i->i^prm = i^p))));; oldgroup := AsList(Group(ggelm)); p := Permutation( Remove(rt,1), erw.roots, function(x, g) return RR_Produkt(erw, x, g); end ); if p <> fail and Value( DefiningPolynomial(erw.K), RR_PrimElImg( erw, p )) = 0 * One(erw.K) then Add( ggelm, p ); fi; until Order(Group(ggelm)) = Product(erw.degs); else Info( InfoRadiroot, 3, " using slow Galoisgroup computation" ); imgs := DuplicateFreeList(imgs); repeat imgs := Difference(imgs, List(Difference(AsList(Group(ggelm)),oldgroup), p->RR_PrimElImg( erw, p )));; oldgroup := AsList(Group(ggelm)); if Value(DefiningPolynomial(erw.K), imgs[1]) = 0 * One(erw.K) then B := Basis(erw.K,ListElmPower([0..Size(imgs[1])-1],imgs[1]));; p := Permutation( (), erw.roots, function( x, g ) return LinearCombination( B, Coefficients( EquationOrderBasis( erw.K, PrimitiveElement(erw.K) ), x )); end ); Add( ggelm, p ); else imgs := imgs{[ 2..Length(imgs) ]}; fi; until Order(Group(ggelm)) = DegreeOverPrimeField(erw.K); fi; return Group( Difference( ggelm, [ () ] )); end ); ############################################################################# ## #F RR_FindGaloisGroup( , , ) ## ## This function searchs the Galois group of the rational polynomial ## that is compatible to the numbering of the roots of ## in ; it is recommended to use RR_ConstructGaloisGroup if there ## exist many groups conjugated to ## InstallGlobalFunction( RR_FindGaloisGroup, function( erw, poly, galgrp ) local G, H, perm, k, gens, newgens, Sn; k := 1; gens := [ ]; Sn := SymmetricGroup( Degree(poly) ); for G in ConjugacyClassSubgroups( Sn, galgrp ) do newgens := Filtered( GeneratorsOfGroup( G ), gen -> RR_IsInGalGrp( erw, gen ) ); gens := DuplicateFreeList( Concatenation( gens, newgens ) ); H := Subgroup( Sn, gens ); if Order(galgrp) = Order( H ) then return H; fi; od; end ); ############################################################################# ## #E radiroot-2.9/lib/Radicals.gi0000644000175000017500000003175214207520017014454 0ustar billbill############################################################################# #### ## #W Radicals.gi RADIROOT package Andreas Distler ## ## Installation file for the main function of the RADIROOT package ## #Y 2006 ## ############################################################################# ## #F RR_RootOfUnity( , ) ## ## Computes a -th root of unity built up on the roots of unity ## that already exists in the field of the record ## InstallGlobalFunction( RR_RootOfUnity, function( erw, ord ) local i, unity, cond, faktor, m; Info( InfoRadiroot, 2, " Finding root of unity" ); unity := One( erw.K ); if ord = 1 then return unity; fi; cond := 1; m := 1; for i in DuplicateFreeList( Factors( ord ) ) do # first factor of the i-th cyclotomic polynomial in H faktor:=FactorsPolynomialAlgExt(erw.H, CyclotomicPolynomial(Rationals,i))[1]; Info( InfoRadiroot, 3," Cyclotomic polynomial factor: ", faktor ); if Degree( faktor ) = i-1 then cond := cond * i; #unity := unity * E( i ); Info( InfoRadiroot, 4, " Adjoining ", i, "-th root of unity" ); elif Degree( faktor ) = 1 then unity := unity * Image( IsomorphismMatrixField( erw.H ), -Value( faktor, 0 ) ); Info( InfoRadiroot, 4, " Calculate ", i, "-th root of unity" ); else m := i * m; fi; od; if m = 1 then return E( cond ) * unity; else return m * Order( unity ); fi; end ); ############################################################################# ## #M IsSolvablePolynomial( ) #M IsSolvable( ) ## ## Determines whether the rational polynomial is solvable, e. g. whether ## its Galois group is solvable ## InstallMethod( IsSolvablePolynomial, "for a rational polynomial", [ IsUnivariateRationalFunction and IsPolynomial ], 0, function( f ) if not ForAll( CoefficientsOfUnivariatePolynomial( f ), IsRat ) then TryNextMethod( ); fi; f := RR_SimplifiedPolynomial( f ); return ForAll( Filtered( List( Factors(f), RR_SimplifiedPolynomial ), ff -> Degree(ff) <> 1 ), ff -> IsSolvableGroup( TransitiveGroup( Degree(ff), GaloisType(ff) ) ) ); end ); InstallMethod( IsSolvable, "rational polynomials", [ IsPolynomial ], IsSolvablePolynomial ); ############################################################################# ## #M IsSeparablePolynomial( ) ## ## Determines whether the rational polynomial is separable, e.g. whether ## it has single roots only ## InstallMethod( IsSeparablePolynomial, "for rational polynomial", [ IsUnivariateRationalFunction and IsPolynomial ], 0, function( f ) if not ForAll( CoefficientsOfUnivariatePolynomial( f ), IsRat ) then TryNextMethod( ); fi; return Degree(Gcd( f, Derivative( f ))) = 0; end ); ############################################################################# ## #M RootsAsMatrices( ) ## ## return a list of matrices with minimal polynomial . The field ## generated by the matrices is a splitting field of . The dimension of ## the matrices is equal to the dimension of the splitting field over the ## Rationals ## InstallMethod( RootsAsMatrices, "rational polynomials", [ IsUnivariateRationalFunction and IsPolynomial ], function( f ) local L, roots, erw; if not ForAll( CoefficientsOfUnivariatePolynomial( f ), IsRat ) then TryNextMethod( ); fi; if not IsSeparablePolynomial( f ) then Info(InfoWarning, 1, "polynomial is not separable, list contains every root only once"); # make polynomial separable f := f / Gcd( f, Derivative( f ) ); fi; if HasSplittingField( f ) then L := IsomorphicMatrixField( SplittingField( f )); roots := Filtered(Basis(L), mat -> Value(f,mat) = 0*One(L)); if Length( roots ) < Degree( f ) - 1 then erw := rec( H := SplittingField( f ), K := L ); roots:=RR_Roots([[],roots, List(FactorsPolynomialAlgExt(SplittingField(f),f), faktor -> -Value( faktor, 0 ) )], erw);; fi; else erw := RR_Zerfaellungskoerper(f, rec( roots := [ ], degs := [ ], coeffs := [ ], K:=FieldByMatrices([ [[ 1 ]] ]), H:=Rationals ));; L := erw.K; roots := RR_Roots( [ [ ], erw.roots[1], erw.roots[2] ], erw );; fi; Add( roots, -CoefficientsOfUnivariatePolynomial( f )[Degree( f )]*One(L) -Sum( roots ) ); return roots; end ); ############################################################################# ## #F RR_Roots( , ) ## ## The elements in the list of lists are in various forms. They are ## transfered in a matrix representation and returned as duplicate free list ## InstallGlobalFunction( RR_Roots, function( roots, erw ) local i, root, B; # Test whether there are already enough roots as matrices if Length(roots[1]) + Length(roots[2]) >= Length(roots[3]) then return roots[2]; fi; B := EquationOrderBasis( erw.K, PrimitiveElement( erw.K )); # kick out known symbolic roots for root in Concatenation(roots[1], roots[2]) do root := LinearCombination( Basis( erw.H ), Coefficients( B, root ) ); roots[3] := Difference( roots[3], [ root ] ); od; # compute the other roots if roots[1] = [ ] then Unbind(roots[3][Length(roots[3])]); fi; for root in roots[3] do Info(InfoRadiroot,3," Constructing ",Length(roots[2]),". root"); Add( roots[2], LinearCombination( B, ExtRepOfObj( root ))); od; return roots[2]; end ); ############################################################################# ## #F RR_SimplifiedPolynomial( ) ## ## returns the polynomial g(x) with g(x^n) = f(x-a) with greatest possible n ## for the polynomial ## InstallGlobalFunction( RR_SimplifiedPolynomial, function( f ) local deg, coeff, gcd, poly; deg := Degree( f ); poly := f / LeadingCoefficient( f ); poly := Value( poly, UnivariatePolynomial( Rationals, [-CoefficientsOfUnivariatePolynomial(poly)[deg] / deg, 1] ) ); coeff := CoefficientsOfUnivariatePolynomial( poly ); gcd := Gcd(Filtered( [0..Degree(f)], i -> not coeff[i+1] = 0)); if gcd = 1 then return f / LeadingCoefficient(f); fi; return UnivariatePolynomial(Rationals, List([0..deg/gcd], i -> coeff[i*gcd+1])); end ); ############################################################################# ## #F RootsOfPolynomialAsRadicals( , [ , ] ) #F RootsOfPolynomialAsRadicalsNC( , [ , ] ) ## ## For the irreducible, rational polynomial a representation of the ## roots as radicals is computed if this is possible, e. g. if the ## Galois group of is solvable. ## InstallGlobalFunction( RootsOfPolynomialAsRadicals, function( arg ) local f; f := arg[1]; if Length( arg ) >= 2 and arg[2] = "off" then if not IsSeparablePolynomial( f ) then Error( "f must be separable" ); fi; CallFuncList( RootsOfPolynomialAsRadicalsNC, arg ); else # irreducibility test if not IsIrreducible( f ) then Error( "f must be irreducible" ); fi; # solvibility test if not IsSolvable( f ) then Info( InfoRadiroot, 1, "Polynomial is not solvable." ); Info( InfoRadiroot, 3, " GaloisType is ", GaloisType( f ) ); return fail; fi; Info( InfoRadiroot, 3, " GaloisType is ", GaloisType( f ) ); Info( InfoRadiroot, 2, " Galoisgroup is ", TransitiveGroup( Degree( f ), GaloisType( f ))); return CallFuncList( RootsOfPolynomialAsRadicalsNC, arg ); fi; end ); InstallGlobalFunction( RootsOfPolynomialAsRadicalsNC, function( arg ) local erw,elements,lcm,conj,bas,file,dir,poly,B,fix,compser,f,mode,path; f := arg[1]; if 1 = Length( arg ) then mode := "dvi"; else mode := arg[2]; fi; while not mode in [ "off", "dvi", "maple", "latex" ] do Error( " has to be a valid option" ); od; # normed, simplified polynomial if mode <> "off" then # irreducibility test if not IsIrreducible( f ) then Error( "f must be irreducible" ); fi; poly := RR_SimplifiedPolynomial( f ); Info( InfoRadiroot, 2, " Normed, simplified Polynomial: ", poly ); else if LeadingCoefficient( f ) <> 1 then Error( "f must be a normed polynomial" ); fi; poly := f; fi; Info( InfoRadiroot, 2, " Construction of the splitting field" ); erw := RR_Zerfaellungskoerper( poly, rec( roots := [ ], degs := [ ], coeffs := [ ], K:=FieldByMatrices([ [[ 1 ]] ]), H:=Rationals ));; # get all roots, set a basis of the primitive element erw.roots := RR_Roots( [ [], erw.roots[1], erw.roots[2] ], erw );; Add( erw.roots, -CoefficientsOfUnivariatePolynomial(poly)[Degree(poly)]*One(erw.K) -Sum( erw.roots ) ); SetRootsAsMatrices( poly, erw.roots ); # get structure of primitive element to use RR_Produkt erw.coeffs := Filtered(Coefficients(Basis(erw.K),PrimitiveElement(erw.K)), i -> i <> 0 ); # for mode "off" it remains to compute the Galois group if mode = "off" then if not HasGaloisGroupOnRoots( poly ) then erw.unity := 1; erw.galgrp := RR_ConstructGaloisGroup( erw ); SetGaloisGroupOnRoots( poly, erw.galgrp ); fi; return; fi; # try to find root of unity, if fail start all over erw.unity := RR_RootOfUnity( erw, DegreeOverPrimeField(erw.K) ); if IsInt(erw.unity) then erw := RR_SplittField(poly, erw.unity ); # need roots in bigger field erw.roots := RR_Roots( [ [], erw.roots[1], erw.roots[2] ], erw );; Add(erw.roots, -CoefficientsOfUnivariatePolynomial(poly)[Degree(poly)] *One(erw.K) - Sum( erw.roots ) ); erw.coeffs := Filtered( Coefficients( Basis( erw.K ), PrimitiveElement( erw.K )), i -> i <> 0 ); erw.galgrp := RR_ConstructGaloisGroup( erw ); elif HasGaloisGroupOnRoots( poly ) then erw.galgrp := GaloisGroupOnRoots( poly ); else erw.galgrp := RR_ConstructGaloisGroup( erw ); SetGaloisGroupOnRoots( poly, erw.galgrp ); fi; Info( InfoRadiroot, 2, " Galoisgroup as PermGrp is ", erw.galgrp ); if not IsSolvable( erw.galgrp ) then Info( InfoRadiroot, 1, "Polynomial is not solvable." ); return fail; fi; Info(InfoRadiroot,4," h := Lcm( Order( Galoisgroup ) ) = ", Product(Unique(Factors(Order(erw.galgrp)))) ); if IsDiagonalMat( erw.unity ) then Info( InfoRadiroot, 3, " no root of unity in the splitting field"); compser := CompositionSeries( erw.galgrp ); elif Length( erw.degs ) <> Length( erw.coeffs ) then compser := CompositionSeries( erw.galgrp ); else fix := Filtered(AsList(erw.galgrp), p -> RR_Produkt(erw, erw.unity, p) = erw.unity); compser := RR_CompositionSeries( erw.galgrp, AsGroup( fix )); fi; erw.K!.cyclics := RR_CyclicElements( erw, compser );; Info( InfoRadiroot, 2, " computed cyclic elements" ); if 3 = Length( arg ) then file := arg[3]; dir := DirectoryCurrent( ); else dir := DirectoryTemporary( ); file := "Nst"; fi; if mode <> "maple" then if 3 = Length(arg) and IsExistingFile(Concatenation(file, ".tex")) then Error( file, ".tex already exists" ); fi; path := RR_TexFile( f, erw, erw.K!.cyclics, dir, Concatenation( file, ".tex" ) ); if mode = "dvi" then RR_Display( file, dir ); fi; else if 3 = Length(arg) and IsExistingFile(file) then Error( file, " already exists" ); fi; path := RR_MapleFile( f, erw, erw.K!.cyclics, Filename(dir,file)); fi; return path; end ); ############################################################################# ## #E radiroot-2.9/lib/Strings.gd0000644000175000017500000000133614207520017014351 0ustar billbill############################################################################# #### ## #W Strings.gd RADIROOT package Andreas Distler ## ## Declaration file for the functions that generate Tex-strings ## #Y 2006 ## DeclareGlobalFunction( "RR_Radikalbasis" ); DeclareGlobalFunction( "RR_BruchAlsString" ); DeclareGlobalFunction( "RR_KoeffizientAlsString" ); DeclareGlobalFunction( "RR_WurzelAlsString" ); DeclareGlobalFunction( "RR_ZahlAlsString" ); DeclareGlobalFunction( "RR_PolyAlsString" ); DeclareGlobalFunction( "RR_TexFile" ); DeclareGlobalFunction( "RR_Display" ); DeclareGlobalFunction( "RR_NstInDatei" ); ############################################################################# ## #E radiroot-2.9/lib/Strings.gi0000644000175000017500000002414314207520017014357 0ustar billbill############################################################################# #### ## #W Strings.gi RADIROOT package Andreas Distler ## ## Installation file for the functions that generate Tex-strings ## #Y 2006 ## ############################################################################# ## #F RR_Radikalbasis( , , ) ## ## Produces a basis for the matrixfield in the record from the ## generating matrices and returns a Tex-readable strings ## for the basis as well ## InstallGlobalFunction( RR_Radikalbasis, function( erw, elements, stream ) local k, basis, elm, mat, i, ll, basstr, elmstr, m, coeffs, scale; k := DegreeOverPrimeField(erw.K) / Product(erw.degs); basis := Basis(erw.K){[ 1..k ]}; if k =1 then basstr := [""]; else basstr := ["",Concatenation("\\zeta_{",String(Order(erw.unity)),"}")]; fi; for i in [ 2..k-1 ] do Add( basstr, Concatenation("\\zeta_{", String(Order(erw.unity)), "}^{", String(i),"}")); od; AppendTo( stream,"\\\\\n"); for m in [ 1..Length(elements) ] do mat := List( basis, Flat );; elm := elements[m][1]; k := elements[m][2]; coeffs := SolutionMat(mat, Flat(elm^k)); scale := RR_Potfree(Concatenation(List(coeffs, ExtRepOfObj)), k); elm := elm / scale; elements[m][1] := elm; elmstr := RR_WurzelAlsString( k, coeffs / scale^k, basstr ); AppendTo( stream, "$\\omega_", String(m)," = ", elmstr, "$,\\\\\n"); basis := Concatenation( List( [1..k], i -> elm^(i-1) * basis));; ll := [ basstr, List( basstr, str -> Concatenation( str,"\\omega_",String(m) ) ) ]; for i in [ 3..k ] do ll[i] := List( basstr, str -> Concatenation( str, Concatenation( "\\omega_", String(m), "^", String(i-1) ) ) ); od; basstr := Concatenation( ll ); od; AppendTo( stream, "\\\\\n"); return [ basis, basstr ]; end ); ############################################################################# ## #F RR_BruchAlsString( ) ## ## Creates a Tex-readable String for the rational ## InstallGlobalFunction( RR_BruchAlsString, function( bruch ) local str, num, den, sgn; if IsInt( bruch ) then str := String( AbsInt( bruch ) ); else num := String( AbsInt( NumeratorRat( bruch ) ) ); den := String( DenominatorRat( bruch ) ); str := Concatenation("\\frac{", num, "}{", den, "}" ); fi; if IsNegRat( bruch ) then str := Concatenation( " - ", str ); fi; return str; end ); ############################################################################# ## #F RR_KoeffizientAlsString( , ) ## ## Creates a Tex-readable String for the cyclotomic ; if ## is true, positive signs of rationals will be omitted; if is a ## sum, it will be included in brackets; finitely an empty string ## will be returned, if is equal to 1 ## InstallGlobalFunction( RR_KoeffizientAlsString, function( coeff, anf ) local cstr; if coeff = 1 then cstr := ""; elif coeff = -1 then cstr := "-"; else cstr := RR_ZahlAlsString( coeff ); if not IsRat( coeff ) then cstr := Concatenation( "\\left(",cstr,"\\right)" ); fi; fi; if not anf then if IsPosRat( coeff ) then cstr := Concatenation( " + ", cstr ); elif not IsRat( coeff ) then cstr := Concatenation( " + ", cstr ); fi; fi; return cstr; end ); ############################################################################# ## #F RR_WurzelAlsString( , , ) ## ## Creates a Tex-readable String for the -th root of the element ## described by and ## InstallGlobalFunction( RR_WurzelAlsString, function( k, coeffs, basstr ) local i, str, anf; str := ""; anf := true; for i in [ 1..Length(coeffs) ] do if coeffs[i] in [ -1, 1 ] and basstr[i] = "" then if not anf and coeffs[i] = 1 then str := Concatenation( str, " + ", String( coeffs[i] ) ); else str := Concatenation( str, String( coeffs[i] ) ); fi; anf := false; elif coeffs[i] <> 0 then str := Concatenation( str, RR_KoeffizientAlsString( coeffs[i], anf ), basstr[i]); anf := false; fi; od; if k <> 1 then str := Concatenation( "\\sqrt[", String(k), "]{", str, "}" ); fi; return str; end ); ############################################################################# ## #F RR_ZahlAlsString( ) ## ## Creates a Tex-readable String for the cyclotomic ## InstallGlobalFunction( RR_ZahlAlsString, function( zahl ) local bas, basstr, cond, i; if IsRat( zahl ) then return RR_BruchAlsString( zahl ); else cond := Conductor( zahl ); bas := Basis( CF( cond ) ); basstr := [ Concatenation( "\\zeta_{", String(cond), "}" ) ]; for i in Filtered( [ 2..cond ], x -> Gcd( x, cond ) = 1 ) do Add( basstr, Concatenation("\\zeta_{",String(cond),"}^{", String(i), "}")); od; return RR_WurzelAlsString( 1, Coefficients( bas, zahl ), basstr ); fi; end ); ############################################################################# ## #F RR_PolyAlsString( ) ## ## Creates a Tex-readable String for the polynomial ## InstallGlobalFunction( RR_PolyAlsString, function( poly ) local coeffs, polybasis, i; coeffs := CoefficientsOfUnivariatePolynomial( poly ); polybasis := [ "", "x" ]; for i in [ 3..Length(coeffs) ] do polybasis[i] := Concatenation( "x^{", String(i-1), "}" ); od; return RR_WurzelAlsString( 1, Reversed(coeffs), Reversed(polybasis) ); end ); ############################################################################# ## #F RR_TexFile( , , , , ) ## ## Creates a Tex-file for a radical expression of the roots of the ## polynomial . ## InstallGlobalFunction( RR_TexFile, function( poly, erw, elements, dir, file ) local i,cstr,bas,root,coeffs,B,k,offset,str,min,stream; # Create tex-Code and write to file, using stream because of linebreaks Info( InfoRadiroot, 2, " creating tex-file." ); file := Filename( dir, file ); stream := OutputTextFile( file, false ); SetPrintFormattingStatus( stream, false ); AppendTo(stream, "\\documentclass[fleqn]{article} \n", "\\setlength{\\paperwidth}{84cm} \n", "\\setlength{\\textwidth}{80cm} \n", "\\setlength{\\paperheight}{59.5cm} \n", "\\setlength{\\textheight}{57cm} \n", "\\begin{document} \n", "\\noindent\n", "An expression by radicals for the roots of the polynomial $", RR_PolyAlsString( poly ), "$ with the $n$-th root of unity $\\zeta_n$ and\n"); bas := RR_Radikalbasis( erw, elements, stream );; AppendTo( stream, "is:\n\\\\\n\\noindent\n$" ); offset := CoefficientsOfUnivariatePolynomial(poly)[Degree(poly)] / (Degree(poly) * LeadingCoefficient(poly)); k := Degree(poly) / Length(erw.roots); if k <> 1 and offset <> 0 then AppendTo( stream, RR_ZahlAlsString(-offset), "+"); fi; B := Basis( erw.K, bas[1] ); coeffs := List([1..Length(erw.roots)], i->Coefficients(B, erw.roots[i])); str := List([ 1..Length(erw.roots) ], i -> RR_WurzelAlsString(k, coeffs[i], bas[2])); min := First( [ 1..Length(erw.roots) ], i -> Length(str[i]) = Minimum( List( str, Length ))); if Length( str[min] ) = 0 then AppendTo( stream, "0" ); elif Length( str[min] ) < 1400 then AppendTo( stream, str[min] ); else AppendTo( stream, RR_NstInDatei( k, coeffs[min], bas[2] )); fi; AppendTo(stream, "$\n\\end{document}\n"); # "$\n\\\\$",String(Length(str[min])), CloseStream( stream ); return file; end ); ############################################################################# ## #F RR_Display( , ) ## ## Displays the latex-file from the directory ## InstallGlobalFunction( RR_Display, function( file, dir ) local dvi, latex; # Execute latex and open the created document latex := Filename( DirectoriesSystemPrograms( ), "latex" ); Process( dir, latex, InputTextNone( ), OutputTextNone( ), [ Concatenation( file, ".tex" ) ] ); dvi := Filename( DirectoriesSystemPrograms( ), "xdvi" ); Process( dir, dvi, InputTextNone( ), OutputTextNone( ), ["-paper","a1r",Concatenation( file, ".dvi" ) ] ); end ); ############################################################################# ## #F RR_NstInDatei( , , ) ## ## Creates a Tex-output containing a string for the -th root of the ## element described by and ## InstallGlobalFunction( RR_NstInDatei, function( k, coeffs, basstr ) local str, i, anf; str := ""; if k <> 1 then str := Concatenation( str, "(" ); fi; anf := true; repeat i := 0; while Length( coeffs ) >= i+1 and Length(RR_WurzelAlsString(1,coeffs{[1..i+1]},basstr{[1..i+1]})) < 1400 do i := i+1; od; if not anf then str := Concatenation(str, "$\\\\\n$+" ); fi; anf := false; str := Concatenation(str, RR_WurzelAlsString(1, coeffs{[1..i]}, basstr{[1..i]})); coeffs := coeffs{[i+1..Length(coeffs)]}; basstr := basstr{[i+1..Length(basstr)]}; until coeffs = [ ]; if k <> 1 then str := Concatenation( str, ")^{\\frac{1}{",String(k),"}}"); fi; return str; end ); ############################################################################# ## #E radiroot-2.9/lib/Maple.gd0000644000175000017500000000122714207520017013755 0ustar billbill############################################################################# #### ## #W Maple.gd RADIROOT package Andreas Distler ## ## Declaration file for the functions that generate maple-strings ## #Y 2006 ## DeclareGlobalFunction( "RR_M_Radikalbasis" ); DeclareGlobalFunction( "RR_M_KoeffizientAlsString" ); DeclareGlobalFunction( "RR_M_WurzelAlsString" ); DeclareGlobalFunction( "RR_M_ZahlAlsString" ); DeclareGlobalFunction( "RR_M_PolyAlsString" ); DeclareGlobalFunction( "RR_MapleFile" ); DeclareGlobalFunction( "RR_M_NstInDatei" ); ############################################################################# ## #E radiroot-2.9/lib/Maple.gi0000644000175000017500000001434714207520017013771 0ustar billbill############################################################################# #### ## #W Maple.gi RADIROOT package Andreas Distler ## ## Installation file for the functions that generate Maple expressions ## #Y 2006 ## ############################################################################# ## #F RR_M_Radikalbasis( , , ) ## ## Produces a basis for the matrixfield in the record from the ## generating matrices and returns Maple-readable strings ## for the basis as well ## InstallGlobalFunction( RR_M_Radikalbasis, function( erw, elements, file ) local k, basis, elm, mat, i, ll, basstr, elmstr, m, coeffs, scale; k := DegreeOverPrimeField(erw.K) / Product(erw.degs); basis := Basis(erw.K){[ 1..k ]}; if k = 1 then basstr := [""]; else basstr := ["",Concatenation("E(",String(Order(erw.unity)),")")]; fi; for i in [ 2..k-1 ] do Add( basstr, Concatenation( basstr[2], "^", String(i) ) ); od; for m in [ 1..Length(elements) ] do mat := List( basis, Flat );; elm := elements[m][1]; k := elements[m][2]; coeffs := SolutionMat(mat, Flat(elm^k)); scale := RR_Potfree(Concatenation(List(coeffs, ExtRepOfObj)), k); elm := elm / scale; elements[m][1] := elm; elmstr := RR_WurzelAlsString( k, coeffs / scale^k, basstr ); AppendTo( file, "w", String(m)," := ", elmstr, ";\n"); basis := Concatenation( List( [1..k], i -> elm^(i-1) * basis));; ll := [ basstr, List( basstr, str -> Concatenation( str,"*w",String(m) ) ) ]; for i in [ 3..k ] do ll[i] := List( basstr, str -> Concatenation( str, Concatenation( "*w", String(m), "^", String(i-1) ) ) ); od; basstr := Concatenation( ll ); od; AppendTo( file, "\n"); return [ basis, basstr ]; end ); ############################################################################# ## #F RR_M_KoeffizientAlsString( , ) ## ## Creates a Maple-readable String for the cyclotomic ; if ## is true, positive signs of rationals will be omitted; if is a ## sum, it will be included in brackets; finitely an empty string ## will be returned, if is equal to 1 ## InstallGlobalFunction( RR_M_KoeffizientAlsString, function( coeff, anf ) local cstr; cstr := String( coeff ); if not IsInt( coeff ) then cstr := Concatenation( "(",cstr,")" ); fi; if not anf then if IsPosInt( coeff ) then cstr := Concatenation( " + ", cstr ); elif not IsInt( coeff ) then cstr := Concatenation( " + ", cstr ); fi; fi; return cstr; end ); ############################################################################# ## #F RR_M_WurzelAlsString( , , ) ## ## Creates a Maple-readable String for the -th root of the element ## described by and ## InstallGlobalFunction( RR_M_WurzelAlsString, function( k, coeffs, basstr ) local i, str, anf; str := ""; anf := true; for i in [ 1..Length(coeffs) ] do if coeffs[i] in [ -1, 1 ] and basstr[i] = "" then if not anf and coeffs[i] = 1 then str := Concatenation( str, " + ", String( coeffs[i] ) ); else str := Concatenation( str, String( coeffs[i] ) ); fi; anf := false; elif coeffs[i] <> 0 then str := Concatenation( str, RR_M_KoeffizientAlsString( coeffs[i], anf ), basstr[i]); anf := false; fi; od; if k <> 1 then str := Concatenation( "(", str, ")^(1/", String(k),")" ); fi; return str; end ); ############################################################################# ## #F RR_MapleFile( , , , ) ## ## Creates a file for a radical expression of the roots of the polynomial ## which can be read into Maple. ## InstallGlobalFunction( RR_MapleFile, function( poly, erw, elements, file ) local i,cstr,bas,root,coeffs,B,k,offset,str,min; Info( InfoRadiroot, 2, " creating maple file" ); # Create maple code and write to file bas := RR_M_Radikalbasis( erw, elements, file );; offset := CoefficientsOfUnivariatePolynomial(poly)[Degree(poly)] / (Degree(poly) * LeadingCoefficient(poly)); k := Degree(poly) / Length(erw.roots); AppendTo( file, "a := " ); if k <> 1 and offset <> 0 then AppendTo( file, String(-offset), "+"); fi; B := Basis( erw.K, bas[1] ); coeffs := List([1..Length(erw.roots)], i->Coefficients(B, erw.roots[i])); str := List([ 1..Length(erw.roots) ], i -> RR_M_WurzelAlsString(k, coeffs[i], bas[2])); min := First( [ 1..Length(erw.roots) ], i -> Length(str[i]) = Minimum( List( str, Length ))); if Length( str[min] ) < 1400 then AppendTo( file, str[min] ); else AppendTo( file, RR_M_NstInDatei( k, coeffs[min], bas[2] )); fi; AppendTo( file, ";\n" ); return file; end ); ############################################################################# ## #F RR_M_NstInDatei( , , ) ## ## Creates a Maple-output containing a string for the -th root of the ## element described by and ## InstallGlobalFunction( RR_M_NstInDatei, function( k, coeffs, basstr ) local str, i, anf; str := ""; if k <> 1 then str := Concatenation( str, "(" ); fi; repeat i := 0; while Length( coeffs ) >= i+1 and Length(RR_M_WurzelAlsString(1,coeffs{[1..i+1]},basstr{[1..i+1]})) < 1400 do i := i+1; od; str := Concatenation(str, RR_M_WurzelAlsString(1, coeffs{[1..i]}, basstr{[1..i]})); coeffs := coeffs{[i+1..Length(coeffs)]}; basstr := basstr{[i+1..Length(basstr)]}; until coeffs = [ ]; if k <> 1 then str := Concatenation( str, ")^(1/",String(k),")"); fi; return str; end ); ############################################################################# ## #E radiroot-2.9/init.g0000644000175000017500000000103414207520017012744 0ustar billbill############################################################################# ## #W init.g RADIROOT package Andreas Distler ## ## The init file for the RADIROOT package ## #Y 2005 ## ReadPackage( "RADIROOT", "lib/Radicals.gd" ); ReadPackage( "RADIROOT", "lib/SplittField.gd" ); ReadPackage( "RADIROOT", "lib/Manipulations.gd" ); ReadPackage( "RADIROOT", "lib/Strings.gd" ); ReadPackage( "RADIROOT", "lib/Maple.gd" ); ############################################################################# ## #E radiroot-2.9/CHANGES0000644000175000017500000000516714207520017012637 0ustar billbill=========================================================================== This file describes changes in 'RadiRoot' beginning from version 2.1: =========================================================================== ========================== Changes from 2.8 -> 2.9: (01/03/2022) ========================== - clarify license is GPL 2 *or later* ========================== Changes from 2.7 -> 2.8: (23/04/2018) ========================== - add GAP Team as package maintainer - move package homepage to GitHub - use TestDirectory to run tests, fix whitespace in .tst files - require GAP >= 4.7 and Alnuth >= 3.0 ========================== Changes from 2.6 -> 2.7: (09/04/2014) ========================== - fixed bug in output regarding the powers of the root of unity reported by Daniel Blazewicz on 31/03/2014 - coefficients in representations of cyclics elements in the output are now reduced (as follow-up to a suggestion by Daniel Blazewicz) ========================== Changes from 2.5 -> 2.6: (04/11/2011) ========================== - replacing the archive that mistakenly became public as 2.5 ========================== Changes from 2.4 -> 2.5: (28/10/2011) ========================== - adjusted package to GAP 4.5 and new location of homepage - fixed bug reported by Max Horn, regarding method selection, added TryNextMethod in various methods which are for rational polynomials, to delegate other polynomials to appropriate methods ========================== Changes from 2.3 -> 2.4: (22/01/2008) ========================== - Corrected documentation, reported by David Sevilla - Bug for linear polynomials reported by David Sevilla fixed in 'RR_RootOfUnity' (introduced with the fix in 2.3) - Polynomials for which the cyclotomic polynomial would splitt in non-linear factors over the splitting field the subsequent function calls to the main functions would give wrong results. FIXED - Introduced method for 'IsomorphismMatrixField' for the Rationals - Corrected output for polynomial 'x' ========================== Changes from 2.2 -> 2.3: (15/06/2007) ========================== - Testfile with examples from documentation added - Bug in 'RR_RootOfUnity' reported by David Sevilla fixed by use of 'IsomorphismMatrixField' instead of 'EquationOrderBasis' ========================== Changes from 2.1 -> 2.2: (09/05/2007) ========================== - Added this file to document the changes between versions. - Introduced a copyright. - Improvements in documentation due to the final report of the referee. - New status of the package is 'accepted'. :) radiroot-2.9/doc/0000755000175000017500000000000014211721314012376 5ustar billbillradiroot-2.9/doc/intro.tex0000644000175000017500000000677614207520027014276 0ustar billbill%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %W intro.tex Radiroot documentation Andreas Distler %% %Y 2005 %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Chapter{Introduction} This package provides functionality to deal with one of the fundamental problems in algebra. The roots of a rational polynomial shall be expressed by radicals. This means one is only allowed to use the four basic operations $(+, -, \cdot \,,\div)$ and to extract roots. For example, a radical expression for the roots of the polynomial $x^4 - x^3 - x^2 + x + 1$ is $$ \matrix{ \frac{1}{4} + \frac{1}{4}\sqrt{-3} + \frac{1}{2}\sqrt{\frac{7}{2} + \frac{1}{2}\sqrt{-3}}. } $$ There are formulas to solve the general equation $x^n+ a_{n-1}x^{n-1}+ \dots + a_1x+a_0 = 0$ up to degree 4. For higher degrees such formulae do not exist (\cite{Abel26}). It was \'Evariste Galois (1811 -- 1832) who discovered that there exists a radical expression for the roots if and only if the Galois group of the polynomial - initially a permutation group on the roots - is solvable \cite{Galois97}. But the task itself was impractical in his days. This package is the first public tool which provides a practical method for solving a polynomial algebraically. The implementation is based on Galois' ideas and the algorithm is described in \cite{Distler05}. The package can provide the result in various forms. As a default an expression is given in a similar way as in the example above. Alternatively, a file containing the roots might be created which is readable by Maple \cite{Maple10}. In {\GAP} itself some information deduced during the computation is available. The user should be aware that radical expressions can get very complicated even for polynomials of small degree. Especially because the algorithm will find an irreducible radical expression. That means one gets a root of the given polynomial for every choice of a value of the radicals in the expression. Moreover it is not the aim of this package to give a simplest expression, in any sense. In Chapter 2 the methods provided by this package are listed and explained. Chapter 3 gives details about the info class of this package. See Section "ref:Info Functions" in the {\GAP} reference manual for general information about info classes. While the installation of the package follows standard {\GAP} rules the Chapter 4 contains information about external programs required by {\Radiroot} in its default setup. % In its default use the package creates a LaTex file for the radical %expression and displays the according dvi-file. Therefore you need a Latex %compiler and the dvi viewer xdvi, to use the main functionality. This package uses the interface in the package \Alnuth, to factorise polynomials over algebraic number fields. This functionality must be available to use the functions in {\Radiroot}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Section{License} This package 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. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %E radiroot-2.9/doc/manual.bib0000644000175000017500000000343214207520027014336 0ustar billbill@mastersthesis{Distler05, author = {Andreas Distler}, title = {Ein {A}lgorithmus zum {L}\accent127osen einer {P}olynomgleichung durch {R}adikale}, school = {TU Braunschweig}, year = 2005, type = {Diplomarbeit}, note = {\URL{http://www.icm.tu-bs.de/ag_algebra/software/distler/Diplom.pdf}} } @article{Kant, author = {M. Daberkow and C. Fieker and J. Kl\accent127uners and M. Pohst and K. Roegner and K. Wildanger}, title = {Kant {V4}}, journal = {J. Symb. Comput.}, volume = 24, year = {1997}, pages = {267 -- 283}} @ARTICLE{Abel26, AUTHOR = {Abel, Niels Henrik}, TITLE = {{B}eweis der {U}nm\accent127oglichkeit, algebraische {G}leichungen von h\accent127oheren {G}raden als dem vierten allgemein aufzul\accent127osen}, JOURNAL = {J. f\accent127ur die reine und angewandte Math. (Crelle's Journal)}, YEAR = 1826, VOLUME = 1, PAGES = {65--84} } @BOOK{Galois97, AUTHOR = {Galois, \'Evariste}, TITLE = {Oeuvres Math\'ematiques d'\'Evariste Galois}, PUBLISHER = {Gauthier-Villars}, YEAR = 1897, ADDRESS = {Paris} } @BOOK{Maple10, author = {Michael B.~Monagan and Keith O.~Geddes and K.~Michael Heal and George Labahn and Stefan M.~Vorkoetter and James McCarron and Paul DeMarco}, title = {Maple~10 Programming Guide}, publisher = {Maplesoft}, year = {2005}, volume = {}, series = {}, address = {Waterloo ON, Canada}, edition = {}, month = {}, note = {}, key = {}, annote = {In acknowledging any {Maple} work, a statement similar to the following should be used. (Changes with respect to the exact use of {Maple} are expected.) ``The computations in this paper were performed by using Maple${}^\mathrm{TM}$."}, } radiroot-2.9/doc/info.tex0000644000175000017500000000245014207520027014057 0ustar billbill%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %W info.tex Radiroot documentation Andreas Distler %% %Y 2006 %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Chapter{The Info Class of the Package} The `info' mechanism in {\GAP} allows functions to print information during the computation (see Section "ref:Info Functions" in the {\GAP} reference manual for general information). \> `InfoRadiroot' V is the info class of this package. \> SetInfoLevel( InfoRadiroot, ) sets the info level for `InfoRadiroot' to , where has to be an integer in the range 0-4. The default value for `InfoRadiroot' is 1. Information why a function returns `fail' will be given with this setting. \beginexample gap> InfoLevel(InfoRadiroot); 1 gap> RootsOfPolynomialAsRadicals(x^5-4*x+2); #I Polynomial is not solvable. fail \endexample Setting the info level to a higher value will cause messages to show up during single steps of the computation. On level 2 one gets a rough overview. Those who want to go into the details of the algorithm described in \cite{Distler05} and of the implementation itself will find the information on level 3-4 helpful. To use the package in silent mode the info level can be given the value 0. radiroot-2.9/doc/manual.tex0000644000175000017500000000557714207520027014416 0ustar billbill%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %W manual.tex GAP documentation Andreas Distler %% %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %F gapmacro . . . . . . . . . . . . . . . . . read the GAP macro package %% \input ../../../doc/gapmacro \Package{Radiroot} %This defines {\Radiroot} . . see "ext:The Main File" \Package{Alnuth} %This defines {\Alnuth} . . see "ext:The Main File" % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %F BeginningOfBook . . . . . . . . . . . . . . . . . . . start the book %% \BeginningOfBook{radiroot} % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %F UseReferences . . . . . . . . . . . . . . . . . . specify references %% \UseGapDocReferences{../../../doc/ref} \UseGapDocReferences{../../gapdoc/doc} %Refs to a GAPDoc-produced manual % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %F TitlePage . . . . . . . . . . . . . . . . . . . . . . nice title page %% \TitlePage{ \centerline{\titlefont Radiroot}\bigskip \centerline{\titlefont ---}\medskip \centerline{\subtitlefont Roots of a Polynomial by Radicals}\bigskip\bigskip \centerline{\subtitlefont A GAP Package}\bigskip\bigskip \centerline{\secfont Version 2.9}\vfill \centerline{\secfont by}\vfill \centerline{\secfont Andreas Distler}\bigskip \centerline{\tt a.distler@tu-bs.de}\vfill \centerline{\secfont{\Month} \Year} } % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %F TableOfContents . . . . . . . . . . . . generate a table of contents %% \OneColumnTableOfContents %since it's very short %\TableOfContents %use instead if ToC is longer than a column % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %F FrontMatter %% \FrontMatter %The following is needed if there are %\cite commands and a `manual.bib' file \immediate\write\citeout{\bs bibdata{./manual,../../../doc/manual}} % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %F Chapters %% \Chapters \Input{intro} %generally there are several chapters \Input{radiroot} \Input{info} \Input{install} %each chapter *must* go in a separate file % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %F Appendices %% \Appendices %\Input{hints} \Bibliography \Index %to generate a proper index `manual.mst' % %must be present % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %F EndOfBook . . . . . . . . . . . . . . . . . . . . . . . . . that's it %% \EndOfBook % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %E manual.tex . . . . . . . . . . . . . . . . . . . . . . . . ends here radiroot-2.9/doc/manual.lab0000644000175000017500000000224414207520027014340 0ustar billbill\makelabel{radiroot:Introduction}{1} \makelabel{radiroot:License}{1.1} \makelabel{radiroot:Functionality of the Package}{2} \makelabel{radiroot:Methods for Rational Polynomials}{2.1} \makelabel{radiroot:IsSeparablePolynomial}{2.1.1} \makelabel{radiroot:IsSolvable}{2.1.2} \makelabel{radiroot:IsSolvablePolynomial}{2.1.2} \makelabel{radiroot:SplittingField}{2.1.3} \makelabel{radiroot:IsomorphicMatrixField}{2.1.3} \makelabel{radiroot:RootsAsMatrices}{2.1.3} \makelabel{radiroot:IsomorphismMatrixField}{2.1.3} \makelabel{radiroot:GaloisGroupOnRoots}{2.1.4} \makelabel{radiroot:Solving a Polynomial by Radicals}{2.2} \makelabel{radiroot:RootsOfPolynomialAsRadicals}{2.2.1} \makelabel{radiroot:The Info Class of the Package}{3} \makelabel{radiroot:InfoRadiroot}{3} \makelabel{radiroot:SetInfoLevel}{3} \makelabel{radiroot:Installation}{4} \makelabel{radiroot:Getting and Installing this Package}{4.1} \makelabel{radiroot:Loading and Testing the Package}{4.2} \makelabel{radiroot:Additional Requirements}{4.3} \makelabel{radiroot:Bibliography}{} \setcitlab {Abel26}{Abe26} \setcitlab {Distler05}{Dis05} \setcitlab {Galois97}{Gal97} \setcitlab {Maple10}{MGH{+}05} \makelabel{radiroot:Index}{} radiroot-2.9/doc/manual.six0000644000175000017500000000117514207520027014407 0ustar billbillC intro.tex 1. Introduction S 1.1. License C radiroot.tex 2. Functionality of the Package S 2.1. Methods for Rational Polynomials F 2.1. IsSeparablePolynomial F 2.1. IsSolvable F 2.1. IsSolvablePolynomial F 2.1. SplittingField F 2.1. IsomorphicMatrixField F 2.1. RootsAsMatrices F 2.1. IsomorphismMatrixField F 2.1. GaloisGroupOnRoots S 2.2. Solving a Polynomial by Radicals F 2.2. RootsOfPolynomialAsRadicals C info.tex 3. The Info Class of the Package F 3.0. InfoRadiroot F 3.0. SetInfoLevel C install.tex 4. Installation S 4.1. Getting and Installing this Package S 4.2. Loading and Testing the Package S 4.3. Additional Requirements radiroot-2.9/doc/manual.dvi0000644000175000017500000005425014207520027014370 0ustar billbill; TeX output 2022.03.01:2337pڍ\Ne9V$ phvb7tNRadirGootD|G_,Oe9V phvb7tORootsOofaP3?ol@ynomialbyRadicals,xAOGAPPfoackag31e&ōǽ,Pe9V phvb7tPVYersion&2.9XˍfbuyYAndreas&Distler޾V zptmcm7t(+A? zptmcm7mA;Dƛ zptmcm7yDA;DA;D)andtoe٠xtractroots.Forexample,aradicalexpressionfortherootsofthepolynomialLKj ptmri7tLx^?޾V zptmcm7t4@D8Lx^3DLx^2+Lx@+1isԍd`1ԟЉf`4+`l1lЉf`4F$Dps$c ܍3q+`l1lЉf`2FKGCq zptmcm7vGqFKc-4 n`33733Љf`2F+`l1lЉf`2$Dps$c ܍3?hasasolvableGaloisgroupandfalseotherwise.Itsignalsanerroriftheree٠xistsanirreduciblefgactorwithdegreegreaterthan15.3S3̟^ISplittingField(?Lf)36IIsomorphicMatrixField(?LF)36IRootsAsMatrices(?Lf)36IIsomorphismMatrixField(?LF)4VF٠oroapnormed,rationalpolynomialLfu,SplittingField(Lf)oreturnsthesmallestalgebraice٠xtension eldLLoftherationals%containingall&rootsofLfu.The eldisconstructedwithFieldByPolynomial(seeCreationofnumber eldsinQAlnguth).\;Theprimitiv٠eelement\:ofLLcisdenotedbya.A\1matrix eldLKisomorphictoLLis\:knownafterthecomputationandcanbeaccessedusingIsomorphicMatrixField(LL.Thematrices,oneforeachdistinctrootofLfu,inthelistproduced GbyRootsOfMatrices(Lfu)liein HLK.IsomorphismMatrixField(?LLG) #returnsanisomorphismofLLontoLK.9gap>?x:=Indeterminate(Rationals,"x");;9gap>?f:=UnivariatePolynomial(Rationals,[1,3,4,1]);9x^3+4*x^2+3*x+19gap>?L:=SplittingField(f);99gap>?y:=Indeterminate(L,"y");;9gap>?FactorsPolynomialAlgExt(L,f);9[?y+(-3/94*a^4-24/47*a^3-253/94*a^2-535/94*a-168/47),y+(-3/94*a^4-24/47*a^3-253/94*a^2-441/94*a+20/47),y+(3/47*a^4+48/47*a^3+253/47*a^2+488/47*a+336/47)?]9gap>?IsomorphicMatrixField(L);99gap>?Display(RootsAsMatrices(f)[1]);9[?[0,1,0,0,0,0],[0,0,1,0,0,0?],[ -1,-3,-4,0,0,0?],[0,0,0,0,1,0?],[0,0,0,0,0,1?],[0,0,0, -1,-3,-4?]]荟LSection2.SolvingaP37olynomialbyRadicalsO5p9gap>?MinimalPolynomial(Rationals,RootsAsMatrices(f)[1]); 9x^3+4*x^2+3*x+19gap>?iso:=IsomorphismMatrixField(L);9MappingByFunction(?,?,?function(x)...end,function(mat)...end)9gap>?PreImages(iso,RootsAsMatrices(f));9[?-3/47*a^4-48/47*a^3-253/47*a^2-488/47*a-336/47,3/94*a^4+24/47*a^3+253/94*a^2+441/94*a-20/47,3/94*a^4+24/47*a^3+253/94*a^2+535/94*a+168/47?]T37o{fgactorisezapolynomialo٠verits{splitting eldonehastouseFactorsPolynomialAlgExt(seeQAlnguth)insteadofFactors.3S4̟^IGaloisGroupOnRoots(?Lf)N8calculatestheGaloisgroupLGoftherationalpolynomialLfu,whichhastobeseparable,asapermutationgroupwithrespecttotheorderingoftherootsofLfgiv٠enasmatricesbyRootsAsMatrices.9gap>?GaloisGroupOnRoots(f);9Group([?(2,3),(1,2)])N8IftyouonlywgantttogettheGaloisgroupabstractlyY,andifLfoisirreducibleofde٠greeatmost15,itisoftenbettertousethefunctionGaloisType(seeChapter66.11intheQGAPreferencemanual).N8P2.2Solving&aPzolynomialbuyRadicals3S1̟^IRootsOfPolynomialAsRadicals(?Lf[,Lmode[,L le]])N8computesoJaoKsolutionbyradicalsfortheirreducible,rationalpolynomialLf uptode٠gree15iftheGaloisgroupofLfisksolvable,andkreturnsfailotherwise.IfitsucceedsandLmodeisnotoff,thefunctionreturnsthepathtoa lecontainingthedescriptionoftherootsofLfandgeneratorsofc٠yclicradicalextensionstoproduceitssplitting eld.N8The[userZhassev٠eraloptionstospecifywhathappenswiththeresultsofthecomputation.ThereforetheoptionalsecondargumentLmode,astring,canbesettooneofthefollowingvalues:9"dvi"Pro٠videdlatexandthedviviewerxdviareavailable,thisoptionwilldisplaytheirreducibleradicale٠xpressionfortherootsandc٠yclicextensiongeneratorsinanewwindowY.Thepackageusesthisoptionasthedefgault.9"latex"A,LaTLeX le?RootsOfPolynomialAsRadicalsNC([,[,]])9does?essentiallythesameas`RootsOfPolynomialAsRadicals'except 9that?itrunsnotestontheinputbeforestartingtheactual9computation.?Thereforeitcanbeusedforpolynomialswitharbitrary9degree,?butitmayrunforaverylongtimeuntila9non-solvable?polynomialisrecognizedassuch.9Detailed?examplesforthesetwofunctionscanbefoundinthenextsection.9%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9\Section{Examples}9The?function`RootsOfPolynomialAsRadicals'doesnotgenerateoutput9inside?\GAP.Dependingonthechosenmode,variouskinds9of?filescanbecreated.Asanexamplethepolynomialfromthe9introduction?willbeconsidered.9\beginexample9gap>?g:=UnivariatePolynomial(Rationals,[1,1,-1,-1,1]);9x^4-x^3-x^2+x+19gap>?RootsOfPolynomialAsRadicals(g);9"/tmp/tmp.8zkw5B/Nst.tex"N8willcauseadvi letoappearinanewwindow:N8Ane٠xpressionbyradicalsfortherootsofthepolynomialLx^4@D8Lx^3DLx^2+Lx@+1withtheLn-throotofunityATnandA!1=$Dp $c ܍3,WA!2=]Gq ]c"̟ 덍`33733Љf`2FD`l1lЉf`2A!1/,pA!3=]Gq ]c"̟ 덍`33733Љf`2F+`l1lЉf`2A!1/,ɍis:`33133Љf`4FD`l1lЉf`4A!18+`l1lЉf`2A!2Ifvonevwgantstowgorkwiththeroots,itmightbehelpfultouseMaple[MGH+05],inwhichane٠xpressionlikge2^(1B? zptmcm7mB=2)Eisvalid.9gap>?RootsOfPolynomialAsRadicals(g,"maple");9"/tmp/tmp.k9aTCz/Nst"N8willcreatea lewiththefollowingcontent:9w1?:=(-3)^(1/2);9w2?:=((7/2)+(-1/2)*w1)^(1/2);9w3?:=((7/2)+(1/2)*w1)^(1/2);9a?:=(1/4)+(1/4)*w1+(1/2)*w3;N8Afterthosecomputationssev٠eralattributesareknownforthepolynomialinQGAP.3LSection2.SolvingaP37olynomialbyRadicalsO7p9gap>?RootsOfPolynomialAsRadicalsNC(g,"off"); 9gap>?time;909gap>?SplittingField(g);99gap>?time;909gap>?GaloisGroupOnRoots(g);9Group([?(2,4),(1,2)(3,4)])9gap>?time;90=p֭M3q NThe >InfGoClass,ӳof the PacGkag\%e<|TheinfomechanisminQGAPallowsfunctionstoprintinformationduringthecomputation(seeSection7.4inthe QGAPreferencemanualforgeneralinformation).3S1̟^IInfoRadirootVN8istheinfoclassofthispackage.3S2̟^ISetInfoLevel(?InfoRadiroot,Lle٠velB)setstheinfolev٠elforInfoRadiroottoLlevel,whereLlevelhastobeanintegerintherange0-4.N8ThedefgaultvalueforInfoRadirootis1.Informationwh7yafunctionreturnsfailwillbegiv٠enwiththissetting.9gap>?InfoLevel(InfoRadiroot); 919gap>?RootsOfPolynomialAsRadicals(x^5-4*x+2);9#I Polynomial?isnotsolvable.9failN8Setting.theinfo.lev٠eltoahighervalue.willcausemessagestoshow.upduringsinglestepsofthecomputation.Onlev٠el2onegetsaroughoverviewY.Thosewhowganttogointothedetailsofthealgorithmdescribedin[Dis05]andoftheimplementationitselfwill ndtheinformationonlev٠el3-4helpful.T37ousethepackageinsilentmodetheinfolev٠elcanbegiv٠enthevalue0. ?pԼ\M4_NInstallation8N8P4.1Getting&andInstallingthisP.acuka޹g!FeN8Thispackageisavailableat9https://gap-packages.github.io/radiroot/informofagzippedtar-archiv٠e.ForinstallationinstructionsseeChapter76.1intheQGAPreferencemanual.Normally youwillunpackthearchiv٠einthepkgdirectoryofyourQGAPversionbytyping:#9bash>?tarxfzradiroot-2.9.tar.gz)#forthegzippedtar-archiveP4.2Loading&andT8SestingtheP.acuka޹g!FeT37ousetheQRadirootpackageyouhav٠etorequestitexplicitlyY.Thisisdonebycalling9gap>?LoadPackage("radiroot"); 9-----------------------------------------------------------------------------9Loading RadiRoot?2.9(RootsofaPolynomialasRadicals)9by?AndreasDistler(a.distler@tu-bs.de).9Homepage:?https://gap-packages.github.io/radiroot/9-----------------------------------------------------------------------------9trueN8TheLoadPackagecommandisdescribedinSection76.2.1intheQGAPreferencemanual.N8If youwgant toloadtheQRadirootpackagebydefgault,youcanputtheLoadPackagecommandintoyourgaprc le(seeSection3.2.2intheQGAPreferencemanual).OnceMztheMypackageisloaded,itispossibletocheckthecorrectinstallationbyrunningthetestsuiteofthepackagewiththecommand#9gap>?ReadPackage("radiroot","tst/testall.g");P4.3Ad޹ditional&RequirementsN8T37ouseQRadirootthepackageQAlnguthinv٠ersion3.0orhigherhastobeloadedwithitsinterfacefullyfunctional.Inthestandardmodeadvi leiscreatedtodisplaytherootsofapolynomial.Asdefgaultthepackageusesthecommandlatexfsearchedforinyoursystemprogramstocreatethedvi legandthecommandxdvitostartthedviviewers8.IfyoucankPnotusethissettingskQyouwillhav٠etochangethefunctionRREff&fǫDisplayinthe leStrings.giinthesubdirectorylibofthepackage. E1pC NBibliographGy޾V zptmcm7t;3{ ptmr7t3u7msam7 tar xfz radiroot-2.9.tar.gz # for the gzipped tar-archive \endexample %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Section{Loading and Testing the Package} To use the {\Radiroot} package you have to request it explicitly. This is done by calling \beginexample gap> LoadPackage("radiroot"); ----------------------------------------------------------------------------- Loading RadiRoot 2.9 (Roots of a Polynomial as Radicals) by Andreas Distler (a.distler@tu-bs.de). Homepage: https://gap-packages.github.io/radiroot/ ----------------------------------------------------------------------------- true \endexample The `LoadPackage' command is described in Section~"ref:LoadPackage" in the {\GAP} reference manual. If you want to load the {\Radiroot} package by default, you can put the `LoadPackage' command into your `gaprc' file (see Section~"ref:The gaprc file" in the {\GAP} reference manual). Once the package is loaded, it is possible to check the correct installation by running the test suite of the package with the command \beginexample gap> ReadPackage( "radiroot", "tst/testall.g" ); \endexample %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Section{Additional Requirements} To use {\Radiroot} the package {\Alnuth} in version 3.0 or higher has to be loaded with its interface fully functional. In the standard mode a dvi file is created to display the roots of a polynomial. As default the package uses the command `latex' searched for in your system programs to create the dvi file and the command `xdvi' to start the dvi viewer. If you can not use this settings you will have to change the function `RR_Display' in the file `Strings.gi' in the subdirectory `lib' of the package. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %E radiroot-2.9/doc/manual.pdf0000644000175000017500000045165614207520027014372 0ustar billbill%PDF-1.5 % 3 0 obj << /Length 311 /Filter /FlateDecode >> stream xmKO0 96Ǎ!҄*.!k7(=NQ|^A{ sbmϞGe3M'3D MRϹ"D&dTeD"\hi_b*a-|>4\٧K㼸3aMץna٤.>Wyݯf_+A)5Oa:(=Yk^"!uaU6UCܥa>D_dd;]vC/՗/w FW!- ]}} endstream endobj 26 0 obj << /Length 654 /Filter /FlateDecode >> stream xݗn@~Y‚霹ϲ*U*U) bJ5߾cf5b1\~y &^ 14Ś+`=UdeSO  E +BeeaKj渥!`#tIHcN%fb@j)s1azkƏsGM1ﳗ80}M0-[J@D-ȫ>;FJ0g#I~KKJlG^Ժ/Y0iwؤ endstream endobj 53 0 obj << /Length 3141 /Filter /FlateDecode >> stream xڭ]6}NĪHt{to4LlkMeGD$v !^}:VUj{XЏy懌W JJ3 WT]Wg+ W$lJ/pV p{,G;\pk&OE ,DjD;"rW]ve~">EдwM#tkW7uݵkxz렖 c~"\U}* @x1-iӄ~87yM=Ib28iEC/ p.@IˁUlo7 ow{"}qo-{!|bk df3DDІ "( N\ @]Rp1Bxa-s˖,=T" KO+~'5C-ǯdݸ\ X@;XxĖ s⮤+rsaǰq'I}2\ +%j`=a#~pىN>4KnϾՔR<[ W 2ox" +:㕶`V<~Ke"T߂U|īc-]KC& ߡ񑔣qYɥ%qA0G#_P/K`$jhH-(c:\}$,H"@jA'a;ΟI.KYֹyYVKq|˴E. 4O:I~WP?SgɅ:O'L&3Fhbc&Sg2[ /]U%5(ֱq$XU2& XɕI{33qIѣzÔ4HLjxq0mXv׻.X/x~3RÅǝߐ>\gL \(# 2<f`̽oi$mI˺hGͲ1z\ł{r?eEǖ+;>9D╢ >5W4!/h+p+ >Sβq4kmf pڌ ѫ`|s͔n1ݦ9*AnWsdp{u~ǍmFK#C=%хv|goqsJq/A(P]Nڼ< y)Ng" #ҘNPLyYNn;mTroZJuMl> i{Avw֢Ӆ z+.@Oyw3޺M28M RI" ɳ{w)d?AxkVrp # J4\vo]N08z@׼_0fی 5% e{)y'/"cFgʇ+PB ej4?O+6CHa^-tnՖK4rr 8|Z~_h&){L|A| v8tﴝL#CANkɀVk|ƍdd5[|wJfMvh93q2{/cu%~ x*(7o/MmF -طP9338_d:#4krۅzƐu _8xm}mFm)Y%:^KO1%;(_`ibSIG`^cݗBw4jKD[+HO~Y@t|Xt*hQSoփ1= =ў=r_|ok(]S67Ɠ` &B3uFY4>c/SbI(߫b)U{3fN†')U*pς+uqpRAY*,#9`-DnrFEG4ޛ\biqBT+cwcɣW|IiM1vKRWTzUa71=w9}3_Ɏo}|ܣ$ԃR߁2+^6D 9"Ϧ"wG!&jq&!ϘӅyH^! bڗiKu)d>9e‹(C;<~Hi==U΄LM6åS}"` =]b}j;K,LŶdJC,,ɖtyJ~UWq<4}3Gkh0AuXmfR/Rqߤ'2& cˡu  P`3P;$zvןm w9D [pJ`,nTTo$qԌYY _^J1> FsFf$B魵l'Yp1Y 0DN錘hL=_8tm1ӏ昮j%JLDp' O"|`wmN=T&x?B@90a9SHئ!Ζ`/pq K eT,3uOuV,i2H͉d1;$f(GXHV)Hll$vhƽlr]b ^ hН3-[O}/GKȂ&&6D{`iJS=kn=LS $o㈲a 0fʼ &[)5#9s"u|fOr/{/A媶Kg{ j0'~Ѥ 1U1޾`N@7?kDhftk|b^߮|k~Ow|uHl# uS n7VgT?H endstream endobj 72 0 obj << /Length 1843 /Filter /FlateDecode >> stream xڭXIs6Whrb NL֝4'7)J„"5$ 7Z"[@R$Hr&ˉHh"xrL  (ΐ%i"u`>ED|HV.gsYgfg OtFK2#x7src2Q,4b`2K0WZ׳94Mɶ*YduZ̿b5rO#nF4yr{]Y5=(hʲ h1",n I%Yes)(;۸@KX(1Gd6OuZGj4Z|Hë|F(7:N&V(V DSi!`2b EjBgqD $Qـmx}{M{e$Iˀq[`CB 4FWY:AhDæڅGℶDz=춝!+1[9&QDDKNsrs*aa` S~BK3d[_F6)y,)oǃ ·:0w%>^mmV{?\l;c L$ך.Jǽ{{)T.amۿLna\xi/b9OJ tP d| .􂽸 5z;(0 Vo? (CÓٖw-#> stream xڭZmo8_a'Y@{ n 0m*K$7!ԛ$E+f w޼O"%iĢfEpxq->/?uWŊ`>?UŷE,XV\8w2ײh/n_QEh* cb8oƭX &2gW \Sjс}}~]U7nO9HB /2|]׏Էe%o+7|^վj] *AqGYנwagYl}#5N1~GNawlmԄ{ܣ_~n7GFYbFpsrA8"؃ٯ@=iF]]7yY5g\_7aZ~ Wa#a'LW Ȕ% -KML0fbAO% 3e$!ЎI9Ҿ58q1|XwU $>1R{uAG-2Z\j":x+q9YiYևVy J”;yodkx[l}ȢMu(MLHBI& UPLqNJCI s',>S. c'ZHd`I,q;4"N 8GAS8a; c._ þ罕Ul}7nZ5C'1@9zNx4a4^o"QAdr}_(DD)D$ma_XW).5Ј,xX E4fy ` 16OBٜ&lSog]qjWlHPwgc%$44cJv Fcueqĩe0Un˜f\PUt".ۮrЎץNz5p>ZӼiTvX P~a}CPa$:O0u䫑lIp ѽZ(<PX+ϙEH4g%;YpARw0ޑ?%.Qըr\pSSI TkN!YW ƍER7n,/X<%6 fHibfBͨh82&J^>_yi(M2o~][>B0s%᤼>)5Lo|CnM.۪8dgԳ3T Nc*Qh_/ O&W (L1q`5XCSC)áIFaڟ"}JUq&l *ȀiE~9ϥv2M|-T!!}\( ҾS#^+òʼn٦I2FuM: OSw:b&O46Sn7^F3=?d*FǛo!3yу&(z.ƵNYQoGit AUQS\>Ea%!q"/q8Rx(۞΢s^=kH1G UJT*dBʷNZʭ}ځ I-e{x|q֫oQۋT|ўӉd;+63':l {zؿ%zz9/Yݡ̻+dC[3G0M,r_a©*ijK`b]slPʜ'%9GVs}+2'0m_`2Ͷ߷rWo8ӪiJy D9Oyß _ |˛Lr@'j4 )K+mb +MnV> )qC-OnA9btnbw02ΙA2UtV)4ʄ\wXleĐ.`W`tKbo4M o@cJo6w2_KԺ33˽r?-RvPX)wL+11TG_~P R}3@gpC63f6E$PLτˠ2頕3ɌyD64)#ζȷ`#`Qq0R;)F!CI< vVa^[72U=cq;7))$dbB>ԳiF&`з%;>|~\f53p z'⋭$atoP){Ea o,Q#nj#xU"%HJ r=Eˆ/_Ws^V,ً7TLdЈ:v!Hإ"\(%g3'!ёdf[* B蓇C` "ڗDOn8\z!'.$_TpΛ%j g}3.%.) ]9uOD> stream xڽYms۸_LvmAd'w3wMs''"$qL:XJ:]  [yD!.w],VoO.J4bz # uݜg2%%ޮĦ,ӀO]9oE~CB_ە7TNQthvjg#7{m̫k-Nk }?ѩQ% k#XfYƥlMW.hE2/k)I;c>p8&F oЍZveD+`2SoF9IӚ>R2;=`FU l釪j,WŗZ碸j>,G?؟(s*ӱE^O (?J6Z@6,[0_|=k(G|#5)Z$juWB۲gl#oXoo墪\l$-m'vâ3Ѳh٩kL߁ @DyBۼÉL* v\C&tsruwX/rTŽl<Sy,fM7_~&f }49"5h/05_T]"Lֺ;sg~*V#N`fGCNs)KYCHZ3RzAn M alUYz/НWj>zT;W(fL;5%颮"uuۼ(&T=Hŝo2/'ݶ̼_ey>,C^ 7^߹L>g|wN]#S,Zyuٮ7Cw/MKZ{ hH(g^@ 4zqfo+l}8/GL Vb8+|vF(>G Zw_PPР,Q"! #1S,C-D٨R)T ; = ܣ 'Z☛v|;j6o4  yth I 3Mf̗T5~?ݎH3 aP4 Ń~$g {,dP&)n+$f#tk|`Յ8'FhN~>DA{dBO@y'!D4aIm{ѵG!^zϓ7t5gtQGIeN|BhJ~^#T7xc} G))~s!?J<$1X Lj|>'$">U.F0=5Z&Ic,rN(6NEI+u;RH (Alu^q>NH$}?7SWqR5NHӾx9͞ۇ<b(yMj&E06TMS<}QѾ|ÆpEj҄4̛.P^3a߃'c532(/rQE%s vVH/ ʆ!x9i39o c8LAA?UpUߡ.C9.j :_ZVꡕ,6S}̂WvY8~W;< ^fFpfIeO0~i6Еpbv'0hJuؾ ׽c !W#Jl?r?ԦuPG FWFM_wTp8^Eg9 xVD|uD.o&÷4~ҨS`7Ƈ=<'yUl_Ŗ=j3fYଷ;zRgz*56ʾ;v3U jK?E h:U?uDAQR<ؗcOO;R &QQˊ endstream endobj 97 0 obj << /Length 323 /Filter /FlateDecode >> stream xڵMO0 NԆ4m!$@l6m5-fj=Mݍ ';cs C NB4GEQ؏PFv)#`WZeYY1:z/v3㪶7c 4B" |2 0I"RXveR릞狋m}{&V8`:Iᄱ_"AɦiO4Be)S WV\o(橏{|-9Lx?KθҲU0/oŢ} Hx5ܦsT8XjJaï endstream endobj 105 0 obj << /Length 1191 /Filter /FlateDecode >> stream xڭV[6~_aƪP($%"ۃe&GLX?^n~=K\ (i9iE (K0@J9J, e,C#4p0oI*628A)A=4Tf]pXF""8"'A&ƈrB@0F4!g3,,Py-aG 8 d};0P8cO,6GDXn_,c Q[ܗS;+ nƶj€,8~rNh /dy>" q.&4ACAHu!wre_v*p\(_좖GUC ){ZE! YPq+(@6-8 ӎrE]ִߍIjՒ]K;,KSTr{fɥLR҉bU gֶDO>&JFD `G%H3IkibU8(;b) 9K蹯au NpB!_Xh z>@.*.NE5-j9E_%9MtХ(7 CƃIEfl,oZ_OmT#~q;#:/4k qgUj8YARs5zکnt (3Ju:#&FϴOKڰ#lu37ݠC6"Bi">)[3+xk=vYA=ܵ'")B)]jr#0#0w`HaA Tצ f)[xl#*e_b:5;|'yr|vg Λ~/P_1AcLf0׍-ZiOD, IylXڼ VL(0t&9~T=rlы3Nv1< # , > `W\\s/%m5U `ysT Zz^ amj'8YP?d'iy> stream xڵXK6 Ф{&g:it:m-Ah[YR$zRvV q% } }ȋ`:// X*gK5/aI(Cܘ֒Ih5Efҝ'Lqɛ iQ~N heG[%J{c.mVv ?nXQ_i^um.g ]'GbQoIK4:'I[پC,EЌT_Kݒj1 i :iM~ا-I! [ !?]9TLz[]evCZҚ,E ƹ }}xeIca1IB:i[E,7v31p:jul0[@mG!7v+s@Ҽ9xg2ݤ;DBmav3_B~C NvE䍞%$LX YbD ְbX/CHΌAkbX# Naa*@. A3{Н 3΀ս5՟pJ OԨxהEVH0X0pb6JOY:O@Np,faqxK@ ķ}Jr!] lЀ>\ Xw9ϔoEZZUUnnkt']UyݤWEgJݞMYNqXlnn/hTwCO-_y.5lÁX` sem EKek-6u* 8xf{7Khb[ҴsTAlUE%Y gM% Fݱ0V7Cc nf5p.ẉ2v'eb Lg.l8&= E UI-,3ؤ\C]+K7&r1T8KZE[UYqgʃ&U1n6@n8=ƚH`v=o"Tp?!rɴ=e %Ỹ"hI|s+OInbv,h;B2?ۦe;a$z#vE(tg=7g (.S=`|/ٛnڴM1{q 8p>1_ .8TEG3w^uoF⏋4"> stream xڍUn:+k|] |릷uEmіJJ))Fw(RN@`cg W4 Gv@x(- ,eWxw V"֝.R%9A=J4I60u:w4R*G=I-8z~([=Y( Ypi " /m9ՙ5슪-> (f`a1SU"-SKMYl *AjpuSIv&VߝG"JHÍk躝NJb=]~5I1nE==*7ٺE˝50\M~M_GSd `IJ4UɹVGPAPޞͶK+a .HI(`"ɕYr?H1(HXZ{K9 'K}i O{0Քɮ0CWިɨY Lcf1Y] H񿥐ɛR8({]ُHZSKDC|sД#B_ C.5$<$3ﲩ`mx+eFQ1ICe\btS[7ܼoGDh6fxuCCj]=`Ǐrs!i8CxS0>4$dʱڗ`oǽJ;\ZeNu lUe|?uӸB2(*Q endstream endobj 6 0 obj << /Type /ObjStm /N 100 /First 813 /Length 1841 /Filter /FlateDecode >> stream xڭYn8}ẈB6Ai @aw<8 u,CնDg3CF$EQ HHIKi2ђ2 %g`<+& `i!ECAVؓ,Z w~=x%E:A"9@{D y6Іʍ1x|g2Vu<Ƴ&0m$4 IO>A 4ȍ1f!` m Z[ ,IC?Q5 %$`;MI|"E2%2YAd=@J:b9Ća`+SO f89Ld].r<,77# @ƘtANHA')SXaPО|zہAD }`&bY9V2Ss;'Cz3ɓqi0>NNK9FɜOE8!;;/O9oT.|Լs>*_E*!>d2pssIggԿ"mG#@i9+ԿUP.KzKׁUo,DW?LJHHbLQR_7nѲnTRt-azc5.&?r:ʧ5Y45{}zҞy`%Iz֘Ӳ]-,0nGM%%Ha7,yT1k͉PBFAC ~`\;R^D;tIt]W.Y5Χq>  )GT65|%>&v^ [56cnJ+>-f[5JTD􋃿F7*Җ ,Fnh٦ƛZndF>ݑyfo1쾜\ŝ=:>%&u[4ty;' :h\kIm.A\{{[W ͞׌:fa.;8/~ΛA8_ GJ@}Hq qWN["d}"0g endstream endobj 164 0 obj << /Length 872 /Filter /FlateDecode >> stream xڭVMo8W(1#~Iѻh ${%f+D'ͿФla؋Eof gzR$Iy2[$q3!Y|KoJ0O}8H$w1-`s -f+ݍTqgHMSS7[f+k7SȥfX#V$gh+k]vdh{\p1+=ɗCNVo^V\&&.Gƪ]NS$ccDD1Fiᄌ;Cl[3_]U);My#K1.N% P_@fbB]otw%[YZeCy,3\-84V1ek@ C/p\ PVldZUy~mu֪e00eq 7ꞐݍKkh`'pis_p6t|O`hMzpM'˟08řР p,̣t GR *rv$vCYv}/m_kUWhB0,8In}&?(@OzRyLژ6:1 q (,| z22=Lb Qr .UE[O}%=d@'٨R٣S<#qw/w>{eW PKd?a°i'M G0 88k> stream xڍtT6)H)- 3 1ÐCwH)]t+% "n9g_֬us]/;1UGQ@!iP $$" $$LnCAA^0\?*H(P.@ i!!@R A8ԋ]Ꮔ990u~p@)) %w( 3S r#0()dQ(iAA___$FP/( rM` apDPC^o8`tP_`|?J'W"w0 F{0P| rB`A> :da&3 @y x~(+ fjp  GyO1{sp/8!h yzCT`0&ۜ(8 0v13=G #G@(74@FN08cPǿΘGBB~z0 ULՌx/2 K b a@?``-# WEݳpQ7B\f;G_YWwGnn\?7 #]F CҮ.vo _y cҚ 5@x~}]@!av|A0bϒjp0Khb '\3$@1@~ (G0!xAGם11A$k0_N{#&߲B`YX&ҥ1G_qwydOr eRHš׉Kn[3AL#Î FstCoKw(n^zawg/$7(;4XMf6EiMX4{C = ?#!աwTo?%K)C[',V{0cg=z3ɁVʼ=ld%ZC$ )FOj~UQSF1CjȄ|-ؽsR &acif&stPh^." ,z"(2G'WdNtJIR:~sE)G>  SװGUy$,}| %GpM68U1W*\Ynbg\1)aEQ*`\'PidԮo;/+9wIW=.s֜i;O|? O\[vvH[&rKҪ'.Y6Gx="C;*k~o@ATAjy#oUGgZ?5 r/{kP*eL8! N)l:ut/mf|?Sߍrln2Msq, FX)o<[-s k6 ( !gG%i%h&("@fMz>p_0vhzޭTSFoZm]97ǓϛcvJ%>[(=|{yJ;l%xsChLՑvL:98&; *,c2N/gH5@m_Ϙ{domFqQ3~Mʹ4c0:FY)|̶Eغտ~ :5nc̟'d~.3:$ ՞(-&XQc:ĶZ92HvnZ~πXV.QsÐ렬wzQ'ܥԴ,Z\Lu5q~}u6pI2+\m Ietlq֙kxɁH}Rj("ڋN`އ[swNڢRg~ݳ8g,z7SU\r7>V GHs͜-or]kXC>.tnq!GR ]K"?<\#ܮ+.gb,pvUM~jwzn7?Z4VuPFAf7n?ͬ]?H#׮H\~J89wׄBU^ h7݄2M1(sE2*&u6ϪNp/ 4)lMΓfTi2r$?ĉ Nf( [~v}#W&o&>~oxyH(}鈽X7;x4tY깼veGՄ;4}v坚4oX6d$I?,?}[ͱߥ!$U:6s!qS/Uui&HBV*`s"N}T˸Ҏ,(u{ȋ¹ʃQ7>4,Nkɸn2[mdlO|X_}և&>zޞaDzh/)ٴY2ʒ[b ۚF8N ;݊wFg2.?q>ZsR\y3:΅DO6P\H +̝U,0*~3Vu1O'a5vyɩO&!*ݟ3]YK0Ӭ!yL%ϊǮa%OS:FH͢>2u#٤ck~^?QQt-;??fIt]6A Z^(TK+f]d~ T~%6Th9N1hFzPG>qQ}Eae+fv{ox۝zZvjZJP&"# , "'N+])w<wqrWE"nB)HOF.?lg)}ɳȇF]Жw4+nS5efxlQ {sk)@kȰ֣vǭ;gV68ʴLUQby j%ԃ}8baRzVb[{gVzI&lc\RR@"C,yuF,+}<"gr9Mo_L@ܫ!ٌӌ\Hs͂O37݈-%4(.7 A m+dhoFJcF=:%CEY5kJ1xl.$e=-7ZL<0aD6o+71k659ly @i{|z9zGv37*UĊ=IȞfj{I}Bk%% J6J OTN7DBWJgq0'} xeYa}OP@+ϸ7uXeܴY;u@aQ#SƑ|0$NE8C͌#"6,hEYMT=[[zU@7_6NFßȩvz,F;^"9=Լo[{F̿ZhtC~iEF}DWE%ݠ& O?9kxd]LT˃INkx)ܟVߪDZjZ492i4Q*x>8[kc&mGd-):!odO)6bmO[:^qQ][^lSX>%]ʀɰAD^w:HpMiʚ 38"~_{ N}4Oj=Uo{^߰TͼsBU1`R+M*H(r1Abog<=$??tԡ;VNj _AX_[:}VO㒌 B"J >teͭg&|U nx:-"`|CW1a c55[q&04Dˊ, Z]hj BG598S u6Uw]1ߵ"JGNQ?sYkx2ץ׮zKyahO6s7jE\ҰOs%vjJ҇]OHgD܉(Ka!OF_N 7 Mr ڜ]9u&=g<[dd șe}}j4uf|扽*{Bnse!ƛ°O6&ZPx^g8yv ym/%1+#.#0}cGJ?g o&qYI 3+*[Ƚ\b Uqs~A9 l/@^lV/eKqNy²{zLmo:iQ)>}!|olA֡Y'E?#xagߔ7@-UjWIs{-A'd+綪:ësD2)O-OH<Tr5vrkAn)8Jhem%>fޒp0EAy3ԗاo e 3*G*{j >A-CG̨wN趚%QUWIǧ󁦪KÞNÂZr$Akϥ]tvbl@z 4;LJ̦gd{[{zY@N:ܞ X] ;nѷ+w' (Tt8P;omc bQnI, `W*Uǝ!oEX^Mt )2PcUl׫:EܟTcF29e2j@;¾xɒH 6Feُ&fј% N+/Y+ @y0UPM )!}_*J{.sgg݋&@y%bOO=uJ$ }qt1"UV:!z`''ՖPK\|3IoSdDڷuOлt&=?'$_&C( 2L(I.uA?Bi8\ u9uܨJP9=V6!\Kbd XJ_#s(*ʹTJj GK](͚.eOo][KY7+/Z,לkeᕷQbO$WE+/ϖ2DݰxC`s[z\W>۾\C*hФ/$*Zel*{d(@ImHOsJۺC܁M?͍gVjS&#tpJ\Ra $JΑ ~g>p Z_5)Dv?2 c[fآ0wS/HCrScUâِm518Bms5,v*> stream xڍwT6ҤJ8t{EJBIB)H(7{ RUJ(|{gfyf7\&J{: *zzZ EȸLa789!PAA z8@$ IHH Po"% P{zBm&RA }P0'g n<^HJ/w;=0v 0(!xd1-@9 `g1 EyB?KݡJ":п &G7 G\(nw. &&$W??࿜ NG`+pD{an`{W`O}h Ġ05 ;f5  Ǡ~ CA!s\W8 wpY9A1qQIq8  eq5"H# ?!E= ? \@:d׸`+ N~ _O89 n>j)eTVFx|EE"@(& {gC0OwD~/xL/8Bn%Ka!8sj8"Pd?-.ƍ;'#qB8 n`/CP _W }F@dB]C;kXWGevҏ-EGlH0}jK&93:zA6.]ǹ|W}ם/L&ޚj{b|SՇgCMgEW}$/n2;aݵeٺ R۟1m}r{?*M?l YW ,M/ۋ mo5AVU5~znek)n9U,:nYs$wqKvmcOhµh-IGh Ola:>3=c?iYK\ozWm*͊?C6樂cHA?[!Oؤds|ɬTh{%(',p火w}b{3518Xbì_fѓFHF] }Я{ZwQ_pQ,Bt+:4Q=VȃxeA xdeA[-L>KTnx]|Ib_w4@m1w%ȹhto'C RE*gA<(C6v(-NԱL~( "z9{k_ԉy/[U-%7eVͻؿ04d\n  xCvDvۼbUMh|#w7ZǗ:˽k] ζlr]s\C^wCv V@oxw|ҝLZ "/7mi[>71:xo6XKMH H>R7y}kM}b7p |8LVxyv?6C3qjۢ^dV=ˮ"r|pjnmv%x0:@|eaN=&MDehr94s48S}X> y7;-Ï}sel -phbOo/ :mաS:Jtlkk<;5uԲ`oH WCٓt7 ߷AtGS3G:?}ɯ&̑Z*Y<=ڴ D7h~+sbI,fmLx4}#ٗk˂[ww=0ݴkcɼᒄ&)>7heэ".)6K!\r}'+k#V\Oo8|ufjZMjp` s;fդ@ʰ))AnPݪҁlْx1&WJjԧ(m$1g(+$>0GH䞨4cN ˠ]1_%\@w8 2W.b .v^2y|q{Q^tMz[|MўBR%7jnI;iAndH< ~5e}{pDwppU91W'ͻqޞW9nes4a]U12 6\Z{s\WŪ&N2f/]#IyJ> Q _+IA7խxb ~ğ(2ơ𢿤wW]w4 \W8w*X]#~@ji=iP]{bV##. j}ݺOjzn ^Ytlv4"L}ϚPcƂm ӯNaN֘2)6 K i]|M, 4{/OQc1ԇ˿.XSS}kR͏u>._Ӽ MiPh5_nfyB> ˷bΎ8Ҧs⛳rdףe:ɣـ=X[=d(&6#‡⮴یGrF^wDfNy'P`fˠk40tC_zDp 3E9#rQ*wQw.-zrT7%c8w'vs9ZԣF[/7ftdl9jkq6ynNwTmŘ8MM %Z!-p" @l)B ޴d߂O7g;f_I*M?[8 ΤN@1^k߼Er[tZx|f9o(j4bZb{>.c [N7ӌZf.W :m:бfUt1%jwB(-ʳ>ĬgoVՋ`s'EɚH`@Mnsv3עlyseMBծ`( ۯUc}޺ң闰5&|v^QI Lgƕ{T5ORKpsO Ay Ǩj"qbrr]|ҭ w܁,㣠@k]Y~_f{OXB)7sA׎gmKgtnV))^D7-1}RՊ*;0[9lҹlBN}[+ceȅôL*%>]\*Aݭp49`g"-L^ .S זfd6W c9.U^=0~Xc820)Ss~ݓPw MzKJX?>7yU6 !Je"k̼} ;+E-<6ft5;{*D*.=bZ\.hNg&Ząҝ,2"aܺ!+xGPУ )Ig« cɈ|ǯ %5h[KO_rBLX9sہ)џf8RVTI'nKP<|x&d˳٬sRV4p{U&:OT%A޳.ӣW,T'rRWl1rfH$:8BH١2-4.jKxE󊠕8oXmyEHkMEr4S/ٳh BuOe|LĂû^>./ؙ^$tZuX~&7RYlh&vS >%2T}80bϊ6l*ܧ8u F4R:+<ԯp2yv~l} _L5jFs" ur^0+gSHd'xK=%5{RBćo<=R"J2C!'jŇnp#Xxnbϛ7l17 ]!ɼTcPВ'TilDj}{lk3OM*>&4\v]Ui3pAb9u'XڃGgB]Fe۰=~- 4t¨^͎ƳJ.7>0j/synwMAwcQʭ%sy&~众 Y=TeySw΋>|cBrsFV\&i*IFLA{wo_f9F7Br6fb&Uj iA~w}q{Q ۵>$sqp%'ɗ|lmc_T={ܽD€$EyfYR!L!*ѳ8VG>[N_yh-RU`?p?v)蠒"/ &S‡1c){# |ww43<m!W>N9XOS5Յ8Z z\&$޿nW,$cr / Onf겅S+Q9:.n' &\z>qwUIO[KI=V%dIY"d.lM#3Ja;S0!sY {[y`-D0tє&+6`?E9dq<غMV> ;#o/wd^YE>kKܥ*&E26F˚{UƓ?Vg M,pB,hp$V{t6CnqNpjyN/4T־Է̏bL- Yǿ xsz'zز)rIRG+#h-62  %Li1mJ)#´9X5-mq7##T^Ԥ s5RLtW}i' 9n,)Ls b[%({xI *Xz5Qef׮ o]L9p"w3]"h#_7zJ:^=("ܱ%$at0iFFtdӳZ1@rtfGVc󫝏C>[qqGt_M:f{[qwxk-[4KLlohEHO<ހy M\WaWeq55#h+ΟF+PdR%86RpVL˞ zCS^ӳ*Q8XI Ww;S`#D QQA|즹Nbrkwo2G҅YT>\ٞvTAy?Ot)`F^wm-S&g'%;,~r_> jxLga=*g_]5ykVm/LnN> stream xڍtT6!HHĀt)!3034H ()0"Rҍ4;ƽ[֬s}>هXP!hA @E(%4a0 "2XLtp %eR2""QH* h!  uuCc JKK v(CP'0 FAܱ':acG974CFXGB ]y>P !΀_? pLܠ?1FBXuQX/3 0{@:w @Pog ].PB`/"B``( % )rBB=(!D_awVAChɯTHtq]~!l zzA4UR0W !"""%-x Nn¿›y@~`lA H# @!4  ܑgqI C\GB}"X"~^b匀C_auMumSVFE"/IaA cMj]?b_{3Z?"q~RS(/wB /췙0ݡ0hE`TsȟՅ8C۪cA 5BQ /vr?)A Yb[_6h9=>($ jp'H ؝ Ego4-/@$ ;`"}0 ?(/Ű0 GbN^H,[:ج@ '1lʈ7J}W s D6zݼ"3ly̒ϡE懪uɆ? ԓL ~(TzL$hxhG-O7 N|}u`{V W+$I1_Mۄug'D 2Q SbzO/V` tD`EόH;E7PT8i\!K23E3*Fq𚶷޽Mg۟P#i*o@כ\gZ\?g 0BfRsq  L>@>57ؙi t^9DHgmL;9ߟU5-P|(mï%?>+`pSsȌPky;m([  - $-JL|(To[/ */cVfZ(oȶ'ط^ڥ.}伾xTRlG0;+Q~D*"QQf~Rޫ6b;&l5 &Ζ_`4U9 'u;7'm'T ބ(>: l?yk g4ʷMN/഍[b<+y-^ x{6~0qKl휩RیOkw7Poi 3t ƒ/g)&+GTQEܳiWU1F!b?MUpUʡ#?zˇN,6!6uulǚuyovU|Zucg.:}i)Rڛ 9O2fsCNgcweR[hF[7ozv8FJY=of6wTȰrIMύZdfH_wI'#v8(kcV/Cnh;WRZN$_z=+V+E )N칾Dq)/=hNhӘgRQ?46Xh.˺~דMKme.{om$X"O9O;C8>u|*j/4>{*d7&R$Ú zWlu"oyz/4Ϊ)7_uFiկu+֘F8rL ;sH߼ޞ<,rؖk4P͕a1S5V^HPaT珳`IyMXAIDq8/p"M (ZMx.Tc)/6-_I伵k<YY8)X-9wX]Z㻗^<S0%Zkf LAkff sw(iki AF,FkC!'^[[Pu0̩ 31:9%$y\N1#ݒjh'F+U* >\zCFBcw;'ar?aؾ8D́Ildk86޲GIGr;,m!OeR PÇ)5.72g#D}(a#T>W_3oQ r<6|Kӝbc635n8ru/24yW-PAo6e,8<ڶ5`Qwg2KRBuŵ՝iTOȫo_14琲e҅Y3A1zYP@5*4i]qNSLec >JD֤V#!=W vN~M)A6ށvrܞ$} kZuGCQ%yüQN e3p߰p(7jߒwj<"=u4ӆxO;Sp˾%-y>-}I<{~) UX73@EHJRuz"xWsA W=$p/ msXԲ^A;~R>Z>s6I4bR4AsݩPvg=^M!Ƅc: ֆQ:nKK?@RxtPEZjanzt~T]Sk^oG22yMi7N_㊨ 8োZ޹7+CmgpL^ǐOs)JE_0o~]1>8\Z"HCV'"qj^ߙv[ܟv y3;qkr.޲TlUؽ^# pUqrv쮗 r?uKgDCYѬ'[7Mp9P&ir{~3ȬsVk}]P]&v +mfA%;~!z&ї[l.(4Sk% E3C5gC]/ mf^xst Qr/NY饒inX+pߨ{_%aqz'9ZB|ɂ2xOU BUYQÄݗG%>ז5JEb.JaPҐơݭ/[̪G2 S,׍ gJhDj:0mq@zvCEv1؂cǵ;~"om|k-[`7rW::ʠ=oֺǮu'F=y!p`U2Nv6WWO]myCUgCjnFs';G|I4c=_]""M\$zUrڨ,fk1xg| x]GW E}yv-:De 탇7 x?iʔ7TE?NQ+B~>ִ_9x5pj[]B߾5iMKld bZ'ؽ?MeRi]jDSSrW8$+M,)ݙ/y~%zgM!gh4Dl3&F)U,X-j}Ԋ?BxCBr]wBQ>ònCx^ïm3UuuACU]tLI]/^'IJ7h jSst|fxql7̈O*FjF5"yeq1;PQNVV^}GiZ=W;HV_7yw_TۆN%MrAű6o [45F~ 6+l+NvH[̊+w[0# mwRqKxgkgL0$  ҫUTQqLjIoDo9kbC~}yiU!>÷%>4;0"3:B]t얤& kZ̑LOnW|"A64DbSw{-2]{' " zxcfR~YpC MuNLb6T{Y`4*l` o2- q7nUM3&mtsDV;Z2}Z)S@OJkXK^-Vm@\ȁgfs$/3 #gL[,dMM+8q.%֫Q6: oyfok|n0lXlAD8SxCXzK8y)ҎZ Yf_(WE|.䬩rA8&4D>W3l"6S[/T[a|ּx \ N>sFnKڮĠT ]˶y`%̮>ZAg#Ul3xE]9gZz_ i}nu9r{*jpoA[$SڬnU@}1a a?*pj8~93.L^nN4G!3)o"=xK Wl%1uF־oJu)g(twߙT&(5ًJr7R%:?z,+̉괱c 4#]}2Pʮј̓mm9TDpV5UpC苽lQ&kbY>owT(7AmAr*MK$m6mU|mQiΨ xCD1eAזW\ )f]WtZ| =-=&,c"'=,Re/spC5$5yYF]9S3)pkb().FNs<_%l~3$zRdh tԅ͗0*[ٳ.&m5W@Aa,x'?ꌸҝQ<.:9Jk7@hz5 q uT}S&5_dEDQ*͕ ’yF, v+3fwckʐrX^tb^Ow$\:yn, 8 endstream endobj 185 0 obj << /Length1 1444 /Length2 6293 /Length3 0 /Length 7285 /Filter /FlateDecode >> stream xڍxT6Ҥ.K! wJG#MzWt*HtϽ_VJ3g<V]y;-L I)  !ppR?0)A0X x`QI$$&%JO@ xB$(Ww#ߏn(,!! sC!Hs ((Gdx^p#@{JhC\`Jp  ({8Dc]4Apį2NCb$Sàs\g$ USWB$`HBTT `PG_~\Q{l= A⇆xwX"vp(` s#I Zc@^z*Dł fƪ|JQA H`0X &&g]OᫎG$J{NGX(ra $bgvWUC\? r=0)BagԇFW fpo:yV{@нp8Z Ӆc/׼!H. u`@a ꌽEXi63}Pݯa@!>$^cW"?0v*`޿ "Q [cNvpF@A8/ t eu`O_@b}pwz6׿/%AAœ^3x ,-wF'E`8g9jfN)UNם+g|>m:'x1M-ܷp ?E0&J%Iߜ+eXfFU'zLb(>dMc<ō5ee_ ZPt70T7ǟ)}Y5MN_aFOhe5-t4I98 "eltE.x6bߧ ے=oiN=z?~pMIo/v^VBDVyf6%\0፻[ b3y ?KY?y%D. k2p[xƌW{=\j ԶClaEVŏ4Ff"HgRւ]~/wSPܤ ^ '2T";IoAqI 1Tu=[k BBTĿ{ $h#GUC7({K%GT o Lt4VZnTRH'n pu{O/j0g)?9,lI=d5"P W\Ŭkr,/Axn (.zMi? Rpe.F} aYF^Q38Ϫ~#wN~XcJev1!}zѳ?ՓJ)/Ha$&Y|iwT2֡[ƨ{ɲuOXJ_-`֘u{Bb\~# 5pEMǶMys]+L,b;A5_gnpD=!#]:{?Ѳ4}8}= c-瘛59tv3B#Rn_|}g4?{=Qqݮr+L'm`t*E\vՁpjz}kG82E'Hljc<8L"Y9ё_k~+ ;3sB\G>+5USUrPfZ$W(5{:ҷTK? ?ꢔcoo8%#r3_`%;hۚ@XͲ7qƭZR#R֚-aaWVxX { dG/>Ϗ-wK%l^zXDȋf*HS/D4\%Lkg 8+$ ˛Jê_*BF]W>Mi|q@+>.k҆0^X킔eYoNb)I?u&u6-${u<:|05"&[S]Ƈ\B\PSԾk$ZolA7 sjO0vkMhCMC{Ϝ6WP\pI{azJh+yֆ7Jw EM+GJS?%aGy̽O^%k V2b.`Y۞ڟ7TEH>Z6o'{Yýb"N>Y{]6җJ:(%%}{՚uMzۺab`/QkR_F~D\شzl>ʩh_)HO0rg yG=E O8QW:n??nڱD *MZOT,aB:Պ3u)杀JԡxBǮ9`+jLLZRMGo~^B@F,9nيmʬkN♇ ɸ">@<ɑ*8ŧv`犊1N+  UL,nM zaSwl3)/ƨz;F-d U.$յZv1Δ(R yj^"aDsSf=KwdQw1MD2'$Iɏ I3 Slэ޸w<1؍i'T=5G~9ܶR^H?,֢Q6N]o"aF1;ng?㲰gEtu{Y_KSxI\k_K;UP)eL&InHc n 20 09˭1@6F/#=]n3ڌzڕ;%+z4] Ǐ$ ZiIb-e[OW[S|vꪻT!sk-{Or˱a Wc# ?t#~q?cЗ'z~{ayמ6Hj?}}3!hg 2z퓦:UF2@kjBTg}wH E/-7?KmTwI\ƄK*(OIcEoO']sAyBST,Ѯ/BlvW乭uNhP4m@ 3a*i *Cr璳ih_aY'~͟;|OApgmKZw/qkgY!CW:ɲ&HDA~y[$c?۶2l[#Υ>稕shn%s D]g~4CE=^t˙T@vMGzLΩ33j}sE5e"4OO]YzR62mKi]5=c4LqTǷ1-O܅ܥ{GE#ޏWtW.A9\mn\Wn&Aא q·DeB.twWm8(KXsA%cM _c&t4=g`)}Sl쎝0R>|gqW+@>s(WJrAw-<*zʮ(h8 uhʃ_sJ#ǚ%v"ᆖV+IC]['gcЙҺ6NP/:Vs',(6V\Mc4"}Ҵ&F- N=%10diK98Jm.:,e3M!?N&Y_lTҰҦ6:oe:EGO]]1!Dz-E鶐~H|U9]ǺGC;QADěҞ]_VVd M`(pO=T}4-M3DB{_y@oy{<}vp%+p n9XBix*Y=f(HM jO\S6~ =OoV="rR8z%W3%m P@.>YA(NıI8X]eSRd.HgO$b^BGL&sQAYI5WLŴ94J^jD9Gϒ SFʐfe62IS=^# ʴXrLtN8 ℣C xp5՜ I}^ZAKF,鮅yXG+bX5LJ٬'9+sKIUӊû1:߾"*qMk^*Uq'UaŇ!wUzߙ'5 i3?u34/f_${"3(eOGe|:C`%ænDx '=-aDac}륡[Js[:sjO\^&/)4u^Ggs;yYgw>ڍ|f|A<9Y(t͓bݰyb4kپ>c0"v{6}r~}tD\$Uoml1Z B/ྏX;\Y/Dv;Ӱʼ|tՓ;<ә~M: -5:3BovXƓVگ rfٶR->ʳ_D:k6u8_=N@ Ec 6z9y]_j P%נKnնd|ڴ{I|Pcw H%á\ ZyоyzFCȿ 3ֺ%:`Prh^hYf5&KaP{:[#' S˥ssc {;һb7ɬ?=s//R_RȊ|Lf A9+{5\SgVrlzݵavAa5 W v|o iqpk!TMI4,߳ۤ4k{Fo ,N{Q=&ԫ 8=)ςjUTXb Vxos(;%&L3;4y-y|Rn>7L G8~NU{8OR,>(dT+#w xT6U0VґI{y_ bgd,FZ.&Hb`>SW#j=bo_vx-*gbVWR$b w78)(s1?%kw#ݍB<:3_.xr*(UQvWekPVΞEݰgf3&xz=1w߾v7I,gtQ5ܓt)^lMIN`CRYqp!&D(J'QX1 2$7< &ܚJ~br2<@1Rlg2634UۦFIz~u)nnOT#j-En靋IrFF"xOJA%fU-n#sv>Im/02s ̛-\&-6fjPbtroC)71wìB%y endstream endobj 187 0 obj << /Length1 2651 /Length2 18596 /Length3 0 /Length 20121 /Filter /FlateDecode >> stream xڌPX.ww;$HKpOp|^սEZTYQ(`WPWge3!PR[#Pj]wƮ E{-`ca3ୱ@ `tAwprtG)-/s`j E459Z]FՑÃ΅Baj P݁f_%Ƅ@ Pr[`a [+S E+pL#+MM-V@<+엢WIQ1s1urtuarU#/7c7wڻ ﭕ3t^4WfnVNn@(ߜ:̿{9A58:8Aé?>.@O++`GDƠ;[yX@ `'}Є9zVҲPL`dcgpsx~llOX؛;xNtJK g=h[ cd1b<_^_f$fko?us퀂hUY_1hD-l=H+I+O_7kl.Vn#+ t{F/;(ao`k8^,Ib \A&Pu~sg_-0F\f߈,Ff7 Y7b0KFl2(o)FxJ"P<A7EP8Z/(o4v12r6u`Ńw]ۂr5@&Ʀ6..lLM@s?hW_'6@ 8A:؂:8~1vv+5of@PHo M@6fn_b7? @*=L*Dx,-h8? 6@PShk~AoN/{Kbٻٙ,t3;+VVPeŠ?`o#A4#g]tu];ܜ\f&Ȭ tTo #NJpVﰠg܀? @Pflruwr O@Cf5ust]"|]t0 鸯%`ܛʠe6:'hV4uڮ͍ Od'gDՙvi"xBFu}ߟNm [d)xP 0=<VTfc5b޽/7KHG~:s;;J"Hw^䣻^ҍGKy>>C#v&SZ) ls|wOO^+8_{={>$=5#G:%\zsI~pgz3xXE/P7:'7r'guSzޣz;;Xkbo;a*^tZg鳞:uT2X.q[0r$|5o ZIU&q 'oF/۔bNfk3] (dő2Z{rU*vS ò'34r C(y-ZQ7QҜ:+uEzcTy2 w1`Pq-m̛#*s(ŞGFWK [f}׏HPSj~E()'K_C1;ף59\S^;^^X6z^?/a{߃_gfWߌ͢5ؼ1iuXA99:O}tq5d&=Gsݾ\"G;-}KTE6Fj!rlo ֨qׇ| .I_}hH"XYaO+V]SxRRFb[O ӮWtsz@GFbɭPjLGv~sʗXSpK7Sd/}iY>uNώ|iΌj1~JA`6XdEPE ͎{,(3mg_'180o ]̛ VdpN'h*<<yMFSgvXlOS9vyK룟MIq Qrkjv{+TUċġ 9_m P $hQ3@ H!1:'燥.`XB1|,=z0Y.AvUgхڌ1XMj5]#52P.ZĖ"¡O*׻-alXÛIl&'ˌ>;OAe_4'J*+wxkabZ̚x#wUM| i4§D`5ўlzX 6zhI]=^^:hD<#KRbLjMAr&S 9ނ.OF yOCN∽mQY Kvl9ML֝ҤoJ5<wRߡa&jR :{,͘!!`ouv1XPNi.|D]vhHAC/5])yZarU~^N Մl)xlz'Mbt^,D[5Ba|)y,[-Lߋ=8iܓ7ٝTz8)&\G,_uJ9rE·c2 i`%6I(JΥǨNwA;fDlT\Y|<1P̜0 Jx]B/1t_&xt%lIC5,f<6-%M@46 M . fZ{V;\?):9j5 { n*|%JivF&XX7h͞L*ijVzI}>LmdH!vD,wjrywmUj;6i$mSjOI(T4}{UtiI*ulk fpL4|=;9L1锅N]eBBGޞ +>I;\Ua7k?JN;y(0Z"䝑}ͻ*(~t7t(ef.ަMY%OAR˽-chyrBt]}oa)c-цL!\zŜn+#yJu[0|kߣv?}t}S~>Mq*(OYS%\fy3jA@XrMyn>(LQ%z{Z!AZ{}itOao6>Mr=)I04-gGi44paM7_n vMjҥy96S?fz# %;18 qҎ5;AX˅uTwQMz-yF*Hq%è^BYa9x?usd&"id*)X ڬw7 NS4?{8C*Ǯ[qXVn1N&'IGlOx&~s3畸PCL_}hjH,%nǺⱈbH}W0:.5MZʽ-H#6%|i x q-A9DMxEW㻂G ŋd3cVs =<)J疀T{ PI1QٻJdL ڈzs¼w|xvw[ JS'/*`3ҏ*WWFC&wmƞXHtC {U)7,dY.ٓjU^HOzOŬ5) hh2B/ )2`f9貼T2䵀&Sv14pJ5I-{0)ULeJSaC N]~uoya8gRBˍ' o*2v-lF!$x0!3r#aJP&wج K]iEv}ŋ7􍝹voCZ :ģo#UN#uJd Ū-K杮0xHGO tw+U ]dt+8eh8x,X}gOYMTt"F,~ vUjQb8:VpS:K gau)"B%,{ B(Yd\dbOl)8z;A`d&.[VNB D}1qZeb ũCknZ#tu.5,u{q9bR#xқQw2zQa^p9aG[*?}{Ez[L&ǥ LM~#Cs=3>OZ6ǽ'҆?;l6'1 rm͠:.[<k. }Zev@\(ԬEG+>2X} KQqR1,IVi 2=ǢJ@%zRo%H:wȢ8~Zo?uRl3G =̴7HIC" Y,Kj gl׬ܴ!vTZ*ȻɴÖ~$N$61Etw"HdA@Q &Ʒ΀D*#m.do's+:;OX7ti5HWHhƜ!YuX"?rYgO}~_JQ'i1ҙy%lf}GWBӈz.ݘ2Zf9+҉mF whV$k07āʷi.,jB|NdxU?.k,ߨvg>-} U1P(UR1n] ꪹJ~sɘxH-η=LKaߏ;gGK[39;5+)[DyoVJ(C|Pz?cK2sH5p% \ 6|SL²q ψR\ -7XT!5E`G 4WdpAPȧ'kڏc+Y">k28{Դj]7y̎Y^Z>/^e~Q˸Ɩ?7w`BkWKUPMԜTi|k\(#i.Y<S\Ò_Mb#l)Ju]/]`W]R -+बʤNTکvYPG Ӹ(ll=dt1+~ W/kyY) *~vVõg A1,Pq= #pE_Jsh27ghK>e5"瞓o%#? Mb1g.עViֈFQ嵀u?O ʇ2x uV)cILmb#͚XG>hZ<.n?CZ|j<Ɲoji?aNpl D%;%_;ngo'j$\ bmgѡ+>Ă{h`RJ #վ8Yyadfsr:MK =hSh;!(sg!9f bpV? {iֳc.CkBzvuh%|pS3*@"mP=38Bِmo׻$Ug\l>] T"^Ш5Atm Qן)^]" > Nja3M(0ڜ?-T,bt㲷Phs5KI %2JvUje]v;uG1jD  VKNnȔztZ5.8هGcrVpiː/BӖil:iEs*r}^RUj?Rn %5[ÌpUΜZHoE`f$ݵy 7vV|0vjBr]ˀ ]{QR6CLc&TMJ2ۺ6LS]_Kd3޷9avẳzM!fIkQڄ ~%"((bXc8Nhlb%)#sh8W$n\Nhi VxCgL2Ľ׸z nkgQߝ`[S빾8"81,kؽ<`jn:GpO)iܽM{^կF謮8A󝌷 lDW>U[S*>`ݦ\PtI]QOXg-_[K[LEu 7[D$f,>/7^}[neϙ;y4N,'8n-1oo3Zv/3e0T~13#BvK<혶FMX2R` nD"Gq4]x)'8^IKklʋz c9yZk Qs:]9H!iNo\v?9u,lٮ#Q7;7_p͸Ը( Ye-RcFٶdG-'x۹qEަΆY4y7K]~bN h;-4)_{7QH85YhL r؉4EAZ 2ˉfk{ɇS1n8-LFtC>z Vo$k5l9#{2*ɷxWݜWj"m?k[$!hPW{~uHVrX2(XӋ1\yp-^6.:N."VԹҹ=ĕ_àyClg'oܝ'ݏ^IG;f0Fx߉DB~ԩ)xī]0b}"{` rݵW*l÷._ӏücy.+!IM9pr,KwODH!K $6J%b~䦎OM.Xq­U*qF&:ܦv<ϟ_:wj^RMl2"b8P*(l T 0w|"m# [HcۇIѮ-փTԫI.GmP.bu,$^Mj CG% L82ڄ[Y.2GQ\:#eKg*fwq˥HVq=8c.afFxS(ba3F'()¬9H<cX'SRߍu46nݿi4M]`VYZ]i).=])YSEF_d>t_:Ny&ni9y W y|ǎU T SivEbe|^)W\?xH GHiOlRcB~|U8%Ultug ڎdǟ=HN%3.õg(1}vt1 ; e\2[)ieCK"z0-ΡBw̼bNp4iϨ**>mfY2O2oa3? w+{vEm̅ͳ/mILOZo#>xyTOk棝 Xs9gjI|n' u:&|kU ?نK`f ǔ iFF#l&"f^~/D>wcԄے$J>}K^v& /NQiCWџ)-s+d"յ9ѓ ׻xLWnWiP 4ׄ~{> Nh/ HV]E+gDDmj9L2^hԙTչtz\;rB j-"|EXľ7m, 6@H Vjh)oL5b}L %q)xc`::QBstJO\Ȉn {j`zOC&O+/r-' `\IakUyz%$Nܧ SC1'\KO_ `rɃh D#)`EX YSdrXgb֘65l%jQ޻kUlPOAM|!$lWożWOA:I&Ims=tH_w\aZѣRҨÌϏ~66$E]gׄŭG~'G;W{pQ2#}j&1*6-!^[ ~W[Ncp%^ig?XuZT/%ڲ A´`mKߥ x㜘c:<'X2x";?*3W@EƲ:Puat5qagLt?+\.{T%P,uW xE߽pUSC5}[kѷ,7s{3 mw*@Tʣś+ZRsV&nUgՋӓnfIɔPt[YS[ı`SZY4MQKv[ `YܢL7|OK[81"t; `0acWZH;`SW۾|NC@Sq/[W i{/'^L.J"E9"/,2?uko~šJ9l>]"* EnquEQ'uX\'6 lRamSP=ϢInQcb?h·LaJnDgRV E#I>H?ڏZ֣ CJ\ԗޟ]&E-rBl3*9 EkBV|[j!9/f;Ei>Qf)Ř*jsh0#0=(mm;#FDBA[(6ӹRڤeIDn{"e Y $q(BFbTo+8AnN=ʱoۏF>q%[JEP_q; &kGIGM_.åփ&u"59܇=+mv:QעsY{s/ڃe*)xLe3ޗ$.?B#w-8ˬ)3?xgEڣQm E8_ڊ, 2ԃ_iV>yV|F]TiTO5gM6n؟ `S_=1cXzG/!>IO7-vQ/RǴYRn4뎎:1 R[/dK%VѱYy⛍8L4rbE"-F;6k >~4VTᆮjyrGS C3JONHV#;iwH%j{o/`Cr 4O^n o\Q7-^ħ{MN1Q 腥.Kcd$9wZ"+ёgZؘ#]4)c)p&; CèCwP验KƜW`^rB4ioeH= /𥞅avPd!H W:/n!i d,U_SV&Y#+B0^ʍti45˥-U湬QG]*tRÇ*$8'Iȱf'`]ˍ=wO"D~~OBtKG,һ1 QKKHzd)4ߡѨ;z[QAWkdQUOCY㌺0^Ɓ< V8l{NZu4'z*DR]X+v&y bƁi ,Э:jI]0nQum]fiƚ?ݯ :)@,qzំ8;C6uAt R$2FΆm2b0'Cylrj)HWDgyFL_tSaTG>FǠv[~ڝTL5\ .jZZ>w^Xh疍} :?Y /lk/Jq,qduԴp3]$[KUq*".Tp'xKNT޳0FO5ͤrA#UnJrfYuDHkYY)eR4z`, zhIJ4pǍ-5Oo0GߒOg<l:P,?уL]?:\yʆ#">}.63+뵳[qca; + Y ?=u!ԚK'/%G*ʢ"#il=y>pZ?|0 Y̠x)8>nTD!&p^g,|u߸8PXmrV2|J!q+ ְl"" (/Ihd`da,p)Z)3~>qQAɭ:(V-ĴYSCysHpľE8=icu#BРHmjM, Cκ֒F{Vy9ylCܡ`@Sa8K+IVoB&($޸پ%g3x\ k1YFgjsE>iU^hYWYI$Sg pC= Rj!B;LKG ],#V;`XͶ7ݡe%u[Б{`7(>6kCN0%h1Ʉ#ڏ/g54ފacIM)0(n;7W*:} X*/w8|a 51byʽ8 m}-{͊:nm}JIwԠVoP/삖i y!Jt{qCb-WGql~QKV ?C|&rF2AgcVَlOH6v.2IC}J1U-!IS:b „~.Ӧy]0til%s>$\-\7s[z5v31N ?5 J{A*eo]*i/+e7G|_H ;/ !풜8x_U̒3/9a5rYv<0lQe5^\מ$Y"d<v7JveՄɰt|'MD,É*qZ̻1/ݣF5:Rc%뒅c@DTSN.Fzr*ۑǖz(-iz܁Gqۄhz;όe4pG}fy,I8n:XoD.i!=DoYsr9I@_# s4j'ʣ'nReM"1vC7Х~Ns-' glH׆w9@ wm%eL-HܛL` b{2@NgȴV8pq0qRa6 ')N2=~Rc"֩)zZA":gn$mĩBMc :'ag-Ec4@45T56IoY N,yqIXMhtB*HסL/.i 1Cr]Q4 LER󓇁)嫄W4'Ɔܖ*76e%gPqƉx+A "t@hM3al11w ?dmG<]aĽ{g7 4C|8 rh:y*>D~Zg$ N׽:/K5&.UT79 ܸިY( ru62C"!ƇmEB@>Zt@BZb^wg%|CV&5FN%gvQm|'Tc$oXwiqL=ՙrgL0Il;8a~C3Z>Q%[AXRf611k@X߾ffdhCװ>}56e#ex "Տ)YyC.REd6'zgW o9Q~)*)mr;:f9kBY5=4`z0ohLBՄ^EA1lɄ[=S6g#lI$PdR ŋ*tM+'G1HFf\+8 4ݘ3*7nn7в:oU*v5I]h`;7Ŗ?SvS^3!\.2w!=Ca:i_vҁDGJ3V;op{[z؏Oҍ6^vj:n׽]A!+V.[L0m5q/Dk.~ZI %{ ,ynIzc,lY vW[ڃ?F?ޒ {?|3h72cF?P[nT ߵ|,3P2ϱNE/(G[Qa9%r endstream endobj 189 0 obj << /Length1 1313 /Length2 6528 /Length3 0 /Length 7434 /Filter /FlateDecode >> stream xڍwTT{6%- 000t7"ҡ t7 *H#Hw}k}:ks޿>k]y!yx%ZZb~~!^~~A\C Kb FA0PD; 4ܡ!$??@_?@8BZ 8 ˢwF@_ 1yg0b H݉@(n #]t:2Ov#< @gxqY?zP-v0XWoW 3yC`; QEz!@u=(;s @E^+lD_a )0 ]۽L %A` _E]`Ww_;?:{0 /$/ ^|z~*uCw\_7D}El?`?/9,àϗOQW^WŐO^_A @@X /w] 4Ubk2-߱w!M]o ENH mfm?@g@ F7gU [Ց;7t!H[?߾0[8׆n>wWn@`;;`G)_g Sl==ƻ#^J0 l;5 sk:/Y~e$w ~y+UT>eik߭*ȆDƟ~WV/Vq'GɻGr+hqhx V]Q[5X޸}Kz٩UU831Z*3 ,96)1<؜$^_ONdk~!`Ÿ\[3%- z7߂ݓ^unMSwSCR=lGbb֪GCQ dCnE;, Ws͋c]R-NA gľ 6fx=5߶ׅGnp^ 57qR^>b_dY<2)U 8yk콺'|>oy@SĠ=LB* @dz; uyo2$(r]II_\yg'[9 KQqf% cߣ5izkrQeaam:Z|k=JޙLUԬ!DfhPjFS2ag0yQ^G>4-H}ښֱ# |9"#7^펳O+ F =ꁨoV":.^dd;|s;*Cr|Y Ϋj`ޤw O.ԪJZOxu0|ﻗd1-U4&1txG \=[G_uxi ߳WETs>x/K;7p8 P_%aY_oj| H%{"~%]t.V*Lecw22f '{Jcsk !E3 ߇YTf*M>ɉQcoZ5}hզNCΫ|Ŝ roƽV[bOifӽ:hauݻ\\imy[C' &rpwk0~eAon*OfK}2+0LxI#8+rPڟ mc`^F޻9j8>y-Z3aDa(:C)Sb34=h c߂pFg^%홨e,$ ̙qL1 ~Srw?&e< aJ$멏L܄;DاG+[ҾIǘͽ79syS!9BVV}HE.r_EE|7F|! })1<&(nA0](2MMj:Ll#ij.IO?V,H5n3lg<{y!om. aa +CFi~&t8pQ)h۵|,1M]]PíI޿IjVq?Fxǖ',ɔt^ݢU,|ʼvt攍yICբe+^;K(۩KΦDNדSnh-Nj: hd["fkFϾ涱jC~I8l }y9\f7?q37W?zVim{d!flPZkL/ͷPes_,Əy,*(oozKL^nd?ph!B84WMsqd#Y*'A?i|?AͲ ڨQ|Ka%{Jã}<-gMzK2m?iqQĿ}rN/LjQķXSGj/]j^x%}AGJfE%a*#.1GLhd7k!&_y~uk9)ZۙWװԇKx؇γyB]=f+3 5q#Ih_nt ^Lpw̾:hW\0%N1 2Qf0,v\ O'8'/FZ6+Uŕ3 :$̮ra1Ir EEuȚrR'qg5z9.JeC^O?5V!ÖS+灷PGͧ9urdsb}]4wZ0o{INlՉ.]VcO^"|#Y 6^|Ѐ39݀:O8(k(}LJGlµFH5:hen~m lD]ucjP ;Ȃ]=X Ba刨U# XY9a?O:lq1+lʪF~O|i@]eq+N;݇xc"Eb DrfT1qr)wDClAHĭz9ƙ77quAcgV_~!ikyܡ|BS\?vO^ ~$ӹi  ^ΕMuWH%΃ CeG|[zBODd6߬WpaIG:gхE+(S5&kf$ Ikbyn-(.LD79IM-i/ 9;  )E(imMcXеøTꒉ&w9zC} ub/n2_>+Z©Ȟ֫T"U=AM ZKla!TSO&!C.e/qi1]]e^PgdjF~16v 8]&ڥv;1SeU+򀫝X\_9L VFayصx,֦W-ͻ0'5d!/FTȭp2d+\o0h`%db>RW<%~Fg)h:Ì>)z{(86^JsLQq,%Svz[}~=\Ū"Z|9uگbPkϗ X11NcjRD\⓺uFS +-ݬ8޳E/WI>Qʈ0T<xr;O,'zFfwQ|Dv-'qvUp.QU(9]e LUDAfElνeS/%wIyvɈԄbʽAw {tG.^'9<ɩ/V&URRk)lRh>./b8B۲ {y!Oao~Zmn\bR`.l\⦆n'r+zGB H/4Æ v>wёs.x|=3Ytuf0i/[-4ģL Au/<Ԟa0Q@gfAua|]3ζN8SΫ Aåay(D$ |&T"ʤ;y1+{)gǨ2rdWU pF޸+{k;@,M2NЊR'kyBʄnK4 *yn-SqSx=z{e7ȣ54 SR;<w$kx]4s=N}oqVʛ^LHF>_`fxI\A~"s=fez2\ ӛKP,,V9;_(-mg1z< pvQ~hk[;hu؂aĸdW,N#+n򄾤.E*; 57ӏ_!u>fZYd#ؚl{q;#m$T]3`&SbGiʔȕMLm34iٞaAfit3B2*[@7|NQIdž5lc CcQwOh4iUkO0qSM0g[MoVi,D*3_BbKa?gj_ZXnbՎaM$$={4iQ{H9Lk<B@/eJUozE PůVF-㗋FPlj?XG}F-e{ -@m7`E!{%Vq-_ +圗SRm[M-jk JBWG80ccUK Cmn GkDXdmQd==)7ȁ᳠@כEDIRS3Dtg V*b))ags`Fm7nLCo!=qYSAX Pr2AN`| S+t5vnD-8Mٿ]F|q,1s4U!q]wdO"Z :ܦ:*8Uȶd d>` QQƃ85RdH֧2?"16ךD19P;^ʣr&2Y Xt@B\aM b _>Uf@h ~UThѳK2"OX_RUs:ӡ3e۷\{Q)KlVPYc:,?>~BADOS\3-[蛮/#sھ!~;e%dg$" B?2H=殙0)@yrJFG{| YKTT8@AsBSf8 7VGNƍK{mo\!ǭI3n o/9*ۻoGUj-c yԫi U! M'¿9,^~1ieMF8cvSkbK[.ɩl'| ,n*D1A x=uF:ڷ5 TGyEؓҙo/+QH~.T3wƖ'qMo-vԲUr&tJ߬(e3'st.|H,=iJ`ywA dwmc`bd3KxDLR:8-W+/ )˲PĆ5=e٭;qG`ȂW͠W3c?OC}2u˨I!QdqJ}-' OmXKQ endstream endobj 191 0 obj << /Length1 1608 /Length2 9212 /Length3 0 /Length 10042 /Filter /FlateDecode >> stream xڭwuT642J0CwHwtItwwtÇ{|{oggZCG*a 1Bά@6A \ * q<9y0` 3g[X$YANNP@@ zlm:zL,I{g$ p9@ pl@)5uU9@.e[ bXA` Okp', 8 ,l-@?!sßp5 4glb yp|=Cp -TU]ZLK˟ƞ`f`89`i :y<~lpۂɀY,@pO u{78:AVl@ΧOmEl9tg; ?;DvX0U!O%;}"$o&j.>+<0p29:x Di `')88ᴅں,m-lVfO3[``Г`KLgC 2/oveCU }Mf?}"}@,!) qx\|O -? b u=5iϞh9-V.0ؓoSi]rd9?zo\I3$m -/ UՎ>4zLAl}'r`hKfS2-cdWu4bˡ>r%?k? (Eju{?//{{ێQ۷ș?b &Q'9{j,X?%S[t]We[\mj)]Eʪ._߷6iIq7QL6s #A [Ea>Np}NLyEa_.Eze}t7ޘ+'3P#wD*K˨lڪǢU|}ˡ> Dz.n" ^9)i7i#7q=U2S.2YρݐKT"kQ=gOT#HX$q.֤#ƤLcRBNN$i3yÙdGA 2M)Ó<$A-wE}/lh#.;z6Tub%oF-lj(U &R*lQ0jE.vq9{."+y J)$e$?s"Zg$]t5h9y٭o5VYX56,ʅ|Ç%ӃfkNY aݙ'V sګg =*Dߔ!{۵{~+I֧Hdjl6uu޷ڠ|u3&81GI3"]婑5,R*A YY`kh_"WYN]Y*vHͭʲh1Wu8v 琩;"\X=IyDev)c9B%(8E<*:6KOFaz:Y Zi+!P6®d O^ ^:&(`vOVqn_ a-XqFɪY:X-:\3vqGRslt<o>+&r(qudߓz\BpΙ[[Q%na݄oG$JF+^ LcN.3Kޓ/֟S+sG0~WQcU 8@*_{9򨕽oT]Ne,^eZ餝` [h+,҄9X9ވۈ}'+һkd쁘y$VGr;z|*zHPwWW /p Ql&p߳| !Gk~( :o+.Ibs8xɮ[ ؤ[T'pǚCBEBﴨ1I/mYIx9,Wl uzo0(ExF<ΕdU{.|?ڔ+AU⑗u@xވX_%g&5erڶr:ʇ:z vddBmLl}~q`[lj0k.KC_. = 'hR"<5K:] de? $ v*-etB8q3>^cS.+labĄU_#K^{y9quP 6SeDAH1ĀZN1/J}bZ ұWSBiE2ݷXr*ShN':6>yNx5g(M<ԣstG^PtN9yIslžc0F8dc(ϑɵo{FB}%\hlsE¶V&2o <S}{[:/u)T{Xu>bz.vMOzMEAQ_kFX\J#-'^4N+T : KƓJ(ێIâ"asXI;#Zw=@eNrBjl_='7- XK";k `XiGUءIHKuE|˛wU; 9Nv̰-q{s"/9 .nZT{mY17 L+!`Kby+tYC35ȁѽY1"xΞ\Uށ]e?CCNsu "3FҺH t04 (uS ;(9"Xh|>_ڞ#>Όa/Fh[pHdCCdŝh`MMVdB '";kcCt}|˖//HqқI וUMG2۫ђs12VWBk,9p F9*ۦ nΛ?65JkKmkƈfj.s>Lnd^eqMTy4,Psv,*=ߍo:.w&ۛH;0,=# AUTL)3/w/薍h|ZnC3v LtmX$zuxZbͺRs6Ѱ ?PƑƅ{S\2}sj' B%sÅSv$]$%o6x_ͧ-@:ɺ$rXa`_,)+z\}+ [H͠EԳdg!KdI eePClI ͈res9 Ž}Ғl$~*CtDa%:[P׽!xJ;Ɨ.oK⒒FEJG/ ct>6?v2M@C9FޥJYO 9Um*0f:5ˆ:](VՕ#i@)pRhOWK@S>Z7fjo&&奔fZc?6N(lY߾.hV#"_~[mO2kM# c-Ǽ58xջ"aD/3vvo\$ǧDCq ElWF0Ŗ.|3?_Ga=38ja>_UPhHG" 抆b+eDwANi֠4XcR߈Cx F1#bv8hԞ2֛Acw9΋r? UZ}ff%5\V* Fo`eB5ބ=F",@þ(.2`ӍZ|)"YeRCoʱPzͼ=R (0P Ig)l`hR&EN)?& ?->YC1ZKĊ :!Q-mzdcT8[~*X nkPr=ŏԌ%^[":~YbBjĺ8GjIjNuFxW362wj UNjbpx|vyk}'ȝ[G@inW"v)0]f6(Ӕ0gLQP2Рzly](Kѣ-^3)+$ѣjn6G$oOiwe;(I{z$+1;mXDMZNǦҒsݍNb;a|jH_f[.Wy"gO8MkȿAigT]U !S;zTtCW؟CL=NbSҦ2"`oml*Y@tڇ '! JQC}m받afV:`)&ҟEQVh4qnFr9@[:)2Nj5-?vg32}e}6ݟ!=гC»zʉÌ N1Z%w*ACI4'7&- O3÷#|%uZM߸>zI.n=g:㋣U57+",:\l|lM 6-eN@*=~)f=@"$ŸICZ0*?6.'Uo@erǴOyp }mޯ5uM|v+EU_I5זBt̙) vsyٛSyâv&śK ƃFR *=An ^9/+ԥI ]"ed)XocJQ<ֶzsDxa:A̸]_'^o4u}+-`/0VSJ;wV]rt5@Pdi ܡZ}F))"\*mo@`)^D}JA@=>('Cs7B/)~9T{7S#Kdm_)=xA@d6Qp:!GoAa~q# !2h_FNoвP nx0XDjƆ>[Pv Cp)>Fr/ZWЛ ̐(Ґ>qJO"EN5ˋKo_s'.5^`%<{ f`5bwD nW__keFX5˶Ai,y ᝘\v±[WA+!~:_R_"S;)%ɞ n{;߸oq^UK=Xrҷl-nJX QT-Hz q0h/{NG8k0< QϩJT9)䯓ب'5Xu-y*lzNC=UXM05/˯#'h}'#arP+xs1H2Ngf5?6;ȼ Y><=5wێd7__ؾ2F"^ -1})R}:D`UsfwXSno\w+pzo+ZQDa*Ma+Pu B)Mq{ +Mo(Z>ƞ̸DO{;I$1+N8evBNu}FCTpE\%ƈG>t~PQyob@ǡy~yڑ㹂RӳEz5g]”918<8^ώjG;,12ȇoák/Bf^ie&q/(~Kѡx4CyfjIC8#Վs1g4Rt[x_w+9퀼ydd>jȿ1JdhY[j_o.ӞWF&x$ept $p"U52%Ŕ?(~ySmR囩Zŀz.6py%h-|}ƒ}w\!{Av9^;peq yfK'ĥʶFNݏ˽VV{oؘN~$:0QoyjҥjL#SNW{Q(-@{7䈋1dsr^іpWk639QlE?!Ҡee(' > *o wGҋ "4z8&4ԇj]GebXw-T",i F*U+ E5x*r5aIͱpܯYWZF8Ӡ ۧJE=:ԃ܋lAZuRmxfCݹ,zr=0Gc/(U 9$;|S d3hPŋk$ ȧCD^]&8N Y.~ݵ߯HٕK= 20cI\% -C5p Q;O೒@ojEL4%jLJǺY,we_Nv(eJg]1Yl ob&ARD*!7:];&@ bD'< Xwƭv&&"=u^G9 _yc1#'2Hc#K7JR$`l;_w2qP—0Bvʂ(ݙ&Ymg,(K>ؤwy>ɬ׼THWm2~adaR:{?,4oG 4_ Q5P br(:fkՈ4n/{".c:_`$erCml@ G%gRuO6 |vD}ɣń<؎]F7!v|?tɺAHs=)weJ;lWke =_2ktA2}Q3'zHn(W}mU&-6"ckẍXQT'_gI_y&qP*؈Oyat_vATv88u/mבR)sO(kVl匃E$1*>~MMYsRQHG0+(٘La2:&9ꞩ W|g!%OZ@t}cu98P9HwDoK:G>Ƀ:rRJpTW|yKua}gKكPWnsBî-9E&k<(Z; Z%N/~6'*~e:&DH $uӈYʘDIn5FA' JLKHBiI;2ӄ&vk;o_X.GnZou'E/0 endstream endobj 193 0 obj << /Length1 1144 /Length2 3569 /Length3 0 /Length 4321 /Filter /FlateDecode >> stream xuTy?:fd$2 ` xA($|qb 7 V~|p3L` }?( [J`{2H/;H ?8zL0::DDi_-TWUET qFzgM3%湏^+3ct"Fa" 7O7i  PUeFveug)=nh⑋›.kH(5⣵)`fXտ%cVasp͐C@ Vrȹ@CQO~clڪR7Tvu vN~j~ڣ( (}0_]sDU$?R-Od91v|[p{~R궭t!?ߟ5jif(saH,M8KZ8ofќ~Z/r'bCIbfPt!K~m lÉw&e왞F*Xƚ DD5x, f\)^JXwK\r#vn_FˉM uEQv"2N+wdzMOMg?C}9=Gp4_[rQ_tCZlHwh\BDZ#kgx F0;ʔ%iTlOهbׁ,>c=*Lvz gV3~xR 'UC1q};g})P Cv<⋟=>XU׼Kel+Kx\{q!dxZ_'ۂ4ƁR%mYv'_XɄ{Jf' x>g QgyMVoC W٨5^c,/VE2?S\kɓ-S5ZؘH#GLqLFߚLdn&†_zF罝OHOR`i/"-[y8^*%%I 2lU-£koCy]@ Cn-G2A•asuH:Y %TbxŧaMdۉm(0J|tP@_L%_1toZ;&^fW Saf*>@D/ԦIׄҡ)K46[\ p|zDLdƈf9ZG MS7@iWW?@"TTeHukDKժXZ<7r+xeho+_xkPyz[x*n;Ϛ:oYځ1ϰخvu"?fn}@j83Ǒy$z4 d@ٴhӒ!4>܅@r1M \J0D LrrEGo !+aqO2M &F 8Ȼ]Q,UN6ޕ/9wy [oD@]-m  KkW4WZAF%Q^Ciʇ( Ģt6Xc-a-&8ĺ3sX:ob:ւ=2 2| ]\7^v.]"r+k.G錕u'< W݀IJwFOQ[|N_x5(VFzM $9ZvBOetL9H"׺XG+O#\ TxCmh oT!Ǖ*h{Δ;83 ^`Wl6Ar>=ծi%t眨ٵ׺?2J]'PW}rЪmzf-xlv(`hF\D98׉&dh`Ty*TYa\3BTO ^^5E{d dZ#3 N pqɬoJ331l+\"yR_HE}sQ^PK sز Xe.`spt.7S ~BC*!.A溶"Fdžrmg c*AOi]49N,S;ذcy94ehyo/,Fd{`x}UZxš#w bc["C 7${ ,=5;<ݩk>邥 h2 aua*ocBDX4xU2sNq`X_}\p`ڭ3Do(8Sa[{{<̀9-~_dbdwLDg]r~˗ =>VOŰTnhj*d5.ЙkT-sUp:x.#]BVOrʃX~bȋk7іu3Ne(DUc]J|eңt'6pS>cU1Ee呍*I9@]a-t9RZ9K]yzuYO%QiAtvwݵ]kxZ.k깿XIDT endstream endobj 195 0 obj << /Length1 1634 /Length2 2363 /Length3 0 /Length 3215 /Filter /FlateDecode >> stream xڭTy>ѯtO|914~Bu='v ?Zaj(h<|:U l{I>N^K^NIMkfu|y}9\lӗ:cgD]TvN^PB WKZn.:|ƄqҁHTة >:nqXj_ZYV5Ge?jMw&n~}KK*~`ؘu?94x7v?{}UuSΥ}LٔJާ̍Kh&\VHRM$xz~.;Ps2UܓJk)?XRz88|Ol}`7nEeAzhڦ@`nՈRjKRwwB:*$sMkDr>׬ѨtB85m϶bKqo%Pcg ;ov K=]?Z8.['K7cۂ܋׭bldVN*'Y' j=&Jb 6wwJ$uwn/ʝ^eAOR Pi8;|'\]޺Im?͠N@ QuUuuk=<~*B\h-]8+)Pu>yEuh\vI4+>ɎNLA89m^6 SZb1bo^飭y2Sƞ߼#=iʒ`QfEuO{ G+ͫVEuU{N<̻츳z{"zã9ڄôUb#;r)*ѻ9|ѐ؞L-8xdY|jڼQprLqCD\KTZ49[Jca]:7x eڏ7+){Tn;F1K_4X d7r/3;z#P~o;BڠF{iBD{Kqq]!Ε fBeBb\lfa;f{V/#O?xH)+v=эtb~E2%sUB" Fͦ-2+dadW2g]+oe3},0 `a"68S*6/-Էm?-41hٺz1 kpe팮ǥӢ+{X :LMqoU>7a2E7_0"sBZ NW5\͊TM+I׺J<1펵A|Oq+Jk̮OƏL NP?K Tǣwv]Al# Y (#춂M~L"|H֨J"8ɝ[Fv,Q1u>ۚ`j__}kʕG0=QmvrAwz2R/o{c}δ/x__\r@Be7(k+O,n}/u*?2 ~k_׶DA$X~$wfoLn2WsgԫxCtƕSAH\a>oRz2w+ 5?y+ ݐR63KZ\Gd7n;Mb><4P;D($OLaܯU4N{<_V߰T=%= endstream endobj 197 0 obj << /Length1 1626 /Length2 10636 /Length3 0 /Length 11458 /Filter /FlateDecode >> stream xڭxUTݖmp  ww \ )]wwKp/qnߗPc|{\s~(JRe5F3 P 02LTv`^yFΉLI)4XA @ hȔ1%@EKO/_!z2,@-AՀ@0Ĕud4R) hl Pv62[AN@Z9` 25'7,'1hjt3b޾VN Gcm0 djl79oB72 dheUUO1NVon- lWK`޼c+tU0r5vfh7 g'+ſ0Ǝf@'77쿦>{c{{[G'+֜ )䭶],9t{@4  c30`4GfVCJhg*3 +K{ZVmczhc;+[WҿGkVlk>HD@o0h$i4SZ̍m]dtt{FV[Zڀ. I7y/" w@߸G+ `<#* vx2r9X!^.@:+Co}u7 )쯵Q6? Mu;MA֩iqqnV`z<*pojoSu0S$K,p7-uW279mO:U;7^A1ZڑVٜ&.ͽ*EOē쎈gw~.y~}LSbphxYxDdhpg>;'4nx]omNcSYc[y:os}6+;$(Q"q߳RcIK4b6B`CGoY8kd+jZh-1ȹqĎx|fL*5T|4Iߋv\@{,j ^|hh_tƟ M]96Jń揋ю2.%cb䎌7i}mQu1#=\< ɋ$-Q3qM~b˃` ?؃׷ ӊ*(%5$%STQCj3)תzaF#"qf w~/._a K?gĮp&"I 8zYUaO+iv$T}i@Xf_5e f4nn{Wx YNHq9w/_2c7͹Pƶʙ 2."- _̻S*FҋoT/OFۨ^?HWM?һjM㴹e/'[~q[!nU[a>pʶ/$u7d}跅gH?>,$ŕuN0(}^0:,ztYty9i\Ve^F!jeuT{,6=UDAo7jb>0u]8ܒE'{}TqA@[o]s~0Nqpr ]dVD"fd^gkq-ų"W{f+W }ء)??-ž:&#[X8Jh)9 ~-1 d28AhWആ ^ {3W{15v!b56~cmDd{)wuSEM32ϓqx2MR]|.ie\.qFMʡXqa[~rBaA²!%|{sucɠ4?Nr1n8|Λ9~No@@HEP O B9tBa@?6ha>flB ~/< O-aU:05O[C,~v`ggd|sm]cX.7p~}}4ϰ8mo:*'43P[:QO IQTWZAw-YczYBةpW,.<}Nem_vlбB ~ͯ>NB!%f^cZ,8IDǵ JX;0Uk__ٝl s;2GRW)7y'R^u%HNepJ͊^*Ymm(8Bewv(Hp~"/yQ"&AKɒ8 =U։8EU_R M뎆xGS+B..tFf}y3+=c7S}d\@7ʨ1 gX7)u쪜=iDL,+Ajiਪ4}UO^밉9"LDQC#qRv@ԴN/is={j\*n1?oTH!9_CҬ.udzD?VpDgW# _f`]<Ӡ`걦}(Xl=YK@IMż (SvzN}?pF<9o۳A@^y*Kq^lf pp &x2i rQ4L }7Vl/;Q>iJ( KI((6'O״Ց:EC*ҟ;> ԣl% <=/s}!n~ոz#DNlPxnCb,2>eDd=KxQY®Yz}/^^RcKC ,?^ѝ+Sr1;dᗐ8d_#.9h4`߷V7ްݲs40{LH@40eԕY97[ÔxAH._K⸫Cuc@]*::å(6(}׸_kx{mhN->l_WF|Gs/]}D.@d/'⥭p[j="HQ~aR+6]4ܫB:^^6=iiKB^*t; E9vTr<Q+2)<7s N=%aix8,odfRñT߷Šm6KcLEyˁ!xG%6aƍhg̞=W ~'a.oq "T"S݄ sĦTuX$Oԡvf~YzFus5J0~N <÷&sWIHXxiXc,i"5,rV%Nqe[}^óy9K;?tr~cx,A{~7_0uK{&!_Gn3-7'J7 };医YўSiw ط9It%ȗ.7TwJt.OḒF#6Xy P1y<\Wi.l21gY"腫?굗d%S gjYU7a٬9GJ6_ aM(yaoe* W%)QI6Đ#XpD?$b(z4.NEbA#s#iqX]c)[?iiP-.S끽DTѦWq2͠Fv>b2[&u(Όix|]]|_;2i[XmrM=@ՒGRL1ᔪ gܞ-Jؤ&'?|JEGȁ6G۞햊?z#@4QgY;8\? <1y>琄*blY> A=qM4ML<5nxYV-Fg u_ %^&? HU.<f@W 4-M,K}xa 7g{rw\ž 0]QטqLJmT$9(B1T1;l%d>}h4D';jՔRn!h%kSR&=zOK}"TF49BNLozQ-vLd-bk#=?4pW%/)cDKӹR9L=50-kKvnW+|caBLW٨ݨdޝDrʨ}Uq$Z7L0G'{)6Neѧ2ycZeZ/Iet.ZPY\'חE=F*t˓{hǮLaZDlY8o h450 ]Bd4E:ec) (j 6>Z=!NͅF~-aIZHqހ9LrLc%O,ʭ4m7Lmə  HizBH 3c r02ft-sp>kmǓS~驄"F N.]4MFlj5{6 n;zsnMQ²^BHt̆eVO,8z}L?0L=b䝊9qٍgɊU*NK6ٯ,4y .fX0nЋ|'`q3saőR]܌Uu"~sl`}]!G+4 ǽa)ƼXlElƃvo yEJ> 'ȳ1iO>y\t݂h֗캥邌鑸-zxy枔H8`Z].8Mx&kƒ]hQz||y= Z--,3syÄ6.cݏ 1}3azЦ)׻ZOҊ$MNWz]¾ѯRԌIz;oL8X?Co D~c1Jh=H* t1gGٶ֮mU(R;nzC-C;{ Ju<\ s:"|jݟr,9Ϊkb̃{## -D3ga'g e|AM3#˰;>O^4uX?o/7&k`O>$? 9ac;zkkHظiG^i=Quv{, 3UOΦ(rl5^%Z@ D%gwKjs#NQ 94j\m֖3=p\1>I[8{}ʵڈPܐ&ZJz-K_ecApPw 4ch3G`3wWTW?RL-݅LNϴwʃOF1"fӺ+K_5ʶnp'>6^4elfAOO" FPß<>°\"SS9} HfנkpvW tp>9{P)f ǸFG?O򧂝eR`lw(soB|dmKOq=nL/)GIkw&.P[~gTvsއNx]ݤBNQAҨHARvʦnPz]'87Oqp/ռ]q[y?j ~wxJZkil Ҷ:?~<le-lgrH0a̩hTJTѤ6L@GyK'Wldhhm0 6SܒGG:[g K0!y[M5d~nϾ k119GӋbyZ]k$O4Ɛa#d^ި- :dZ|?!]3[˄OǼ$ua#֎9;ɔ;3rg8UV O~$h|&'&T;{ĮKmB;6`+qRuۚ.=EѦZ~'[Uu阸*n?mA7H tfC}* C.hsI4Ɏ>[D\ BRʸ2~ɨFș3iW1~X"ح(ğSnXr>׎賨P*4}ԉOBp孺 !se߃lTzoEjQsQ#53@*.<NJgK2^+)'l׵G2E-Ҳտ&H`:S󃘒'cԭ6.DdUs5C\}y0a྾4P\ёV# qF0lt/Yt^ܐiШtI4$ CsUtcnJ21`+`IUuH5(GU/s , *vtY{w2 D")$EjIU_?C`fv>%*ùZV"S9k Ϝ (seaƒv0> ><7 ŠLnW! vnxv- Y>0jZf_0WtƠwVLu!|Q;.{y U=Y[dr#,_vh}A%;utP*ej:"he{PQ%NݮAdˏ=)gP{ѓCcho[:loR$lWn>ڂ V'^)UK|y Jǖ}'̖cfǫ1 tWؘ-_'># އ<%fɅе)yD4߶d(XKũb0&YV;h$ƕ3AJ֠T`& ˹-eG1biPͦ'b-͘-;.;opk1úٸ+k J.l$+懜"_8n/O1#It ェFB|7w93`ڦ%;~Z!;b\+Y1aofVi<~ lƢx"RSN?⬼T֮!@ZwQ5/O!)Xs?Z`lrVs~3g͓WDni dSC O "ʽ{3|LLNBߘ R,Q27-1lAoI)O6wN{ZL\eIR=ݢG9V7;[u% } Z}ތG9s;Volb.qx&EhݒUŜ,8iNR@NwiyUFb$:"cvRmۚdv"xOLofASB2b r(,~_Ar kD}æ!74&ugS*1ĉ`,%Avp:S؎8!e:sO!|XtD- ɦ1J }5T :ύ.T۸B *,U+^71SPίeR6Jn2a{حZmwTFpn}P;]s]S~pKl7'|o:0F!Oem85Dpc6?.L/B-6XTA6FőlWH|_Z:-U8ɳG 0c//&gbtIj|Ov^7+DT)'\~i>NcArgeINJW& O{p`B_s M0B0 {~tyz7Oz*S[XȣlSfbOwOγckK3ѫA~6kG_:^Dm/?C) [@L-.B7O"-u{XMz!WQ?%}(+ +%1e]O1\ӿ`&$5E$Ҫ8JV~>kD=}ǁ^.zyCp=qh; mp0Zbw,}y¦n½xFbzjäHrS 5b 8+0EĂ;y+]诛| ]CX洯&p.h endstream endobj 199 0 obj << /Length1 1630 /Length2 17510 /Length3 0 /Length 18353 /Filter /FlateDecode >> stream xڬctem&۩c۶m;m۬ضYI***6z޷O}~1=qM\kMFB'djol&noBD :+s)YĎ\vF.f 3S GwtZX(Ք5hhhS ?4=vnf6fv.!U.fs@DAQKJ^@)!03s2(M@3;g3*)Ҝb 9f&nf&fhfN@g3o\@;W+7WBN-l);88\*;OK#b;-MM\)_0.F@;g?@g#Ͽ983?38Y9ژ9;OwNR翼e?s8٘11i7Y301[n:735򟙡'AoH}$7PB oWKz+]2Fv{ g9|l6'jat`R.F"dgFz @3SE%o%W35sڙ_m112%23_3iKo G5r@M_@Ly3rqzt?OzFQq13;mS/Znmބ'*#;ӥ+dRTg |$ԡI0־?#b.ys@pӆ/ߗju0A 1\#jQvBQpwRIY` *ĭ0Izc(Jqzhu$ rM<ݹ{ f Hl f;W~#k<~m>Dy<[3G&(QÕcBV&,U ع) j&CGbFS%ܟ:RfxrP,o;1Zv٨ef Elt2mX*]f5Ra&{-ݸ+VCA/6qڊepůz~F+:~Ǽ|wB3(_1sJTku$Zp8WyH2؃~o>$R?~8^y:P]<a9w~w \@mr*g!C_xZdm߳.ᅳ2 pNyEr&Ti]ĈbK*r $ ~f3$N =+sbHX'Gd$V `1\Yq s R,.T ?7ѵיd6Id$!\0L"H#W8垻cgۯ+|Z>#eƏTaO>W6N:Ώ{=io>kERO{=6E"oU7vɷoQKr5*ny2 R--?i7n];u5HQ:HFxu0}<bVHYA`' ?~s3.h͏vIg]htW$ҔkjW"eI a+vd*QZC dsQXIirxM"&,Pmtx ]05doABBmbA#dQ镝E垎FO/8 _7Zbo>3GSJu68烳!HIꜞ`{Y1 -a:Cj&&gQtԹ~+783.PV:pBVBypӹ :JN|}pwۇWqTʛ/is*Rk"_ ik-?냑'y7yY[#Rr@~!5*GDqqD=pì%Qb]ct_+|AmD""&h4/GB[ PFUr/Bz-߯mۧlo!ydoGs#8!Y|c[ߨGP]=_ }A-{xrL6D~M>HFj ?W_'/(7qlZ|2U q[\쁾_IV{ ) 9f[ EZ7%PtV~W|ssxZ=Ӎ߆AD_ R\`4-tEp#wgOa۽pW˦EFrCl¶gX"Q5Z_+t<[)pEԍ!6gK+03; 4Vw! 'hHOYsx@ED``cܳ ?L@_Bԭ QZ݁FڍXoUM.A 0VMB^yhS7O+ZZkߗ]{pҖ^A: *HWاt1|є #UJm@#7ϫel`a06w>^QLMd]9JsrnEL{iAjK>XtI] p_*bJ?68it˽c@Cy*V,HV2"Wc*4ǣYLXSzb#ߣ }s~įKQΑ[;?!)T͈r~TvEaDҎ/~N<1CM'̖P~(^dBh4 j| Ml%b\xok u\~dP/)PUUnlA0&+ujfTiV~67!14LdKʹm_pki A=F@֔ P-c}fPX2 T~BLP>nD$G*Rn5,2#}qdRU5 v0[Ks;S3`刉V]629s5u蜤3M/m>΢ipd o@ⱂ xšLuk Uva9BrL \܈xI!15EMayN#hz/#~*"rٻˀިpWb 6D=@x" 2ɍ d,J ꚺ=&/%ea{: \ 80iSQOлܭm B1QME! yP4`s4N9131ծya.e#½Eah( Ei`ƂZ[Wgct\9q,G!z?; rVwK[QUV q;>KkS躮Pa$ t%K <ꭔPpܢP#n1k)7(xV {,T?="ݩ 4z9w7aճ~A:-Cq/ 䘕t*/ئ|qϚD|﫬Myj;5P+y Oަzb/\RzCD᳅ZCSGMv.~7T0ʈR,03!(s+; ?MQ\Ǥ7 }6HHZ4xrWkC).Ⱦ~tY '8UhRI { W 4^M@SƟܐ͈Ar_Ո8 Ĝ9RQ*|r LP-,i,:݇n^a ;˟A?M#`dLYw*Ȃvj"Xv@ ^Nb _ -M䦡TSQ@?K=~}HAgmŘyH+yc.4AP/_mɥXo+}sMr~35lعuˌb<~J_x{d\ibM,Qhz zOpڍ;q0q OE ,F䪲sI"o&@vvYLHvMfĤ{'t{ؤ*ܰhpcޡ/6=yK5ɕnxaX0%r0nňӰjI~E j?iUb{&`% 5fFZ~꩏u7.PJː-$ϹJiWM뫘6E_G8-I',́VߑXB C>K& k9,Y&{@[X.v3U!a}!l5hS B9RGJS ,V -!>0 xAZ$dǜe`ti@iL8`ó1v hr-=iFm[JFL)wnwU9]CbyfK&('aGHj+\ˢM/U0$]]J?X1м'WBv9>l]hvN|b?ع+/kl{Ά~{uZIkyI*h ۅB"XrXӪM;-,|K ]wWAðj|וDmW]z 兑7iol#= ߂|55mzl$mA恾mmЕJj仫BfɀO׽ۛ##|a@݀үcղ9oT^ȴaYGKB{ Uh1j71vtc$D%4JPc8D~us{KIR¨&Z\9lp _3<~<#Y!n#(]YOBC}`cr ws%ʣ깷BG~+πOL#a㩦w4y5l9x>`\eALHh*՝.p)>9ǹԮ(XV)w LU_V5q=Pz52Sߠ>$2hz~h`ݿ chp,߬;]ɗ\IMT5_ӧ_`h'Cr$QT'̌#'m(ӯ:E720S8,Y;k7XI%7aΧ+" efwփyr ) _^)nϰ9gH\8y0)$$ Е{ ie@lmևXѨ.PQ]_LA.2Mq@W/DI6ܬ4>W;)į6U8N6MO/ESmn)kcx+SJܾ^#pԅ^#!OWcDQFTeB^aXHm@I 4:4ɿ'z\yV)USSZgTR@Ɯl% fx|̮c ?#ǬݽꌕN1-'U\l=ڌGI3aO)ʰ,{,bYE}'IUV1b4JR~Sqyu={ 'n/HFmpT1+ u RlW Boi>6?$;@8y1~ ^Y&JLwwKD^/@JCĺX7.t:*i| ZVNCg`"g ,{82OgzG RDLS42ktIc&<&8rkvB#߫30m0mƱ0竞h}UЖIP?^lַaP/n1ԓϯXAuB8³v=vU^p`47(ؓeWp4,U%B9PmH\[]6EYp"Jh4|Ҩ%nTRFlik_]3)sQItn#DO*Ky{/3#kŜpi[o $|%Y͟> [?z);gDF]/钒g%nP0ү@!;.N.7 0Ƀ@B3UhLW74$ c)i<㉕,!^6d%z8Z=^=܀IOM]ɔEZ=t y w#}૟*b=7"畴V"WƴՌy7t[}Gn{'wGa詁 ( Zk Ɇbaũ2:ԩg<}l^VS|J=,] :h߾QgS%v6ѰmjFpEa962hj V9A"ranXt xZƒ-B"'- 6l؎qPsxIIo%&y xYZ%QHVio|J'5/ǘAQ>,2 PY}mWa7M~^h3 Ǫx$:@dl2\MV#â(!qSr֩y.:'C}|=Us˗堍XORQӯD7س7*9^zV'V,r%?N.%9|"FZ,d0+a6_c ۸tTyN͗(A 8< j$HF"4E䃏z1`{\n @2bM %ג{y>G*H)M|.Iv%F2Dpp~sW~,g^*ёi8^F1{/ڗ 8猐2 ȰO1ڭ# JupdP3wje@p]V}4$ݞ%/ A6 F3>.)Xd(؎S_X7BǕR^}Urh&ʫ./<.* )@=~0% n8b{oLK26A&P1G}᪞}Y1reP5 y׈nSfky{GNLqC2 ɼwS\8`xavҹyj 4`ِr1C{w&ohf~{1ػ.tFV9چnY`[|YV̊'eƌw\[(swb4D9yA0,!D0kǕR\fQbW[p= 3e{}֝-#ŝx?[X>JdjSJ(. e=Nyr۾*sZ)[J}1E*L&2~ hq8AR?dO?\D R0+˟gl%"OaV/^,|?6M}A+$xEz;(CѸ|z3S&py72s`7nyH|va; `,Cl$\Q#Jsti^ɳ1`v;YQu+Z)5coJ[7"b]r^E!|4EՆ p僝gԅrslVλ5 }kŵo(,h 0 mb1fz?9"FE  b@Kv \US"Btذ B<郡(jq$3ەH:[lX&,tC?Wn%4+P]S ^R9rPu*JVDjB*TـА^$y"uXIAɯ+-=\u{@/ ~[n {/8S)pZַd[*cO8fpo>KYVs ME֮w`M](E; R?(7f.T$g )N(e`pR2O3hrt=>c,y'ŢƓy3,[}$1V)`#Y["ab؝&v@| -L 5檾qw8oqiط'y[BݺzotgBDZT;"[2„x}L*>X.JRZGR#C_^!5h<~X;.#<&3VA{'p.1+Hldfjх΋퇵K[&!PU -]gKJ̯W~W 1 Mﰯf=0i :"suBfEIFaS^!5Ȍ|bC5qpX@,.H16ު;Љ:*=cA𕗋|_zv4FA3lq[mL9GG j"'Py'A}cILXfT׆%V6E7'a?<tg4mRY510Nݿ"[7k]Pp\2aggTЌ2;果C.np<~ce[ҏCiH#id+ -`Hr&̈H t ,NUv>m\VՊ!熴 Bk> Bi3&nDxj.8޳Za 7rw.oU|lQ;Ut,y@ѱSx_vKքJyƣC%f)HFd1'K6t[: ә`aYHnv7>aV=)E,-F/0o+?w"uV-:CKR3x*B /VVB(nr^+H 3:~k$3@D~zrsǘΛ tstuKdCѧp5ҧbrFTfkWm'asdM7Z>8W=75R\:vVMfYFCn,=ieݣ$^J '.¾/>LC@d^qo"zvI8omAݳ,oƤ KɒQb dJ{ AZ\4$Q:=`FIaYu$ M k{N,Yq#f[t(h NQ}]G4 PB|ד.JMuz ֆ(s R8eGAC[)p< "V2#-bFdVv}!֝S[}d,^&ko6o)RĨkFr|z %ҧfC,(+mg F7vc25$sgr HVeGq]"˙1v_zpQrO@2%|#sqzGp4&N'Fx[-ٜIFWhaeY"UD}[?Z4ݯ H \ iWo s.&QU`0U d"PKˊuEw[!A_6[hY%*XUԺ9ŒXg-D#ﭶ!18Jy~WCnfwgwuyrޕe9/J-zGw.@%8)_9Դy#}F[ ֲߋbJsj͖|5AEǐ}NSZ?_*;2s_vkzͽv{CT^5QŞ!VzF.ek 2G$42b4ֿ;}v轪v꟞{`rH"q%JsV.HWTH%oؽ*N4 ʨ0G*f kQf%JKy_zO&'({A)_,(n8{&[ձldCdʨ ړX"ˑi 4`f~?M'˕eǧ,p#HiPP,Ioni)_f RZkEv@0-{4:w7(1ݡ#X&Rj%DFPU I"]Pȭ)vEz<3;}#6۰ǁ BRew3NiPpR)m UGT TN endstream endobj 201 0 obj << /Length1 1644 /Length2 10554 /Length3 0 /Length 11404 /Filter /FlateDecode >> stream xڭweT]%7ABpn4AK Adͽw73f~NSdשFCCB<ܢ5;'KW-TDC l x 309p;(D < AgAav6p> Y^Xzbg0>0'0L `# a`VT(!`g#@ jgYPg+(d4g.[==;vvsqyعlsP7g5`N3bljȿWp[ olg~ Z- .87%s9=c?Ib_6@g#owNR=sϭvD}imcA;+k(_v+?07? b;3,IAP'FRŸCTA[5_{w7j@׎*'ҳoݏB1bx$٩uT̾* .H8ϋalE* <1K+}N7 )q jEJ %bPĎ*K ڬKJB'kGG4ϖ{{qniiCP+;uq2uIJ?QRcm0ݑ)tRf89O2k4nHQ5%e1S+~CCh1j9~IFӖU}uuƑ;&ke-(WnRXS1}*C/.͹lwU* jbFknr#c-ޏ.AGT澜 ddmdWmS<v{' 1,0զ–P2l-*)_ l׬W!/vqXR2GaPѕ+fW8:x|uýr\i hD. pqeo*h #^^gkJ r^6U^%sT>C<Ex.Hv۳Ihq~Mw*@$+_ f7modχM5aOusr@zD ey垠|oFk2@14%H5&1>"?KaNJb"EB5F/gx^c,PѲ ^]!A;wz,].|DtN&vĿs 2ލgiQLExˍ@~bՓ!jpKC(#R}&!8?l+}KnzMYl,B3JF~Sj:iXqno%qVsYi7ns(Yjy)g )8ᝋ[úՄF`'/ahݜ[V|Q 叢PQ޵g8"Yڼ)Pa#-r\ÀЕ +jv`Nȇm!M Q" e0<N-'IiV/ۺ*':Z1fFpk;7fD$Ɉ߲qaM]X"(=ԺtkhȱJrO<ڼيgq~oSG_ KV99'ƘUi':T']xriV>M./RP rCR=,QV*U=ӻ~zpw}dH;HuMn_XK׀𖾷zMvţ[u ۀUȹ&U>MحKy$~{_uD^/s>1sp;+Rh08K@3n suY0}3ξ Ø"U2 9O^P\LnmN( ON Yow,5pl~,amgAYkHe@ P'j;Or}7|Nw4p@gcJ1ږB (qZ)[\G@muȹ۫: .*B3Nks=%%͒ \0S: X2xaX09?߮?t:uo(mdNb$Z3]uM!r|Q'ΛZo\.e;QSW]*{c닝r#f_6=U5\509h|-i7s_%FǙ7dN tv50c¡sM]8{V-Y(L&]riWFP^E5!QyυNWpql1.$&6=e6MajN!EfŚ98z-Lǔw[R*'P^yS%2KHzӀ|^*]_);#GM1L/']9;myd3V}Cz ZUʙ>hwVвѥaE7!BFǙ[vgT`܏H8zEŰHկ;rA7"f24|6I\F\ìvȿN󦥅I~MʊbDxөȨ{QMZāE{q"j7N^Tcݰ*Ѫ;fciweW=z7ƑoLXdTDC UABPHݑB-EGU(šbSk]gڠ gM1ph V麪A#@BxB&e6%bv򋭪qWSDr+O1ژ4Vo(p/)ޞ;TuK87 x:_r-WRC!uq7c$q7l_¨6nOD?I.lO-W?jd\ؤ{a00/ϋ+r7ٶV({ٔm% C9ʄ߂lcY[o3;mݞ0$oy*M1-EK%'a_$=eF']F8Z{^Tb!#1S25J+m>ԏi`0z<܉AN3-aRu, jW*lB jE~ᄏ!]u Wūu53e,GAj]!*G䙶GVn2 l_%S{K-;qn#:{8R7Aҫ>䃦\,r *pVGC BrԹʕ:?bb,$nӧTo WYVCgy>FAdBjBFY* 4j. Bng׳~oUͅ*+W%l-O4#|Ɯ+vW%lIʏs&hb%}zRE>vaޅutD'M. D*"6iCq#`c[p,QlT(rDV}j+Hg ULdNEpjb+nn!Ixu@$k|UwJM`,qܲûCFc'ǡR/.Z#3XX]sߨjKAd='DWDVK ow{)W\V8!Eg4to}*}n?oE KEo+x*fQĈ>8B_L cA@E+ ևLH:B05A5'cn6s`;#|؂S|f ϜZ 3O%'jI0^a| eދ}㇑SL+ɲQ#+tb#tTR"/ Ƭ>xd?"ͥj:.w/yI?2Y VQU.%YiJM=36k|^)SG)S($?F6";.LJ\Bs[y!%&kdttcolQjRBr'~lWN+{kجޠ㨢&@e]N1<&nCU3uEc,xpj-Ys s~5qTAf,O,:|FWNLT[ YU?.DIjo.2-瞎_zYi'3&:Vle}śp/X9ݿ MÁr֑G,&ДpJܱޓ?tb\l: bgݾORn<ύ5aXywX^73/y`Ÿ>^=t^j+!7b\Q, VT 0ASAx1<3`ejU>\?Z 8MhmJXmU*jn5Qu_hPLTByC\P ˯x[\aR)UҫۘӁн\HtlG T|!|X|"%͍xQYv2qDk4*Q؈YTN%5N3pO+*" 'S5<=tW9?B~}ާz:(x |'b*njݰ"ڮ|3"q&Df.Yɬ8J>]>U%y|mbDMTv b !Jbi\Zt]b )P([,/ :;9Éjs !isk2Ys`ק]rn[=H1 ; zF|)XgϨ1ׁĢ9v+[+&pq]q~J]u<m/,mp.w~,Zthyk@ܔ9SYWKh_2tE \# CdVR^r[S+ t1T Lmt%_>M%eI< ZLD UI.Zm>C񕃖Dƨ@˾ceXuZKj NK)h`McHK 缲5"8vu].0i"3Kgv%h Yx+ga-{ᮤVE?v'~~cDMX=g:JEAKqZA0˗M"Cy5N]Ӹ*>#}RsL&jE,Y[HJ̭qѕ*=0mkR+~hߑF>yGŴ[ @VRTښC(NWĥ5Ѯ,sj+Z4zk 0t{ԛSXa.I009\_3dPI-}PEkO~5t\xBwoi_eMc,5'r?,&UiŸ,OC_YcxVj:@_Nh"jeY;c檽mTB&phic˴Uh)lۻXCXx`^M,Ag>u)swߪ^WK3l.p\LL܊Ə!\섕0Yڢ,k1$E`Q`R_D4^Ux eϘРp1A[P Y>jsKQjA "E,G8_okB$ي"@%MRK2| ъ2>xBXQGnWY};Eẁy$3Y ZIs…M-_Xgp>S+۱5DQ]3|w l^HpBOk4ߍ35m@|7D7 Kmu0gETd]|і ^/=FQ([ms-ĚY3wnkzJ!Z2~ߊt@ zz:DʪK)2Ȅ{ZOHvS n jw쑴Me݆ۣزދ|z-21YS7S=?/[=)&[A6AFm7󄖖2i5;yNkJ蟑l@b ?6מ@LuAr;(̩8ۢ3HOL*x[bN%;4Ag|b8 g}Ѱ,;'٘_#uW?Fn ڂ&g oX}B~6ꁆ,s\Bd [s}ߗ:ȆƒI3`z:mDrtlQb&Ђ]syʶnߎs u8;D'#j=B:= ͔Sb0em/Ŭ~aq ȾLlWfߚ12r6"^`hd?!)RVAj/_fJe4{WwZ!?LNGUL7P1 bj'L*PM>u쀎ǩdLI%K,D8C*B?|fXܦ#u` f#a~P"lyS[~ny)/I:봪\d=Vcl$,]F/Qɰ͜mt I '#[l|Rf:Evoܯ4mC2b'7Ng~: 4D]~;DpK'ε9muƔ6Էǂt7O;s1"ب{x=G5R3,I[g4D_&鼤/t.kor )>/FV\aV)B3N) I@}<15g '9IE} VyQq s1QTce`m>GryfKق%\OYWj=ioOrg]r_:H`~1J2c46yD2 Bߏ  poCH4ݖcҒr'ĩKҡ?~W endstream endobj 203 0 obj << /Length1 1647 /Length2 11303 /Length3 0 /Length 12153 /Filter /FlateDecode >> stream xڭveTے-Am Np6qwwww'5H<ι}~c񭚫fUYƢ QRe63J:302@6.N*v6 v2%;'g'G3#?t0r+ؙ}43qdp;09[y| w_F@'N_uKF{?s9;XX?b86"0/ҶfvM]> z# #S;[k) I#$2 "ߩ%\l>s1hl kX98 d9nM?BC!FAN w`fdqxmM [3aj +ۿ5>t&e -yYefY+<쁀)ogDD^ ,<V.qyX}a&bZefdff|޿шؙۚGF`Gs%݁&?L[ge8 O@ؗ54| al}oX:ۓŶI^oPvp2!gjF{].mAp2koO*藾Nw9]>cۣ5}Dkè+:9L:z깆çˍbrBaxh셙B`Kn'Z9OQv4U$ͩqբrB F QGkzs7*3A&zfƕTdo &j3i|M#-v_$֨U~f!ދ(}J,Yv.!mk,J8zI)v;*QcCL{>&?sQQ5c8Y\Zi}`%;ՍY9?(]=r𝥥PPt /"BpQmts(VTwO[^SOq?x p{L|QN4us!#sk^bRaJ%B ?ѝ;[j>T+_f >*wC H:^88-p9ѬH,hș._j-Fɧ9) ۷nq'nYl3,xYy.lkׇmR&7՚)xg\-'^[BY `suߪ'eh#]}@8@/n3)j:,+ᢶ@{W.ܼaU\ʂEѦ-*!V ^r{(7DA՜1t?{mIF)GyDJƅp/>K#\7\eՎ0a8W%oLKqɼl6;)8YMp$*O֤JN썛QXNKC2Wm1.vSRK4+9:¦~TGtv2:UD6@ N"==;tsŒRqW (-`zo:{s;TѸSd+ C\do>* lߝx>`6dBwQlQa!stx֪!mD@{Seƨgr4c)UN= d?uIOut+4ti,CNF+8e!ٝzܜ^[` |w%,ޫU^'kqiLi$tXDC()hR#xr'{ht&xvyehFd ggۼ٪(͟O;eS:T!p%xVDJtUKt:vJ{o jCx4`+J FՈM9E;vof}tLvt躗nQ)Cx.͉{٘aV 5%|^<3.ΑYϽWWE]I|H)a/Mo2~`Nְ-DyH.KE<6ː+30!>Uq iW.*H,ъ!}a.y֚ȄVYxtXJ=Lb>klVfk>hG_☹ sLlm4<3nbvZzp>BX{ _U.M=Dk`"bBqeQx`{E1^ 9 Uye-> lPrKf+}*6ֳNNHka wPW3U߂) "}Wn4BZ,5|}H@pX~IBWS Hɔ\ onք 5Yk1Upn650kVܛ'\,>^/g6wka ?:[K!BrEtdרIhS)\/YQ2x:RB3>1$Tnrye:;C>ZB !&d`|q MŴ.'άɆ4U48.!oVWyU/_Wk짦wmE]RjޏnJ65|4a$Ǹ B#i՟|Ǘm&[J{暊ppܕs-ceGN+olhoD yϳHTBdrg竭;ΤhRa1で6bJ]֜V|\|"m\8n\PM& /T)Plh6 FО"{X0uIrm͏m6fcx۸*k1b@Zք@<$ ?,66Q}'f .(Dy Qۄ*4!F* H :XJ!T^yߘ`*P`hx'TMY6RyH;2 ZBUiH԰0u;IwLNsÅmKS#9M[U~]&emK8P|?-;&Ԓ@X{0$3W.i&$gºbW4GJ#k}L1*Z _8Dh9=SЉT'x2>7)Ѷǟy'h(uN|K5| )PT@"_-+~4?($;!,lTڎiJ|M(˘B d8i',]~ƃs_OQ2S@<;L4/ݿ`O 8+9[H|!* Y+UCī'z|ė'kYFQ$$kg!ܥSJB _a$#ۻ[zYK½N-ͭct~llcwO :^nE>: eJEGro9ʼnu8Ұ6vwbm(N`VKLXCv}xdD{Ԇ#a3!n@cy ׃Ls@Ѭ$)pqBd %^DF^= ^A(S93>[W4l0&v7낧ndݞ8qp܅t)ݰaTpZYJF^"#E2[S9j]A I5o&踢v(YNlƔg>lfu_'Ps- E#ꓟ0]5Q:ȩ ^r枆w=c/ /Z?$hiex,\=f꾹Cr"m.@Tc780hrjdC ,R<-\S@zBYSь#NkĖzQzb {IHuk{vpAWঽn -Wi 6(NSpP$&J!\rqo0|=~DH"x |.YF-)_UfeAxJeTaq\jgZ'|7&"h3 R%!S`}AD͞;Y3~/N 7-R ]vEkz-,sr |z4>T}~."ы1 x.b`RCJ6]B%Uozh,ekoGPBXЗk\rl'~1(mUX%i:KB9i ZwCCdc KtJdO_jc[T w5 NL4CjJFZy?Y*κQf^XkS1Q4qQofw5gÇ70T`k.M]9gTòB?FsED,}` #K}m-g:#%@jpHbew#3TZC"YO&iX*7|@)E6Vd^S}k-ncƑr ?p®E%Jb.TX%'C9W l1oYhM.m\6ހW2@Y5\ ;Gpqߍ 33<Dݚn;]Ofv!7U| >2;\(D-XlޠgپwCn0 H([Vxyֻ/SPk^̧W!:J4v+$Cj|?a+RՓ;#hڬBpG*Gl 10Y%ᛋl#Ǽ`J )=6 Cv^`jGLٶw7ܖ~ nwmƘA:tBK))D"etCx}{A@ f귒{R<+ u'Ys-ٰGp*5ۍmƀP\ɉ-;2`R@ "q}Bѯ|`CdHBcYJԠ׷l1dݛ"Z9=G6zDwiؔO"s2KT)r 9i%_b ,9o>vs|XJ2ʵ=BYPRd (+)d$S^OhMsua?X|cD2g]1&iK> 񽲭7&sHgIYY;* ВU7sLv1{m ,Plb9OV.DdaѬ-wd0#@&»Ie3i$?[]zwlWs5שކH9j/m[`g>k詴FA]&.$TJ.3ΈQȴ2hQU˧L֨1"q 묝xbN {Yc=za cOIyz>~vbbR)I%]a5[~sp_5d !^$Y={VOk`*Is}Q)ŶQ6= Rm[>[w&>MH1;?D[Ij*KvZ E%~Yv6xxPA g3:\82R¥ 8lb'EUbCRXp c_.@p[\LD3ze^9 ۼD!]娊 N8¯Ua\αnNbZKaZٜ6ELCsx?O-_T Uo{rqy ]p‡rZgn½$o+h; FWHc\Ep$4DЈ KL(^s~fS'йBO۟`5,p.+tº::})gP%Z*]xĄ>a,VQ/; / ]ۻe<Or#D$goZ놶:IDovN iB\ 8*$E/b&( vwa4r4yԑΪfTkg};"|N/4ob^V,RBD%)Eoqe+Q^TݖW~o < lW~ o({CYga`~!sзΟ#/g6=>`;LI[[BVm®A4:%iʷ#b~tA8 .݉4n 4LX[F G-$ݦntY^ 3 nN5t ZUE] X e"*E՞dQl Epxq234+XA :Iћ4qj\}y R?_*] Z =䀫҈KdA>ƱMNIүeW򬁭u#o ROcEƙ"9H-sOLL7XY0 j%CE*Ú4E!ɁtD瑾zMc^bT7mwD2j?r6TMdWGO{\ˠ}W'PeBYl*8Sg $L`~]g!g/{-`/1 Qj͹㺕{[3bVheMBrm(lduA@9c@KVx) ˛U+$|p]/<|Kb:= 7'J~SGĵXy~z43R-rŋm)mn:~ 9ezSs! ++^jH-r,{cٱDu YFwiarۇ/q*m}۝Ա.~'HS/Ԁp$4!|^ ˴_qhs´\光 [.h ",*-v`"-m,8r #TWj7'U&GK"(dۤHOy_NJPk _ԵǧkaB-ې j+(.2>GPG{=}jxइ7tki3zG{od*eF*ҔɆ(Ȯ|쯗6$[ IPC_UKjTMz,T{x&$&gc&:zw#c\e ]ŻnDC_((bHQ+Y^֖ HDᆽu^׆Ub>sU9AP[A-Ei>gHNn Sxgz=ps:T[W3?Cec0\~/:rKW<^I>o!;pu8M$4<O$e ouA[L WmZſvRtλܻIULaPE&,j>4/\oIVI5{"I^ EP!}ڠ$ m13KGS |i߭S^&mOLZO헡e}Ӿj~ 9񮳉$ż_D/1)!ZZp_x`Z;aF>ߏ~3R.u .ޅ|h0N%2X\nQd>yӾan~mf+f=sे8U}6V ew1JE@H+ھPD1xl hAycNG*FTEǵoW;lQߒR]=:ubQjԱQ>DŽ sӃ~*kE3%E'PiM ;Zˊ^?_l m3i(z,ae(Th+bMsyĐ?}FTNrzVhme4LsۺbJ2[Bp=ȲzΡ^R-8."0q*!G7d) bf+QZ`v0^kydUf٣#Fytx,y.=<ҿD *x!-ש4fZtuZC78h0$/OnYi^,O>LRdH:XC=, 5SLyNŠ vv@S2U@cm#V9pa5k? HѕY! A%}pc"(|n^FwsYfq̰!@BgלSNr9Fq3@nUd%L,Siϔ=*MqL7S_wG)"ܟy[1h.HbW.9CK[*?^]VHowN;qj:uWD}r&!t aY0h(w2Z~* .n#l5r9~ex7ɯ)NbdLW}3IK^o*—e2h;áŎznԱQOF,vņQɇk>uiy$IbP@cmT^Bdv>[g_W6R< Aα?3QBG[dwk< zDmFN.BxS>bW>MXvt)rsZ$_B*#k-MIpzc+XU 0}}zӒ 7ޢ!;b>?)WVIݽqi>`;Ÿ^djq41 Ͱ57$oX߱7/0e:7pt17kW?Ua'ŮqX?Tf!7l߽@( >Bx/r$ j^v5/3M4[ ɦP 져_xc:sH)uK_kt6s endstream endobj 216 0 obj << /Producer (pdfTeX-1.40.22) /Subject (GAP Manual) /Author (The GAP Group) /Creator (TeX) /CreationDate (D:19700101000000Z) /ModDate (D:19700101000000Z) /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.141592653-2.6-1.40.22 (TeX Live 2021) kpathsea version 6.3.3) >> endobj 150 0 obj << /Type /ObjStm /N 89 /First 788 /Length 4004 /Filter /FlateDecode >> stream x[ms:_tb!! sgg4I{&tvMظ=GX`~^s3I@ "H1Q0ňN~ CטH1I^(JJFBWI`pDp8!+EpZLk<L=+@w1b@\xbHBFpb U+D1K"(ǜar,@*@8& QC]Dpb0YbИ(~Ux HJ8!#q@{`XX:ЌH02hCb-i@# 󌳂4W$ B=s.(PrF $@gql%@0%c  1úPb ݋[N``U"23VWɓ>.?|4~eǯp|^/RB_'t:E@0^˴*8Lt%ϊSRP*g#d|°BH"Dd[)>020صhZlx3ִȍ\ _[}];лѷϵ$ O`N8Nܠށgh.0q( QlZzHuwg\;'I@4ګXϥ=hBoLո.vY\=x-agBӏ<6\W߮qGc/B#å1nBd*@3;pNόU r1G 9lL6tFs`hXsx1V7m;㷱\|7v1vpAǤ[pZ܋F^7Eضmms'rDia9)<8ˉ(r8GڝMYrp9ně'x X(GbeҜ  hh(pQ` Fg[V0LjVɍgd8`&gBGp~s&\N2،TY&3elHU:qUNuRTQ_t_Uz#)qxǏ.㝯}β}`WdM؎&ڞ5Ug7bn zߠ1+)XלYS6V)i Jt[7 |\Lnos,$ԾW+X6]|όƁ(Ϩc31eˆѪ :~ڇy?DtBDGK[ Zk&˕-)04ã62 ,ojsgIvtn^֛o8NY=Kw٤`8~ᅴ}2cms;3}XP@܃ǝν|gϥ>ڝ}ɭ].QyS7>`XCPg&vlK_5h*AGYH z ï m{˲ewDݨ~` ܗ-<䯐}K_>U/ݣ})"5ԛ̨b/;k?S/RW73K9n?ΚMlDW~F|ZZvފ?uYS5B~mk,]7צtl}~3&7vغڹ??lD [ZBo%"֠\"^ђ[iZ|Xbhڧ%!ZAK+ҒZPhôPAg5~Il[}pq26&At!뙮Ymi19ze,&CV@el[=( A&OFL'fㆰ2hc\-UsjVx0ji<[ujr#5V@lŻduM%'=}dM357N2Nka^|WL| pvˈ97z^B_x=76^L,euk;`WG:`2duV̓eV3}>in򬘖zݲqV'_7i>xU`20{cI^d` k"L_ӧr,@0t-v9[EK"z9N iY,ż, $;KLӺI6`m}U!l>I[|Evsה[4 kCɦ.rl{S:YQ.,m}ŽjfJI,KrX.JuEݰn]*o8 hʖpt8Whf'a^$'uZ!c>, ׁLW,Ie 2Na~;Q|mfBqbT.*шy-Nlcd%7dE tlԿ񱣀@d |urkuw}f\m6ײW9=#emY}s&꾪٨(Ἐ7UzQSd_R endstream endobj 217 0 obj << /Type /XRef /Index [0 218] /Size 218 /W [1 3 1] /Root 215 0 R /Info 216 0 R /ID [ ] /Length 528 /Filter /FlateDecode >> stream xWQg\PLS(%AMBzRB6ZX]8e+[m;l^s{3Yr07ns06Vp3G{!>Zp!a8975.E>kV(B7 L ̂j $=8 MpNB3Mpڠ-N>8 pxo,C;Od8EKM?Ȱ= 4PbH:AOL!N-]Ѱ[ҁ][_U^!M\Qy ^C  on) $m|܆4}jyx nښ~cK'J k iXhPeHB߀ _4HGF'_>hvP91Emfʂ*9? FA&M6Jn_*u\St}^V*~W*(u)ܿTzP,Z- Ղ+ ]w *?=Twseq endstream endobj startxref 151710 %%EOF radiroot-2.9/doc/manual.mst0000644000175000017500000000046414207520027014407 0ustar billbillpreamble "" 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 radiroot-2.9/doc/radiroot.tex0000644000175000017500000001753314207520027014757 0ustar billbill%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %W radiroot.tex Radiroot documentation Andreas Distler %% %Y 2005 %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Chapter{Functionality of the Package} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% This chapter describes the methods available in the {\Radiroot} package. \Section{Methods for Rational Polynomials} \> IsSeparablePolynomial( ) returns `true' if the rational polynomial has simple roots only and `false' otherwise. \> IsSolvable( ) \> IsSolvablePolynomial( ) returns `true' if the rational polynomial has a solvable Galois group and `false' otherwise. It signals an error if there exists an irreducible factor with degree greater than 15. \> SplittingField( ) \> IsomorphicMatrixField( ) \> RootsAsMatrices( ) \> IsomorphismMatrixField( ) For a normed, rational polynomial , `SplittingField()' returns the smallest algebraic extension field of the rationals containing all roots of . The field is constructed with `FieldByPolynomial' (see Creation of number fields in \Alnuth). The primitive element of is denoted by `a'. A matrix field isomorphic to is known after the computation and can be accessed using `IsomorphicMatrixField('. The matrices, one for each distinct root of , in the list produced by `RootsOfMatrices()' lie in . `IsomorphismMatrixField( )' returns an isomorphism of onto . \beginexample gap> x := Indeterminate( Rationals, "x" );; gap> f := UnivariatePolynomial( Rationals, [1,3,4,1] ); x^3+4*x^2+3*x+1 gap> L := SplittingField( f ); gap> y := Indeterminate( L, "y" );; gap> FactorsPolynomialAlgExt( L, f ); [ y+(-3/94*a^4-24/47*a^3-253/94*a^2-535/94*a-168/47), y+(-3/94*a^4-24/47*a^3-253/94*a^2-441/94*a+20/47), y+(3/47*a^4+48/47*a^3+253/47*a^2+488/47*a+336/47) ] gap> IsomorphicMatrixField( L ); gap> Display(RootsAsMatrices(f)[1]); [ [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ -1, -3, -4, 0, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ], [ 0, 0, 0, 0, 0, 1 ], [ 0, 0, 0, -1, -3, -4 ] ] gap> MinimalPolynomial( Rationals, RootsAsMatrices(f)[1]); x^3+4*x^2+3*x+1 gap> iso := IsomorphismMatrixField( L ); MappingByFunction( , , function( x ) ... end, function( mat ) ... end ) gap> PreImages( iso, RootsAsMatrices( f ) ); [ -3/47*a^4-48/47*a^3-253/47*a^2-488/47*a-336/47, 3/94*a^4+24/47*a^3+253/94*a^2+441/94*a-20/47, 3/94*a^4+24/47*a^3+253/94*a^2+535/94*a+168/47 ] \endexample To factorise a polynomial over its splitting field one has to use `FactorsPolynomialAlgExt' (see \Alnuth) instead of `Factors'. \> GaloisGroupOnRoots( ) calculates the Galois group of the rational polynomial , which has to be separable, as a permutation group with respect to the ordering of the roots of given as matrices by `RootsAsMatrices'. \beginexample gap> GaloisGroupOnRoots(f); Group([ (2,3), (1,2) ]) \endexample If you only want to get the Galois group abstractly, and if $f$ is irreducible of degree at most 15, it is often better to use the function `GaloisType' (see Chapter~"ref:Polynomials over the Rationals" in the {\GAP} reference manual). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Section{Solving a Polynomial by Radicals} \> RootsOfPolynomialAsRadicals( [, [, ] ] ) computes a solution by radicals for the irreducible, rational polynomial up to degree 15 if the Galois group of is solvable, and returns `fail' otherwise. If it succeeds and is not `off', the function returns the path to a file containing the description of the roots of and generators of cyclic radical extensions to produce its splitting field. The user has several options to specify what happens with the results of the computation. Therefore the optional second argument , a string, can be set to one of the following values: \beginexample "dvi" \endexample Provided `latex' and the dvi viewer `xdvi' are available, this option will display the irreducible radical expression for the roots and cyclic extension generators in a new window. The package uses this option as the default. \beginexample "latex" \endexample A LaTeX file is generated which contains the encoding for the expression by radicals. This gives the user the opportunity to adjust the layout of the individual example before displaying the expression. \beginexample "maple" \endexample The generated file can be read into Maple \cite{Maple10} which makes a root of available as variable `a'. \beginexample "off" \endexample In this mode the function does not actually compute a radical expression but is only called for its side effects. Namely, the attributes `SplittingField', `RootsAsMatrices' and `GaloisGroupOnRoots' are known for afterwards. This is slightly more effective than calling the corresponding operations one by one. With the optional third argument the user can specify a file name under which the description files will be stored in the directory from which \GAP\ was called. Depending on the option for an extension like `.tex' might be added automatically. If is not given, the function places description files in a new directory `/tmp/tmp.' with names such as `Nst' and `Nst.tex'; the temporary directory is removed at the end of the {\sf GAP} session. %Note that it is not possible to have as the second argument. The computation may take a very long time and can get unfeasible if the degree of is greater than 7. \beginexample \endexample \> RootsOfPolynomialAsRadicalsNC( [, [, ] ] ) does essentially the same as `RootsOfPolynomialAsRadicals' except that it runs no test on the input before starting the actual computation. Therefore it can be used for polynomials with arbitrary degree, but it may run for a very long time until a non-solvable polynomial is recognized as such. Detailed examples for these two functions can be found in the next section. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Section{Examples} The function `RootsOfPolynomialAsRadicals' does not generate output inside \GAP. Depending on the chosen mode, various kinds of files can be created. As an example the polynomial from the introduction will be considered. \beginexample gap> g := UnivariatePolynomial( Rationals, [1,1,-1,-1,1] ); x^4-x^3-x^2+x+1 gap> RootsOfPolynomialAsRadicals(g); "/tmp/tmp.8zkw5B/Nst.tex" \endexample will cause a dvi file to appear in a new window: An expression by radicals for the roots of the polynomial $x^{4}-x^{3}-x^{2} + x + 1$ with the $n$-th root of unity $\zeta_n$ and $\omega_1 = \sqrt{ - 3}$, $\omega_2 = \sqrt{\frac{7}{2} - \frac{1}{2}\omega_1}$, $\omega_3 = \sqrt{\frac{7}{2} + \frac{1}{2}\omega_1}$, is: $\frac{1}{4} - \frac{1}{4}\omega_1 + \frac{1}{2}\omega_2$ If one wants to work with the roots, it might be helpful to use Maple \cite{Maple10}, in which an expression like $2^{(1/2)}$ is valid. \beginexample gap> RootsOfPolynomialAsRadicals(g, "maple"); "/tmp/tmp.k9aTCz/Nst" \endexample will create a file with the following content: \beginexample w1 := (-3)^(1/2); w2 := ((7/2) + (-1/2)*w1)^(1/2); w3 := ((7/2) + (1/2)*w1)^(1/2); a := (1/4) + (1/4)*w1 + (1/2)*w3; \endexample After those computations several attributes are known for the polynomial in \GAP. \beginexample gap> RootsOfPolynomialAsRadicalsNC( g, "off" ); gap> time; 0 gap> SplittingField( g ); gap> time; 0 gap> GaloisGroupOnRoots( g ); Group([ (2,4), (1,2)(3,4) ]) gap> time; 0 \endexample %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %E