From 3d38b69f0f7b75a04ed6c7dad098986a6489755a Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Sat, 5 Oct 2013 19:47:33 +0100 Subject: [PATCH 001/163] updated gap & libgap to 4.5.6 --- build/pkgs/gap/checksums.ini | 6 +++--- build/pkgs/gap/package-version.txt | 2 +- build/pkgs/gap/spkg-install | 2 +- build/pkgs/gap/spkg-src | 16 ++++++++++++++-- build/pkgs/libgap/SPKG.txt | 20 +++++++++++++++++++- build/pkgs/libgap/checksums.ini | 6 +++--- build/pkgs/libgap/package-version.txt | 2 +- src/sage/interfaces/gap.py | 4 ++-- 8 files changed, 44 insertions(+), 14 deletions(-) diff --git a/build/pkgs/gap/checksums.ini b/build/pkgs/gap/checksums.ini index 08549c0e42f..286a3094329 100644 --- a/build/pkgs/gap/checksums.ini +++ b/build/pkgs/gap/checksums.ini @@ -1,3 +1,3 @@ -sha1=c3400e3224d857bcf8b20f6ea42dfa8f5c295931 -md5=5d24a0262e2534fb5175d14fc23c1b7e -cksum=1074480371 +sha1=7ef5cc06c5bda115998c56c72ff51215429eef6d +md5=d3cb3dfc93babb304ef5afbf2883c8d9 +cksum=1061697955 diff --git a/build/pkgs/gap/package-version.txt b/build/pkgs/gap/package-version.txt index 6dd8eac1319..d156b0af115 100644 --- a/build/pkgs/gap/package-version.txt +++ b/build/pkgs/gap/package-version.txt @@ -1 +1 @@ -4.6.4.p0 +4.6.5.p0 diff --git a/build/pkgs/gap/spkg-install b/build/pkgs/gap/spkg-install index b20874ceba5..a8ab8ffd8c4 100755 --- a/build/pkgs/gap/spkg-install +++ b/build/pkgs/gap/spkg-install @@ -11,7 +11,7 @@ if [ -z "$SAGE_LOCAL" ]; then fi # Read gap-version, which was written by spkg-src -VERSION=`cat gap-version` +VERSION=`cat src/gap-version` GAP_DIR="gap-$VERSION" INSTALL_DIR="$SAGE_LOCAL/gap/$GAP_DIR" diff --git a/build/pkgs/gap/spkg-src b/build/pkgs/gap/spkg-src index 396389418e5..d5fa4c2604a 100755 --- a/build/pkgs/gap/spkg-src +++ b/build/pkgs/gap/spkg-src @@ -1,5 +1,10 @@ #!/usr/bin/env bash +if [ $# -ne 0 ]; then + UPSTREAM_SOURCE_TARBALL=$1 + echo "Using $UPSTREAM_SOURCE_TARBALL instead of downloading tarball" +fi + SPKG_ROOT=`pwd` set -e @@ -7,7 +12,11 @@ shopt -s extglob # Remove old sources and download new rm -rf src -tar xjf <( curl ftp://ftp.gap-system.org/pub/gap/gap4/tar.bz2/gap4r6p4_2013_05_04-16_36.tar.bz2 ) +if [ -z "$UPSTREAM_SOURCE_TARBALL" ]; then + tar xjf <( curl ftp://ftp.gap-system.org/pub/gap/gap46/tar.bz2/gap4r6p5_2013_07_20-20_02.tar.bz2 ) +else + tar xjf "$UPSTREAM_SOURCE_TARBALL" +fi mv gap4r6 src @@ -46,5 +55,8 @@ rm -r !(Makefile.in) # Write version to gap-version cd "$SPKG_ROOT" -autoconf --trace='AC_INIT:$2' src/cnf/configure.in >gap-version +autoconf --trace='AC_INIT:$2' src/cnf/configure.in > src/gap-version rm -rf autom4te.cache + + +# tar cjf gap-`cat src/gap-version`.tar.bz2 src/ && rm -rf src/ diff --git a/build/pkgs/libgap/SPKG.txt b/build/pkgs/libgap/SPKG.txt index 1f317382527..5e840492eeb 100644 --- a/build/pkgs/libgap/SPKG.txt +++ b/build/pkgs/libgap/SPKG.txt @@ -42,14 +42,32 @@ namespace collisions in Sage. == Changelog == +=== libgap-4.6.5.p0 (Volker Braun, 5 October 2013) === + * Update to latest upstream + === libgap-4.6.4.p0 (Volker Braun, 3 June 2013) === - * Trac #14682: Update to latest upstream + * Update to latest upstream * Code cleanups following a code review by Fedora GAP packager Jerry James, see https://bugzilla.redhat.com/show_bug.cgi?id=919703 +=== libgap-4.6.3.p0 (Volker Braun, 25 April 2013) === + * Update to latest upstream + +=== libgap-4.6.2.p0 (Volker Braun, 9 March 2013) === + * Update to latest upstream + === libgap-4.5.7.p2 (Volker Braun, 28 Feb 2013) === * Trac #14323: remove one more SIGCHLD handler +=== libgap-4.5.7.p1 (Volker Braun, 30 Jan 2013) === + * See mercurial log + +=== libgap-4.6.2.p0 (Volker Braun, 22 March 2013) === + * Bump to latest upstream + +=== libgap-4.5.7.p1 (Volker Braun, 25 March 2013) === + * Removed last remaining SIGCHLD handler + === libgap-4.5.7.p1 (Volker Braun, 30 Jan 2013) === * Cygwin fix diff --git a/build/pkgs/libgap/checksums.ini b/build/pkgs/libgap/checksums.ini index 86db6abfa2b..dabf90c7e55 100644 --- a/build/pkgs/libgap/checksums.ini +++ b/build/pkgs/libgap/checksums.ini @@ -1,3 +1,3 @@ -sha1=068efc14c080b1b5ff2512eaedb7de0a472a2436 -md5=6c4173b4cedb3174fd5fb80831f95ad7 -cksum=2022442901 +sha1=c2e774ad9499bf45a2ef2fa1f665334e5221b7eb +md5=d7b7ffe563d5ef2490d5712900b76456 +cksum=3726733477 diff --git a/build/pkgs/libgap/package-version.txt b/build/pkgs/libgap/package-version.txt index 6dd8eac1319..d156b0af115 100644 --- a/build/pkgs/libgap/package-version.txt +++ b/build/pkgs/libgap/package-version.txt @@ -1 +1 @@ -4.6.4.p0 +4.6.5.p0 diff --git a/src/sage/interfaces/gap.py b/src/sage/interfaces/gap.py index b16a766941d..cd36bc5b7a4 100644 --- a/src/sage/interfaces/gap.py +++ b/src/sage/interfaces/gap.py @@ -858,7 +858,7 @@ def version(self): EXAMPLES:: sage: gap.version() - '4.6.4' + '4.6.5' """ return self.eval('VERSION')[1:-1] @@ -1841,7 +1841,7 @@ def gap_version(): sage: gap_version() doctest:...: DeprecationWarning: use gap.version() instead See http://trac.sagemath.org/13211 for details. - '4.6.4' + '4.6.5' """ from sage.misc.superseded import deprecation deprecation(13211, 'use gap.version() instead') From e22921bba743e36ff372cdaabd8b54e631af45f6 Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Sat, 5 Oct 2013 20:55:05 +0100 Subject: [PATCH 002/163] moved gap_packages to new build system, deleted braid package --- build/pkgs/gap_packages/SPKG.txt | 169 ++++++++++++++++ build/pkgs/gap_packages/checksums.ini | 3 + build/pkgs/gap_packages/package-version.txt | 1 + .../gap_packages/patches/guava/Makefile.in | 186 ++++++++++++++++++ build/pkgs/gap_packages/spkg-install | 77 ++++++++ build/pkgs/gap_packages/spkg-src | 42 ++++ src/sage/graphs/generators/smallgraphs.py | 2 +- src/sage/tests/gap_packages.py | 1 - 8 files changed, 479 insertions(+), 2 deletions(-) create mode 100644 build/pkgs/gap_packages/SPKG.txt create mode 100644 build/pkgs/gap_packages/checksums.ini create mode 100644 build/pkgs/gap_packages/package-version.txt create mode 100644 build/pkgs/gap_packages/patches/guava/Makefile.in create mode 100755 build/pkgs/gap_packages/spkg-install create mode 100755 build/pkgs/gap_packages/spkg-src diff --git a/build/pkgs/gap_packages/SPKG.txt b/build/pkgs/gap_packages/SPKG.txt new file mode 100644 index 00000000000..723de9fb8d5 --- /dev/null +++ b/build/pkgs/gap_packages/SPKG.txt @@ -0,0 +1,169 @@ += gap_packages = + +== Description == + +Several "official" and "undeposited" GAP packages available from +http://www.gap-system.org/Packages/packages.html + +== SPKG Maintainers == + + * William Stein + * Robert Miller + * David Joyner + * Dmitrii Pasechnik + +== Upstream Contact == + + * Dmitrii Pasechnik, dimpase@gmail.com + * David Joyner, wdjoyner@gmail.com (on the GAP team) + * Steve Linton, sal@dcs.st-and.ac.uk (basically the GAP lead developer) + +== Dependencies == + + * GAP (a standard spkg) + +== TODO == + +The crystallographic group packages are untested/untestable. They rely +on polymake and the dependency "cryst" is missing. This needs to be +cleaned up. + +== Changelog == + +=== gap_packages-4.6.5 (Volker Braun, 5 October 2013) === + * Deleted the braid gap package, its not in upstream and we have our + own braid implementation. + * Added spkg-src + * Moved to new git workflow. + +=== gap_packages-4.6.4 (Volker Braun, 19 July 2013) === + * Trac #14909: Add polycyclic, Alnuth-3.0.0, autpgrp as new + dependencies. Removed reference to HAPprime which isn't included. + +=== gap_packages-4.6.4 (Volker Braun, 3 June 2013) === + * No changes to the packages we ship + +=== gap_packages-4.6.3 (Volker Braun, 25 April 2013) === + * Update to latest gap version: ctbllib, Hap1.10, laguna, sonata + +=== gap_packages-4.5.7 (Volker Braun, 20 December 2012) === + * Update to latest gap version, none of the contained packages changed + +=== gap_packages-4.5.6 (Volker Braun, 22 September 2012) === + * Update to latest upstream version + +=== gap_packages-4.5.5 (Volker Braun, 26 August 2012) === + * Update to latest upstream version + * Forked braid-1.2 to fix a function name clash + +=== gap_packages-4.4.12.p1 (Jeroen Demeyer, 27 March 2012) === + * Trac #12758: do not use "newest_version" in spkg-install. This is + needed since "newest_version" was deleted in #10492. + * Clean up spkg-install: use a for loop to copy packages. + +=== gap_packages-4.4.12.p0 (Dima Pasechnik, 17 March 2010) === + * fixed a GNU-ism in spkg-install, that made in break on Solaris 10 + * started proper version numbering. + +=== gap_packages-4.4.12_2 (Dima Pasechnik) === +bumped up design, toric and laguna packages to the latest stable revisions +stripped package directory names in src/, and appropriate places in +spkg-install, of package version numbers, to make it consistent, +and avoid changing spkg-install in the future unnecessarily. + +=== gap_packages-4.4.10_3 (Michael Abshoff) === + * fix "implausibly old time stamp 1969-12-31 16:00:00" + +=== gap_packages-4.4.10_2 === + +NOTES (Added by William Stein): + + grape -- it hardcodes cc as compiler, which of course doesn't work. +I've changed to hardcode gcc as compiler, which is more likely to work. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Prepared by David Joyner (2008-24-07) + +This directory contains several "official" and "undeposited" +GAP packages available from +http://www.gap-system.org/Packages/packages.html. They are +all released under the GPL with the following exception: +(*) grape contains Brendon McKay's nauty program. + +To load a package, for example grape, into SAGE type + +sage: gap('LoadPackage("grape")') + +All these packages come with documentation in the +doc or htm subdirectory (e.g., for grape, it would be in +SAGEHOME/local/lib/gap-4.4.12/pkg/grape/htm). After loading all +the packages, you can type gap_reset_workspace() +so you don't have to reload them again. + +A brief description of each package follows: + +braid is a GAP package for computing with braids, covering curves, +and Hurwitz spaces. +(Authors: K. Magaard, S. Shpectorov and H. Voelklein) + +crime - package to compute the cohomology ring of finite +p-groups, induced maps, and Massey products. +(Author: Marcus Bishop) + +cryst - Computing with crystallographic groups +(Authors: Bettina Eick, Franz Gähler, Werner Nickel) + +CTblLib - The GAP Character Table Library +(Author: Thomas Breuer) + +DESIGN is a package for classifying, partitioning and studying block designs. +(Author: Leonard H. Soicher) + +FactInt is a package providing routines for factoring integers, in particular: + * Pollard's p-1 + * Williams' p+1 + * Elliptic Curves Method (ECM) + * Continued Fraction Algorithm (CFRAC) + * Multiple Polynomial Quadratic Sieve (MPQS) +(Author: Stefan Kohl) + +GAPDoc is a package containing a definition of a structure for +GAP documentation, based on XML. It also contains conversion +programs for producing text-, DVI-, PDF- or HTML-versions of such +documents, with hyperlinks if possible. +(Authors: Frank Luebeck, Max Neunhoeffer) + +GRAPE is a package for computing with graphs and groups, and is primarily +designed for constructing and analysing graphs related to groups, +finite geometries, and designs. +(Author: Leonard H. Soicher) + +GUAVA is included here, and with Sage standard. + +HAP (Homological Algebra Programming) is a GAP package +providing some functions for group cohomology computation. +(Author: Graham Ellis) + +HAPcryst - an extension package for HAP, which allows for +group cohomology computation for a wider class of groups. +(Author: Marc Roeder) + +LAGUNA - this package provides functionality for calculation of the +normalized unit group of the modular group algebra of the finite +p-group and for investigation of Lie algebra associated with group +algebras and other associative algebras. +(Authors :Victor Bovdi, Alexander Konovalov, Richard Rossmanith, +Csaba Schneider) + +polymake - an interface with the (standalone) polymake program +used by HAPcryst. +(Author: Marc Roeder) + +SONATA ("System Of Nearrings And Their Applications") is a package +which constructs finite nearrings and related objects. +(Authors: Erhard Aichinger, Franz Binder, Jürgen Ecker, Peter Mayr, +Christof Noebauer) + +TORIC is a GAP package for computing with toric varieties. +(Author: David Joyner) diff --git a/build/pkgs/gap_packages/checksums.ini b/build/pkgs/gap_packages/checksums.ini new file mode 100644 index 00000000000..aa35fc28db1 --- /dev/null +++ b/build/pkgs/gap_packages/checksums.ini @@ -0,0 +1,3 @@ +sha1=16a66881fb5274f9b06cd782a6258b0317699d2b +md5=38c97b2e5cfca171f25f566a7b97667d +cksum=913933974 diff --git a/build/pkgs/gap_packages/package-version.txt b/build/pkgs/gap_packages/package-version.txt new file mode 100644 index 00000000000..f18045d6459 --- /dev/null +++ b/build/pkgs/gap_packages/package-version.txt @@ -0,0 +1 @@ +4.6.5 diff --git a/build/pkgs/gap_packages/patches/guava/Makefile.in b/build/pkgs/gap_packages/patches/guava/Makefile.in new file mode 100644 index 00000000000..96ab49ac201 --- /dev/null +++ b/build/pkgs/gap_packages/patches/guava/Makefile.in @@ -0,0 +1,186 @@ +CC = gcc +CFLAGS = -O2 -I/usr/include/ # needed for osx +DEFINES = -DINT_SIZE=32 +SRCDIR = ../../src/leon/src + +GAP_PATH=../.. +PKG_PATH=.. +SRCDISTFILE=guava + +all: + ( test -d bin || mkdir bin; \ + test -d bin/@GAPARCH@ || mkdir bin/@GAPARCH@; cd bin/@GAPARCH@; \ + $(MAKE) -f ../../Makefile all2 CC="$(CC)" CFLAGS="$(CFLAGS)"; \ + cp wtdist ../wtdist; cp desauto ../desauto ) + +all2: leonconv desauto wtdist + +# rules to make the executables, just link them together +leonconv: leonconv.o + $(CC) $(CFLAGS) -o leonconv leonconv.o +desauto: desauto.o addsgen.o bitmanp.o cdesauto.o chbase.o cmatauto.o \ + code.o compcrep.o compsg.o copy.o cparstab.o cstborb.o cstrbas.o \ + errmesg.o essentia.o factor.o field.o inform.o matrix.o new.o \ + oldcopy.o optsvec.o orbit.o orbrefn.o partn.o permgrp.o permut.o \ + primes.o ptstbref.o randgrp.o randschr.o readdes.o readgrp.o \ + readper.o rprique.o storage.o token.o util.o + $(CC) $(CFLAGS) -o desauto \ + desauto.o addsgen.o bitmanp.o cdesauto.o chbase.o cmatauto.o \ + code.o compcrep.o compsg.o copy.o cparstab.o cstborb.o cstrbas.o \ + errmesg.o essentia.o factor.o field.o inform.o matrix.o new.o \ + oldcopy.o optsvec.o orbit.o orbrefn.o partn.o permgrp.o permut.o \ + primes.o ptstbref.o randgrp.o randschr.o readdes.o readgrp.o \ + readper.o rprique.o storage.o token.o util.o +wtdist: wtdist.o bitmanp.o code.o copy.o errmesg.o essentia.o factor.o \ + field.o new.o partn.o permgrp.o permut.o primes.o readdes.o \ + storage.o token.o util.o + $(CC) $(CFLAGS) -o wtdist \ + wtdist.o bitmanp.o code.o copy.o errmesg.o essentia.o factor.o \ + field.o new.o partn.o permgrp.o permut.o primes.o readdes.o \ + storage.o token.o util.o + +# rules to make the .o files, just compile the .c file +# cannot use implicit rule, because .c files are in a different directory +leonconv.o: ../../src/leonconv.c + $(CC) -c $(CFLAGS) -o leonconv.o -c ../../src/leonconv.c +addsgen.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/essentia.h $(SRCDIR)/permgrp.h $(SRCDIR)/permut.h $(SRCDIR)/cstborb.h $(SRCDIR)/addsgen.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/addsgen.c +bitmanp.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/bitmanp.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/bitmanp.c +ccent.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/compcrep.h $(SRCDIR)/compsg.h $(SRCDIR)/cparstab.h $(SRCDIR)/errmesg.h $(SRCDIR)/inform.h $(SRCDIR)/new.h $(SRCDIR)/orbrefn.h $(SRCDIR)/permut.h $(SRCDIR)/randgrp.h $(SRCDIR)/storage.h $(SRCDIR)/ccent.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/ccent.c +ccommut.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/addsgen.h $(SRCDIR)/copy.h $(SRCDIR)/chbase.h $(SRCDIR)/new.h $(SRCDIR)/permgrp.h $(SRCDIR)/permut.h $(SRCDIR)/storage.h $(SRCDIR)/ccommut.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/ccommut.c +cdesauto.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/code.h $(SRCDIR)/compcrep.h $(SRCDIR)/compsg.h $(SRCDIR)/errmesg.h $(SRCDIR)/matrix.h $(SRCDIR)/storage.h $(SRCDIR)/cdesauto.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/cdesauto.c +cent.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/groupio.h $(SRCDIR)/ccent.h $(SRCDIR)/errmesg.h $(SRCDIR)/permgrp.h $(SRCDIR)/readgrp.h $(SRCDIR)/readper.h $(SRCDIR)/storage.h $(SRCDIR)/token.h $(SRCDIR)/util.h $(SRCDIR)/cent.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/cent.c +chbase.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/addsgen.h $(SRCDIR)/cstborb.h $(SRCDIR)/errmesg.h $(SRCDIR)/essentia.h $(SRCDIR)/factor.h $(SRCDIR)/new.h $(SRCDIR)/permgrp.h $(SRCDIR)/permut.h $(SRCDIR)/randgrp.h $(SRCDIR)/storage.h $(SRCDIR)/repinimg.h $(SRCDIR)/settoinv.h $(SRCDIR)/chbase.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/chbase.c +cinter.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/compcrep.h $(SRCDIR)/compsg.h $(SRCDIR)/errmesg.h $(SRCDIR)/orbrefn.h $(SRCDIR)/cinter.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/cinter.c +cjrndper.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/groupio.h $(SRCDIR)/code.h $(SRCDIR)/copy.h $(SRCDIR)/errmesg.h $(SRCDIR)/matrix.h $(SRCDIR)/new.h $(SRCDIR)/permut.h $(SRCDIR)/readdes.h $(SRCDIR)/randgrp.h $(SRCDIR)/readgrp.h $(SRCDIR)/readpar.h $(SRCDIR)/readper.h $(SRCDIR)/readpts.h $(SRCDIR)/storage.h $(SRCDIR)/token.h $(SRCDIR)/util.h $(SRCDIR)/cjrndper.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/cjrndper.c +cmatauto.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/code.h $(SRCDIR)/compcrep.h $(SRCDIR)/compsg.h $(SRCDIR)/errmesg.h $(SRCDIR)/matrix.h $(SRCDIR)/storage.h $(SRCDIR)/cmatauto.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/cmatauto.c +code.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/errmesg.h $(SRCDIR)/storage.h $(SRCDIR)/code.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/code.c +commut.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/groupio.h $(SRCDIR)/ccommut.h $(SRCDIR)/errmesg.h $(SRCDIR)/factor.h $(SRCDIR)/permgrp.h $(SRCDIR)/readgrp.h $(SRCDIR)/readper.h $(SRCDIR)/storage.h $(SRCDIR)/token.h $(SRCDIR)/util.h $(SRCDIR)/commut.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/commut.c +compcrep.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/cputime.h $(SRCDIR)/chbase.h $(SRCDIR)/cstrbas.h $(SRCDIR)/errmesg.h $(SRCDIR)/inform.h $(SRCDIR)/new.h $(SRCDIR)/optsvec.h $(SRCDIR)/orbit.h $(SRCDIR)/orbrefn.h $(SRCDIR)/partn.h $(SRCDIR)/permgrp.h $(SRCDIR)/permut.h $(SRCDIR)/rprique.h $(SRCDIR)/storage.h $(SRCDIR)/compcrep.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/compcrep.c +compgrp.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/groupio.h $(SRCDIR)/errmesg.h $(SRCDIR)/permgrp.h $(SRCDIR)/permut.h $(SRCDIR)/readgrp.h $(SRCDIR)/util.h $(SRCDIR)/compgrp.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/compgrp.c +compsg.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/cputime.h $(SRCDIR)/addsgen.h $(SRCDIR)/chbase.h $(SRCDIR)/copy.h $(SRCDIR)/cstrbas.h $(SRCDIR)/errmesg.h $(SRCDIR)/inform.h $(SRCDIR)/new.h $(SRCDIR)/optsvec.h $(SRCDIR)/orbit.h $(SRCDIR)/orbrefn.h $(SRCDIR)/partn.h $(SRCDIR)/permgrp.h $(SRCDIR)/permut.h $(SRCDIR)/ptstbref.h $(SRCDIR)/rprique.h $(SRCDIR)/storage.h $(SRCDIR)/compsg.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/compsg.c +copy.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/essentia.h $(SRCDIR)/storage.h $(SRCDIR)/copy.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/copy.c +cparstab.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/compcrep.h $(SRCDIR)/compsg.h $(SRCDIR)/errmesg.h $(SRCDIR)/orbrefn.h $(SRCDIR)/cparstab.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/cparstab.c +csetstab.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/compcrep.h $(SRCDIR)/compsg.h $(SRCDIR)/errmesg.h $(SRCDIR)/orbrefn.h $(SRCDIR)/csetstab.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/csetstab.c +cstborb.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/errmesg.h $(SRCDIR)/essentia.h $(SRCDIR)/factor.h $(SRCDIR)/storage.h $(SRCDIR)/cstborb.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/cstborb.c +cstrbas.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/chbase.h $(SRCDIR)/cstborb.h $(SRCDIR)/inform.h $(SRCDIR)/new.h $(SRCDIR)/orbrefn.h $(SRCDIR)/permgrp.h $(SRCDIR)/ptstbref.h $(SRCDIR)/optsvec.h $(SRCDIR)/storage.h $(SRCDIR)/cstrbas.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/cstrbas.c +cuprstab.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/compcrep.h $(SRCDIR)/compsg.h $(SRCDIR)/errmesg.h $(SRCDIR)/orbrefn.h $(SRCDIR)/cuprstab.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/cuprstab.c +desauto.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/groupio.h $(SRCDIR)/cdesauto.h $(SRCDIR)/errmesg.h $(SRCDIR)/permgrp.h $(SRCDIR)/readdes.h $(SRCDIR)/readgrp.h $(SRCDIR)/readper.h $(SRCDIR)/storage.h $(SRCDIR)/token.h $(SRCDIR)/util.h $(SRCDIR)/desauto.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/desauto.c +errmesg.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/errmesg.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/errmesg.c +essentia.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/essentia.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/essentia.c +factor.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/errmesg.h $(SRCDIR)/factor.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/factor.c +field.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/errmesg.h $(SRCDIR)/new.h $(SRCDIR)/storage.h $(SRCDIR)/field.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/field.c +fndelt.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/groupio.h $(SRCDIR)/errmesg.h $(SRCDIR)/new.h $(SRCDIR)/oldcopy.h $(SRCDIR)/permut.h $(SRCDIR)/readgrp.h $(SRCDIR)/readper.h $(SRCDIR)/randgrp.h $(SRCDIR)/util.h $(SRCDIR)/fndelt.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/fndelt.c +generate.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/groupio.h $(SRCDIR)/enum.h $(SRCDIR)/storage.h $(SRCDIR)/cputime.h $(SRCDIR)/errmesg.h $(SRCDIR)/new.h $(SRCDIR)/readgrp.h $(SRCDIR)/randschr.h $(SRCDIR)/stcs.h $(SRCDIR)/util.h $(SRCDIR)/generate.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/generate.c +inform.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/groupio.h $(SRCDIR)/cputime.h $(SRCDIR)/readgrp.h $(SRCDIR)/inform.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/inform.c +inter.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/groupio.h $(SRCDIR)/cinter.h $(SRCDIR)/errmesg.h $(SRCDIR)/permgrp.h $(SRCDIR)/readgrp.h $(SRCDIR)/readper.h $(SRCDIR)/token.h $(SRCDIR)/util.h $(SRCDIR)/inter.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/inter.c +matrix.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/errmesg.h $(SRCDIR)/storage.h $(SRCDIR)/matrix.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/matrix.c +new.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/errmesg.h $(SRCDIR)/partn.h $(SRCDIR)/storage.h $(SRCDIR)/new.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/new.c +oldcopy.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/storage.h $(SRCDIR)/oldcopy.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/oldcopy.c +optsvec.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/cstborb.h $(SRCDIR)/essentia.h $(SRCDIR)/new.h $(SRCDIR)/permut.h $(SRCDIR)/permgrp.h $(SRCDIR)/storage.h $(SRCDIR)/optsvec.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/optsvec.c +orbdes.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/groupio.h $(SRCDIR)/chbase.h $(SRCDIR)/errmesg.h $(SRCDIR)/new.h $(SRCDIR)/oldcopy.h $(SRCDIR)/permut.h $(SRCDIR)/readdes.h $(SRCDIR)/readgrp.h $(SRCDIR)/storage.h $(SRCDIR)/util.h $(SRCDIR)/orbdes.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/orbdes.c +orbit.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/cstborb.h $(SRCDIR)/orbit.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/orbit.c +orblist.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/groupio.h $(SRCDIR)/addsgen.h $(SRCDIR)/chbase.h $(SRCDIR)/cstborb.h $(SRCDIR)/errmesg.h $(SRCDIR)/factor.h $(SRCDIR)/new.h $(SRCDIR)/randgrp.h $(SRCDIR)/readgrp.h $(SRCDIR)/readpar.h $(SRCDIR)/readpts.h $(SRCDIR)/storage.h $(SRCDIR)/util.h $(SRCDIR)/orblist.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/orblist.c +orbrefn.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/errmesg.h $(SRCDIR)/partn.h $(SRCDIR)/storage.h $(SRCDIR)/orbrefn.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/orbrefn.c +partn.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/storage.h $(SRCDIR)/permgrp.h $(SRCDIR)/partn.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/partn.c +permgrp.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/copy.h $(SRCDIR)/errmesg.h $(SRCDIR)/essentia.h $(SRCDIR)/new.h $(SRCDIR)/permut.h $(SRCDIR)/storage.h $(SRCDIR)/permgrp.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/permgrp.c +permut.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/factor.h $(SRCDIR)/errmesg.h $(SRCDIR)/new.h $(SRCDIR)/storage.h $(SRCDIR)/repimg.h $(SRCDIR)/repinimg.h $(SRCDIR)/settoinv.h $(SRCDIR)/enum.h $(SRCDIR)/permut.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/permut.c +primes.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/primes.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/primes.c +ptstbref.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/partn.h $(SRCDIR)/cstrbas.h $(SRCDIR)/errmesg.h $(SRCDIR)/ptstbref.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/ptstbref.c +randgrp.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/new.h $(SRCDIR)/permut.h $(SRCDIR)/randgrp.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/randgrp.c +randobj.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/groupio.h $(SRCDIR)/errmesg.h $(SRCDIR)/randgrp.h $(SRCDIR)/readpar.h $(SRCDIR)/readpts.h $(SRCDIR)/storage.h $(SRCDIR)/token.h $(SRCDIR)/util.h $(SRCDIR)/randobj.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/randobj.c +randschr.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/groupio.h $(SRCDIR)/addsgen.h $(SRCDIR)/cstborb.h $(SRCDIR)/errmesg.h $(SRCDIR)/essentia.h $(SRCDIR)/factor.h $(SRCDIR)/new.h $(SRCDIR)/oldcopy.h $(SRCDIR)/permgrp.h $(SRCDIR)/permut.h $(SRCDIR)/randgrp.h $(SRCDIR)/storage.h $(SRCDIR)/token.h $(SRCDIR)/randschr.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/randschr.c +readdes.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/groupio.h $(SRCDIR)/code.h $(SRCDIR)/errmesg.h $(SRCDIR)/new.h $(SRCDIR)/token.h $(SRCDIR)/readdes.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/readdes.c +readgrp.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/groupio.h $(SRCDIR)/chbase.h $(SRCDIR)/cstborb.h $(SRCDIR)/errmesg.h $(SRCDIR)/essentia.h $(SRCDIR)/factor.h $(SRCDIR)/permut.h $(SRCDIR)/permgrp.h $(SRCDIR)/randschr.h $(SRCDIR)/storage.h $(SRCDIR)/token.h $(SRCDIR)/readgrp.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/readgrp.c +readpar.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/groupio.h $(SRCDIR)/storage.h $(SRCDIR)/token.h $(SRCDIR)/errmesg.h $(SRCDIR)/readpar.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/readpar.c +readper.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/groupio.h $(SRCDIR)/errmesg.h $(SRCDIR)/essentia.h $(SRCDIR)/readgrp.h $(SRCDIR)/storage.h $(SRCDIR)/token.h $(SRCDIR)/readper.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/readper.c +readpts.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/groupio.h $(SRCDIR)/storage.h $(SRCDIR)/token.h $(SRCDIR)/errmesg.h $(SRCDIR)/readpts.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/readpts.c +relator.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/enum.h $(SRCDIR)/errmesg.h $(SRCDIR)/new.h $(SRCDIR)/permut.h $(SRCDIR)/stcs.h $(SRCDIR)/storage.h $(SRCDIR)/relator.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/relator.c +rprique.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/storage.h $(SRCDIR)/rprique.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/rprique.c +setstab.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/groupio.h $(SRCDIR)/cparstab.h $(SRCDIR)/csetstab.h $(SRCDIR)/cuprstab.h $(SRCDIR)/errmesg.h $(SRCDIR)/permgrp.h $(SRCDIR)/readgrp.h $(SRCDIR)/readpar.h $(SRCDIR)/readper.h $(SRCDIR)/readpts.h $(SRCDIR)/token.h $(SRCDIR)/util.h $(SRCDIR)/setstab.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/setstab.c +stcs.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/groupio.h $(SRCDIR)/enum.h $(SRCDIR)/repimg.h $(SRCDIR)/addsgen.h $(SRCDIR)/cstborb.h $(SRCDIR)/errmesg.h $(SRCDIR)/essentia.h $(SRCDIR)/factor.h $(SRCDIR)/new.h $(SRCDIR)/oldcopy.h $(SRCDIR)/permgrp.h $(SRCDIR)/permut.h $(SRCDIR)/randschr.h $(SRCDIR)/relator.h $(SRCDIR)/storage.h $(SRCDIR)/token.h $(SRCDIR)/stcs.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/stcs.c +storage.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/errmesg.h $(SRCDIR)/storage.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/storage.c +token.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/groupio.h $(SRCDIR)/errmesg.h $(SRCDIR)/token.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/token.c +util.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/util.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/util.c +wtdist.o: $(SRCDIR)/group.h $(SRCDIR)/extname.h $(SRCDIR)/groupio.h $(SRCDIR)/errmesg.h $(SRCDIR)/field.h $(SRCDIR)/readdes.h $(SRCDIR)/storage.h $(SRCDIR)/token.h $(SRCDIR)/util.h $(SRCDIR)/wt.h $(SRCDIR)/swt.h $(SRCDIR)/wtdist.c + $(CC) -c $(CFLAGS) -I $(SRCDIR) $(DEFINES) $(SRCDIR)/wtdist.c + +# pseudo targets +clean: + ( cd bin/@GAPARCH@; rm -f *.o ) + +distclean: + ( rm -rf bin/@GAPARCH@ ) + +# for GAP distribution +src_dist: + @(cmp ${PKG_PATH}/guava/doc/guava.tex \ + ${GAP_PATH}/doc/guava.tex \ + || echo \ + "*** WARNING: current 'guava.tex' and 'doc/guava.tex' differ ***") + @zoo ah ${SRCDISTFILE}.zoo \ + ${PKG_PATH}/guava/Makefile \ + ${PKG_PATH}/guava/doc/guava.tex \ + ${PKG_PATH}/guava/init.g \ + `find ${PKG_PATH}/guava/lib -name "*.g" -print` \ + `find ${PKG_PATH}/guava/tbl -name "*.g" -print` \ + `find ${PKG_PATH}/guava/src -print` + @zoo PE ${SRCDISTFILE}.zoo + diff --git a/build/pkgs/gap_packages/spkg-install b/build/pkgs/gap_packages/spkg-install new file mode 100755 index 00000000000..97611fe3ea3 --- /dev/null +++ b/build/pkgs/gap_packages/spkg-install @@ -0,0 +1,77 @@ +#!/usr/bin/env bash + +# WARNING -- if you add a package here, also add it to +# the gap_reset_workspace() command in +# /devel/sage/sage/interfaces/gap.py +# + +if [ -z "$SAGE_LOCAL" ]; then + echo >&2 "SAGE_LOCAL undefined ... exiting" + echo >&2 "Maybe run 'sage --sh'?" + exit 1 +fi + +GAP_DIR="$SAGE_LOCAL/gap/latest" +PKG_DIR="$GAP_DIR/pkg" + +# Some GAP packages have weird permissions which can prevent us from +# overwriting them +chmod -R u+rwX "$PKG_DIR" || mkdir -p "$PKG_DIR" + +$CP -p SPKG.txt "$PKG_DIR" +if [ $? -ne 0 ]; then + echo >&2 "Error copying SPKG.txt" + exit 1 +fi + + +cd src/ + +# HAPprime should be added in the future? +for p in \ + crime ctbllib design factint grape \ + guava-3.12 Hap1.10 HAPcryst laguna polymaking \ + sonata toric1.8 polycyclic-2.11 autpgrp Alnuth-3.0.0 +do + echo "Copying package $p" + $CP -pr $p "$PKG_DIR" + if [ $? -ne 0 ]; then + echo >&2 "Error copying package $p." + exit 1 + fi +done + + +# Build GRAPE package +cd "$PKG_DIR/grape" +rm -rf bin # added since rebuilding breaks otherwise +./configure "$GAP_DIR" +if [ $? -ne 0 ]; then + echo >&2 "Error configuring GRAPE package." + exit 1 +fi +$MAKE -j1 +if [ $? -ne 0 ]; then + echo >&2 "Error building GRAPE package." + exit 1 +fi + + +# Build GUAVA package +cd "$PKG_DIR/guava-3.12" +./configure "$GAP_DIR" +if [ $? -ne 0 ]; then + echo >&2 "Error configuring GUAVA packagae." + exit 1 +fi +$MAKE -j1 +if [ $? -ne 0 ]; then + echo >&2 "Error building GUAVA package." + exit 1 +fi + +# Some GAP packages have weird permissions +chmod -R u+rwX "$PKG_DIR" + +touch "$SAGE_LOCAL/bin/gap_stamp" + diff --git a/build/pkgs/gap_packages/spkg-src b/build/pkgs/gap_packages/spkg-src new file mode 100755 index 00000000000..94e5b7a441a --- /dev/null +++ b/build/pkgs/gap_packages/spkg-src @@ -0,0 +1,42 @@ +#!/usr/bin/env bash + +if [ $# -ne 0 ]; then + UPSTREAM_SOURCE_TARBALL=$1 + echo "Using $UPSTREAM_SOURCE_TARBALL instead of downloading tarball" +fi + +SPKG_ROOT=`pwd` + +set -e +shopt -s extglob + +# Remove old sources and download new +rm -rf src +if [ -z "$UPSTREAM_SOURCE_TARBALL" ]; then + tar xjf <( curl ftp://ftp.gap-system.org/pub/gap/gap46/tar.bz2/gap4r6p5_2013_07_20-20_02.tar.bz2 ) +else + tar xjf "$UPSTREAM_SOURCE_TARBALL" +fi +GAP=`pwd`/gap4r6 + +# Make everything writable +chmod -R u+w "$GAP" + + +mkdir src +for pkg in \ + crime ctbllib design factint grape \ + guava Hap HAPcryst laguna polymaking \ + sonata toric polycyclic autpgrp Alnuth +do + echo "Copying package $pkg" + pkg_dir=`ls -d "$GAP/pkg/$pkg"*` + pkg_lower=`echo $pkg | tr [:upper:] [:lower:]` + cp -rap "$pkg_dir" src/ + cp -p "$GAP/pkg/README.$pkg_lower" src/ +done + +rm -rf "$GAP" + + +# tar cjf gap_packages-4.6.5.tar.bz2 src/ && rm -rf src/ diff --git a/src/sage/graphs/generators/smallgraphs.py b/src/sage/graphs/generators/smallgraphs.py index 146d45c2574..5bdc5c8685b 100644 --- a/src/sage/graphs/generators/smallgraphs.py +++ b/src/sage/graphs/generators/smallgraphs.py @@ -2986,7 +2986,7 @@ def McLaughlinGraph(): blocks = map(Set, blocks) B = [b for b in blocks if 0 in b] C = [b for b in blocks if not 0 in b] - g = graph.Graph() + g = Graph() for b in B: for x in range(23): if not x in b: diff --git a/src/sage/tests/gap_packages.py b/src/sage/tests/gap_packages.py index 17e4d44810b..79ed2e42bc3 100644 --- a/src/sage/tests/gap_packages.py +++ b/src/sage/tests/gap_packages.py @@ -53,7 +53,6 @@ def test_packages(packages, only_failures=False): Failure HAPcryst fail Hap true autpgrp true - braid true crime true ctbllib true design true From 358f1590d02e634e91dc696d86c03b134cc3bb9a Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Sat, 5 Oct 2013 22:00:20 +0100 Subject: [PATCH 003/163] provide a spkg-check to run the libgap testsuite --- build/pkgs/libgap/spkg-check | 6 ++++++ build/pkgs/libgap/spkg-install | 7 ++++++- 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100755 build/pkgs/libgap/spkg-check diff --git a/build/pkgs/libgap/spkg-check b/build/pkgs/libgap/spkg-check new file mode 100755 index 00000000000..11ea3ca10e2 --- /dev/null +++ b/build/pkgs/libgap/spkg-check @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + + +cd src +make check + diff --git a/build/pkgs/libgap/spkg-install b/build/pkgs/libgap/spkg-install index 112d017bc21..76dd57f091c 100755 --- a/build/pkgs/libgap/spkg-install +++ b/build/pkgs/libgap/spkg-install @@ -24,9 +24,14 @@ fi source "$SAGE_LOCAL/gap/latest/sysinfo.gap" echo "GAP was configured with $GAParch_system" +# location of the corresponding gap installation +# only used for the testsuite +CPPFLAGS="$CPPFLAGS"'-DSYS_DEFAULT_PATHS=\"'"$SAGE_LOCAL/gap/latest"'\"' + echo "Configuring libGAP..." cd src -./configure --disable-static CFLAGS="$CFLAGS" CXXFLAGS="$CXXFLAGS" \ +./configure --disable-static \ + CFLAGS="$CFLAGS" CXXFLAGS="$CXXFLAGS" CPPFLAGS="$CPPFLAGS" \ --with-gap_system_arch="$GAParch_system" \ --with-sage="$SAGE_LOCAL" --with-gmp="$SAGE_LOCAL" --prefix="$SAGE_LOCAL" if [ $? -ne 0 ]; then From 4d03d78bf0b4610cb706caae9272c96c6f558b50 Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Sat, 5 Oct 2013 22:33:27 +0100 Subject: [PATCH 004/163] checked in the build scripts for the database_gap spkg --- build/pkgs/database_gap/SPKG.txt | 63 +++++++++++++++++++++ build/pkgs/database_gap/checksums.ini | 3 + build/pkgs/database_gap/package-version.txt | 1 + build/pkgs/database_gap/spkg-check | 10 ++++ build/pkgs/database_gap/spkg-install | 59 +++++++++++++++++++ build/pkgs/database_gap/spkg-src | 35 ++++++++++++ 6 files changed, 171 insertions(+) create mode 100644 build/pkgs/database_gap/SPKG.txt create mode 100644 build/pkgs/database_gap/checksums.ini create mode 100644 build/pkgs/database_gap/package-version.txt create mode 100755 build/pkgs/database_gap/spkg-check create mode 100755 build/pkgs/database_gap/spkg-install create mode 100755 build/pkgs/database_gap/spkg-src diff --git a/build/pkgs/database_gap/SPKG.txt b/build/pkgs/database_gap/SPKG.txt new file mode 100644 index 00000000000..c6e8b3a9951 --- /dev/null +++ b/build/pkgs/database_gap/SPKG.txt @@ -0,0 +1,63 @@ += database_gap = + +== Description == + +The databases of GAP: finite groups and tables of marks + +== SPKG Maintainers == + + * William Stein + * Robert Miller + * David Joyner + * Dmitrii Pasechnik + +== Upstream Contact == + +Dmitrii Pasechnik, dimpase@gmail.com +David Joyner, wdjoyner@gmail.com (on the GAP team, but +Steve Linton, sal@dcs.st-and.ac.uk, is basically the lead developer) + +== Dependencies == + +needs GAP (a standard spkg) + +== Special Update/Build Instructions == + +Copy the following databases out the gap source tarball: + * small -- small group's database + * pkg/tomlib -- just contains the "Table of Marks" + * prim + * trans +See also the spkg-src script. + +== Changelog == + +=== gap_packages-4.6.5 (Volker Braun, 5 October 2013) === + * Update to latest upstream version + * Added spkg-src + * Moved to new git workflow. + +=== gap_packages-4.6.4 (Volker Braun, 3 June 2013) === + * Update to latest upstream version + +=== database_gap-4.6.3 (Volker Braun, 25 April 2013) === + * Update to latest upstream version + +=== database_gap-4.5.7 (Volker Braun, 20 December 2012) === + * Update to latest upstream version + +=== database_gap-4.5.6 (Volker Braun, 22 September 2012) === + * Update to latest upstream version + +=== database_gap-4.5.5 (Volker Braun, 26 August 2012) === + * Update to latest upstream version + +=== 4.4.12.p1 (John Palmieri, 20 March 2012) === + * cleaned up spkg-install, made it work following the deletion of the + "newest_version" script (trac #10492). + +=== 4.4.12.p0 (2010.03.17 Dmitrii Pasechnik) === + * fixed this file + +=== 4.4.12.p0 (2010.03.15 Dmitrii Pasechnik) === + * made spkg-install Solaris-compatible diff --git a/build/pkgs/database_gap/checksums.ini b/build/pkgs/database_gap/checksums.ini new file mode 100644 index 00000000000..df1130d4c5d --- /dev/null +++ b/build/pkgs/database_gap/checksums.ini @@ -0,0 +1,3 @@ +sha1=ccba6c2b8d9cdb016544fe97bdce2877c0488e60 +md5=ea2705ef0ba3f80d59a73bccfc4a2196 +cksum=450624507 diff --git a/build/pkgs/database_gap/package-version.txt b/build/pkgs/database_gap/package-version.txt new file mode 100644 index 00000000000..f18045d6459 --- /dev/null +++ b/build/pkgs/database_gap/package-version.txt @@ -0,0 +1 @@ +4.6.5 diff --git a/build/pkgs/database_gap/spkg-check b/build/pkgs/database_gap/spkg-check new file mode 100755 index 00000000000..330f8ba40ee --- /dev/null +++ b/build/pkgs/database_gap/spkg-check @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + + +# Test taken from Simon King's p-group cohomology spkg: +SMALL_GROUPS=`echo "SmallGroup(13,1); quit;" | $SAGE_ROOT/sage -gap -b -T | grep "13"` +if [ "$SMALL_GROUPS" = "" ]; then + echo >&2 "Error, the testsuite for the database_gap spkg failed!" + exit 1 +fi +echo "The testsuite for the database_gap spkg succeeded!" diff --git a/build/pkgs/database_gap/spkg-install b/build/pkgs/database_gap/spkg-install new file mode 100755 index 00000000000..ac4a8142d63 --- /dev/null +++ b/build/pkgs/database_gap/spkg-install @@ -0,0 +1,59 @@ +#!/usr/bin/env bash + +if [ -z "$SAGE_LOCAL" ]; then + echo >&2 "SAGE_LOCAL undefined ... exiting" + echo >&2 "Maybe run 'sage --sh'?" + exit 1 +fi + +touch "$SAGE_LOCAL/bin/gap_stamp" + +GAP=`echo 'Print(Concatenation("gap-", GAPInfo.Version));' | gap -q` +if [ -z "$GAP" ]; then + echo >&2 "Error determining the version of GAP installed in Sage." + exit 1 +fi +# GAP should now be set to installed gap version - eg, GAP=gap-4.4.12 + +echo "********************************************************************" +echo "Installing optional GAP databases, which may not be open source." +echo "Installing GAP packages to $SAGE_LOCAL/lib/$GAP/..." +echo "Please see SPKG.txt for license details." +echo "********************************************************************" + +cd src/ + +rm -rf "$SAGE_LOCAL/gap/latest/small" +cp -rp small "$SAGE_LOCAL/gap/latest/" +if [ $? -ne 0 ]; then + echo >&2 "Error installing small group database." + exit 1 +fi +echo "Installed small group database." + +rm -rf "$SAGE_LOCAL/gap/latest/prim" +cp -rp prim "$SAGE_LOCAL/gap/latest/" +if [ $? -ne 0 ]; then + echo >&2 "Error installing prim database." + exit 1 +fi +echo "Installed prim database." + +rm -rf "$SAGE_LOCAL/gap/latest/trans" +cp -rp trans "$SAGE_LOCAL/gap/latest/" +if [ $? -ne 0 ]; then + echo >&2 "Error installing trans database." + exit 1 +fi +echo "Installed trans database." + +rm -rf "$SAGE_LOCAL/gap/latest/pkg/tomlib" +cp -rp pkg/tomlib "$SAGE_LOCAL/gap/latest/pkg/" +if [ $? -ne 0 ]; then + echo >&2 "Error installing tomlib database." + exit 1 +fi +echo "Installed tomlib database." + +sage -c "gap_reset_workspace()" + diff --git a/build/pkgs/database_gap/spkg-src b/build/pkgs/database_gap/spkg-src new file mode 100755 index 00000000000..21e28890813 --- /dev/null +++ b/build/pkgs/database_gap/spkg-src @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + +if [ $# -ne 0 ]; then + UPSTREAM_SOURCE_TARBALL=$1 + echo "Using $UPSTREAM_SOURCE_TARBALL instead of downloading tarball" +fi + +SPKG_ROOT=`pwd` + +set -e +shopt -s extglob + +# Remove old sources and download new +rm -rf src +if [ -z "$UPSTREAM_SOURCE_TARBALL" ]; then + tar xjf <( curl ftp://ftp.gap-system.org/pub/gap/gap46/tar.bz2/gap4r6p5_2013_07_20-20_02.tar.bz2 ) +else + tar xjf "$UPSTREAM_SOURCE_TARBALL" +fi +GAP=`pwd`/gap4r6 + +# Make everything writable +chmod -R u+w "$GAP" + + +mkdir src +mkdir src/pkg +for pkg in small pkg/tomlib prim trans +do + cp -rap "$GAP/$pkg" "src/$pkg" +done +rm -rf "$GAP" + + +# tar cjf database_gap-4.6.5.tar.bz2 src/ && rm -rf src/ From e4ea66996a274096de1c04a37bc100cce49e3318 Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Sun, 6 Oct 2013 18:14:30 +0100 Subject: [PATCH 005/163] fix typo in version number --- build/pkgs/gap_packages/SPKG.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/gap_packages/SPKG.txt b/build/pkgs/gap_packages/SPKG.txt index 723de9fb8d5..261b107aef8 100644 --- a/build/pkgs/gap_packages/SPKG.txt +++ b/build/pkgs/gap_packages/SPKG.txt @@ -36,7 +36,7 @@ cleaned up. * Added spkg-src * Moved to new git workflow. -=== gap_packages-4.6.4 (Volker Braun, 19 July 2013) === +=== gap_packages-4.6.4.p1 (Volker Braun, 19 July 2013) === * Trac #14909: Add polycyclic, Alnuth-3.0.0, autpgrp as new dependencies. Removed reference to HAPprime which isn't included. From 1f6c156dfd70534f26ddb2e639f57c040dc199fa Mon Sep 17 00:00:00 2001 From: Nathann Cohen Date: Wed, 4 Dec 2013 09:53:56 +0100 Subject: [PATCH 006/163] trac #15482: Say very loud that LP variables are positive by default --- src/sage/numerical/mip.pyx | 52 +++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/src/sage/numerical/mip.pyx b/src/sage/numerical/mip.pyx index 8045c3ad889..1f111655c3f 100644 --- a/src/sage/numerical/mip.pyx +++ b/src/sage/numerical/mip.pyx @@ -170,7 +170,6 @@ from sage.structure.sage_object cimport SageObject from sage.misc.cachefunc import cached_method from sage.numerical.linear_functions import is_LinearFunction, is_LinearConstraint - cdef class MixedIntegerLinearProgram(SageObject): r""" The ``MixedIntegerLinearProgram`` class is the link between Sage, linear @@ -358,7 +357,7 @@ cdef class MixedIntegerLinearProgram(SageObject): """ Return the parent for all linear constraints - See :mod:`~sage.numerical.linear_constraints` for more + See :mod:`~sage.numerical.linear_functions` for more details. EXAMPLES:: @@ -527,14 +526,10 @@ cdef class MixedIntegerLinearProgram(SageObject): argument you may like, as ``x[5]`` or ``x["b"]``, and has methods ``items()`` and ``keys()``. - Any of its fields exists, and is uniquely defined. + .. WARNING:: - By default, all ``x[i]`` are assumed to be non-negative - reals. They can be defined as binary through the parameter - ``binary=True`` (or integer with ``integer=True``). Lower and - upper bounds can be defined or re-defined (for instance when you want - some variables to be negative) using ``MixedIntegerLinearProgram`` methods - ``set_min`` and ``set_max``. + By default, all ``x[i]`` are assumed to be non-negative. See + :meth:`set_min` to set a different lower bound. INPUT: @@ -550,6 +545,14 @@ cdef class MixedIntegerLinearProgram(SageObject): only useful when exporting the linear program to a file using ``write_mps`` or ``write_lp``, and has no other effect. + .. SEEALSO:: + + - :meth:`set_min`,:meth:`get_min` -- set/get the lower bound of a + variable. Note that by default, all variables are non-negative. + + - :meth:`set_max`,:meth:`get_max` -- set/get the upper bound of a + variable. + EXAMPLE:: sage: p = MixedIntegerLinearProgram() @@ -739,11 +742,11 @@ cdef class MixedIntegerLinearProgram(SageObject): INPUT: All arguments given to this method are forwarded to the constructor of - the :class:`Polyhedron` class. + the :func:`Polyhedron` class. OUTPUT: - A :class:`Polyhedron` object whose `i`-th variable represents the `i`-th + A :func:`Polyhedron` object whose `i`-th variable represents the `i`-th variable of ``self``. .. warning:: @@ -1739,15 +1742,12 @@ cdef class MixedIntegerLinearProgram(SageObject): """ return self._backend.is_variable_continuous(self._variables[e]) - def solve(self, solver=None, log=None, objective_only=False): + def solve(self, log=None, objective_only=False): r""" Solves the ``MixedIntegerLinearProgram``. INPUT: - - ``solver`` -- DEPRECATED -- the solver now has to be set - when calling the class' constructor - - ``log`` -- integer (default: ``None``) The verbosity level. Indicates whether progress should be printed during computation. The solver is initialized to report no progress. @@ -1762,6 +1762,11 @@ cdef class MixedIntegerLinearProgram(SageObject): The optimal value taken by the objective function. + .. WARNING:: + + By default, all variables of a LP are assumed to be positive. See + :meth:`set_min` to change it. + EXAMPLES: Consider the following linear program:: @@ -1813,9 +1818,6 @@ cdef class MixedIntegerLinearProgram(SageObject): sage: p.solve() 9.0 """ - if solver != None: - raise ValueError("Solver argument deprecated. This parameter now has to be set when calling the class' constructor") - if log != None: self._backend.set_verbosity(log) self._backend.solve() @@ -1826,6 +1828,10 @@ cdef class MixedIntegerLinearProgram(SageObject): r""" Sets the minimum value of a variable. + .. WARNING:: + + By default, all variables are defined to be non-negative. + INPUT: - ``v`` -- a variable (not a ``MIPVariable``, but one of its @@ -1833,6 +1839,10 @@ cdef class MixedIntegerLinearProgram(SageObject): - ``min`` -- the minimum value the variable can take. When ``min=None``, the variable has no lower bound. + .. SEEALSO:: + + - :meth:`get_min` -- get the minimum value of a variable. + EXAMPLE:: sage: p = MixedIntegerLinearProgram() @@ -1994,13 +2004,14 @@ cdef class MixedIntegerLinearProgram(SageObject): cpdef sum(self, L): r""" Efficiently computes the sum of a sequence of - :class:`~sage.numerical.linear_function.LinearFunction` elements + :class:`~sage.numerical.linear_functions.LinearFunction` elements INPUT: - ``mip`` -- the :class:`MixedIntegerLinearProgram` parent. - - ``L`` -- list of :class:`~sage.numerical.linear_function.LinearFunction` instances. + - ``L`` -- list of + :class:`~sage.numerical.linear_functions.LinearFunction` instances. .. NOTE:: @@ -2026,7 +2037,6 @@ cdef class MixedIntegerLinearProgram(SageObject): d[id] = coeff + d.get(id,0) return self.linear_functions_parent()(d) - def get_backend(self): r""" Returns the backend instance used. From b50d7af25a94022efa29eccd3637bcd9396fab16 Mon Sep 17 00:00:00 2001 From: Nathann Cohen Date: Wed, 4 Dec 2013 16:11:39 +0100 Subject: [PATCH 007/163] trac #15482: addressing the reviewer's comments --- src/sage/numerical/mip.pyx | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/sage/numerical/mip.pyx b/src/sage/numerical/mip.pyx index 1f111655c3f..e4278c4a0f3 100644 --- a/src/sage/numerical/mip.pyx +++ b/src/sage/numerical/mip.pyx @@ -41,7 +41,7 @@ A mixed integer linear program can give you an answer: :meth:`add_constraint `. #. Also add the inequality constraint. #. Add an inequality constraint `w_3 \geq 1` to exclude the trivial solution. - #. By default, all variables have a minimum of `0`. We remove that constraint + #. By default, all variables are non-negative. We remove that constraint via ``p.set_min(variable, None)``, see :meth:`set_min `. #. Specify the objective function via :meth:`set_objective `. In our case that is just `w_3`. If it @@ -175,19 +175,17 @@ cdef class MixedIntegerLinearProgram(SageObject): The ``MixedIntegerLinearProgram`` class is the link between Sage, linear programming (LP) and mixed integer programming (MIP) solvers. - See the Wikipedia article on `linear programming - `_ for further information - on linear programming and the documentation of the :mod:`MILP module - ` for its use in Sage. + A Mixed Integer Linear Program (MILP) consists of variables, linear + constraints on these variables, and an objective function which is to be + maximised or minimised under these constraints. - A mixed integer program consists of variables, linear constraints on these - variables, and an objective function which is to be maximised or minimised - under these constraints. An instance of ``MixedIntegerLinearProgram`` also - requires the information on the direction of the optimization. + See the :wikipedia:`Linear_programming` for further information on linear + programming, and the :mod:`MILP module ` for its use in + Sage. INPUT: - - ``solver`` -- the following solvers should be available through this class: + - ``solver`` -- selects a solver: - GLPK (``solver="GLPK"``). See the `GLPK `_ web site. @@ -205,7 +203,7 @@ cdef class MixedIntegerLinearProgram(SageObject): web site. - If ``solver=None`` (default), the default solver is used (see - ``default_mip_solver`` method. + :func:`default_mip_solver`) - ``maximization`` @@ -218,6 +216,11 @@ cdef class MixedIntegerLinearProgram(SageObject): - ``constraint_generation`` -- whether to require the returned solver to support constraint generation (excludes Coin). ``False by default``. + .. WARNING:: + + All LP variables are non-negative by default (see :meth:`new_variable` + and :meth:`set_min`). + .. SEEALSO:: - :func:`default_mip_solver` -- Returns/Sets the default MIP solver. From 9a666314188dc3681dea63922458096e6380ea41 Mon Sep 17 00:00:00 2001 From: Nathann Cohen Date: Wed, 4 Dec 2013 21:16:23 +0100 Subject: [PATCH 008/163] trac #15482: Scream where I had not thought of screaming before --- .../thematic_tutorials/linear_programming.rst | 65 +++++++++---------- src/sage/numerical/backends/coin_backend.pyx | 1 - src/sage/numerical/linear_functions.pyx | 5 -- src/sage/numerical/mip.pyx | 12 ++-- 4 files changed, 36 insertions(+), 47 deletions(-) diff --git a/src/doc/en/thematic_tutorials/linear_programming.rst b/src/doc/en/thematic_tutorials/linear_programming.rst index c0f39fcb869..42f36acf675 100644 --- a/src/doc/en/thematic_tutorials/linear_programming.rst +++ b/src/doc/en/thematic_tutorials/linear_programming.rst @@ -81,8 +81,9 @@ Let us ask Sage to solve the following LP: \text{Such that: } & x + 2y \leq 4\\ \text{} & 5z - y \leq 8\\ -To achieve it, we need to define a corresponding ``MILP`` object, -along with the 3 variables we need:: +To achieve it, we need to define a corresponding ``MILP`` object, along with 3 +variables ``x,y`` and ``z`` (which by default can only take **non-negative +values**, see next section):: sage: p = MixedIntegerLinearProgram() sage: x, y, z = p['x'], p['y'], p['z'] @@ -132,19 +133,14 @@ We can read the optimal assignation found by the solver for `x, y` and Variables ^^^^^^^^^ -The variables associated with an instance of ``MILP`` belong to the -``MIPVariable`` class, though we should not be concerned with this. In -the previous example, we obtained these variables through the -"shortcut" ``p['x']``, which is easy enough when our LP is defined -over a small number of variables. This being said, the LP/MILP we will -present afterwards very often require us to associate one -- or many --- variables to each member of a list of objects, which can be -integers, or the vertices or edges of a graph, among plenty of other -alternatives. This means we will very soon need to talk about vectors -of variables or even dictionaries of variables. +In the previous example, we obtained variables through ``p['x'], p['y']`` and +``p['z']``, which is a convenient shortcut when our LP is defined over a small +number of variables. This being said, larger LP/MILP will require us to +associate a LP variable to many Sage objects, which can be integers, strings, or +even the vertices and edges of a graph. We use in this case an alternative syntax. -If an LP requires us to define variables named `x_1, \dots, x_{15}`, we -will this time make use of the ``new_variable`` method +If we need 15 variables `x_1, \dots, x_{15}`, we will first define a dictionary +of variables with the ``new_variable`` method .. link @@ -152,7 +148,8 @@ will this time make use of the ``new_variable`` method sage: x = p.new_variable() -It is now very easy to define constraints using our `15` variables +With this new object ``x`` we can now write constraints using +``x[1],...,x[15]``. .. link @@ -160,9 +157,9 @@ It is now very easy to define constraints using our `15` variables sage: p.add_constraint(x[1] + x[12] - x[14] >= 8) -Notice that we did not need to define the length of our -vector. Actually, ``x`` would accept any immutable object as a key, as -a dictionary would. We can now write +Notice that we did not need to define the "length" of ``x``. Actually, ``x`` +would accept any immutable object as a key, as a dictionary would. We can now +write .. link @@ -171,33 +168,31 @@ a dictionary would. We can now write sage: p.add_constraint(x["I am a valid key"] ... + x[("a",pi)] <= 3) -Other LPs may require variables indexed several times. Of course, it is -already possible to emulate it by using tuples like `x[(2,3)]`, though -to keep the code understandable the method ``new_variable`` accepts as -a parameter the integer ``dim``, which lets us define the dimension of -the variable. We can now write + +And because any immutable object can be used as a key, doubly indexed variables +`x^{1,1}, ..., x^{1,15}, x^{2,1}, ..., x^{15,15}` can be referenced by +``x[1,1],...,x[1,15],x[2,1],...,x[15,15]`` .. link :: - sage: y = p.new_variable(dim=2) - sage: p.add_constraint(y[3][2] + x[5] == 6) + sage: p.add_constraint(y[3,2] + x[5] == 6) -Typed variables -""""""""""""""" +Typed variables and bounds +"""""""""""""""""""""""""" -By default, all the LP variables are assumed to be non-negative -reals. They can be defined as binary through the parameter -``binary=True`` (or integer with ``integer=True``). Lower and -upper bounds can be defined or re-defined (for instance when you want -some variables to be negative) using the methods ``set_min`` and -``set_max``. +By default, all the LP variables represent **non-negative reals**. -It is also possible to change the type of a variable after it has been -created with the methods ``set_binary`` and ``set_integer``. +**Types :** If you want a variable to assume only integer or binary values, use +the ``integer=True`` or ``binary=True`` arguments of the ``new_variable`` +method. Alternatively, call the ``set_integer`` and ``set_binary`` methods. +**Bounds :** By default all variables represent **non-negative reals**. If you +want a variable to represent arbitrary reals (or arbitrary integers), you should +redefine its lower bound using the ``set_min`` method. If you want to set an +upper bound on a variable, use the ``set_max`` method. Basic linear programs --------------------- diff --git a/src/sage/numerical/backends/coin_backend.pyx b/src/sage/numerical/backends/coin_backend.pyx index 81fff180242..b7da2538ab8 100644 --- a/src/sage/numerical/backends/coin_backend.pyx +++ b/src/sage/numerical/backends/coin_backend.pyx @@ -359,7 +359,6 @@ cdef class CoinBackend(GenericBackend): sage: p.set_verbosity(2) # optional - Coin """ - self.model.setLogLevel(level) cpdef remove_constraint(self, int i): diff --git a/src/sage/numerical/linear_functions.pyx b/src/sage/numerical/linear_functions.pyx index 242566b9047..88d11d04f3e 100644 --- a/src/sage/numerical/linear_functions.pyx +++ b/src/sage/numerical/linear_functions.pyx @@ -63,7 +63,6 @@ See :trac:`12091` :: 2*x_0 <= x_1 <= x_2 """ - #***************************************************************************** # Copyright (C) 2012 Nathann Cohen # Copyright (C) 2012 Volker Braun @@ -82,13 +81,10 @@ from cpython.object cimport * cdef extern from "limits.h": long LONG_MAX - from sage.structure.parent cimport Parent from sage.structure.element cimport ModuleElement, Element from sage.misc.cachefunc import cached_function - - #***************************************************************************** # # Utility functions to test that something is a linear function / constraint @@ -144,7 +140,6 @@ def is_LinearConstraint(x): """ return isinstance(x, LinearConstraint) - #***************************************************************************** # # Factory functions for the parents to ensure uniqueness diff --git a/src/sage/numerical/mip.pyx b/src/sage/numerical/mip.pyx index e4278c4a0f3..605cc45c8fc 100644 --- a/src/sage/numerical/mip.pyx +++ b/src/sage/numerical/mip.pyx @@ -27,16 +27,16 @@ and this additional inequality: - `w_0 - w_1 - w_2 \geq 0` -where all `w_i \in \mathbb{Z}`. You know that the trivial solution is -`w_i = 0 \; \forall i`, but what is the first non-trivial one with -`w_3 \geq 1`? +where all `w_i \in \mathbb{Z}^+`. You know that the trivial solution is `w_i=0`, +but what is the first non-trivial one with `w_3 \geq 1`? A mixed integer linear program can give you an answer: #. You have to create an instance of :class:`MixedIntegerLinearProgram` and -- in our case -- specify that it is a minimization. - #. Create a variable vector ``w`` via ``w = p.new_variable(integer=True)`` and - tell the system that it is over the integers. + #. Create an dictionary ``w`` of integer variables ``w`` via ``w = + p.new_variable(integer=True)`` (note that **by default all variables are + non-negative**, cf :meth:`~MixedIntegerLinearProgram.new_variable`). #. Add those three equations as equality constraints via :meth:`add_constraint `. #. Also add the inequality constraint. @@ -53,7 +53,7 @@ A mixed integer linear program can give you an answer: The following example shows all these steps:: sage: p = MixedIntegerLinearProgram(maximization=False, solver = "GLPK") - sage: w = p.new_variable(integer=True) + sage: w = p.new_variable(integer=True) # all variables are non-negative by default sage: p.add_constraint(w[0] + w[1] + w[2] - 14*w[3] == 0) sage: p.add_constraint(w[1] + 2*w[2] - 8*w[3] == 0) sage: p.add_constraint(2*w[2] - 3*w[3] == 0) From d2870e1a5a9d449ecabf1859f2d380308eb5dcab Mon Sep 17 00:00:00 2001 From: Nathann Cohen Date: Fri, 6 Dec 2013 14:52:21 +0100 Subject: [PATCH 009/163] trac #15482: shortening a line --- src/doc/en/thematic_tutorials/linear_programming.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/doc/en/thematic_tutorials/linear_programming.rst b/src/doc/en/thematic_tutorials/linear_programming.rst index 42f36acf675..612fdd8e231 100644 --- a/src/doc/en/thematic_tutorials/linear_programming.rst +++ b/src/doc/en/thematic_tutorials/linear_programming.rst @@ -137,7 +137,8 @@ In the previous example, we obtained variables through ``p['x'], p['y']`` and ``p['z']``, which is a convenient shortcut when our LP is defined over a small number of variables. This being said, larger LP/MILP will require us to associate a LP variable to many Sage objects, which can be integers, strings, or -even the vertices and edges of a graph. We use in this case an alternative syntax. +even the vertices and edges of a graph. We use in this case an alternative +syntax. If we need 15 variables `x_1, \dots, x_{15}`, we will first define a dictionary of variables with the ``new_variable`` method From cd5bb43f35adfc8c03c2893275aa8245d76b1204 Mon Sep 17 00:00:00 2001 From: Nathann Cohen Date: Sat, 7 Dec 2013 16:00:32 +0100 Subject: [PATCH 010/163] trac #15482: positive -> non-negative --- src/sage/numerical/mip.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/numerical/mip.pyx b/src/sage/numerical/mip.pyx index 605cc45c8fc..7cde4504420 100644 --- a/src/sage/numerical/mip.pyx +++ b/src/sage/numerical/mip.pyx @@ -1767,8 +1767,8 @@ cdef class MixedIntegerLinearProgram(SageObject): .. WARNING:: - By default, all variables of a LP are assumed to be positive. See - :meth:`set_min` to change it. + By default, all variables of a LP are assumed to be + non-negative. See :meth:`set_min` to change it. EXAMPLES: From dd7bde803644daee20e4b0439914814eb1cf48cb Mon Sep 17 00:00:00 2001 From: Nathann Cohen Date: Mon, 16 Dec 2013 15:16:26 +0100 Subject: [PATCH 011/163] trac #15482: a broken doctest --- src/sage/graphs/graph.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index 27b84a27efd..db23679bdb9 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -4709,7 +4709,7 @@ def topological_minor(self, H, vertices = False, paths = False, solver=None, ver G = self from sage.numerical.mip import MixedIntegerLinearProgram, MIPSolverException - p = MixedIntegerLinearProgram() + p = MixedIntegerLinearProgram(solver=solver) # This is an existence problem p.set_objective(None) @@ -4731,7 +4731,6 @@ def topological_minor(self, H, vertices = False, paths = False, solver=None, ver for g in G: p.add_constraint( p.sum( v_repr[h][g] for h in H), max = 1) - ################### # Is representent # ################### @@ -4744,7 +4743,6 @@ def topological_minor(self, H, vertices = False, paths = False, solver=None, ver for h in H: p.add_constraint( v_repr[h][g] - is_repr[g], max = 0) - ################################### # paths between the representents # ################################### @@ -4821,7 +4819,7 @@ def topological_minor(self, H, vertices = False, paths = False, solver=None, ver # Now we can solve the problem itself ! try: - p.solve(solver = solver, log = verbose) + p.solve(log = verbose) except MIPSolverException: return False From aa82d85328da4a54e6b0d45ee6a8f7408d4d8fd7 Mon Sep 17 00:00:00 2001 From: Punarbasu Purkayastha Date: Fri, 20 Dec 2013 20:42:25 +0800 Subject: [PATCH 012/163] fix output of enumerate_totallyreal_* The output of enumerate_totallyreal_fields_prim, enumerate_totallyreal_fields_all, and enumerate_totallyreal_fields_rel are in general simply the output of Pari. They should belong to Sage proper, so that the output can be later used right away. This patch makes sure that the output of integers are Integers, and the output that looks like polynomials belong to PolynomialRing --- src/sage/rings/number_field/totallyreal.pyx | 11 +++++--- .../rings/number_field/totallyreal_rel.py | 25 +++++++++++++------ 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/sage/rings/number_field/totallyreal.pyx b/src/sage/rings/number_field/totallyreal.pyx index 5aae1e9a0ee..484affed584 100644 --- a/src/sage/rings/number_field/totallyreal.pyx +++ b/src/sage/rings/number_field/totallyreal.pyx @@ -125,7 +125,7 @@ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.integer import Integer from sage.rings.integer cimport Integer from sage.rings.integer_ring import IntegerRing -from sage.rings.all import ZZ +from sage.rings.all import ZZ, QQ from sage.misc.misc import cputime from sage.rings.number_field.totallyreal_data import tr_data, int_has_small_square_divisor @@ -472,11 +472,14 @@ def enumerate_totallyreal_fields_prim(n, B, a = [], verbose=0, return_seqs=False sys.stdout = saveout sage_free(f_out) + # Make sure to return elements that belong to Sage if return_seqs: - return [[ counts[i] for i in range(4) ], - [[s[0],s[1].reverse().Vec()] for s in S]] + return [[ZZ(counts[i]) for i in range(4)], + [[ZZ(s[0]), map(QQ, s[1].reverse().Vec())] for s in S]] else: - return S + Px = PolynomialRing(QQ, 'x') + return [[ZZ(s[0]), Px(map(QQ, s[1].list()))] + for s in S] def weed_fields(S, Py_ssize_t lenS=0): r""" diff --git a/src/sage/rings/number_field/totallyreal_rel.py b/src/sage/rings/number_field/totallyreal_rel.py index a224b775e1c..c126cb5d327 100644 --- a/src/sage/rings/number_field/totallyreal_rel.py +++ b/src/sage/rings/number_field/totallyreal_rel.py @@ -93,6 +93,7 @@ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.number_field.totallyreal import weed_fields, odlyzko_bound_totallyreal, enumerate_totallyreal_fields_prim from sage.libs.pari.gen import pari +from sage.rings.all import ZZ, QQ import math, bisect, sys @@ -665,9 +666,9 @@ def enumerate_totallyreal_fields_rel(F, m, B, a = [], verbose=0, return_seqs=Fal OUTPUT: - the list of fields with entries [d,fabs,f], where - d is the discriminant, fabs is an absolute defining polynomial, - and f is a defining polynomial relative to F, + the list of fields with entries ``[d,fabs,f]``, where + ``d`` is the discriminant, ``fabs`` is an absolute defining polynomial, + and ``f`` is a defining polynomial relative to ``F``, sorted by discriminant. EXAMPLES:: @@ -845,10 +846,15 @@ def enumerate_totallyreal_fields_rel(F, m, B, a = [], verbose=0, return_seqs=Fal fsock.close() sys.stdout = saveout + # Make sure to return elements that belong to Sage if return_seqs: - return [counts,[[s[0],s[1].reverse().Vec(),s[2].coeffs()] for s in S]] + return [map(ZZ, counts), + [[s[0], map(QQ, s[1].reverse().Vec()), s[2].coeffs()] + for s in S] + ] else: - return S + Px = PolynomialRing(QQ, 'x') + return [[s[0], Px(map(QQ, s[1].list())), s[2]] for s in S] def enumerate_totallyreal_fields_all(n, B, verbose=0, return_seqs=False): r""" @@ -912,7 +918,12 @@ def enumerate_totallyreal_fields_all(n, B, verbose=0, return_seqs=False): fsock.close() sys.stdout = saveout + # Make sure to return elements that belong to Sage if return_seqs: - return [counts,[[s[0],s[1].reverse().Vec()] for s in S]] + return [map(ZZ, counts), + [[ZZ(s[0]), map(QQ, s[1].reverse().Vec())] for s in S]] else: - return S + Px = PolynomialRing(QQ, 'x') + return [[ZZ(s[0]), Px(map(QQ, s[1].list()))] + for s in S] + From a31f831bfd92e4fa139d12f951b7b12be9a41c55 Mon Sep 17 00:00:00 2001 From: Punarbasu Purkayastha Date: Fri, 20 Dec 2013 21:43:49 +0800 Subject: [PATCH 013/163] add more fixes for enumerate_totallyreal_* Introduce a new keyword return_pari_objects that is set to True by default so that current usage of these functions is not affected. Fix documentation and add doctests to the functions to show the new behavior if return_pari_objects is set to False --- src/sage/rings/number_field/totallyreal.pyx | 52 ++++++++++++----- .../rings/number_field/totallyreal_rel.py | 57 ++++++++++++++++++- 2 files changed, 91 insertions(+), 18 deletions(-) diff --git a/src/sage/rings/number_field/totallyreal.pyx b/src/sage/rings/number_field/totallyreal.pyx index 484affed584..5996aedc2c7 100644 --- a/src/sage/rings/number_field/totallyreal.pyx +++ b/src/sage/rings/number_field/totallyreal.pyx @@ -183,7 +183,8 @@ cpdef double odlyzko_bound_totallyreal(int n): def enumerate_totallyreal_fields_prim(n, B, a = [], verbose=0, return_seqs=False, phc=False, keep_fields=False, t_2=False, - just_print=False): + just_print=False, + return_pari_objects=True): r""" This function enumerates primitive totally real fields of degree `n>1` with discriminant `d \leq B`; optionally one can specify the @@ -202,24 +203,28 @@ def enumerate_totallyreal_fields_prim(n, B, a = [], verbose=0, return_seqs=False INPUT: - - ``n`` (integer): the degree - - ``B`` (integer): the discriminant bound - - ``a`` (list, default: []): the coefficient list to begin with - - ``verbose`` (integer or string, default: 0): if ``verbose == 1`` + - ``n`` -- (integer) the degree + - ``B`` -- (integer) the discriminant bound + - ``a`` -- (list, default: []) the coefficient list to begin with + - ``verbose`` -- (integer or string, default: 0) if ``verbose == 1`` (or ``2``), then print to the screen (really) verbosely; if verbose is a string, then print verbosely to the file specified by verbose. - - ``return_seqs`` (boolean, default False)If ``return_seqs``, then return + - ``return_seqs`` -- (boolean, default False) If ``True``, then return the polynomials as sequences (for easier exporting to a file). - ``phc`` -- boolean or integer (default: False) - - ``keep_fields`` (boolean or integer, default: False) If ``keep_fields`` is True, - then keep fields up to ``B*log(B)``; if ``keep_fields`` is an integer, then - keep fields up to that integer. - - ``t_2`` (boolean or integer, default: False) If ``t_2 = T``, then keep - only polynomials with t_2 norm >= T. - - ``just_print`` (boolean, default: False): if ``just_print`` is not False, - instead of creating a sorted list of totally real number fields, we simply - write each totally real field we find to the file whose filename is given by - ``just_print``. In this case, we don't return anything. + - ``keep_fields`` -- (boolean or integer, default: False) If + ``keep_fields`` is True, then keep fields up to ``B*log(B)``; if + ``keep_fields`` is an integer, then keep fields up to that integer. + - ``t_2`` -- (boolean or integer, default: False) If ``t_2 = T``, then + keep only polynomials with t_2 norm >= T. + - ``just_print`` -- (boolean, default: False): if ``just_print`` is not + False, instead of creating a sorted list of totally real number + fields, we simply write each totally real field we find to the file + whose filename is given by ``just_print``. In this case, we don't + return anything. + - ``return_pari_objects`` -- (boolean, default: True) if + ``return_seqs`` is ``False`` then it returns the elements as Sage + objects; otherwise it returns pari objects. OUTPUT: @@ -247,6 +252,21 @@ def enumerate_totallyreal_fields_prim(n, B, a = [], verbose=0, return_seqs=False 2720 sage: len(enumerate_totallyreal_fields_prim(5,5**8)) # long time 103 + + Each of the outputs must be elements of Sage if ``return_pari_objects`` + is set to ``False``:: + + sage: enumerate_totallyreal_fields_prim(2, 10) + [[5, x^2 - x - 1], [8, x^2 - 2]] + sage: enumerate_totallyreal_fields_prim(2, 10)[0][1].parent() + Interface to the PARI C library + sage: enumerate_totallyreal_fields_prim(2, 10, return_pari_objects=False)[0][0].parent() + Integer Ring + sage: enumerate_totallyreal_fields_prim(2, 10, return_pari_objects=False)[0][1].parent() + Univariate Polynomial Ring in x over Rational Field + sage: enumerate_totallyreal_fields_prim(2, 10, return_seqs=True)[1][0][1][0].parent() + Rational Field + """ cdef pari_gen B_pari, d, d_poly, keepB, nf, t2val, ngt2, ng @@ -476,6 +496,8 @@ def enumerate_totallyreal_fields_prim(n, B, a = [], verbose=0, return_seqs=False if return_seqs: return [[ZZ(counts[i]) for i in range(4)], [[ZZ(s[0]), map(QQ, s[1].reverse().Vec())] for s in S]] + elif return_pari_objects: + return S else: Px = PolynomialRing(QQ, 'x') return [[ZZ(s[0]), Px(map(QQ, s[1].list()))] diff --git a/src/sage/rings/number_field/totallyreal_rel.py b/src/sage/rings/number_field/totallyreal_rel.py index c126cb5d327..745acd1ff54 100644 --- a/src/sage/rings/number_field/totallyreal_rel.py +++ b/src/sage/rings/number_field/totallyreal_rel.py @@ -634,7 +634,9 @@ def incr(self, f_out, verbose=False, haltk=0): # Main routine #*********************************************************************************************** -def enumerate_totallyreal_fields_rel(F, m, B, a = [], verbose=0, return_seqs=False): +def enumerate_totallyreal_fields_rel(F, m, B, a = [], verbose=0, + return_seqs=False, + return_pari_objects=True): r""" This function enumerates (primitive) totally real field extensions of degree `m>1` of the totally real field F with discriminant `d \leq B`; @@ -662,7 +664,11 @@ def enumerate_totallyreal_fields_rel(F, m, B, a = [], verbose=0, return_seqs=Fal - ``B`` -- integer, the discriminant bound - ``a`` -- list (default: []), the coefficient list to begin with - ``verbose`` -- boolean or string (default: 0) - - ``return_seqs`` -- boolean (default: False) + - ``return_seqs`` -- (boolean, default False) If ``True``, then return + the polynomials as sequences (for easier exporting to a file). + - ``return_pari_objects`` -- (boolean, default: True) if + ``return_seqs`` is ``False`` then it returns the elements as Sage + objects; otherwise it returns pari objects. OUTPUT: @@ -678,6 +684,22 @@ def enumerate_totallyreal_fields_rel(F, m, B, a = [], verbose=0, return_seqs=Fal sage: enumerate_totallyreal_fields_rel(F, 2, 2000) [[1600, x^4 - 6*x^2 + 4, xF^2 + xF - 1]] + TESTS: + + Each of the outputs must be elements of Sage if ``return_pari_objects`` + is set to ``False``:: + + sage: enumerate_totallyreal_fields_rel(F, 2, 2000)[0][1].parent() + Interface to the PARI C library + sage: enumerate_totallyreal_fields_rel(F, 2, 2000, return_pari_objects=False)[0][0].parent() + Integer Ring + sage: enumerate_totallyreal_fields_rel(F, 2, 2000, return_pari_objects=False)[0][1].parent() + Univariate Polynomial Ring in x over Rational Field + sage: enumerate_totallyreal_fields_rel(F, 2, 2000, return_pari_objects=False)[0][2].parent() + Univariate Polynomial Ring in xF over Number Field in t with defining polynomial x^2 - 2 + sage: enumerate_totallyreal_fields_rel(F, 2, 2000, return_seqs=True)[1][0][1][0].parent() + Rational Field + AUTHORS: - John Voight (2007-11-01) @@ -852,15 +874,29 @@ def enumerate_totallyreal_fields_rel(F, m, B, a = [], verbose=0, return_seqs=Fal [[s[0], map(QQ, s[1].reverse().Vec()), s[2].coeffs()] for s in S] ] + elif return_pari_objects: + return S else: Px = PolynomialRing(QQ, 'x') return [[s[0], Px(map(QQ, s[1].list())), s[2]] for s in S] -def enumerate_totallyreal_fields_all(n, B, verbose=0, return_seqs=False): +def enumerate_totallyreal_fields_all(n, B, verbose=0, return_seqs=False, + return_pari_objects=True): r""" Enumerates *all* totally real fields of degree `n` with discriminant `\le B`, primitive or otherwise. + INPUT: + + - ``n`` -- integer, the degree + - ``B`` -- integer, the discriminant bound + - ``verbose`` -- boolean or string (default: 0) + - ``return_seqs`` -- (boolean, default False) If ``True``, then return + the polynomials as sequences (for easier exporting to a file). + - ``return_pari_objects`` -- (boolean, default: True) if + ``return_seqs`` is ``False`` then it returns the elements as Sage + objects; otherwise it returns pari objects. + EXAMPLES:: sage: enumerate_totallyreal_fields_all(4, 2000) @@ -870,6 +906,19 @@ def enumerate_totallyreal_fields_all(n, B, verbose=0, return_seqs=False): [1957, x^4 - 4*x^2 - x + 1], [2000, x^4 - 5*x^2 + 5]] + TESTS: + + Each of the outputs must be elements of Sage if ``return_pari_objects`` + is set to ``False``:: + + sage: enumerate_totallyreal_fields_all(2, 10) + [[5, x^2 - x - 1], [8, x^2 - 2]] + sage: enumerate_totallyreal_fields_all(2, 10)[0][1].parent() + Interface to the PARI C library + sage: enumerate_totallyreal_fields_all(2, 10, return_pari_objects=False)[0][1].parent() + Univariate Polynomial Ring in x over Rational Field + + In practice most of these will be found by :func:`~sage.rings.number_field.totallyreal.enumerate_totallyreal_fields_prim`, which is guaranteed to return all primitive fields but often returns many non-primitive ones as well. For instance, only one of the five fields in the example above is primitive, but :func:`~sage.rings.number_field.totallyreal.enumerate_totallyreal_fields_prim` finds four out of the five (the exception being `x^4 - 6x^2 + 4`). """ @@ -922,6 +971,8 @@ def enumerate_totallyreal_fields_all(n, B, verbose=0, return_seqs=False): if return_seqs: return [map(ZZ, counts), [[ZZ(s[0]), map(QQ, s[1].reverse().Vec())] for s in S]] + elif return_pari_objects: + return S else: Px = PolynomialRing(QQ, 'x') return [[ZZ(s[0]), Px(map(QQ, s[1].list()))] From af627db8bfdca5dbc85fe6c6109a91964b1b9ed7 Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Tue, 24 Dec 2013 14:22:39 +0000 Subject: [PATCH 014/163] update to gap-4.7.2 --- build/pkgs/database_gap/checksums.ini | 6 +++--- build/pkgs/database_gap/package-version.txt | 2 +- build/pkgs/database_gap/spkg-src | 6 +++--- build/pkgs/gap/checksums.ini | 6 +++--- build/pkgs/gap/package-version.txt | 2 +- build/pkgs/gap/spkg-src | 4 ++-- build/pkgs/gap_packages/checksums.ini | 6 +++--- build/pkgs/gap_packages/package-version.txt | 2 +- build/pkgs/gap_packages/spkg-src | 6 +++--- 9 files changed, 20 insertions(+), 20 deletions(-) diff --git a/build/pkgs/database_gap/checksums.ini b/build/pkgs/database_gap/checksums.ini index 941375b9a0c..a3fb57644ae 100644 --- a/build/pkgs/database_gap/checksums.ini +++ b/build/pkgs/database_gap/checksums.ini @@ -1,4 +1,4 @@ tarball=database_gap-VERSION.tar.bz2 -sha1=ccba6c2b8d9cdb016544fe97bdce2877c0488e60 -md5=ea2705ef0ba3f80d59a73bccfc4a2196 -cksum=450624507 +sha1=983a2317e9f483f77bda7ee0a1aa2413c607e53f +md5=bc2ca78ef65b714ca94d88a6d9b2fad7 +cksum=335130228 diff --git a/build/pkgs/database_gap/package-version.txt b/build/pkgs/database_gap/package-version.txt index f18045d6459..af9764a59e1 100644 --- a/build/pkgs/database_gap/package-version.txt +++ b/build/pkgs/database_gap/package-version.txt @@ -1 +1 @@ -4.6.5 +4.7.2 diff --git a/build/pkgs/database_gap/spkg-src b/build/pkgs/database_gap/spkg-src index 21e28890813..0014096c262 100755 --- a/build/pkgs/database_gap/spkg-src +++ b/build/pkgs/database_gap/spkg-src @@ -13,11 +13,11 @@ shopt -s extglob # Remove old sources and download new rm -rf src if [ -z "$UPSTREAM_SOURCE_TARBALL" ]; then - tar xjf <( curl ftp://ftp.gap-system.org/pub/gap/gap46/tar.bz2/gap4r6p5_2013_07_20-20_02.tar.bz2 ) + tar xjf <( curl http://www.gap-system.org/pub/gap/gap47/tar.bz2/gap4r7p2_2013_12_01-10_17.tar.bz2 ) else tar xjf "$UPSTREAM_SOURCE_TARBALL" fi -GAP=`pwd`/gap4r6 +GAP=`pwd`/gap4r7 # Make everything writable chmod -R u+w "$GAP" @@ -32,4 +32,4 @@ done rm -rf "$GAP" -# tar cjf database_gap-4.6.5.tar.bz2 src/ && rm -rf src/ +tar cjf database_gap-`cat package-version.txt`.tar.bz2 src/ && rm -rf src/ diff --git a/build/pkgs/gap/checksums.ini b/build/pkgs/gap/checksums.ini index 31c3c15223b..8c5bcc2481a 100644 --- a/build/pkgs/gap/checksums.ini +++ b/build/pkgs/gap/checksums.ini @@ -1,4 +1,4 @@ tarball=gap-VERSION.tar.bz2 -sha1=7ef5cc06c5bda115998c56c72ff51215429eef6d -md5=d3cb3dfc93babb304ef5afbf2883c8d9 -cksum=1061697955 +sha1=1169b6edcff95a59a8ad37398a044d22d30ec641 +md5=573753d606e4d8b900f2387c377b3dcd +cksum=781240400 diff --git a/build/pkgs/gap/package-version.txt b/build/pkgs/gap/package-version.txt index d156b0af115..af9764a59e1 100644 --- a/build/pkgs/gap/package-version.txt +++ b/build/pkgs/gap/package-version.txt @@ -1 +1 @@ -4.6.5.p0 +4.7.2 diff --git a/build/pkgs/gap/spkg-src b/build/pkgs/gap/spkg-src index d5fa4c2604a..c033c8d2c07 100755 --- a/build/pkgs/gap/spkg-src +++ b/build/pkgs/gap/spkg-src @@ -13,11 +13,11 @@ shopt -s extglob # Remove old sources and download new rm -rf src if [ -z "$UPSTREAM_SOURCE_TARBALL" ]; then - tar xjf <( curl ftp://ftp.gap-system.org/pub/gap/gap46/tar.bz2/gap4r6p5_2013_07_20-20_02.tar.bz2 ) + tar xjf <( curl http://www.gap-system.org/pub/gap/gap47/tar.bz2/gap4r7p2_2013_12_01-10_17.tar.bz2 ) else tar xjf "$UPSTREAM_SOURCE_TARBALL" fi -mv gap4r6 src +mv gap4r7 src # Make everything writable diff --git a/build/pkgs/gap_packages/checksums.ini b/build/pkgs/gap_packages/checksums.ini index 2a2d03f4942..b623c0c4841 100644 --- a/build/pkgs/gap_packages/checksums.ini +++ b/build/pkgs/gap_packages/checksums.ini @@ -1,4 +1,4 @@ tarball=gap_packages-VERSION.tar.bz2 -sha1=16a66881fb5274f9b06cd782a6258b0317699d2b -md5=38c97b2e5cfca171f25f566a7b97667d -cksum=913933974 +sha1=72be0c1a763bb7d0d6f7708f96796f2e40f23b63 +md5=dabef4d7f69069906134a1178ef5e000 +cksum=693425859 diff --git a/build/pkgs/gap_packages/package-version.txt b/build/pkgs/gap_packages/package-version.txt index f18045d6459..af9764a59e1 100644 --- a/build/pkgs/gap_packages/package-version.txt +++ b/build/pkgs/gap_packages/package-version.txt @@ -1 +1 @@ -4.6.5 +4.7.2 diff --git a/build/pkgs/gap_packages/spkg-src b/build/pkgs/gap_packages/spkg-src index 94e5b7a441a..2ab58c3e64f 100755 --- a/build/pkgs/gap_packages/spkg-src +++ b/build/pkgs/gap_packages/spkg-src @@ -13,11 +13,11 @@ shopt -s extglob # Remove old sources and download new rm -rf src if [ -z "$UPSTREAM_SOURCE_TARBALL" ]; then - tar xjf <( curl ftp://ftp.gap-system.org/pub/gap/gap46/tar.bz2/gap4r6p5_2013_07_20-20_02.tar.bz2 ) + tar xjf <( curl http://www.gap-system.org/pub/gap/gap47/tar.bz2/gap4r7p2_2013_12_01-10_17.tar.bz2 ) else tar xjf "$UPSTREAM_SOURCE_TARBALL" fi -GAP=`pwd`/gap4r6 +GAP=`pwd`/gap4r7 # Make everything writable chmod -R u+w "$GAP" @@ -39,4 +39,4 @@ done rm -rf "$GAP" -# tar cjf gap_packages-4.6.5.tar.bz2 src/ && rm -rf src/ +tar cjf gap_packages-`cat package-version.txt`.tar.bz2 src/ && rm -rf src/ From 8cbcbe13ae66499ebf4aa4800a16fe7d3691e3e5 Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Tue, 24 Dec 2013 15:20:58 +0000 Subject: [PATCH 015/163] upstream merged Jeroens cflags patch --- build/pkgs/gap/patches/cflags.patch | 26 -------------------------- 1 file changed, 26 deletions(-) delete mode 100644 build/pkgs/gap/patches/cflags.patch diff --git a/build/pkgs/gap/patches/cflags.patch b/build/pkgs/gap/patches/cflags.patch deleted file mode 100644 index 6e9287a66c4..00000000000 --- a/build/pkgs/gap/patches/cflags.patch +++ /dev/null @@ -1,26 +0,0 @@ -diff -ru src/cnf/aclocal.m4 b/cnf/aclocal.m4 ---- src/cnf/aclocal.m4 2012-09-16 03:02:32.000000000 +0200 -+++ b/cnf/aclocal.m4 2012-12-20 10:34:45.787513315 +0100 -@@ -148,7 +148,8 @@ - gp_cv_cflags="-O";; - esac - ]) --CFLAGS="$CFLAGS $gp_cv_cflags"]) -+# Put user-supplied CFLAGS last, don't override them -+CFLAGS="$gp_cv_cflags $CFLAGS"]) - - dnl ######################################################################### - dnl ## -diff -ru src/cnf/configure.out b/cnf/configure.out ---- src/cnf/configure.out 2012-09-16 03:02:57.000000000 +0200 -+++ b/cnf/configure.out 2012-12-20 10:47:47.607512905 +0100 -@@ -4402,7 +4402,8 @@ - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gp_cv_cflags" >&5 - $as_echo "$gp_cv_cflags" >&6; } --CFLAGS="$CFLAGS $gp_cv_cflags" -+# Put user-supplied CFLAGS last, don't override them -+CFLAGS="$gp_cv_cflags $CFLAGS" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking Linker default flags" >&5 - $as_echo_n "checking Linker default flags... " >&6; } - if ${gp_cv_ldflags+:} false; then : From 349ca1ab584b5de2228342b1484c507583a7727b Mon Sep 17 00:00:00 2001 From: Anne Schilling Date: Tue, 24 Dec 2013 11:41:49 -0800 Subject: [PATCH 016/163] Removed kschur.py --- src/sage/combinat/sf/all.py | 2 - src/sage/combinat/sf/classical.py | 2 +- src/sage/combinat/sf/kschur.py | 389 ------------------------------ 3 files changed, 1 insertion(+), 392 deletions(-) delete mode 100644 src/sage/combinat/sf/kschur.py diff --git a/src/sage/combinat/sf/all.py b/src/sage/combinat/sf/all.py index 1e00516c638..c7c11c81ebe 100644 --- a/src/sage/combinat/sf/all.py +++ b/src/sage/combinat/sf/all.py @@ -11,6 +11,4 @@ lazy_import('sage.combinat.sf.kfpoly', 'KostkaFoulkesPolynomial') -lazy_import('sage.combinat.sf.kschur', 'kSchurFunctions') - from ns_macdonald import NonattackingFillings, AugmentedLatticeDiagramFilling, LatticeDiagram diff --git a/src/sage/combinat/sf/classical.py b/src/sage/combinat/sf/classical.py index f3ac3bb99ed..48aa676361e 100644 --- a/src/sage/combinat/sf/classical.py +++ b/src/sage/combinat/sf/classical.py @@ -114,7 +114,7 @@ def _element_constructor_(self, x): sage: s([[],[]]) s[] - sage: McdJ = SymmetricFunctions(QQ['q','t'].base_ring()) + sage: McdJ = SymmetricFunctions(QQ['q','t'].fraction_field()).macdonald().J() sage: s = SymmetricFunctions(McdJ.base_ring()).s() sage: s._element_constructor_(McdJ(s[2,1])) s[2, 1] diff --git a/src/sage/combinat/sf/kschur.py b/src/sage/combinat/sf/kschur.py deleted file mode 100644 index 2494647f0c7..00000000000 --- a/src/sage/combinat/sf/kschur.py +++ /dev/null @@ -1,389 +0,0 @@ -""" -k-Schur Functions -""" -#***************************************************************************** -# Copyright (C) 2007 Mike Hansen , -# -# Distributed under the terms of the GNU General Public License (GPL) -# -# This code 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. -# -# -# The full text of the GPL is available at: -# -# http://www.gnu.org/licenses/ -#***************************************************************************** -from sage.categories.morphism import SetMorphism -from sage.categories.homset import Hom -import sage.combinat.partition -import sfa - - -def kSchurFunctions(R, k, t=None): - """ - Returns the k-Schur functions. See the examples below for caveats - on their use. - - EXAMPLES:: - - sage: ks3 = kSchurFunctions(QQ, 3); ks3 - doctest:1: DeprecationWarning: Deprecation warning: Please use SymmetricFunctions(QQ).kschur() instead! - See http://trac.sagemath.org/5457 for details. - k-Schur Functions at level 3 over Univariate Polynomial Ring in t over Rational Field - sage: s = SymmetricFunctions(ks3.base_ring()).schur() # Allow 't' coefficients for the Schurs. - - sage: t = ks3.t # Allow 't' as input - sage: s(ks3([3,2,1])) - s[3, 2, 1] + t*s[4, 1, 1] + t*s[4, 2] + t^2*s[5, 1] - - :: - - sage: ks3(s([3, 2, 1]) + t*s([4, 1, 1]) + t*s([4, 2]) + t^2*s([5, 1])) - ks3[3, 2, 1] - - k-Schurs are indexed by partitions with first part `\le - k`. Constructing a k-Schur function for a larger partition raises - an error:: - - sage: ks3([4,3,2,1]) # - Traceback (most recent call last): - ... - TypeError: do not know how to make x (= [4, 3, 2, 1]) an element of self (=k-Schur Functions at level 3 over Univariate Polynomial Ring in t over Rational Field) - - Note: this used to return 0 instead. What is preferable? - - Similarly, attempting to convert a function that is not in the - linear span of the k-Schur's raises an error:: - - sage: ks3(s([4])) - Traceback (most recent call last): - ... - ValueError: s[4] is not in the space spanned by k-Schur Functions at level 3 over Univariate Polynomial Ring in t over Rational Field. - - Note that the product of k-Schurs is not guaranteed to be in the - space spanned by the k-Schurs. In general, we only have that a - k-Schur times a j-Schur is a (k+j)-Schur. This fact is not - currently incorporated into the Sage design, so the multiplication - of k-Schur functions may return an error. This example shows how to - get around this 'manually'. - - :: - - sage: ks2 = kSchurFunctions(QQ, 2) - sage: ks2([2,1])^2 - Traceback (most recent call last): - ... - ValueError: s[2, 2, 1, 1] + s[2, 2, 2] + s[3, 1, 1, 1] + (2*t+2)*s[3, 2, 1] + (t^2+1)*s[3, - 3] + (2*t+1)*s[4, 1, 1] + (t^2+2*t+1)*s[4, 2] + (t^2+2*t)*s[5, 1] + t^2*s[6] is not in the - space spanned by k-Schur Functions at level 2 over Univariate Polynomial Ring in t over - Rational Field. - - :: - - sage: f = s(ks2([2,1]))^2; f # Convert to Schur functions first and multiply there. - s[2, 2, 1, 1] + s[2, 2, 2] + s[3, 1, 1, 1] + (2*t+2)*s[3, 2, 1] + (t^2+1)*s[3, - 3] + (2*t+1)*s[4, 1, 1] + (t^2+2*t+1)*s[4, 2] + (t^2+2*t)*s[5, 1] + t^2*s[6] - sage: ks4 = kSchurFunctions(QQ, 4) - sage: ks4(f) # The product of two 'ks2's is a 'ks4'. - ks4[2, 2, 1, 1] + ks4[2, 2, 2] + ks4[3, 1, 1, 1] + (t+2)*ks4[3, 2, 1] + (t^2+1)*ks4[3, 3] + (t+1)*ks4[4, 1, 1] + ks4[4, 2] - - However, at t=1, the product of k-Schurs is in the span of the - k-Schurs. Below are some examples at t=1. - - :: - - sage: ks3 = kSchurFunctions(QQ, 3, 1); ks3 - k-Schur Functions at level 3 with t=1 over Rational Field - sage: s = SymmetricFunctions(ks3.base_ring()).schur() - sage: ks3(s([3])) - ks3[3] - sage: s(ks3([3,2,1])) - s[3, 2, 1] + s[4, 1, 1] + s[4, 2] + s[5, 1] - sage: ks3([2,1])^2 - ks3[2, 2, 1, 1] + ks3[2, 2, 2] + ks3[3, 1, 1, 1] - """ - sage.misc.superseded.deprecation(5457,"Deprecation warning: Please use SymmetricFunctions(QQ).kschur() instead!") - return cache_t(R, k, t) - - -class kSchurFunctions_generic(sfa.SymmetricFunctionAlgebra_generic): - def _change_by_triangularity(self, el, to_other_cache, unitriang=False): - """ - Returns self(el) converted by triangularity. - - INPUT: - - - ``el`` - a symmetric function - - - ``to_other_cache`` - a dictionary containing the - change of basis from self to el's basis - - - ``unitriang`` - a boolean, if True, the coefficient - of part in self( el.parent()(part) ) is assumed to be 1. - - - EXAMPLES:: - - sage: ks3 = kSchurFunctions(QQ, 3) - doctest:1: DeprecationWarning: Deprecation warning: Please use SymmetricFunctions(QQ).kschur() instead! - See http://trac.sagemath.org/5457 for details. - sage: ks3._s_cache(3) - sage: l = lambda c: [ (i[0],[j for j in sorted(i[1].items())]) for i in sorted(c.items())] - sage: d = ks3._self_to_s_cache - sage: l(d[3]) - [([1, 1, 1], [([1, 1, 1], 1)]), ([2, 1], [([2, 1], 1)]), ([3], [([3], 1)])] - sage: el = ks3._s([2,1]) + ks3._s([1,1,1]) - sage: ks3._change_by_triangularity(el, d, True) - ks3[1, 1, 1] + ks3[2, 1] - """ - orig = el - P = el.parent() - zero = self.base_ring().zero() - out = {} - while not el.is_zero(): - l = el.support() - l.sort() - part2 = l[0] - n = part2.size() - - if not to_other_cache[n][part2]: - raise ValueError,"%s is not in the space spanned by %s."%(orig,self) - - c = el.coefficient(part2) - if not unitriang: - c /= to_other_cache[n][part2][part2] - el -= c*P._from_dict(to_other_cache[n][part2]) - - out[part2] = out.get(part2,zero) + c - - return self._from_dict(out) - - - def _multiply(self, left, right): - """ - Multiply left and right by converting to the Schurs, multiplying - there, and converting back. Note that the product of k-Schurs with - t is only guaranteed to be a sum of k-Schurs when t = 1. - - EXAMPLES:: - - sage: ks3 = kSchurFunctions(QQ, 3) - doctest:1: DeprecationWarning: Deprecation warning: Please use SymmetricFunctions(QQ).kschur() instead! - See http://trac.sagemath.org/5457 for details. - - :: - - sage: ks3([1])^2 # indirect doctest - ks3[1, 1] + ks3[2] - - :: - - sage: ks3([2,1])^2 - Traceback (most recent call last): - ... - ValueError: s[2, 2, 1, 1] + s[2, 2, 2] + s[3, 1, 1, 1] + 2*s[3, 2, 1] + - s[3, 3] + s[4, 1, 1] + s[4, 2] is not in the space spanned by k-Schur - Functions at level 3 over Univariate Polynomial Ring in t over Rational - Field. - - :: - - sage: ks3 = kSchurFunctions(QQ,3,1) - sage: ks3([2,1])^2 - ks3[2, 2, 1, 1] + ks3[2, 2, 2] + ks3[3, 1, 1, 1] - """ - return self( self._s(left) * self._s(right) ) - - - class Element(sfa.SymmetricFunctionAlgebra_generic.Element): - pass - -s_to_k_cache = {} -k_to_s_cache = {} -class kSchurFunctions_t(kSchurFunctions_generic): - def __init__(self, R, k, t=None): - """ - EXAMPLES:: - - sage: kSchurFunctions(QQ, 3).base_ring() - doctest:1: DeprecationWarning: Deprecation warning: Please use SymmetricFunctions(QQ).kschur() instead! - See http://trac.sagemath.org/5457 for details. - Univariate Polynomial Ring in t over Rational Field - sage: kSchurFunctions(QQ, 3, t=1).base_ring() - Rational Field - sage: ks3 = kSchurFunctions(QQ, 3) - sage: ks3 == loads(dumps(ks3)) - True - """ - self.k = k - self._name = "k-Schur Functions at level %s"%k - self._prefix = "ks%s"%k - self._element_class = kSchurFunctions_t.Element - - if t is None: - R = R['t'] - self.t = R.gen() - elif t not in R: - raise ValueError, "t (=%s) must be in R (=%s)"%(t,R) - else: - self.t = R(t) - if str(t) != 't': - self._name += " with t=%s"%self.t - - self._s_to_self_cache = s_to_k_cache.get(k, {}) - self._self_to_s_cache = k_to_s_cache.get(k, {}) - - # This is an abuse, since kschur functions do not form a basis of Sym - from sage.combinat.sf.sf import SymmetricFunctions - Sym = SymmetricFunctions(R) - sfa.SymmetricFunctionAlgebra_generic.__init__(self, Sym) - # so we need to take some counter measures - self._basis_keys = sage.combinat.partition.Partitions(max_part=k) - # The following line is just a temporary workaround to keep - # the repr of those k-schur as they were before #13404; since - # they are deprecated, there is no need to bother about them. - self.rename(self._name+" over %s"%self.base_ring()) - - self._s = Sym.s() - # temporary until Hom(GradedHopfAlgebrasWithBasis work better) - category = sage.categories.all.ModulesWithBasis(self.base_ring()) - # This really should be a conversion, not a coercion (it can fail) - self .register_coercion(SetMorphism(Hom(self._s, self, category), self._s_to_self)) - self._s.register_coercion(SetMorphism(Hom(self, self._s, category), self._self_to_s)) - - def _s_to_self(self, x): - """ - Partial morphism from the Schur basis into self - - EXAMPLES:: - - sage: ks3 = kSchurFunctions(QQ, 3) - doctest:1: DeprecationWarning: Deprecation warning: Please use SymmetricFunctions(QQ).kschur() instead! - See http://trac.sagemath.org/5457 for details. - sage: s = SymmetricFunctions(ks3.base_ring()).schur() - sage: ks3._s_to_self(s[2, 1, 1] + ks3.t*s[3, 1]) - ks3[2, 1, 1] - sage: ks3._s_to_self(s[2, 1, 1]) - Traceback (most recent call last): - ... - ValueError: s[2, 1, 1] is not in the space spanned by k-Schur Functions at level 3 over Univariate Polynomial Ring in t over Rational Field. - - This is for internal use only. Please use instead:: - - sage: ks3(s[2, 1, 1] + ks3.t*s[3, 1]) - ks3[2, 1, 1] - sage: ks3(s[2, 1, 1]) - Traceback (most recent call last): - ... - ValueError: s[2, 1, 1] is not in the space spanned by k-Schur Functions at level 3 over Univariate Polynomial Ring in t over Rational Field. - """ - for p in x.support(): - self._s_cache(p.size()) - return self._change_by_triangularity(x, self._self_to_s_cache, True) - - def _self_to_s(self, x): - r""" - Embedding from self to the Schur basis - - EXAMPLES:: - - sage: ks3 = kSchurFunctions(QQ, 3) - doctest:1: DeprecationWarning: Deprecation warning: Please use SymmetricFunctions(QQ).kschur() instead! - See http://trac.sagemath.org/5457 for details. - sage: s = SymmetricFunctions(ks3.base_ring()).schur() - sage: ks3._self_to_s(ks3[2,1,1]) - s[2, 1, 1] + t*s[3, 1] - - This is for internal use only. Please use instead:: - - sage: s(ks3[2,1,1]) - s[2, 1, 1] + t*s[3, 1] - """ - return self._s._from_cache(x, self._s_cache, self._self_to_s_cache, t = self.t) # do we want this t = self.t? - - def _coerce_start_disabled(self, x): - """ - Coerce things into the k-Schurs through the Schurs. - - EXAMPLES:: - - sage: ks3 = kSchurFunctions(QQ, 3) - doctest:1: DeprecationWarning: Deprecation warning: Please use SymmetricFunctions(QQ).kschur() instead! - See http://trac.sagemath.org/5457 for details. - sage: s = SymmetricFunctions(ks3.base_ring()).schur() - sage: ks3([3,3,2,1]) # indirect doctest - ks3[3, 3, 2, 1] - sage: ks3([4,3,2,1]) # indirect doctest - Traceback (most recent call last): - ... - TypeError: do not know how to make x (= [4, 3, 2, 1]) an element of self (=k-Schur Functions at level 3 over Univariate Polynomial Ring in t over Rational Field) - sage: ks3(s([2,1])) - ks3[2, 1] - sage: ks3(s([4])) - Traceback (most recent call last): - ... - ValueError: s[4] is not in the space spanned by k-Schur Functions at level 3 over Univariate Polynomial Ring in t over Rational Field. - """ - pass - if x in sage.combinat.partition.Partitions(): - if len(x) > 0 and max(x) > self.k: - return self.zero() - x = sage.combinat.partition.Partition(x) - return self._from_dict({x:self.base_ring().one()}) - - - def _s_cache(self, n): - """ - Computes the change of basis from the kSchurs to the Schurs for - partitions of size n. - - EXAMPLES:: - - sage: ks3 = kSchurFunctions(QQ, 3) - doctest:1: DeprecationWarning: Deprecation warning: Please use SymmetricFunctions(QQ).kschur() instead! - See http://trac.sagemath.org/5457 for details. - sage: ks3._s_cache(3) - sage: l = lambda c: [ (i[0],[j for j in sorted(i[1].items())]) for i in sorted(c.items())] - sage: l(ks3._self_to_s_cache[3]) - [([1, 1, 1], [([1, 1, 1], 1)]), ([2, 1], [([2, 1], 1)]), ([3], [([3], 1)])] - """ - if n in self._self_to_s_cache: - return - - R = self.base_ring() - t = self.t - s = self._s - zero = s.zero() - - if n == 0: - p = sage.combinat.partition.Partition([]) - self._self_to_s_cache[0] = {p: {p:R.one()}} - return - else: - self._self_to_s_cache[n] = {} - - - #Fill in the cache from the k-Schurs to the Schurs - for p in sage.combinat.partition.Partitions_n(n): - if max(p) > self.k: - self._self_to_s_cache[n][p] = {} - continue - katom = p.k_atom(self.k) - res = sum( [t**tab.charge()*s(tab.shape()) for tab in katom], zero) - self._self_to_s_cache[n][p] = res.monomial_coefficients() - - class Element(kSchurFunctions_generic.Element): - pass - -############# -# Cache # -############# -from sage.misc.cache import Cache -cache_t = Cache(kSchurFunctions_t) - -# Backward compatibility for unpickling -from sage.structure.sage_object import register_unpickle_override -register_unpickle_override('sage.combinat.sf.kschur', 'kSchurFunction_t', kSchurFunctions_t.Element) From 32c38bd0795e6f43cf9e471e6da6f41032a07245 Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Tue, 24 Dec 2013 20:22:02 +0000 Subject: [PATCH 017/163] udpate to libgap-4.7.2 --- build/pkgs/libgap/checksums.ini | 6 +++--- build/pkgs/libgap/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/libgap/checksums.ini b/build/pkgs/libgap/checksums.ini index bd80677b4b6..6e2b6e5484a 100644 --- a/build/pkgs/libgap/checksums.ini +++ b/build/pkgs/libgap/checksums.ini @@ -1,4 +1,4 @@ tarball=libgap-VERSION.tar.gz -sha1=c2e774ad9499bf45a2ef2fa1f665334e5221b7eb -md5=d7b7ffe563d5ef2490d5712900b76456 -cksum=3726733477 +sha1=1ba33b0b0f228c20cf53521896f4499e12f65513 +md5=23354a42d241abc457c0602aded53173 +cksum=2180725721 diff --git a/build/pkgs/libgap/package-version.txt b/build/pkgs/libgap/package-version.txt index d156b0af115..af9764a59e1 100644 --- a/build/pkgs/libgap/package-version.txt +++ b/build/pkgs/libgap/package-version.txt @@ -1 +1 @@ -4.6.5.p0 +4.7.2 From 20f5d3ae56780f96cb70476075f03b1e22d7dd2c Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Wed, 25 Dec 2013 09:21:40 -0800 Subject: [PATCH 018/163] Updated checksum for libgap spkg. --- build/pkgs/libgap/checksums.ini | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build/pkgs/libgap/checksums.ini b/build/pkgs/libgap/checksums.ini index 6e2b6e5484a..03a4468735e 100644 --- a/build/pkgs/libgap/checksums.ini +++ b/build/pkgs/libgap/checksums.ini @@ -1,4 +1,4 @@ tarball=libgap-VERSION.tar.gz -sha1=1ba33b0b0f228c20cf53521896f4499e12f65513 -md5=23354a42d241abc457c0602aded53173 -cksum=2180725721 +sha1=357d533ace5016d10d9635ff28e0abdba98b5c56 +md5=dff641319181e68cff5ffcbc03ea4b6b +cksum=3929362303 From efc340a0518c81ef6244fe990eadd22ddb561cd4 Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Thu, 26 Dec 2013 15:13:01 +0000 Subject: [PATCH 019/163] fix doctests in the gap interface --- src/sage/interfaces/gap.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/interfaces/gap.py b/src/sage/interfaces/gap.py index cd36bc5b7a4..256865c439c 100644 --- a/src/sage/interfaces/gap.py +++ b/src/sage/interfaces/gap.py @@ -650,7 +650,7 @@ def _keyboard_interrupt(self): sage: import sage.tests.interrupt sage: try: ... sage.tests.interrupt.interrupt_after_delay() - ... while True: SymmetricGroup(8).conjugacy_classes_subgroups() + ... while True: SymmetricGroup(7).conjugacy_classes_subgroups() ... except KeyboardInterrupt: ... pass Interrupting Gap... @@ -857,8 +857,8 @@ def version(self): EXAMPLES:: - sage: gap.version() - '4.6.5' + sage: print gap.version() + 4.7... """ return self.eval('VERSION')[1:-1] @@ -1838,10 +1838,10 @@ def gap_version(): EXAMPLES:: - sage: gap_version() + sage: print gap_version() doctest:...: DeprecationWarning: use gap.version() instead See http://trac.sagemath.org/13211 for details. - '4.6.5' + 4.7... """ from sage.misc.superseded import deprecation deprecation(13211, 'use gap.version() instead') From 9bb3e1ac947c3967d53b450f934c464d8ea7e01b Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Thu, 26 Dec 2013 16:24:12 +0000 Subject: [PATCH 020/163] add atlasrep to database_gap (dependency for tomlib) --- build/pkgs/database_gap/SPKG.txt | 3 ++- build/pkgs/database_gap/checksums.ini | 6 +++--- build/pkgs/database_gap/spkg-src | 2 +- src/sage/tests/gap_packages.py | 10 +++++++++- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/build/pkgs/database_gap/SPKG.txt b/build/pkgs/database_gap/SPKG.txt index c6e8b3a9951..0b228e55048 100644 --- a/build/pkgs/database_gap/SPKG.txt +++ b/build/pkgs/database_gap/SPKG.txt @@ -24,8 +24,9 @@ needs GAP (a standard spkg) == Special Update/Build Instructions == Copy the following databases out the gap source tarball: - * small -- small group's database + * small -- small groups database * pkg/tomlib -- just contains the "Table of Marks" + * pkg/atlasrep -- dependency for tomlib * prim * trans See also the spkg-src script. diff --git a/build/pkgs/database_gap/checksums.ini b/build/pkgs/database_gap/checksums.ini index a3fb57644ae..7785f73940f 100644 --- a/build/pkgs/database_gap/checksums.ini +++ b/build/pkgs/database_gap/checksums.ini @@ -1,4 +1,4 @@ tarball=database_gap-VERSION.tar.bz2 -sha1=983a2317e9f483f77bda7ee0a1aa2413c607e53f -md5=bc2ca78ef65b714ca94d88a6d9b2fad7 -cksum=335130228 +sha1=0e2b4e42717f39f75d2a700b3b050fc2265a2d4a +md5=0ecb28c96493eeef6a1435a9e5cef66e +cksum=3670665484 diff --git a/build/pkgs/database_gap/spkg-src b/build/pkgs/database_gap/spkg-src index 0014096c262..983b8d0ed21 100755 --- a/build/pkgs/database_gap/spkg-src +++ b/build/pkgs/database_gap/spkg-src @@ -25,7 +25,7 @@ chmod -R u+w "$GAP" mkdir src mkdir src/pkg -for pkg in small pkg/tomlib prim trans +for pkg in small pkg/tomlib pkg/atlasrep prim trans do cp -rap "$GAP/$pkg" "src/$pkg" done diff --git a/src/sage/tests/gap_packages.py b/src/sage/tests/gap_packages.py index 79ed2e42bc3..ee68d7012c5 100644 --- a/src/sage/tests/gap_packages.py +++ b/src/sage/tests/gap_packages.py @@ -5,10 +5,18 @@ sage: from sage.tests.gap_packages import all_installed_packages, test_packages sage: pkgs = all_installed_packages(ignore_dot_gap=True) - sage: test_packages(pkgs, only_failures=True) # optional: gap_packages + sage: test_packages(pkgs, only_failures=True) # optional - gap_packages Status Package GAP Output +---------+----------+------------+ Failure HAPcryst fail + +These are packages in the ``database_gap`` package:: + + sage: test_packages(['atlasrep', 'tomlib']) # optional - database_gap + Status Package GAP Output + +--------+----------+------------+ + atlasrep true + tomlib true """ import os From b89547724ad8d4ccaa53afa2c80e088e945ff537 Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Thu, 26 Dec 2013 17:31:01 +0000 Subject: [PATCH 021/163] fix doctests: different gap generator orders --- src/doc/de/tutorial/tour_groups.rst | 16 ++-- src/doc/en/constructions/groups.rst | 32 +++---- src/doc/en/constructions/rep_theory.rst | 66 +++++++------- .../en/prep/Quickstarts/Abstract-Algebra.rst | 2 +- .../en/thematic_tutorials/lie/weyl_groups.rst | 4 +- .../tutorial-comprehensions.rst | 12 +-- src/doc/en/tutorial/tour_groups.rst | 16 ++-- src/doc/fr/tutorial/tour_groups.rst | 16 ++-- src/doc/ru/tutorial/tour_groups.rst | 16 ++-- src/sage/algebras/iwahori_hecke_algebra.py | 3 +- src/sage/categories/group_algebras.py | 3 +- src/sage/categories/groups.py | 15 ++-- .../root_system/root_lattice_realizations.py | 6 +- src/sage/combinat/root_system/root_system.py | 6 +- src/sage/combinat/tiling.py | 86 +++++++++---------- src/sage/combinat/tutorial.py | 12 +-- src/sage/groups/finitely_presented.py | 19 ++-- src/sage/groups/libgap_mixin.py | 16 ++-- .../groups/matrix_gps/finitely_generated.py | 5 +- src/sage/groups/matrix_gps/matrix_group.py | 13 +-- src/sage/groups/perm_gps/permgroup.py | 8 +- src/sage/groups/perm_gps/permgroup_named.py | 4 +- 22 files changed, 186 insertions(+), 190 deletions(-) diff --git a/src/doc/de/tutorial/tour_groups.rst b/src/doc/de/tutorial/tour_groups.rst index f219a21ccc7..d21d5237a6d 100644 --- a/src/doc/de/tutorial/tour_groups.rst +++ b/src/doc/de/tutorial/tour_groups.rst @@ -38,9 +38,9 @@ erhalten: sage: latex(G.character_table()) \left(\begin{array}{rrrr} 1 & 1 & 1 & 1 \\ - 1 & 1 & -\zeta_{3} - 1 & \zeta_{3} \\ - 1 & 1 & \zeta_{3} & -\zeta_{3} - 1 \\ - 3 & -1 & 0 & 0 + 1 & -\zeta_{3} - 1 & \zeta_{3} & 1 \\ + 1 & \zeta_{3} & -\zeta_{3} - 1 & 1 \\ + 3 & 0 & 0 & -1 \end{array}\right) Sage beinhaltet auch klassische und Matrixgruppen über endlichen Körpern: @@ -52,11 +52,11 @@ Sage beinhaltet auch klassische und Matrixgruppen über endlichen Körpern: sage: G = MatrixGroup(gens) sage: G.conjugacy_class_representatives() ( - [1 0] [0 1] [0 1] [0 1] [0 1] [0 1] [0 1] [0 3] [0 3] [0 1] - [0 1], [6 1], [6 3], [6 2], [6 6], [6 4], [6 5], [2 2], [2 5], [6 0], + [1 0] [0 6] [0 4] [6 0] [0 6] [0 4] [0 6] [0 6] [0 6] [4 0] + [0 1], [1 5], [5 5], [0 6], [1 2], [5 2], [1 0], [1 4], [1 3], [0 2], - [6 0] - [0 6] + [5 0] + [0 3] ) sage: G = Sp(4,GF(7)) sage: G @@ -84,4 +84,4 @@ Sie können auch mit (endlichen oder unendlichen) abelschen Gruppen rechnen. sage: AbelianGroup(5) Multiplicative Abelian group isomorphic to Z x Z x Z x Z x Z sage: AbelianGroup(5).order() - +Infinity + +Infinity \ No newline at end of file diff --git a/src/doc/en/constructions/groups.rst b/src/doc/en/constructions/groups.rst index 19847a631e5..1e0bc3c4e67 100644 --- a/src/doc/en/constructions/groups.rst +++ b/src/doc/en/constructions/groups.rst @@ -132,8 +132,8 @@ You can compute conjugacy classes of a finite group using sage: CG = G.conjugacy_classes_representatives() sage: gamma = CG[2] sage: CG; gamma - [(), (1,2), (1,2)(3,4), (1,2,3), (1,2,3)(4,7), (1,2,3,4), (1,2,3,4,7)] - (1,2)(3,4) + [(), (4,7), (3,4,7), (2,3)(4,7), (2,3,4,7), (1,2)(3,4,7), (1,2,3,4,7)] + (3,4,7) You can use the Sage-GAP interface. @@ -142,11 +142,11 @@ You can use the Sage-GAP interface. sage: gap.eval("G := Group((1,2)(3,4),(1,2,3))") 'Group([ (1,2)(3,4), (1,2,3) ])' sage: gap.eval("CG := ConjugacyClasses(G)") - '[ ()^G, (1,2)(3,4)^G, (1,2,3)^G, (1,2,4)^G ]' + '[ ()^G, (2,3,4)^G, (2,4,3)^G, (1,2)(3,4)^G ]' sage: gap.eval("gamma := CG[3]") - '(1,2,3)^G' + '(2,4,3)^G' sage: gap.eval("g := Representative(gamma)") - '(1,2,3)' + '(2,4,3)' Or, here's another (more "pythonic") way to do this type of computation: @@ -158,15 +158,15 @@ computation: sage: gamma = CG[2] sage: g = gamma.Representative() sage: CG; gamma; g - [ ConjugacyClass( SymmetricGroup( [ 1, 2, 3, 4, 7 ] ), () ), - ConjugacyClass( SymmetricGroup( [ 1, 2, 3, 4, 7 ] ), (1,2) ), - ConjugacyClass( SymmetricGroup( [ 1, 2, 3, 4, 7 ] ), (1,2)(3,4) ), - ConjugacyClass( SymmetricGroup( [ 1, 2, 3, 4, 7 ] ), (1,2,3) ), - ConjugacyClass( SymmetricGroup( [ 1, 2, 3, 4, 7 ] ), (1,2,3)(4,7) ), - ConjugacyClass( SymmetricGroup( [ 1, 2, 3, 4, 7 ] ), (1,2,3,4) ), + [ ConjugacyClass( SymmetricGroup( [ 1, 2, 3, 4, 7 ] ), () ), + ConjugacyClass( SymmetricGroup( [ 1, 2, 3, 4, 7 ] ), (4,7) ), + ConjugacyClass( SymmetricGroup( [ 1, 2, 3, 4, 7 ] ), (3,4,7) ), + ConjugacyClass( SymmetricGroup( [ 1, 2, 3, 4, 7 ] ), (2,3)(4,7) ), + ConjugacyClass( SymmetricGroup( [ 1, 2, 3, 4, 7 ] ), (2,3,4,7) ), + ConjugacyClass( SymmetricGroup( [ 1, 2, 3, 4, 7 ] ), (1,2)(3,4,7) ), ConjugacyClass( SymmetricGroup( [ 1, 2, 3, 4, 7 ] ), (1,2,3,4,7) ) ] - ConjugacyClass( SymmetricGroup( [ 1, 2, 3, 4, 7 ] ), (1,2) ) - (1,2) + ConjugacyClass( SymmetricGroup( [ 1, 2, 3, 4, 7 ] ), (4,7) ) + (4,7) .. index:: pair: group; normal subgroups @@ -207,8 +207,8 @@ Here's another way, working more directly with GAP: sage: print gap.eval("G := SymmetricGroup( 4 )") Sym( [ 1 .. 4 ] ) sage: print gap.eval("normal := NormalSubgroups( G );") - [ Group(()), Group([ (1,4)(2,3), (1,3)(2,4) ]), - Group([ (2,4,3), (1,4)(2,3), (1,3)(2,4) ]), Sym( [ 1 .. 4 ] ) ] + [ Group(()), Group([ (1,4)(2,3), (1,3)(2,4) ]), Group([ (2,4,3), (1,4) + (2,3), (1,3)(2,4) ]), Sym( [ 1 .. 4 ] ) ] .. index:: pair: groups; center @@ -467,4 +467,4 @@ Order Group Description Command(s) 31 `C_{31}` [31,1] ===== =============================================== =============================================================================================== =========================== -Table By Kevin Halasz +Table By Kevin Halasz \ No newline at end of file diff --git a/src/doc/en/constructions/rep_theory.rst b/src/doc/en/constructions/rep_theory.rst index a5728e5276f..1102dce1352 100644 --- a/src/doc/en/constructions/rep_theory.rst +++ b/src/doc/en/constructions/rep_theory.rst @@ -51,10 +51,10 @@ Here is another example: sage: G = PermutationGroup([[(1,2),(3,4)], [(1,2,3)]]) sage: G.character_table() - [ 1 1 1 1] - [ 1 1 -zeta3 - 1 zeta3] - [ 1 1 zeta3 -zeta3 - 1] - [ 3 -1 0 0] + [ 1 1 1 1] + [ 1 -zeta3 - 1 zeta3 1] + [ 1 zeta3 -zeta3 - 1 1] + [ 3 0 0 -1] sage: gap.eval("G := Group((1,2)(3,4),(1,2,3))") 'Group([ (1,2)(3,4), (1,2,3) ])' sage: gap.eval("T := CharacterTable(G)") @@ -62,17 +62,17 @@ Here is another example: sage: print gap.eval("Display(T)") CT2 - 2 2 2 . . - 3 1 . 1 1 + 2 2 . . 2 + 3 1 1 1 . - 1a 2a 3a 3b - 2P 1a 1a 3b 3a - 3P 1a 2a 1a 1a + 1a 3a 3b 2a + 2P 1a 3b 3a 1a + 3P 1a 1a 1a 2a X.1 1 1 1 1 - X.2 1 1 A /A - X.3 1 1 /A A - X.4 3 -1 . . + X.2 1 A /A 1 + X.3 1 /A A 1 + X.4 3 . . -1 A = E(3)^2 = (-1-Sqrt(-3))/2 = -1-b3 @@ -85,25 +85,25 @@ Python command. This makes the output look much nicer. :: sage: print gap.eval("irr := Irr(G)") - [ Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, 1, 1, 1 ] ), - Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, 1, E(3)^2, E(3) ] ), - Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, 1, E(3), E(3)^2 ] ), - Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 3, -1, 0, 0 ] ) ] + [ Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, 1, 1, 1 ] ), + Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, E(3)^2, E(3), 1 ] ), + Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, E(3), E(3)^2, 1 ] ), + Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 3, 0, 0, -1 ] ) ] sage: print gap.eval("Display(irr)") [ [ 1, 1, 1, 1 ], - [ 1, 1, E(3)^2, E(3) ], - [ 1, 1, E(3), E(3)^2 ], - [ 3, -1, 0, 0 ] ] + [ 1, E(3)^2, E(3), 1 ], + [ 1, E(3), E(3)^2, 1 ], + [ 3, 0, 0, -1 ] ] sage: gap.eval("CG := ConjugacyClasses(G)") - '[ ()^G, (1,2)(3,4)^G, (1,2,3)^G, (1,2,4)^G ]' + '[ ()^G, (2,3,4)^G, (2,4,3)^G, (1,2)(3,4)^G ]' sage: gap.eval("gamma := CG[3]") - '(1,2,3)^G' + '(2,4,3)^G' sage: gap.eval("g := Representative(gamma)") - '(1,2,3)' + '(2,4,3)' sage: gap.eval("chi := irr[2]") - 'Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, 1, E(3)^2, E(3) ] )' + 'Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, E(3)^2, E(3), 1 ] )' sage: gap.eval("g^chi") - 'E(3)^2' + 'E(3)' This last quantity is the value of the character ``chi`` at the group element ``g``. @@ -191,17 +191,17 @@ The example below using the GAP interface illustrates the syntax. sage: print gap.eval("Display(T)") CT3 - 2 2 2 . . - 3 1 . 1 1 + 2 2 . . 2 + 3 1 1 1 . - 1a 2a 3a 3b - 2P 1a 1a 3b 3a - 3P 1a 2a 1a 1a + 1a 3a 3b 2a + 2P 1a 3b 3a 1a + 3P 1a 1a 1a 2a X.1 1 1 1 1 - X.2 1 1 A /A - X.3 1 1 /A A - X.4 3 -1 . . + X.2 1 A /A 1 + X.3 1 /A A 1 + X.4 3 . . -1 A = E(3)^2 - = (-1-Sqrt(-3))/2 = -1-b3 + = (-1-Sqrt(-3))/2 = -1-b3 \ No newline at end of file diff --git a/src/doc/en/prep/Quickstarts/Abstract-Algebra.rst b/src/doc/en/prep/Quickstarts/Abstract-Algebra.rst index 8499390d06c..c28e21fb649 100644 --- a/src/doc/en/prep/Quickstarts/Abstract-Algebra.rst +++ b/src/doc/en/prep/Quickstarts/Abstract-Algebra.rst @@ -129,8 +129,8 @@ haven't mentioned before. The string ``\n`` represents a new line. sage: for a in S: ... print a, "\n" + [1 0] [0 1] - [2 0] ... [2 2] [2 1] diff --git a/src/doc/en/thematic_tutorials/lie/weyl_groups.rst b/src/doc/en/thematic_tutorials/lie/weyl_groups.rst index 9f41001e2fd..bcdaab2542c 100644 --- a/src/doc/en/thematic_tutorials/lie/weyl_groups.rst +++ b/src/doc/en/thematic_tutorials/lie/weyl_groups.rst @@ -212,7 +212,7 @@ this as follows:: sage: def bi(u,v) : return [t for t in W if u.bruhat_le(t) and t.bruhat_le(v)] ... sage: bi(s1,s1*s2*s1) - [s1*s2*s1, s1*s2, s2*s1, s1] + [s1*s2*s1, s1*s2, s1, s2*s1] This would not be a good definition since it would fail if `W` is affine and be inefficient of `W` is large. Sage has a Bruhat interval @@ -293,4 +293,4 @@ precisely the pairs such that `u\prec v` in the notation of Kazhdan and Lusztig, and `l(v)-l(u) > 1`. One should not rashly suppose that this is a general characterization of the pairs `(u,v)` such that no reflection stabilizes the Bruhat interval, for this is not true, but -it does suggest that the question is worthy of further investigation. +it does suggest that the question is worthy of further investigation. \ No newline at end of file diff --git a/src/doc/en/thematic_tutorials/tutorial-comprehensions.rst b/src/doc/en/thematic_tutorials/tutorial-comprehensions.rst index 1737872e17e..bbcb75744d2 100644 --- a/src/doc/en/thematic_tutorials/tutorial-comprehensions.rst +++ b/src/doc/en/thematic_tutorials/tutorial-comprehensions.rst @@ -329,16 +329,13 @@ one may iterate through their elements:: True sage: for p in GL(2, 2): print p; print - [0 1] [1 0] - [0 1] - [1 1] - [1 0] [0 1] - [1 0] + + [0 1] [1 1] [1 1] @@ -347,6 +344,9 @@ one may iterate through their elements:: [1 1] [1 0] + [1 0] + [1 1] + sage: for p in Partitions(3): print p [3] @@ -374,4 +374,4 @@ Infinite loops can nevertheless be very useful:: sage: counter_examples = (p for p in Primes() if not is_prime(mersenne(p))) sage: counter_examples.next() - 11 + 11 \ No newline at end of file diff --git a/src/doc/en/tutorial/tour_groups.rst b/src/doc/en/tutorial/tour_groups.rst index 9f3d21c3189..e207a1ee999 100644 --- a/src/doc/en/tutorial/tour_groups.rst +++ b/src/doc/en/tutorial/tour_groups.rst @@ -36,9 +36,9 @@ You can also obtain the character table (in LaTeX format) in Sage: sage: latex(G.character_table()) \left(\begin{array}{rrrr} 1 & 1 & 1 & 1 \\ - 1 & 1 & -\zeta_{3} - 1 & \zeta_{3} \\ - 1 & 1 & \zeta_{3} & -\zeta_{3} - 1 \\ - 3 & -1 & 0 & 0 + 1 & -\zeta_{3} - 1 & \zeta_{3} & 1 \\ + 1 & \zeta_{3} & -\zeta_{3} - 1 & 1 \\ + 3 & 0 & 0 & -1 \end{array}\right) Sage also includes classical and matrix groups over finite fields: @@ -50,11 +50,11 @@ Sage also includes classical and matrix groups over finite fields: sage: G = MatrixGroup(gens) sage: G.conjugacy_class_representatives() ( - [1 0] [0 1] [0 1] [0 1] [0 1] [0 1] [0 1] [0 3] [0 3] [0 1] - [0 1], [6 1], [6 3], [6 2], [6 6], [6 4], [6 5], [2 2], [2 5], [6 0], + [1 0] [0 6] [0 4] [6 0] [0 6] [0 4] [0 6] [0 6] [0 6] [4 0] + [0 1], [1 5], [5 5], [0 6], [1 2], [5 2], [1 0], [1 4], [1 3], [0 2], - [6 0] - [0 6] + [5 0] + [0 3] ) sage: G = Sp(4,GF(7)) sage: G @@ -82,4 +82,4 @@ You can also compute using abelian groups (infinite and finite): sage: AbelianGroup(5) Multiplicative Abelian group isomorphic to Z x Z x Z x Z x Z sage: AbelianGroup(5).order() - +Infinity + +Infinity \ No newline at end of file diff --git a/src/doc/fr/tutorial/tour_groups.rst b/src/doc/fr/tutorial/tour_groups.rst index 1167f9dc82d..5070af05ebc 100644 --- a/src/doc/fr/tutorial/tour_groups.rst +++ b/src/doc/fr/tutorial/tour_groups.rst @@ -37,9 +37,9 @@ On peut obtenir la table des caractères (au format LaTeX) à partir de Sage : sage: latex(G.character_table()) \left(\begin{array}{rrrr} 1 & 1 & 1 & 1 \\ - 1 & 1 & -\zeta_{3} - 1 & \zeta_{3} \\ - 1 & 1 & \zeta_{3} & -\zeta_{3} - 1 \\ - 3 & -1 & 0 & 0 + 1 & -\zeta_{3} - 1 & \zeta_{3} & 1 \\ + 1 & \zeta_{3} & -\zeta_{3} - 1 & 1 \\ + 3 & 0 & 0 & -1 \end{array}\right) Sage inclut aussi les groupes classiques ou matriciels définis sur des @@ -52,11 +52,11 @@ corps finis : sage: G = MatrixGroup(gens) sage: G.conjugacy_class_representatives() ( - [1 0] [0 1] [0 1] [0 1] [0 1] [0 1] [0 1] [0 3] [0 3] [0 1] - [0 1], [6 1], [6 3], [6 2], [6 6], [6 4], [6 5], [2 2], [2 5], [6 0], + [1 0] [0 6] [0 4] [6 0] [0 6] [0 4] [0 6] [0 6] [0 6] [4 0] + [0 1], [1 5], [5 5], [0 6], [1 2], [5 2], [1 0], [1 4], [1 3], [0 2], - [6 0] - [0 6] + [5 0] + [0 3] ) sage: G = Sp(4,GF(7)) sage: G @@ -85,4 +85,4 @@ ou finis) : sage: AbelianGroup(5) Multiplicative Abelian group isomorphic to Z x Z x Z x Z x Z sage: AbelianGroup(5).order() - +Infinity + +Infinity \ No newline at end of file diff --git a/src/doc/ru/tutorial/tour_groups.rst b/src/doc/ru/tutorial/tour_groups.rst index d88c9d4232f..e7a75d74af2 100644 --- a/src/doc/ru/tutorial/tour_groups.rst +++ b/src/doc/ru/tutorial/tour_groups.rst @@ -36,9 +36,9 @@ Sage поддерживает вычисления с группами пере sage: latex(G.character_table()) \left(\begin{array}{rrrr} 1 & 1 & 1 & 1 \\ - 1 & 1 & -\zeta_{3} - 1 & \zeta_{3} \\ - 1 & 1 & \zeta_{3} & -\zeta_{3} - 1 \\ - 3 & -1 & 0 & 0 + 1 & -\zeta_{3} - 1 & \zeta_{3} & 1 \\ + 1 & \zeta_{3} & -\zeta_{3} - 1 & 1 \\ + 3 & 0 & 0 & -1 \end{array}\right) Sage также включает в себя классические и матричные группы для конечных полей: @@ -50,11 +50,11 @@ Sage также включает в себя классические и мат sage: G = MatrixGroup(gens) sage: G.conjugacy_class_representatives() ( - [1 0] [0 1] [0 1] [0 1] [0 1] [0 1] [0 1] [0 3] [0 3] [0 1] - [0 1], [6 1], [6 3], [6 2], [6 6], [6 4], [6 5], [2 2], [2 5], [6 0], + [1 0] [0 6] [0 4] [6 0] [0 6] [0 4] [0 6] [0 6] [0 6] [4 0] + [0 1], [1 5], [5 5], [0 6], [1 2], [5 2], [1 0], [1 4], [1 3], [0 2], - [6 0] - [0 6] + [5 0] + [0 3] ) sage: G = Sp(4,GF(7)) sage: G @@ -82,4 +82,4 @@ Sage также включает в себя классические и мат sage: AbelianGroup(5) Multiplicative Abelian group isomorphic to Z x Z x Z x Z x Z sage: AbelianGroup(5).order() - +Infinity + +Infinity \ No newline at end of file diff --git a/src/sage/algebras/iwahori_hecke_algebra.py b/src/sage/algebras/iwahori_hecke_algebra.py index ac7f3494a8b..9bed998af19 100644 --- a/src/sage/algebras/iwahori_hecke_algebra.py +++ b/src/sage/algebras/iwahori_hecke_algebra.py @@ -1209,7 +1209,7 @@ class T(_Basis): T[1,2,3,1,2,1] sage: T = H.T(prefix="s") sage: T.an_element() - s[1,2,3,1,2,1] + 2*s[1,2,3,1,2] + 3*s[1,2,3,2,1] + s[1,2,3] + 2*s[1,2,3,2,1] + 3*s[1,2,3,1] + s[1,2,3] + 1 TESTS:: @@ -2295,4 +2295,3 @@ def IwahoriHeckeAlgebraT(W, q1, q2=-1, base_ring=None, prefix="T"): from sage.structure.sage_object import register_unpickle_override register_unpickle_override('sage.algebras.iwahori_hecke_algebra', 'IwahoriHeckeAlgebraT', IwahoriHeckeAlgebraT) - diff --git a/src/sage/categories/group_algebras.py b/src/sage/categories/group_algebras.py index bf3cd292728..dd5fd2355b8 100644 --- a/src/sage/categories/group_algebras.py +++ b/src/sage/categories/group_algebras.py @@ -229,7 +229,7 @@ def central_form(self): 4*B[[1, 2, 3, 4]] + 3*B[[2, 1, 3, 4]] + 2*B[[2, 1, 4, 3]] + 2*B[[2, 3, 1, 4]] + B[[2, 3, 4, 1]] sage: QG=GroupAlgebras(QQ).example(PermutationGroup([[(1,2,3),(4,5)],[(3,4)]])) sage: sum(i for i in QG.basis()).central_form() - B[()] + B[(1,2)] + B[(1,2)(3,4)] + B[(1,2,3)] + B[(1,2,3)(4,5)] + B[(1,2,3,4)] + B[(1,2,3,4,5)] + B[()] + B[(4,5)] + B[(3,4,5)] + B[(2,3)(4,5)] + B[(2,3,4,5)] + B[(1,2)(3,4,5)] + B[(1,2,3,4,5)] .. NOTE:: @@ -238,4 +238,3 @@ def central_form(self): Z=self.parent().center() return sum(self[i] * Z.basis()[i] for i in Z.basis().keys()) - diff --git a/src/sage/categories/groups.py b/src/sage/categories/groups.py index 8c1c62cf140..f2624d0b259 100644 --- a/src/sage/categories/groups.py +++ b/src/sage/categories/groups.py @@ -207,12 +207,13 @@ def cayley_table(self, names='letters', elements=None): sage: M.cayley_table() * a b c d e f +------------ - a| c e a f b d - b| d f b e a c - c| a b c d e f - d| b a d c f e - e| f d e b c a - f| e c f a d b + a| a b c d e f + b| b a d c f e + c| c f e b a d + d| d e f a b c + e| e d a f c b + f| f c b e d a + :: @@ -465,4 +466,4 @@ def counit(self,x): return sum(x.coefficients()) class ElementMethods: - pass + pass \ No newline at end of file diff --git a/src/sage/combinat/root_system/root_lattice_realizations.py b/src/sage/combinat/root_system/root_lattice_realizations.py index 17574fdc432..5f8c0109ba3 100644 --- a/src/sage/combinat/root_system/root_lattice_realizations.py +++ b/src/sage/combinat/root_system/root_lattice_realizations.py @@ -2219,9 +2219,7 @@ def plot_alcoves(self, alcoves=True, alcove_labels=False, wireframe=False, **opt Line defined by 2 points: [(1.0, 0.0), (0.0, 0.0)] Line defined by 2 points: [(1.0, 0.0), (1.0, -1.0)] sage: [(line.options()['rgbcolor'], line.options()['thickness']) for line in p] - [('black', 2), ('blue', 1), ('red', 1), ('black', 2), ('blue', 1), - ('black', 2), ('red', 1), ('black', 2), ('blue', 1), - ('black', 2), ('red', 1), ('black', 2)] + [('black', 2), ('blue', 1), ('red', 1), ('black', 2), ('black', 2), ('blue', 1), ('black', 2), ('red', 1), ('black', 2), ('red', 1), ('black', 2), ('blue', 1)] """ plot_options = self.plot_parse_options(**options) if not hasattr(self, "fundamental_weights"): @@ -3315,4 +3313,4 @@ def is_short_root(self): ## now only types BCFG remain and the square length is 2 #if ct.type() == 'C' or ct.type() == 'G': # return True - #return False + #return False \ No newline at end of file diff --git a/src/sage/combinat/root_system/root_system.py b/src/sage/combinat/root_system/root_system.py index 544e015c602..a84c80cf466 100644 --- a/src/sage/combinat/root_system/root_system.py +++ b/src/sage/combinat/root_system/root_system.py @@ -229,13 +229,13 @@ class RootSystem(UniqueRepresentation, SageObject): sage: W = L.weyl_group() sage: S3 = [ w.action(id) for w in W.classical() ] sage: [L.classical()(x) for x in S3] - [(3, 2, 1), (3, 1, 2), (2, 3, 1), (2, 1, 3), (1, 3, 2), (1, 2, 3)] + [(1, 2, 3), (3, 2, 1), (3, 1, 2), (2, 1, 3), (2, 3, 1), (1, 3, 2)] And the action of `s_0` on these yields:: sage: s = W.simple_reflections() sage: [L.classical()(s[0].action(x)) for x in S3] - [(-2, 2, 6), (-1, 1, 6), (-2, 3, 5), (0, 1, 5), (-1, 3, 4), (0, 2, 4)] + [(0, 2, 4), (-2, 2, 6), (-1, 1, 6), (0, 1, 5), (-2, 3, 5), (-1, 3, 4)] We can also plot various components of the ambient spaces:: @@ -844,4 +844,4 @@ def WeylDim(ct, coeffs): rank = ct.rank() fw = lattice.fundamental_weights() hwv = lattice.sum(coeffs[i]*fw[i+1] for i in range(min(rank, len(coeffs)))) - return lattice.weyl_dimension(hwv) + return lattice.weyl_dimension(hwv) \ No newline at end of file diff --git a/src/sage/combinat/tiling.py b/src/sage/combinat/tiling.py index a2bb6d108a4..a35a5f61663 100644 --- a/src/sage/combinat/tiling.py +++ b/src/sage/combinat/tiling.py @@ -258,31 +258,31 @@ def orthogonal_transformation(n, orientation_preserving=True): sage: from sage.combinat.tiling import orthogonal_transformation sage: orthogonal_transformation(2) [ - [-1 0] [ 0 -1] [ 0 1] [1 0] - [ 0 -1], [ 1 0], [-1 0], [0 1] + [1 0] [ 0 1] [-1 0] [ 0 -1] + [0 1], [-1 0], [ 0 -1], [ 1 0] ] sage: orthogonal_transformation(2, orientation_preserving=False) [ - [-1 0] [-1 0] [ 0 -1] [ 0 -1] [ 0 1] [0 1] [ 1 0] [1 0] - [ 0 -1], [ 0 1], [-1 0], [ 1 0], [-1 0], [1 0], [ 0 -1], [0 1] + [1 0] [ 0 -1] [ 1 0] [ 0 1] [0 1] [-1 0] [ 0 -1] [-1 0] + [0 1], [-1 0], [ 0 -1], [-1 0], [1 0], [ 0 -1], [ 1 0], [ 0 1] ] sage: orthogonal_transformation(3) [ - [-1 0 0] [-1 0 0] [-1 0 0] [-1 0 0] [ 0 -1 0] [ 0 -1 0] - [ 0 -1 0] [ 0 0 -1] [ 0 0 1] [ 0 1 0] [-1 0 0] [ 0 0 -1] - [ 0 0 1], [ 0 -1 0], [ 0 1 0], [ 0 0 -1], [ 0 0 -1], [ 1 0 0], + [1 0 0] [ 1 0 0] [-1 0 0] [-1 0 0] [0 0 1] [ 0 0 -1] + [0 1 0] [ 0 -1 0] [ 0 1 0] [ 0 -1 0] [1 0 0] [ 1 0 0] + [0 0 1], [ 0 0 -1], [ 0 0 -1], [ 0 0 1], [0 1 0], [ 0 -1 0], - [ 0 -1 0] [ 0 -1 0] [ 0 0 -1] [ 0 0 -1] [ 0 0 -1] [ 0 0 -1] - [ 0 0 1] [ 1 0 0] [-1 0 0] [ 0 -1 0] [ 0 1 0] [ 1 0 0] - [-1 0 0], [ 0 0 1], [ 0 1 0], [-1 0 0], [ 1 0 0], [ 0 -1 0], + [ 0 0 -1] [ 0 0 1] [0 1 0] [ 0 -1 0] [ 0 1 0] [ 0 -1 0] + [-1 0 0] [-1 0 0] [0 0 1] [ 0 0 -1] [ 0 0 -1] [ 0 0 1] + [ 0 1 0], [ 0 -1 0], [1 0 0], [ 1 0 0], [-1 0 0], [-1 0 0], - [ 0 0 1] [ 0 0 1] [ 0 0 1] [0 0 1] [ 0 1 0] [ 0 1 0] - [-1 0 0] [ 0 -1 0] [ 0 1 0] [1 0 0] [-1 0 0] [ 0 0 -1] - [ 0 -1 0], [ 1 0 0], [-1 0 0], [0 1 0], [ 0 0 1], [-1 0 0], + [ 0 1 0] [ 0 -1 0] [ 0 1 0] [ 0 -1 0] [ 1 0 0] [ 1 0 0] + [ 1 0 0] [ 1 0 0] [-1 0 0] [-1 0 0] [ 0 0 -1] [ 0 0 1] + [ 0 0 -1], [ 0 0 1], [ 0 0 1], [ 0 0 -1], [ 0 1 0], [ 0 -1 0], - [0 1 0] [ 0 1 0] [ 1 0 0] [ 1 0 0] [ 1 0 0] [1 0 0] - [0 0 1] [ 1 0 0] [ 0 -1 0] [ 0 0 -1] [ 0 0 1] [0 1 0] - [1 0 0], [ 0 0 -1], [ 0 0 -1], [ 0 1 0], [ 0 -1 0], [0 0 1] + [-1 0 0] [-1 0 0] [ 0 0 -1] [ 0 0 1] [ 0 0 1] [ 0 0 -1] + [ 0 0 1] [ 0 0 -1] [ 0 1 0] [ 0 -1 0] [ 0 1 0] [ 0 -1 0] + [ 0 1 0], [ 0 -1 0], [ 1 0 0], [ 1 0 0], [-1 0 0], [-1 0 0] ] TESTS:: @@ -1381,25 +1381,25 @@ def dlx_common_prefix_solutions(self): sage: y = Polyomino([(0,0),(1,0),(2,0),(3,0),(2,1)], color='yellow') sage: T = TilingSolver([y], box=(5,10), reusable=True, reflection=True) sage: for a in T.dlx_common_prefix_solutions(): a - [46, 83, 149, 26, 179, 44, 81, 162, 132, 101] - [46, 83, 149, 26, 179] - [46, 83, 149, 26, 179, 154, 81, 162, 132, 175] - [46, 83, 149] - [46, 83, 149, 97, 21, 162, 81, 44, 30, 106] - [46] - [46, 157, 149, 136, 179, 44, 81, 162, 132, 101] - [46, 157, 149, 136, 179] - [46, 157, 149, 136, 179, 154, 81, 162, 132, 175] + [64, 83, 149, 44, 179, 62, 35, 162, 132, 101] + [64, 83, 149, 44, 179] + [64, 83, 149, 44, 179, 154, 35, 162, 132, 175] + [64, 83, 149] + [64, 83, 149, 97, 39, 162, 35, 62, 48, 106] + [64] + [64, 157, 149, 136, 179, 62, 35, 162, 132, 101] + [64, 157, 149, 136, 179] + [64, 157, 149, 136, 179, 154, 35, 162, 132, 175] [] - [82, 119, 40, 97, 20, 87, 8, 45, 30, 107] - [82, 119, 40, 97, 20] - [82, 119, 40, 97, 20, 161, 8, 45, 140, 107] + [82, 119, 58, 97, 38, 87, 8, 63, 48, 107] + [82, 119, 58, 97, 38] + [82, 119, 58, 97, 38, 161, 8, 63, 140, 107] [82, 119] - [82, 119, 150, 136, 180, 45, 8, 161, 131, 175] + [82, 119, 150, 136, 180, 63, 8, 161, 131, 175] [82, 119, 150] - [82, 119, 150, 171, 20, 87, 8, 45, 30, 107] - [82, 119, 150, 171, 20] - [82, 119, 150, 171, 20, 161, 8, 45, 140, 107] + [82, 119, 150, 171, 38, 87, 8, 63, 48, 107] + [82, 119, 150, 171, 38] + [82, 119, 150, 171, 38, 161, 8, 63, 140, 107] """ it = self.dlx_solutions() B = it.next() @@ -1446,16 +1446,16 @@ def dlx_incremental_solutions(self): sage: y = Polyomino([(0,0),(1,0),(2,0),(3,0),(2,1)], color='yellow') sage: T = TilingSolver([y], box=(5,10), reusable=True, reflection=True) sage: for a in T.dlx_solutions(): a - [46, 83, 149, 26, 179, 44, 81, 162, 132, 101] - [46, 83, 149, 26, 179, 154, 81, 162, 132, 175] - [46, 83, 149, 97, 21, 162, 81, 44, 30, 106] - [46, 157, 149, 136, 179, 44, 81, 162, 132, 101] - [46, 157, 149, 136, 179, 154, 81, 162, 132, 175] - [82, 119, 40, 97, 20, 87, 8, 45, 30, 107] - [82, 119, 40, 97, 20, 161, 8, 45, 140, 107] - [82, 119, 150, 136, 180, 45, 8, 161, 131, 175] - [82, 119, 150, 171, 20, 87, 8, 45, 30, 107] - [82, 119, 150, 171, 20, 161, 8, 45, 140, 107] + [64, 83, 149, 44, 179, 62, 35, 162, 132, 101] + [64, 83, 149, 44, 179, 154, 35, 162, 132, 175] + [64, 83, 149, 97, 39, 162, 35, 62, 48, 106] + [64, 157, 149, 136, 179, 62, 35, 162, 132, 101] + [64, 157, 149, 136, 179, 154, 35, 162, 132, 175] + [82, 119, 58, 97, 38, 87, 8, 63, 48, 107] + [82, 119, 58, 97, 38, 161, 8, 63, 140, 107] + [82, 119, 150, 136, 180, 63, 8, 161, 131, 175] + [82, 119, 150, 171, 38, 87, 8, 63, 48, 107] + [82, 119, 150, 171, 38, 161, 8, 63, 140, 107] sage: len(list(T.dlx_incremental_solutions())) 123 """ @@ -1698,4 +1698,4 @@ def animate(self, partial=None, stop=None, size=0.75, axes=False): "in Jmol first") else: raise NotImplementedError("Dimension must be 2 or 3 in order " - "to make an animation") + "to make an animation") \ No newline at end of file diff --git a/src/sage/combinat/tutorial.py b/src/sage/combinat/tutorial.py index 31c3db69c05..8d8cc2d308a 100644 --- a/src/sage/combinat/tutorial.py +++ b/src/sage/combinat/tutorial.py @@ -1189,16 +1189,13 @@ :: sage: for p in GL(2, 2): print p; print - [0 1] [1 0] - [0 1] - [1 1] - [1 0] [0 1] - [1 0] + + [0 1] [1 1] [1 1] @@ -1207,6 +1204,9 @@ [1 1] [1 0] + [1 0] + [1 1] + :: @@ -1893,4 +1893,4 @@ children to explore, and to reduce the cost of each test of canonicity. -""" +""" \ No newline at end of file diff --git a/src/sage/groups/finitely_presented.py b/src/sage/groups/finitely_presented.py index 3446ac9bf83..e1bad56a3e9 100644 --- a/src/sage/groups/finitely_presented.py +++ b/src/sage/groups/finitely_presented.py @@ -892,19 +892,11 @@ def semidirect_product(self, H, hom, check=True, reduced=False): You can turn off the checks for the validity of the input morphisms. This check is expensive but behavior is unpredictable if inputs are - invalid and are not caught by these tests. Due to a failure in GAP - to list elements of an automorphism group in some cases, this check - may cause the method to timeout or raise a GAP error. For example, - if ``H`` is the cyclic group of order 6, then ``semidirect_product`` - appears to fall into an infinite loop due to this failure.:: + invalid and are not caught by these tests:: sage: C5 = groups.presentation.Cyclic(5) sage: C12 = groups.presentation.Cyclic(12) sage: hom = (C5.gens(), [(C12.gens(), C12.gens())]) - sage: C5.semidirect_product(C12, hom) - Traceback (most recent call last): - ... - ValueError: libGAP: Error, is not contained in the source group sage: sp = C5.semidirect_product(C12, hom, check=False); sp Finitely presented group < a, b, c, d | a^5, b^-1*a^-1*b*a, c^-1*a^-1*c*a, d^-1*a^-1*d*a, b^2*d^-1, @@ -912,7 +904,14 @@ def semidirect_product(self, H, hom, check=True, reduced=False): sage: sp.as_permutation_group().is_cyclic(), sp.order() (True, 60) - TESTS:: + TESTS: + + The following was fixed in Gap-4.7.2:: + + sage: C5.semidirect_product(C12, hom) == sp + True + + A more complicated semidirect product:: sage: C = groups.presentation.Cyclic(7) sage: D = groups.presentation.Dihedral(5) diff --git a/src/sage/groups/libgap_mixin.py b/src/sage/groups/libgap_mixin.py index c3b2f972abc..935edbd57d9 100644 --- a/src/sage/groups/libgap_mixin.py +++ b/src/sage/groups/libgap_mixin.py @@ -453,8 +453,8 @@ def __iter__(self): sage: gens = [matrix(F,2, [1,0, -1,1]), matrix(F, 2, [1,1,0,1])] sage: G = MatrixGroup(gens) sage: iter(G).next() + [1 0] [0 1] - [2 0] """ if hasattr(self.list, 'get_cache') and self.list.get_cache() is not None: for g in self.list(): @@ -486,8 +486,8 @@ def list(self): 24 sage: v[:5] ( - [0 1] [0 1] [0 1] [0 2] [0 2] - [2 0], [2 1], [2 2], [1 0], [1 1] + [1 0] [2 0] [0 1] [0 2] [1 2] + [0 1], [0 2], [2 0], [1 0], [2 2] ) sage: all(g in G for g in G.list()) True @@ -500,12 +500,12 @@ def list(self): sage: MG = MatrixGroup([M1, M2, M3]) sage: MG.list() ( - [-1 0] [-1 0] [ 1 0] [1 0] - [ 0 -1], [ 0 1], [ 0 -1], [0 1] + [1 0] [ 1 0] [-1 0] [-1 0] + [0 1], [ 0 -1], [ 0 1], [ 0 -1] ) sage: MG.list()[1] - [-1 0] - [ 0 1] + [ 1 0] + [ 0 -1] sage: MG.list()[1].parent() Matrix group over Integer Ring with 3 generators ( [-1 0] [ 1 0] [-1 0] @@ -574,4 +574,4 @@ def is_isomorphic(self, H): except ValueError: pass return False - return True + return True \ No newline at end of file diff --git a/src/sage/groups/matrix_gps/finitely_generated.py b/src/sage/groups/matrix_gps/finitely_generated.py index 4c5e2a3571c..8cdb316709b 100644 --- a/src/sage/groups/matrix_gps/finitely_generated.py +++ b/src/sage/groups/matrix_gps/finitely_generated.py @@ -11,8 +11,8 @@ sage: G = MatrixGroup(gens) sage: G.conjugacy_class_representatives() ( - [1 0] [0 1] [0 1] [0 2] [0 2] [0 1] [2 0] - [0 1], [2 1], [2 2], [1 1], [1 2], [2 0], [0 2] + [1 0] [0 2] [0 1] [2 0] [0 2] [0 1] [0 2] + [0 1], [1 1], [2 1], [0 2], [1 2], [2 2], [1 0] ) The finitely generated matrix groups can also be constructed as @@ -798,4 +798,3 @@ def invariant_generators(self): singular.eval(SName+'[1,%d]'%(j)) for j in range(2,1+singular('ncols('+SName+')')) ] return [PR(gen) for gen in OUT] - diff --git a/src/sage/groups/matrix_gps/matrix_group.py b/src/sage/groups/matrix_gps/matrix_group.py index 620f9639775..5672581e0d0 100644 --- a/src/sage/groups/matrix_gps/matrix_group.py +++ b/src/sage/groups/matrix_gps/matrix_group.py @@ -681,8 +681,8 @@ def list(self): 24 sage: v[:5] ( - [0 1] [0 1] [0 1] [0 2] [0 2] - [2 0], [2 1], [2 2], [1 0], [1 1] + [1 0] [2 0] [0 1] [0 2] [1 2] + [0 1], [0 2], [2 0], [1 0], [2 2] ) sage: all(g in G for g in G.list()) True @@ -695,12 +695,12 @@ def list(self): sage: MG = MatrixGroup([M1, M2, M3]) sage: MG.list() ( - [-1 0] [-1 0] [ 1 0] [1 0] - [ 0 -1], [ 0 1], [ 0 -1], [0 1] + [1 0] [ 1 0] [-1 0] [-1 0] + [0 1], [ 0 -1], [ 0 1], [ 0 -1] ) sage: MG.list()[1] - [-1 0] - [ 0 1] + [ 1 0] + [ 0 -1] sage: MG.list()[1].parent() Matrix group over Integer Ring with 3 generators ( [-1 0] [ 1 0] [-1 0] @@ -731,3 +731,4 @@ def list(self): if not self.is_finite(): raise NotImplementedError('group must be finite') return tuple(iter(self)) + diff --git a/src/sage/groups/perm_gps/permgroup.py b/src/sage/groups/perm_gps/permgroup.py index a63fc604b2e..f7454b29862 100644 --- a/src/sage/groups/perm_gps/permgroup.py +++ b/src/sage/groups/perm_gps/permgroup.py @@ -1843,7 +1843,7 @@ def conjugacy_classes(self): sage: G = DihedralGroup(3) sage: G.conjugacy_classes() [Conjugacy class of () in Dihedral group of order 6 as a permutation group, - Conjugacy class of (1,2) in Dihedral group of order 6 as a permutation group, + Conjugacy class of (2,3) in Dihedral group of order 6 as a permutation group, Conjugacy class of (1,2,3) in Dihedral group of order 6 as a permutation group] """ cl = self._gap_().ConjugacyClasses() @@ -2710,9 +2710,9 @@ def character_table(self): 12 sage: G.character_table() [ 1 1 1 1] - [ 1 1 -zeta3 - 1 zeta3] - [ 1 1 zeta3 -zeta3 - 1] - [ 3 -1 0 0] + [ 1 -zeta3 - 1 zeta3 1] + [ 1 zeta3 -zeta3 - 1 1] + [ 3 0 0 -1] sage: G = PermutationGroup([[(1,2),(3,4)], [(1,2,3)]]) sage: CT = gap(G).CharacterTable() diff --git a/src/sage/groups/perm_gps/permgroup_named.py b/src/sage/groups/perm_gps/permgroup_named.py index a7a0ca0c94c..eb2ab0b6375 100644 --- a/src/sage/groups/perm_gps/permgroup_named.py +++ b/src/sage/groups/perm_gps/permgroup_named.py @@ -2420,7 +2420,7 @@ def ramification_module_decomposition_hurwitz_curve(self): EXAMPLES:: sage: G = PSL(2,13) - sage: G.ramification_module_decomposition_hurwitz_curve() #random + sage: G.ramification_module_decomposition_hurwitz_curve() # random, optional - database_gap [0, 7, 7, 12, 12, 12, 13, 15, 14] This means, for example, that the trivial representation does not @@ -2468,7 +2468,7 @@ def ramification_module_decomposition_modular_curve(self): EXAMPLES:: sage: G = PSL(2,7) - sage: G.ramification_module_decomposition_modular_curve() ## random + sage: G.ramification_module_decomposition_modular_curve() # random, optional - database_gap [0, 4, 3, 6, 7, 8] This means, for example, that the trivial representation does not From 3bb8bdbd91c70d807b417a4efde29778a04651bf Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Thu, 26 Dec 2013 18:11:31 +0000 Subject: [PATCH 022/163] also fix long doctests --- .../en/thematic_tutorials/group_theory.rst | 34 +++++----- src/sage/games/quantumino.py | 65 +++++++++---------- 2 files changed, 48 insertions(+), 51 deletions(-) diff --git a/src/doc/en/thematic_tutorials/group_theory.rst b/src/doc/en/thematic_tutorials/group_theory.rst index 3d8d0897474..d741b827759 100644 --- a/src/doc/en/thematic_tutorials/group_theory.rst +++ b/src/doc/en/thematic_tutorials/group_theory.rst @@ -894,33 +894,31 @@ example, if `p` is a prime, and `p^r` divides the order of a group could be found among the output of the ``conjugacy_classes_subgroups()`` command by checking the orders of the subgroups produced. The ``map()`` command is a quick way -to do this. The symmetric group on 8 symbols, `S_8`, has order -`8! = 40320` and is divisible by `2^7 = 128`. Let's find one example -of a subgroup of permutations on 8 symbols with order 128. The next -command takes a few minutes to run, so go get a cup of coffee after -you set it in motion. :: +to do this. The symmetric group on 7 symbols, `S_7`, has order +`7! = 5040` and is divisible by `2^4 = 16`. Let's find one example +of a subgroup of permutations on 4 symbols with order 16:: - sage: G = SymmetricGroup(8) - sage: subgroups = G.conjugacy_classes_subgroups() # long time (9s on sage.math, 2011) - sage: map(order, subgroups) # long time - [1, 2, 2, 2, 2, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 10, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 18, 18, 18, 18, 18, 18, 18, 20, 20, 20, 21, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 30, 30, 30, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 40, 42, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 56, 60, 60, 60, 60, 60, 64, 64, 64, 64, 64, 64, 64, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 120, 120, 120, 120, 120, 120, 120, 128, 144, 144, 144, 168, 168, 168, 180, 192, 192, 192, 192, 192, 240, 240, 288, 288, 288, 336, 360, 360, 360, 360, 384, 576, 576, 576, 720, 720, 720, 720, 1152, 1344, 1440, 2520, 5040, 20160, 40320] + sage: G = SymmetricGroup(7) + sage: subgroups = G.conjugacy_classes_subgroups() + sage: map(order, subgroups) + [1, 2, 2, 2, 3, 3, 4, 4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7, 8, 8, 8, 8, 8, 8, 8, 9, 10, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 14, 16, 18, 18, 18, 20, 20, 20, 21, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 36, 36, 36, 36, 40, 42, 48, 48, 48, 60, 60, 72, 72, 72, 72, 120, 120, 120, 120, 144, 168, 240, 360, 720, 2520, 5040] The ``map(order, subgroups)`` command will apply the ``order()`` -method to each of the subgroups in the list ``subgroups``. The output -is thus a large list of the orders of many subgroups (296 to be -precise). If you count carefully, you will see that the 259-th -subgroup has order 128. You can retrieve this group for further study -by referencing it as ``subgroups[258]`` (remember that counting starts at -zero). +function to each of the subgroups in the list ``subgroups``. The +output is thus a large list of the orders of many subgroups (96 to be +precise). If you count carefully, you will see that the 49-th +subgroup has order 16. You can retrieve this group for further study +by referencing it as ``subgroups[48]`` (remember that counting starts +at zero). If `p^r` is the highest power of `p` to divide the order of `G`, then a subgroup of order `p^r` is known as a "Sylow `p`-subgroup." Sylow's Theorems also say any two Sylow `p`-subgroups are conjugate, so the output of ``conjugacy_classes_subgroups()`` should only contain each Sylow `p`-subgroup once. But there is an easier way, -``sylow_subgroup(p)`` will return one. Notice that the argument of -the command is just the prime $p$, not the full power `p^r`. Failure -to use a prime will generate an informative error message. +``sylow_subgroup(p)`` will return one. Notice that the argument of the +command is just the prime $p$, not the full power `p^r`. Failure to +use a prime will generate an informative error message. Groups of small order as permutation groups diff --git a/src/sage/games/quantumino.py b/src/sage/games/quantumino.py index 04369639dd0..a6479a111b9 100644 --- a/src/sage/games/quantumino.py +++ b/src/sage/games/quantumino.py @@ -80,22 +80,22 @@ pentamino:: sage: for p in s: p # long time (<1s) - Polyomino: [(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 2, 0), (1, 1, 0)], Color: deeppink - Polyomino: [(0, 1, 1), (1, 0, 1), (1, 1, 1), (1, 2, 0), (1, 2, 1)], Color: deeppink - Polyomino: [(0, 2, 1), (0, 3, 1), (0, 4, 0), (0, 4, 1), (1, 4, 0)], Color: green - Polyomino: [(0, 3, 0), (1, 3, 0), (2, 2, 1), (2, 3, 0), (2, 3, 1)], Color: green - Polyomino: [(1, 3, 1), (1, 4, 1), (2, 4, 0), (2, 4, 1), (2, 5, 1)], Color: red - Polyomino: [(1, 0, 0), (2, 0, 0), (2, 0, 1), (2, 1, 1), (3, 0, 1)], Color: red - Polyomino: [(2, 1, 0), (2, 2, 0), (3, 2, 0), (3, 2, 1), (3, 3, 1)], Color: blue - Polyomino: [(3, 0, 0), (3, 1, 0), (4, 0, 0), (4, 0, 1), (4, 1, 0)], Color: yellow - Polyomino: [(3, 1, 1), (4, 1, 1), (4, 2, 0), (4, 2, 1), (4, 3, 0)], Color: purple - Polyomino: [(3, 3, 0), (3, 4, 0), (3, 4, 1), (4, 3, 1), (4, 4, 1)], Color: yellow - Polyomino: [(3, 5, 1), (4, 4, 0), (4, 5, 0), (4, 5, 1), (4, 6, 0)], Color: midnightblue - Polyomino: [(2, 6, 1), (2, 7, 1), (3, 7, 0), (3, 7, 1), (4, 7, 0)], Color: purple - Polyomino: [(3, 5, 0), (3, 6, 0), (3, 6, 1), (4, 6, 1), (4, 7, 1)], Color: blue - Polyomino: [(0, 5, 0), (0, 5, 1), (0, 6, 0), (1, 5, 0), (2, 5, 0)], Color: darkblue - Polyomino: [(0, 7, 0), (0, 7, 1), (1, 7, 0), (2, 6, 0), (2, 7, 0)], Color: orange - Polyomino: [(0, 6, 1), (1, 5, 1), (1, 6, 0), (1, 6, 1), (1, 7, 1)], Color: gray + Polyomino: [(0, 0, 0), (1, 0, 0), (1, 1, 0), (1, 1, 1), (1, 2, 0)], Color: deeppink + Polyomino: [(0, 0, 1), (0, 1, 0), (0, 1, 1), (0, 2, 1), (1, 2, 1)], Color: deeppink + Polyomino: [(0, 2, 0), (0, 3, 0), (0, 4, 0), (1, 4, 0), (1, 4, 1)], Color: green + Polyomino: [(0, 3, 1), (1, 3, 1), (2, 2, 0), (2, 2, 1), (2, 3, 1)], Color: green + Polyomino: [(1, 3, 0), (2, 3, 0), (2, 4, 0), (2, 4, 1), (3, 4, 0)], Color: red + Polyomino: [(1, 0, 1), (2, 0, 1), (2, 1, 0), (2, 1, 1), (3, 1, 1)], Color: red + Polyomino: [(2, 0, 0), (3, 0, 0), (3, 0, 1), (3, 1, 0), (4, 0, 0)], Color: gray + Polyomino: [(3, 2, 0), (4, 0, 1), (4, 1, 0), (4, 1, 1), (4, 2, 0)], Color: purple + Polyomino: [(3, 2, 1), (3, 3, 0), (3, 3, 1), (4, 2, 1), (4, 3, 1)], Color: yellow + Polyomino: [(3, 4, 1), (3, 5, 1), (4, 3, 0), (4, 4, 0), (4, 4, 1)], Color: blue + Polyomino: [(0, 4, 1), (0, 5, 0), (0, 5, 1), (0, 6, 1), (1, 5, 0)], Color: midnightblue + Polyomino: [(0, 6, 0), (0, 7, 0), (0, 7, 1), (1, 7, 0), (2, 7, 0)], Color: darkblue + Polyomino: [(1, 7, 1), (2, 6, 0), (2, 6, 1), (2, 7, 1), (3, 6, 0)], Color: blue + Polyomino: [(1, 5, 1), (1, 6, 0), (1, 6, 1), (2, 5, 0), (2, 5, 1)], Color: yellow + Polyomino: [(3, 6, 1), (3, 7, 0), (3, 7, 1), (4, 5, 1), (4, 6, 1)], Color: purple + Polyomino: [(3, 5, 0), (4, 5, 0), (4, 6, 0), (4, 7, 0), (4, 7, 1)], Color: orange To get all the solutions, use the iterator returned by the ``solve`` method. Note that finding the first solution is the most time consuming @@ -483,22 +483,22 @@ def solve(self, partial=None): The explicit solution:: sage: for p in s: p # long time (fast) - Polyomino: [(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 2, 0), (1, 1, 0)], Color: deeppink - Polyomino: [(0, 1, 1), (1, 0, 1), (1, 1, 1), (1, 2, 0), (1, 2, 1)], Color: deeppink - Polyomino: [(0, 2, 1), (0, 3, 1), (0, 4, 0), (0, 4, 1), (1, 4, 0)], Color: green - Polyomino: [(0, 3, 0), (1, 3, 0), (2, 2, 1), (2, 3, 0), (2, 3, 1)], Color: green - Polyomino: [(1, 3, 1), (1, 4, 1), (2, 4, 0), (2, 4, 1), (2, 5, 1)], Color: red - Polyomino: [(1, 0, 0), (2, 0, 0), (2, 0, 1), (2, 1, 1), (3, 0, 1)], Color: red - Polyomino: [(3, 0, 0), (4, 0, 0), (4, 0, 1), (4, 1, 0), (4, 2, 0)], Color: darkblue - Polyomino: [(2, 1, 0), (2, 2, 0), (3, 1, 0), (3, 1, 1), (4, 1, 1)], Color: purple - Polyomino: [(3, 2, 0), (3, 3, 0), (3, 3, 1), (3, 4, 0), (4, 3, 0)], Color: gray - Polyomino: [(3, 2, 1), (4, 2, 1), (4, 3, 1), (4, 4, 0), (4, 4, 1)], Color: orange - Polyomino: [(3, 4, 1), (3, 5, 1), (4, 5, 0), (4, 5, 1), (4, 6, 0)], Color: blue - Polyomino: [(3, 6, 0), (3, 7, 0), (4, 6, 1), (4, 7, 0), (4, 7, 1)], Color: yellow - Polyomino: [(1, 5, 0), (2, 5, 0), (2, 6, 0), (2, 6, 1), (3, 5, 0)], Color: midnightblue - Polyomino: [(1, 7, 0), (2, 7, 0), (2, 7, 1), (3, 6, 1), (3, 7, 1)], Color: purple - Polyomino: [(0, 5, 1), (0, 6, 1), (0, 7, 0), (0, 7, 1), (1, 5, 1)], Color: orange - Polyomino: [(0, 5, 0), (0, 6, 0), (1, 6, 0), (1, 6, 1), (1, 7, 1)], Color: blue + Polyomino: [(0, 0, 0), (1, 0, 0), (1, 1, 0), (1, 1, 1), (1, 2, 0)], Color: deeppink + Polyomino: [(0, 0, 1), (0, 1, 0), (0, 1, 1), (0, 2, 1), (1, 2, 1)], Color: deeppink + Polyomino: [(0, 2, 0), (0, 3, 0), (0, 4, 0), (1, 4, 0), (1, 4, 1)], Color: green + Polyomino: [(0, 3, 1), (1, 3, 1), (2, 2, 0), (2, 2, 1), (2, 3, 1)], Color: green + Polyomino: [(1, 3, 0), (2, 3, 0), (2, 4, 0), (2, 4, 1), (3, 4, 0)], Color: red + Polyomino: [(1, 0, 1), (2, 0, 0), (2, 0, 1), (2, 1, 0), (3, 0, 1)], Color: midnightblue + Polyomino: [(0, 4, 1), (0, 5, 0), (0, 5, 1), (0, 6, 0), (1, 5, 0)], Color: red + Polyomino: [(2, 1, 1), (3, 0, 0), (3, 1, 0), (3, 1, 1), (4, 0, 0)], Color: blue + Polyomino: [(3, 2, 0), (4, 0, 1), (4, 1, 0), (4, 1, 1), (4, 2, 0)], Color: purple + Polyomino: [(3, 2, 1), (3, 3, 0), (4, 2, 1), (4, 3, 0), (4, 3, 1)], Color: yellow + Polyomino: [(3, 3, 1), (3, 4, 1), (4, 4, 0), (4, 4, 1), (4, 5, 0)], Color: blue + Polyomino: [(0, 6, 1), (0, 7, 0), (0, 7, 1), (1, 5, 1), (1, 6, 1)], Color: purple + Polyomino: [(1, 6, 0), (1, 7, 0), (1, 7, 1), (2, 7, 0), (3, 7, 0)], Color: darkblue + Polyomino: [(2, 5, 0), (2, 6, 0), (3, 6, 0), (4, 6, 0), (4, 6, 1)], Color: orange + Polyomino: [(2, 5, 1), (3, 5, 0), (3, 5, 1), (3, 6, 1), (4, 5, 1)], Color: gray + Polyomino: [(2, 6, 1), (2, 7, 1), (3, 7, 1), (4, 7, 0), (4, 7, 1)], Color: orange Enumerate the solutions:: @@ -570,4 +570,3 @@ def number_of_solutions(self): """ return self.tiling_solver().number_of_solutions() - From e2fafd760eba07d967db6e85ece7006e499545e2 Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Wed, 10 Jul 2013 15:09:10 +0000 Subject: [PATCH 023/163] # Wed Jul 10 11:09:10 2013 -0400 # Node ID f595d0e4210ef833f35330ede8a41012ed58390a # Parent 5d8c13e7b81a1e152855073f97a4d48ee97255d1 NTL::mat<> is now a C++ template class instead of a #define hack --- src/c_lib/include/ntl_wrap.h | 32 +++++++++---------- src/c_lib/src/ntl_wrap.cpp | 28 ++++++++-------- src/sage/libs/ntl/decl.pxi | 6 ++-- .../hyperelliptic_curves/hypellfrob.pyx | 3 +- 4 files changed, 35 insertions(+), 34 deletions(-) diff --git a/src/c_lib/include/ntl_wrap.h b/src/c_lib/include/ntl_wrap.h index 77bdef6c589..0cfe3ce7696 100644 --- a/src/c_lib/include/ntl_wrap.h +++ b/src/c_lib/include/ntl_wrap.h @@ -249,20 +249,20 @@ struct ZZ_pEX; //////// mat_ZZ ////////// #ifndef __cplusplus -struct mat_ZZ; +typedef struct {} mat_ZZ; #endif -EXTERN void mat_ZZ_SetDims(struct mat_ZZ* mZZ, long nrows, long ncols); -EXTERN struct mat_ZZ* mat_ZZ_pow(const struct mat_ZZ* x, long e); -EXTERN long mat_ZZ_nrows(const struct mat_ZZ* x); -EXTERN long mat_ZZ_ncols(const struct mat_ZZ* x); -EXTERN void mat_ZZ_setitem(struct mat_ZZ* x, int i, int j, const struct ZZ* z); -EXTERN struct ZZ* mat_ZZ_getitem(const struct mat_ZZ* x, int i, int j); -EXTERN struct ZZ* mat_ZZ_determinant(const struct mat_ZZ* x, long deterministic); -EXTERN struct mat_ZZ* mat_ZZ_HNF(const struct mat_ZZ* A, const struct ZZ* D); -EXTERN struct ZZX* mat_ZZ_charpoly(const struct mat_ZZ* A); -EXTERN long mat_ZZ_LLL(struct ZZ **det, struct mat_ZZ *x, long a, long b, long verbose); -EXTERN long mat_ZZ_LLL_U(struct ZZ **det, struct mat_ZZ *x, struct mat_ZZ *U, long a, long b, long verbose); +EXTERN void mat_ZZ_SetDims(mat_ZZ* mZZ, long nrows, long ncols); +EXTERN mat_ZZ* mat_ZZ_pow(const mat_ZZ* x, long e); +EXTERN long mat_ZZ_nrows(const mat_ZZ* x); +EXTERN long mat_ZZ_ncols(const mat_ZZ* x); +EXTERN void mat_ZZ_setitem(mat_ZZ* x, int i, int j, const struct ZZ* z); +EXTERN struct ZZ* mat_ZZ_getitem(const mat_ZZ* x, int i, int j); +EXTERN struct ZZ* mat_ZZ_determinant(const mat_ZZ* x, long deterministic); +EXTERN mat_ZZ* mat_ZZ_HNF(const mat_ZZ* A, const struct ZZ* D); +EXTERN struct ZZX* mat_ZZ_charpoly(const mat_ZZ* A); +EXTERN long mat_ZZ_LLL(struct ZZ **det, mat_ZZ *x, long a, long b, long verbose); +EXTERN long mat_ZZ_LLL_U(struct ZZ **det, mat_ZZ *x, mat_ZZ *U, long a, long b, long verbose); /* //////// ZZ_p ////////// */ /* #ifndef __cplusplus */ @@ -314,15 +314,15 @@ EXTERN struct GF2EContext* GF2EContext_construct(void *mem, const struct GF2X *p //////// mat_GF2E ////////// #ifndef __cplusplus -struct mat_GF2E; +typedef struct {} mat_GF2E; #endif -EXTERN void mat_GF2E_setitem(struct mat_GF2E* x, int i, int j, const struct GF2E* z); +EXTERN void mat_GF2E_setitem(mat_GF2E* x, int i, int j, const struct GF2E* z); //////// mat_GF2 ////////// #ifndef __cplusplus -struct mat_GF2; +typedef struct {} mat_GF2; #endif -EXTERN void mat_GF2_setitem(struct mat_GF2* x, int i, int j, const struct GF2* z); +EXTERN void mat_GF2_setitem(mat_GF2* x, int i, int j, const struct GF2* z); diff --git a/src/c_lib/src/ntl_wrap.cpp b/src/c_lib/src/ntl_wrap.cpp index 120ce03b51f..017777f4551 100644 --- a/src/c_lib/src/ntl_wrap.cpp +++ b/src/c_lib/src/ntl_wrap.cpp @@ -845,67 +845,67 @@ struct ZZ_pX ZZ_pE_to_ZZ_pX(struct ZZ_pE x) //////// mat_ZZ ////////// -void mat_ZZ_SetDims(struct mat_ZZ* mZZ, long nrows, long ncols){ +void mat_ZZ_SetDims(mat_ZZ* mZZ, long nrows, long ncols){ mZZ->SetDims(nrows, ncols); } -struct mat_ZZ* mat_ZZ_pow(const struct mat_ZZ* x, long e) +mat_ZZ* mat_ZZ_pow(const mat_ZZ* x, long e) { mat_ZZ *z = new mat_ZZ(); power(*z, *x, e); return z; } -long mat_ZZ_nrows(const struct mat_ZZ* x) +long mat_ZZ_nrows(const mat_ZZ* x) { return x->NumRows(); } -long mat_ZZ_ncols(const struct mat_ZZ* x) +long mat_ZZ_ncols(const mat_ZZ* x) { return x->NumCols(); } -void mat_ZZ_setitem(struct mat_ZZ* x, int i, int j, const struct ZZ* z) +void mat_ZZ_setitem(mat_ZZ* x, int i, int j, const struct ZZ* z) { (*x)[i][j] = *z; } -struct ZZ* mat_ZZ_getitem(const struct mat_ZZ* x, int i, int j) +struct ZZ* mat_ZZ_getitem(const mat_ZZ* x, int i, int j) { return new ZZ((*x)(i,j)); } -struct ZZ* mat_ZZ_determinant(const struct mat_ZZ* x, long deterministic) +struct ZZ* mat_ZZ_determinant(const mat_ZZ* x, long deterministic) { ZZ* d = new ZZ(); determinant(*d, *x, deterministic); return d; } -struct mat_ZZ* mat_ZZ_HNF(const struct mat_ZZ* A, const struct ZZ* D) +mat_ZZ* mat_ZZ_HNF(const mat_ZZ* A, const struct ZZ* D) { - struct mat_ZZ* W = new mat_ZZ(); + mat_ZZ* W = new mat_ZZ(); HNF(*W, *A, *D); return W; } -long mat_ZZ_LLL(struct ZZ **det, struct mat_ZZ *x, long a, long b, long verbose) +long mat_ZZ_LLL(struct ZZ **det, mat_ZZ *x, long a, long b, long verbose) { *det = new ZZ(); return LLL(**det,*x,a,b,verbose); } -long mat_ZZ_LLL_U(struct ZZ **det, struct mat_ZZ *x, struct mat_ZZ *U, long a, long b, long verbose) +long mat_ZZ_LLL_U(struct ZZ **det, mat_ZZ *x, mat_ZZ *U, long a, long b, long verbose) { *det = new ZZ(); return LLL(**det,*x,*U,a,b,verbose); } -struct ZZX* mat_ZZ_charpoly(const struct mat_ZZ* A) +struct ZZX* mat_ZZ_charpoly(const mat_ZZ* A) { ZZX* f = new ZZX(); CharPoly(*f, *A); @@ -928,12 +928,12 @@ GF2EContext* GF2EContext_new(const GF2X *p) } -void mat_GF2E_setitem(struct mat_GF2E* x, int i, int j, const struct GF2E* z) +void mat_GF2E_setitem(mat_GF2E* x, int i, int j, const struct GF2E* z) { (*x)[i][j] = *z; } -void mat_GF2_setitem(struct mat_GF2* x, int i, int j, const struct GF2* z) +void mat_GF2_setitem(mat_GF2* x, int i, int j, const struct GF2* z) { (*x)[i][j] = *z; } diff --git a/src/sage/libs/ntl/decl.pxi b/src/sage/libs/ntl/decl.pxi index 82011f06bf5..d1f9c6cf929 100644 --- a/src/sage/libs/ntl/decl.pxi +++ b/src/sage/libs/ntl/decl.pxi @@ -22,7 +22,7 @@ from sage.libs.ntl.ntl_ZZ_pEX_decl cimport *, ZZ_pEX_c cdef extern from "ntl_wrap.h": #### mat_ZZ_c - ctypedef struct mat_ZZ_c "struct mat_ZZ": + cdef cppclass mat_ZZ_c "mat_ZZ": pass # Some boiler-plate @@ -260,7 +260,7 @@ cdef extern from "ntl_wrap.h": object vec_GF2E_to_PyString "_to_PyString"(vec_GF2E_c *x) #### mat_GF2E_c - ctypedef struct mat_GF2E_c "struct mat_GF2E": + cdef cppclass mat_GF2E_c "mat_GF2E": void (*SetDims)(long nrows, long ncols) long (*NumRows)() long (*NumCols)() @@ -311,7 +311,7 @@ cdef extern from "ntl_wrap.h": #### mat_GF2_c - ctypedef struct mat_GF2_c "struct mat_GF2": + cdef cppclass mat_GF2_c "mat_GF2": void (*SetDims)(long nrows, long ncols) long (*NumRows)() long (*NumCols)() diff --git a/src/sage/schemes/hyperelliptic_curves/hypellfrob.pyx b/src/sage/schemes/hyperelliptic_curves/hypellfrob.pyx index 17272a3e8b5..d06cd6b2cbf 100644 --- a/src/sage/schemes/hyperelliptic_curves/hypellfrob.pyx +++ b/src/sage/schemes/hyperelliptic_curves/hypellfrob.pyx @@ -119,7 +119,8 @@ def hypellfrob(p, N, Q): cdef int result sig_on() - result = hypellfrob_matrix(mm.x, pp.x, N, QQ.x) + cdef mat_ZZ_c *mm_x = &mm.x # workaround for Cython misfeature + result = hypellfrob_matrix(mm_x[0], pp.x, N, QQ.x) sig_off() if not result: From 46c4b36857a1976d23ed9e9e4e1698e6864245b3 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Tue, 31 Dec 2013 04:27:02 -0800 Subject: [PATCH 024/163] Update NTL to 6.0.0. --- build/pkgs/ntl/SPKG.txt | 3 +++ build/pkgs/ntl/checksums.ini | 6 +++--- build/pkgs/ntl/package-version.txt | 2 +- build/pkgs/ntl/spkg-src | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/build/pkgs/ntl/SPKG.txt b/build/pkgs/ntl/SPKG.txt index 761661b92c2..a3fdeae474b 100644 --- a/build/pkgs/ntl/SPKG.txt +++ b/build/pkgs/ntl/SPKG.txt @@ -36,6 +36,9 @@ Website: http://www.shoup.net/ntl/ == Changelog == +=== ntl-6.0.0.p0 (Volker Braun, July 10 2013) === + * #14876: Update to latest upstream + === ntl-5.5.2.p3 (Volker Braun, July 10 2013) === * #14692: Add spkg-src and track all files. diff --git a/build/pkgs/ntl/checksums.ini b/build/pkgs/ntl/checksums.ini index c2115e2ed25..06f8b72ab49 100644 --- a/build/pkgs/ntl/checksums.ini +++ b/build/pkgs/ntl/checksums.ini @@ -1,4 +1,4 @@ tarball=ntl-VERSION.tar.bz2 -sha1=60131a6c1858cc4a40340e189efe838e34259c42 -md5=929209ed7055af46f07c8f0e8f7147e9 -cksum=1759745658 +sha1=37f8ed0f19c32339dec52cc99404b121eeab53da +md5=2e37471f4db7717359509e0bb049d663 +cksum=3763537459 diff --git a/build/pkgs/ntl/package-version.txt b/build/pkgs/ntl/package-version.txt index 2814b0e710b..cb3cb5723b8 100644 --- a/build/pkgs/ntl/package-version.txt +++ b/build/pkgs/ntl/package-version.txt @@ -1 +1 @@ -5.5.2.p3 +6.0.0.p0 diff --git a/build/pkgs/ntl/spkg-src b/build/pkgs/ntl/spkg-src index 862ad487feb..42b20a0cccc 100755 --- a/build/pkgs/ntl/spkg-src +++ b/build/pkgs/ntl/spkg-src @@ -1,6 +1,6 @@ #!/usr/bin/env bash -NTL=ntl-5.5.2 +NTL=ntl-6.0.0 SPKG_ROOT=`pwd` From 5c6cf3dc40163956e250836c34f782f5eba93547 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Tue, 31 Dec 2013 05:09:19 -0800 Subject: [PATCH 025/163] Update Singular's patch for NTL 6.0.0 compatibility. --- build/pkgs/singular/SPKG.txt | 4 ++++ build/pkgs/singular/package-version.txt | 2 +- build/pkgs/singular/patches/NTL6_compatibility.patch | 4 +++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/build/pkgs/singular/SPKG.txt b/build/pkgs/singular/SPKG.txt index af447a80d1d..cb700f06b07 100644 --- a/build/pkgs/singular/SPKG.txt +++ b/build/pkgs/singular/SPKG.txt @@ -32,6 +32,7 @@ See spkg-src. == Patches == * NTL6_compatibility.patch taken from commit ddb348e97a991972e5dfee690a66663ba0418f40 + and further updated. * factory_template_instantiation.patch taken from commit 561842a06ad4b44f3b85b28ac35e7946eaba9a30 * assert.patch: logic seems to be broken on some platforms @@ -72,6 +73,9 @@ Other notes == ChangeLog == +=== singular-3-1-6.p1 (Jean-Pierre Flori, 31 December 2013) === + * #14876: update patch for NTL compatibility. + === singular-3-1-6.p0 (Jeroen Demeyer, 26 August 2013) === * Remove the following patches, which were fixed upstream: - NTL_negate.patch diff --git a/build/pkgs/singular/package-version.txt b/build/pkgs/singular/package-version.txt index a20f5edf470..057d7ea1719 100644 --- a/build/pkgs/singular/package-version.txt +++ b/build/pkgs/singular/package-version.txt @@ -1 +1 @@ -3.1.6.p0 +3.1.6.p1 diff --git a/build/pkgs/singular/patches/NTL6_compatibility.patch b/build/pkgs/singular/patches/NTL6_compatibility.patch index 587a9dff1c3..1414d189100 100644 --- a/build/pkgs/singular/patches/NTL6_compatibility.patch +++ b/build/pkgs/singular/patches/NTL6_compatibility.patch @@ -3,7 +3,7 @@ diff --git a/Singular/claptmpl.cc b/Singular/claptmpl.cc index 0fa6109..553afa5 100644 --- a/Singular/claptmpl.cc +++ b/Singular/claptmpl.cc -@@ -123,3 +123,36 @@ template class std::list; +@@ -123,3 +123,38 @@ template class std::list; template class Cache; template class Cache; @@ -14,6 +14,7 @@ index 0fa6109..553afa5 100644 +#include +#include +#include ++#include +#include +#include +#include @@ -30,6 +31,7 @@ index 0fa6109..553afa5 100644 +template class Mat; +template class Mat; +template class Mat; ++template class Vec >; +template class Vec >; +template class Vec >; +template class Vec >; From b6d64b4fef401d71b7a6b573604691a79984fa64 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Tue, 31 Dec 2013 06:58:01 -0800 Subject: [PATCH 026/163] Fix double free issues with NTL 6.0.0. --- src/sage/libs/ntl/ntl_mat_GF2.pyx | 5 ++++- src/sage/libs/ntl/ntl_mat_GF2E.pyx | 5 ++++- src/sage/libs/ntl/ntl_mat_ZZ.pyx | 5 ++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/sage/libs/ntl/ntl_mat_GF2.pyx b/src/sage/libs/ntl/ntl_mat_GF2.pyx index 96a98f9e705..4f3c79a1097 100644 --- a/src/sage/libs/ntl/ntl_mat_GF2.pyx +++ b/src/sage/libs/ntl/ntl_mat_GF2.pyx @@ -127,7 +127,10 @@ cdef class ntl_mat_GF2: return r def __dealloc__(self): - mat_GF2_destruct(&self.x) + # With NTL 6.0.0, mat_GF2 is a proper C++ class. + # Therefore Cython automagically calls the class destructor. + #mat_GF2_destruct(&self.x) + pass def __reduce__(self): """ diff --git a/src/sage/libs/ntl/ntl_mat_GF2E.pyx b/src/sage/libs/ntl/ntl_mat_GF2E.pyx index ff9f5f5f303..d78b824b495 100644 --- a/src/sage/libs/ntl/ntl_mat_GF2E.pyx +++ b/src/sage/libs/ntl/ntl_mat_GF2E.pyx @@ -162,7 +162,10 @@ cdef class ntl_mat_GF2E: return self.c def __dealloc__(self): - mat_GF2E_destruct(&self.x) + # With NTL 6.0.0, mat_GF2E is a proper C++ class. + # Therefore Cython automagically calls the class destructor. + #mat_GF2E_destruct(&self.x) + pass def __reduce__(self): """ diff --git a/src/sage/libs/ntl/ntl_mat_ZZ.pyx b/src/sage/libs/ntl/ntl_mat_ZZ.pyx index 86fd7ad7fea..f681c43ddec 100644 --- a/src/sage/libs/ntl/ntl_mat_ZZ.pyx +++ b/src/sage/libs/ntl/ntl_mat_ZZ.pyx @@ -124,7 +124,10 @@ cdef class ntl_mat_ZZ: mat_ZZ_construct(&self.x) def __dealloc__(self): - mat_ZZ_destruct(&self.x) + # With NTL 6.0.0, mat_ZZ is a proper C++ class. + # Therefore Cython automagically calls the class destructor. + #mat_ZZ_destruct(&self.x) + pass def __repr__(self): """ From d32e8d143893b8b2c1c670f8a8c4b06fec4e5fd1 Mon Sep 17 00:00:00 2001 From: zabrocki Date: Sun, 5 Jan 2014 08:12:00 -0500 Subject: [PATCH 027/163] remove import kschur from classical.py and inaccessible if statements --- src/sage/combinat/sf/classical.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/sage/combinat/sf/classical.py b/src/sage/combinat/sf/classical.py index 48aa676361e..34ce9082dea 100644 --- a/src/sage/combinat/sf/classical.py +++ b/src/sage/combinat/sf/classical.py @@ -33,7 +33,6 @@ import macdonald import jack import orthotriang -import kschur ZZ = IntegerRing() QQ = RationalField() @@ -276,17 +275,6 @@ def _element_constructor_(self, x): else: raise TypeError - ##################### - # k-Schur Functions # - ##################### - if isinstance(x, kschur.kSchurFunctions_generic.Element): - if isinstance(x, kschur.kSchurFunctions_t.Element): - P = x.parent() - sx = P._s._from_cache(x, P._s_cache, P._self_to_s_cache, t=P.t) - return self(sx) - else: - raise TypeError - #################################################### # Bases defined by orthogonality and triangularity # #################################################### From 0cc8d70d5489bb61763329c5553c968d9ec638ce Mon Sep 17 00:00:00 2001 From: Punarbasu Purkayastha Date: Mon, 6 Jan 2014 17:31:21 +0800 Subject: [PATCH 028/163] stop counting polynomials twice The number of polynomials tested was being counted twice. This fixes the count. --- src/sage/rings/number_field/totallyreal_rel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/number_field/totallyreal_rel.py b/src/sage/rings/number_field/totallyreal_rel.py index aa296893f30..73ef21c527a 100644 --- a/src/sage/rings/number_field/totallyreal_rel.py +++ b/src/sage/rings/number_field/totallyreal_rel.py @@ -763,7 +763,7 @@ def enumerate_totallyreal_fields_rel(F, m, B, a = [], verbose=0, nf = nf.subst('x', 'x-t') nf = nf.polresultant(nfF, parit) d = nf.poldisc() - counts[0] += 1 + #counts[0] += 1 if d > 0 and nf.polsturm_full() == n: da = int_has_small_square_divisor(Integer(d)) if d > dB or d <= B*da: From f78fa371cb78f3da5767ac6f7ea3e7171ce8b379 Mon Sep 17 00:00:00 2001 From: Punarbasu Purkayastha Date: Mon, 6 Jan 2014 17:32:33 +0800 Subject: [PATCH 029/163] Ensure that value of n=1, m=1 works. The variable T was being initialized before the special case n = 1 and m = 1. --- src/sage/rings/number_field/totallyreal.pyx | 2 +- src/sage/rings/number_field/totallyreal_rel.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/number_field/totallyreal.pyx b/src/sage/rings/number_field/totallyreal.pyx index 38d1bba578c..8e12762f5cc 100644 --- a/src/sage/rings/number_field/totallyreal.pyx +++ b/src/sage/rings/number_field/totallyreal.pyx @@ -290,7 +290,6 @@ def enumerate_totallyreal_fields_prim(n, B, a = [], verbose=0, return_seqs=False # Initialize n_int = int(n) - T = tr_data(n_int,B,a) S = [] lenS = 0 @@ -369,6 +368,7 @@ def enumerate_totallyreal_fields_prim(n, B, a = [], verbose=0, return_seqs=False else: verb_int = 0 + T = tr_data(n_int,B,a) if verb_int == 2: T.incr(f_out,verb_int,0,phc_flag) else: diff --git a/src/sage/rings/number_field/totallyreal_rel.py b/src/sage/rings/number_field/totallyreal_rel.py index 73ef21c527a..720d4c71d9d 100644 --- a/src/sage/rings/number_field/totallyreal_rel.py +++ b/src/sage/rings/number_field/totallyreal_rel.py @@ -716,7 +716,6 @@ def enumerate_totallyreal_fields_rel(F, m, B, a = [], verbose=0, n = F.degree()*m # Initialize - T = tr_data_rel(F,m,B,a) S = [] Srel = [] dB_odlyzko = odlyzko_bound_totallyreal(n) @@ -738,6 +737,7 @@ def enumerate_totallyreal_fields_rel(F, m, B, a = [], verbose=0, sys.stdout = fsock # Else, print to screen f_out = [0]*m + [1] + T = tr_data_rel(F,m,B,a) if verbose == 2: T.incr(f_out,verbose) else: From 3d728b738617320ef3c077925045d7996f8d2fda Mon Sep 17 00:00:00 2001 From: zabrocki Date: Mon, 6 Jan 2014 08:47:49 -0500 Subject: [PATCH 030/163] remove stray import statement from algebras/nil_coxeter_algebra.py --- src/sage/algebras/nil_coxeter_algebra.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/algebras/nil_coxeter_algebra.py b/src/sage/algebras/nil_coxeter_algebra.py index 51caba9580e..2411c5a48e3 100644 --- a/src/sage/algebras/nil_coxeter_algebra.py +++ b/src/sage/algebras/nil_coxeter_algebra.py @@ -10,7 +10,6 @@ #***************************************************************************** from sage.algebras.iwahori_hecke_algebra import IwahoriHeckeAlgebra from sage.combinat.sf.sf import SymmetricFunctions -from sage.combinat.sf.kschur import kSchurFunctions from sage.misc.misc_c import prod from sage.rings.rational_field import QQ from sage.combinat.partition import Partitions From 173303b76c522cb05378eb141e87d2c24357466f Mon Sep 17 00:00:00 2001 From: Darij Grinberg Date: Mon, 6 Jan 2014 07:46:31 -0800 Subject: [PATCH 031/163] salvaging the doc from kschur.py --- src/sage/combinat/sf/new_kschur.py | 111 ++++++++++++++++++++++++++--- 1 file changed, 103 insertions(+), 8 deletions(-) diff --git a/src/sage/combinat/sf/new_kschur.py b/src/sage/combinat/sf/new_kschur.py index 2d7399e4dbe..4e55bafa979 100644 --- a/src/sage/combinat/sf/new_kschur.py +++ b/src/sage/combinat/sf/new_kschur.py @@ -20,7 +20,7 @@ from sage.structure.unique_representation import UniqueRepresentation from sage.structure.parent import Parent from sage.categories.realizations import Realizations, Category_realization_of_parent -from sage.categories.algebras_with_basis import AlgebrasWithBasis +#from sage.categories.algebras_with_basis import AlgebrasWithBasis #not currently used from sage.categories.graded_hopf_algebras import GradedHopfAlgebras from sage.categories.graded_hopf_algebras_with_basis import GradedHopfAlgebrasWithBasis from sage.categories.graded_coalgebras import GradedCoalgebras @@ -127,7 +127,8 @@ def __init__(self, Sym, k, t='t'): def retract(self, sym): r""" - Retracts ``sym`` from ``self`` to the ring of symmetric functions. + Return the retract of ``sym`` from the ring of symmetric functions + to ``self``. INPUT: @@ -135,7 +136,8 @@ def retract(self, sym): OUTPUT: - - the analogue of the symmetric function in the `k`-bounded subspace (if possible) + - the analogue of the symmetric function in the `k`-bounded + subspace (if possible) EXAMPLES:: @@ -584,12 +586,14 @@ class ElementMethods: def _mul_(self, other): r""" - Method for multiplying two elements. + Return the product of two elements ``self`` and ``other``. - When `t=1`, the `k`-bounded subspace is an algebra, so the product of two - elements is always in the space. For generic `t`, the `k`-bounded subspace is - not closed under multiplication, so the result is returned in the `k`-bounded - subspace if possible and else in the ring of symmetric functions. + When `t=1`, the `k`-bounded subspace is an algebra, so the + product of two elements is always in the space. For generic + `t`, the `k`-bounded subspace is not closed under + multiplication, so the result is returned in the `k`-bounded + subspace if possible and else in the ring of symmetric + functions. EXAMPLES:: @@ -623,6 +627,15 @@ def _mul_(self, other): sage: ks5 = Sym.kschur(5) sage: ks5(ks3[2]) * ks5(ks2[2,1]) ks5[2, 2, 1] + ks5[3, 1, 1] + (t+1)*ks5[3, 2] + (t+1)*ks5[4, 1] + t*ks5[5] + + sage: ks3([1]) * ks3([1]) # indirect doctest + ks3[1, 1] + ks3[2] + sage: ks3([2,1]) * ks3([2,1]) + s[2, 2, 1, 1] + s[2, 2, 2] + s[3, 1, 1, 1] + 2*s[3, 2, 1] + + s[3, 3] + s[4, 1, 1] + s[4, 2] + sage: ks3 = SymmetricFunctions(QQ).kschur(3, t=1) + sage: ks3([2,1])^2 + ks3[2, 2, 1, 1] + ks3[2, 2, 2] + ks3[3, 1, 1, 1] """ if self.parent().realization_of().t == 1: return self.parent()(self.lift()*other.lift()) @@ -837,6 +850,88 @@ class kSchur(CombinatorialFreeModule): """ Space of `k`-Schur functions. + EXAMPLES:: + + sage: Sym = SymmetricFunctions(QQ['t']) + sage: KB = Sym.kBoundedSubspace(3); KB + 3-bounded Symmetric Functions over Univariate Polynomial Ring in t over Rational Field + + The `k`-Schur function basis can be constructed as follows:: + + sage: ks3 = KB.kschur(); ks3 + 3-bounded Symmetric Functions over Univariate Polynomial Ring in t over Rational Field in the 3-Schur basis + + We can convert to any basis of the ring of symmetric functions and, + whenever it makes sense, also the other way round:: + + sage: s = Sym.schur() + sage: s(ks3([3,2,1])) + s[3, 2, 1] + t*s[4, 1, 1] + t*s[4, 2] + t^2*s[5, 1] + sage: t = Sym.base_ring().gen() + sage: ks3(s([3, 2, 1]) + t*s([4, 1, 1]) + t*s([4, 2]) + t^2*s([5, 1])) + ks3[3, 2, 1] + sage: s(ks3[2, 1, 1]) + s[2, 1, 1] + t*s[3, 1] + sage: ks3(s[2, 1, 1] + t*s[3, 1]) + ks3[2, 1, 1] + + `k`-Schurs are indexed by partitions with first part `\le + k`. Constructing a `k`-Schur function for a larger partition raises + an error:: + + sage: ks3([4,3,2,1]) # + Traceback (most recent call last): + ... + TypeError: do not know how to make x (= [4, 3, 2, 1]) an element of self (=3-bounded Symmetric Functions over Univariate Polynomial Ring in t over Rational Field in the 3-Schur basis) + + Note: Is it preferable to return `0` instead? + + Similarly, attempting to convert a function that is not in the + linear span of the `k`-Schur's raises an error:: + + sage: ks3(s([4])) + Traceback (most recent call last): + ... + ValueError: s[4] is not in the image of Generic morphism: + From: 3-bounded Symmetric Functions over Univariate Polynomial Ring in t over Rational Field in the 3-Schur basis + To: Symmetric Functions over Univariate Polynomial Ring in t over Rational Field in the Schur basis + + Note that the product of `k`-Schurs is not guaranteed to be in the + space spanned by the `k`-Schurs. In general, we only have that a + `k`-Schur times a `j`-Schur is a `(k+j)`-Schur. This fact is not + currently incorporated into the Sage design, so the multiplication + of `k`-Schur functions may return an error. This example shows how to + get around this 'manually':: + + sage: ks2 = Sym.kBoundedSubspace(2).kschur() + sage: ks2([2,1])^2 + Traceback (most recent call last): + ... + TypeError: unsupported operand type(s) for ** or pow(): 'kSchur_with_category.element_class' and 'int' + + :: + + sage: f = s(ks2([2,1]))^2; f # Convert to Schur functions first and multiply there. + s[2, 2, 1, 1] + s[2, 2, 2] + s[3, 1, 1, 1] + (2*t+2)*s[3, 2, 1] + (t^2+1)*s[3, + 3] + (2*t+1)*s[4, 1, 1] + (t^2+2*t+1)*s[4, 2] + (t^2+2*t)*s[5, 1] + t^2*s[6] + sage: ks4 = Sym.kBoundedSubspace(4).kschur() + sage: ks4(f) # The product of two 'ks2's is a 'ks4'. + ks4[2, 2, 1, 1] + ks4[2, 2, 2] + ks4[3, 1, 1, 1] + (t+2)*ks4[3, 2, 1] + + (t^2+1)*ks4[3, 3] + (t+1)*ks4[4, 1, 1] + ks4[4, 2] + + However, at `t=1`, the product of `k`-Schurs is in the span of the + `k`-Schurs. Below are some examples at `t=1` :: + + sage: ks3 = Sym.kBoundedSubspace(3, t=1).kschur(); ks3 + 3-bounded Symmetric Functions over Univariate Polynomial Ring in t over Rational Field with t=1 in the 3-Schur basis also with t=1 + sage: s = SymmetricFunctions(ks3.base_ring()).schur() + sage: ks3(s([3])) + ks3[3] + sage: s(ks3([3,2,1])) + s[3, 2, 1] + s[4, 1, 1] + s[4, 2] + s[5, 1] + sage: ks3([2,1])^2 + ks3[2, 2, 1, 1] + ks3[2, 2, 2] + ks3[3, 1, 1, 1] + TESTS: Check that :trac:`13743` is fixed:: From 3c1f5db61a07e05ab662eae90dbdd7a43a20981b Mon Sep 17 00:00:00 2001 From: Darij Grinberg Date: Mon, 6 Jan 2014 08:49:42 -0800 Subject: [PATCH 032/163] correcting my own errors --- src/sage/combinat/sf/new_kschur.py | 50 +++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/src/sage/combinat/sf/new_kschur.py b/src/sage/combinat/sf/new_kschur.py index 4e55bafa979..3e74bfab18f 100644 --- a/src/sage/combinat/sf/new_kschur.py +++ b/src/sage/combinat/sf/new_kschur.py @@ -898,29 +898,49 @@ class kSchur(CombinatorialFreeModule): Note that the product of `k`-Schurs is not guaranteed to be in the space spanned by the `k`-Schurs. In general, we only have that a - `k`-Schur times a `j`-Schur is a `(k+j)`-Schur. This fact is not - currently incorporated into the Sage design, so the multiplication - of `k`-Schur functions may return an error. This example shows how to - get around this 'manually':: + `k`-Schur times a `j`-Schur is a `(k+j)`-Schur. The multiplication of + two `k`-Schur functions thus generally returns a symmetric function + (in the Schur basis, not automatically cast into the `2k`-bounded + subspace) unless it happens to lie in the `k`-bounded subspace (in + which case it is cast into the `k`-Schur basis). + + For technical reasons, the product of a `k`-Schur and a `j`-Schur + is not yet implemented for distinct `k` and `j`. Let us show + how to get around this 'manually'. The error:: sage: ks2 = Sym.kBoundedSubspace(2).kschur() - sage: ks2([2,1])^2 + sage: ks3 = Sym.kBoundedSubspace(3).kschur() + sage: ks2([2,1]) * ks3([3,1]) + Traceback (most recent call last): + ... + TypeError: unsupported operand parent(s) for '*': '2-bounded Symmetric Functions over Univariate Polynomial Ring in t over Rational Field in the 2-Schur basis' and '3-bounded Symmetric Functions over Univariate Polynomial Ring in t over Rational Field in the 3-Schur basis' + + The workaround:: + + sage: f = s(ks2([2,1])) * s(ks3([3,1])); f # Convert to Schur functions first and multiply there. + s[3, 2, 1, 1] + s[3, 2, 2] + (t+1)*s[3, 3, 1] + s[4, 1, 1, 1] + + (2*t+2)*s[4, 2, 1] + (t^2+t+1)*s[4, 3] + (2*t+1)*s[5, 1, 1] + + (t^2+2*t+1)*s[5, 2] + (t^2+2*t)*s[6, 1] + t^2*s[7] + sage: ks5 = Sym.kBoundedSubspace(5).kschur() + sage: ks5(f) # The product of a 'ks2' with a 'ks3' is a 'ks5'. + ks5[3, 2, 1, 1] + ks5[3, 2, 2] + (t+1)*ks5[3, 3, 1] + ks5[4, 1, 1, 1] + + (t+2)*ks5[4, 2, 1] + (t^2+t+1)*ks5[4, 3] + (t+1)*ks5[5, 1, 1] + ks5[5, 2] + + For other technical reasons, taking powers of `k`-Schur functions + is not implemented (even when the answer is still in the `k`-bounded + subspace):: + + sage: ks2([1])^2 Traceback (most recent call last): ... TypeError: unsupported operand type(s) for ** or pow(): 'kSchur_with_category.element_class' and 'int' - :: + .. TODO:: - sage: f = s(ks2([2,1]))^2; f # Convert to Schur functions first and multiply there. - s[2, 2, 1, 1] + s[2, 2, 2] + s[3, 1, 1, 1] + (2*t+2)*s[3, 2, 1] + (t^2+1)*s[3, - 3] + (2*t+1)*s[4, 1, 1] + (t^2+2*t+1)*s[4, 2] + (t^2+2*t)*s[5, 1] + t^2*s[6] - sage: ks4 = Sym.kBoundedSubspace(4).kschur() - sage: ks4(f) # The product of two 'ks2's is a 'ks4'. - ks4[2, 2, 1, 1] + ks4[2, 2, 2] + ks4[3, 1, 1, 1] + (t+2)*ks4[3, 2, 1] - + (t^2+1)*ks4[3, 3] + (t+1)*ks4[4, 1, 1] + ks4[4, 2] + Get rid of said technical "reasons". However, at `t=1`, the product of `k`-Schurs is in the span of the - `k`-Schurs. Below are some examples at `t=1` :: + `k`-Schurs always. Below are some examples at `t=1` :: sage: ks3 = Sym.kBoundedSubspace(3, t=1).kschur(); ks3 3-bounded Symmetric Functions over Univariate Polynomial Ring in t over Rational Field with t=1 in the 3-Schur basis also with t=1 @@ -929,7 +949,7 @@ class kSchur(CombinatorialFreeModule): ks3[3] sage: s(ks3([3,2,1])) s[3, 2, 1] + s[4, 1, 1] + s[4, 2] + s[5, 1] - sage: ks3([2,1])^2 + sage: ks3([2,1])^2 # taking powers works for t=1 ks3[2, 2, 1, 1] + ks3[2, 2, 2] + ks3[3, 1, 1, 1] TESTS: From f55c5a28e24f5cb9cb296dd1974c04dfbfee2cfc Mon Sep 17 00:00:00 2001 From: Darij Grinberg Date: Mon, 6 Jan 2014 08:50:56 -0800 Subject: [PATCH 033/163] removing a bad idea I blindly copied from the old docstrings --- src/sage/combinat/sf/new_kschur.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/sage/combinat/sf/new_kschur.py b/src/sage/combinat/sf/new_kschur.py index 3e74bfab18f..417dfcf18fa 100644 --- a/src/sage/combinat/sf/new_kschur.py +++ b/src/sage/combinat/sf/new_kschur.py @@ -884,8 +884,6 @@ class kSchur(CombinatorialFreeModule): ... TypeError: do not know how to make x (= [4, 3, 2, 1]) an element of self (=3-bounded Symmetric Functions over Univariate Polynomial Ring in t over Rational Field in the 3-Schur basis) - Note: Is it preferable to return `0` instead? - Similarly, attempting to convert a function that is not in the linear span of the `k`-Schur's raises an error:: From e3e520cd2f554b75244683151e5a23b75d15a1ab Mon Sep 17 00:00:00 2001 From: zabrocki Date: Mon, 6 Jan 2014 12:31:46 -0500 Subject: [PATCH 034/163] additions to documentation --- src/sage/combinat/sf/new_kschur.py | 31 +++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/sage/combinat/sf/new_kschur.py b/src/sage/combinat/sf/new_kschur.py index 417dfcf18fa..c548e250531 100644 --- a/src/sage/combinat/sf/new_kschur.py +++ b/src/sage/combinat/sf/new_kschur.py @@ -896,17 +896,22 @@ class kSchur(CombinatorialFreeModule): Note that the product of `k`-Schurs is not guaranteed to be in the space spanned by the `k`-Schurs. In general, we only have that a - `k`-Schur times a `j`-Schur is a `(k+j)`-Schur. The multiplication of - two `k`-Schur functions thus generally returns a symmetric function - (in the Schur basis, not automatically cast into the `2k`-bounded - subspace) unless it happens to lie in the `k`-bounded subspace (in - which case it is cast into the `k`-Schur basis). - - For technical reasons, the product of a `k`-Schur and a `j`-Schur - is not yet implemented for distinct `k` and `j`. Let us show - how to get around this 'manually'. The error:: + `k`-Schur times a `j`-Schur is in the `(k+j)`-bounded subspace. The multiplication + of two `k`-Schur functions thus generally returns the product of the lift of the + functions. If the result happens to lie in the `k`-bounded subspace, then + the result is cast into the `k`-Schur basis:: sage: ks2 = Sym.kBoundedSubspace(2).kschur() + sage: ks2[1] * ks2[1] + ks2[1, 1] + ks2[2] + sage: ks2[1] * ks2[2] + s[2, 1] + s[3] + + Because the target space of the product of a `k`-Schur and a `j`-Schur has several + possibilities, the product of a `k`-Schur and `j`-Schur function is not + implemented for distinct `k` and `j`. Let us show how to get around + this 'manually':: + sage: ks3 = Sym.kBoundedSubspace(3).kschur() sage: ks2([2,1]) * ks3([3,1]) Traceback (most recent call last): @@ -919,14 +924,18 @@ class kSchur(CombinatorialFreeModule): s[3, 2, 1, 1] + s[3, 2, 2] + (t+1)*s[3, 3, 1] + s[4, 1, 1, 1] + (2*t+2)*s[4, 2, 1] + (t^2+t+1)*s[4, 3] + (2*t+1)*s[5, 1, 1] + (t^2+2*t+1)*s[5, 2] + (t^2+2*t)*s[6, 1] + t^2*s[7] + + or:: + + sage: f = ks2[2,1].lift() * ks3[3,1].lift() sage: ks5 = Sym.kBoundedSubspace(5).kschur() sage: ks5(f) # The product of a 'ks2' with a 'ks3' is a 'ks5'. ks5[3, 2, 1, 1] + ks5[3, 2, 2] + (t+1)*ks5[3, 3, 1] + ks5[4, 1, 1, 1] + (t+2)*ks5[4, 2, 1] + (t^2+t+1)*ks5[4, 3] + (t+1)*ks5[5, 1, 1] + ks5[5, 2] For other technical reasons, taking powers of `k`-Schur functions - is not implemented (even when the answer is still in the `k`-bounded - subspace):: + is not implemented, even when the answer is still in the `k`-bounded + subspace:: sage: ks2([1])^2 Traceback (most recent call last): From c7b0cc1e52d5d415ce740062f25e1da2af0405fc Mon Sep 17 00:00:00 2001 From: Anne Schilling Date: Mon, 6 Jan 2014 13:20:30 -0800 Subject: [PATCH 035/163] fixes to new_kschur documentation --- src/sage/combinat/sf/new_kschur.py | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/sage/combinat/sf/new_kschur.py b/src/sage/combinat/sf/new_kschur.py index c548e250531..64a424b7bdf 100644 --- a/src/sage/combinat/sf/new_kschur.py +++ b/src/sage/combinat/sf/new_kschur.py @@ -20,7 +20,6 @@ from sage.structure.unique_representation import UniqueRepresentation from sage.structure.parent import Parent from sage.categories.realizations import Realizations, Category_realization_of_parent -#from sage.categories.algebras_with_basis import AlgebrasWithBasis #not currently used from sage.categories.graded_hopf_algebras import GradedHopfAlgebras from sage.categories.graded_hopf_algebras_with_basis import GradedHopfAlgebrasWithBasis from sage.categories.graded_coalgebras import GradedCoalgebras @@ -127,8 +126,7 @@ def __init__(self, Sym, k, t='t'): def retract(self, sym): r""" - Return the retract of ``sym`` from the ring of symmetric functions - to ``self``. + Return the retract of ``sym`` from the ring of symmetric functions to ``self``. INPUT: @@ -875,9 +873,8 @@ class kSchur(CombinatorialFreeModule): sage: ks3(s[2, 1, 1] + t*s[3, 1]) ks3[2, 1, 1] - `k`-Schurs are indexed by partitions with first part `\le - k`. Constructing a `k`-Schur function for a larger partition raises - an error:: + `k`-Schur functions are indexed by partitions with first part `\le k`. Constructing a `k`-Schur + function for a larger partition raises an error:: sage: ks3([4,3,2,1]) # Traceback (most recent call last): @@ -885,7 +882,7 @@ class kSchur(CombinatorialFreeModule): TypeError: do not know how to make x (= [4, 3, 2, 1]) an element of self (=3-bounded Symmetric Functions over Univariate Polynomial Ring in t over Rational Field in the 3-Schur basis) Similarly, attempting to convert a function that is not in the - linear span of the `k`-Schur's raises an error:: + linear span of the `k`-Schur functions raises an error:: sage: ks3(s([4])) Traceback (most recent call last): @@ -894,9 +891,9 @@ class kSchur(CombinatorialFreeModule): From: 3-bounded Symmetric Functions over Univariate Polynomial Ring in t over Rational Field in the 3-Schur basis To: Symmetric Functions over Univariate Polynomial Ring in t over Rational Field in the Schur basis - Note that the product of `k`-Schurs is not guaranteed to be in the + Note that the product of `k`-Schur functions is not guaranteed to be in the space spanned by the `k`-Schurs. In general, we only have that a - `k`-Schur times a `j`-Schur is in the `(k+j)`-bounded subspace. The multiplication + `k`-Schur times a `j`-Schur function is in the `(k+j)`-bounded subspace. The multiplication of two `k`-Schur functions thus generally returns the product of the lift of the functions. If the result happens to lie in the `k`-bounded subspace, then the result is cast into the `k`-Schur basis:: @@ -909,7 +906,7 @@ class kSchur(CombinatorialFreeModule): Because the target space of the product of a `k`-Schur and a `j`-Schur has several possibilities, the product of a `k`-Schur and `j`-Schur function is not - implemented for distinct `k` and `j`. Let us show how to get around + implemented for distinct `k` and `j`. Let us show how to get around this 'manually':: sage: ks3 = Sym.kBoundedSubspace(3).kschur() @@ -946,8 +943,8 @@ class kSchur(CombinatorialFreeModule): Get rid of said technical "reasons". - However, at `t=1`, the product of `k`-Schurs is in the span of the - `k`-Schurs always. Below are some examples at `t=1` :: + However, at `t=1`, the product of `k`-Schur functions is in the span of the + `k`-Schur functions always. Below are some examples at `t=1` :: sage: ks3 = Sym.kBoundedSubspace(3, t=1).kschur(); ks3 3-bounded Symmetric Functions over Univariate Polynomial Ring in t over Rational Field with t=1 in the 3-Schur basis also with t=1 From cebf1d45e63f0d82877414d39704596483c477c0 Mon Sep 17 00:00:00 2001 From: zabrocki Date: Mon, 6 Jan 2014 21:43:19 -0500 Subject: [PATCH 036/163] clarification on meaning of lift --- src/sage/combinat/sf/new_kschur.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/sage/combinat/sf/new_kschur.py b/src/sage/combinat/sf/new_kschur.py index 64a424b7bdf..ebe979b7a4a 100644 --- a/src/sage/combinat/sf/new_kschur.py +++ b/src/sage/combinat/sf/new_kschur.py @@ -873,8 +873,8 @@ class kSchur(CombinatorialFreeModule): sage: ks3(s[2, 1, 1] + t*s[3, 1]) ks3[2, 1, 1] - `k`-Schur functions are indexed by partitions with first part `\le k`. Constructing a `k`-Schur - function for a larger partition raises an error:: + `k`-Schur functions are indexed by partitions with first part `\le k`. Constructing a + `k`-Schur function for a larger partition raises an error:: sage: ks3([4,3,2,1]) # Traceback (most recent call last): @@ -893,10 +893,11 @@ class kSchur(CombinatorialFreeModule): Note that the product of `k`-Schur functions is not guaranteed to be in the space spanned by the `k`-Schurs. In general, we only have that a - `k`-Schur times a `j`-Schur function is in the `(k+j)`-bounded subspace. The multiplication - of two `k`-Schur functions thus generally returns the product of the lift of the - functions. If the result happens to lie in the `k`-bounded subspace, then - the result is cast into the `k`-Schur basis:: + `k`-Schur times a `j`-Schur function is in the `(k+j)`-bounded subspace. The + multiplication of two `k`-Schur functions thus generally returns the product of + the lift of the functions to the ambient symmetric function space. If the result + happens to lie in the `k`-bounded subspace, then the result is cast into the + `k`-Schur basis:: sage: ks2 = Sym.kBoundedSubspace(2).kschur() sage: ks2[1] * ks2[1] From d1767f9ccc641e6e298ed472724924dea4d79c36 Mon Sep 17 00:00:00 2001 From: Punarbasu Purkayastha Date: Fri, 10 Jan 2014 21:47:03 +0800 Subject: [PATCH 037/163] fix the documentation for the enumerate_totally_real* --- src/sage/rings/number_field/totallyreal.pyx | 5 +- .../rings/number_field/totallyreal_rel.py | 95 ++++++++++++------- 2 files changed, 66 insertions(+), 34 deletions(-) diff --git a/src/sage/rings/number_field/totallyreal.pyx b/src/sage/rings/number_field/totallyreal.pyx index 8e12762f5cc..5ef16299bf1 100644 --- a/src/sage/rings/number_field/totallyreal.pyx +++ b/src/sage/rings/number_field/totallyreal.pyx @@ -144,8 +144,9 @@ cpdef double odlyzko_bound_totallyreal(int n): This function returns the unconditional Odlyzko bound for the root discriminant of a totally real number field of degree n. - NOTE: - The bounds for n > 50 are not necessarily optimal. + .. note:: + + The bounds for n > 50 are not necessarily optimal. INPUT: diff --git a/src/sage/rings/number_field/totallyreal_rel.py b/src/sage/rings/number_field/totallyreal_rel.py index 720d4c71d9d..6711c2b25ac 100644 --- a/src/sage/rings/number_field/totallyreal_rel.py +++ b/src/sage/rings/number_field/totallyreal_rel.py @@ -136,8 +136,8 @@ def integral_elements_in_box(K, C): sage: C = [[0-eps,5+eps]]*3 sage: v = sage.rings.number_field.totallyreal_rel.integral_elements_in_box(K, C) - Note that the output is platform dependent (sometimes a 5 is listed below, and - sometimes it isn't):: + Note that the output is platform dependent (sometimes a 5 is listed + below, and sometimes it isn't):: sage: sorted(v) [-1/2*a + 2, 1/4*a^2 + 1/2*a, 0, 1, 2, 3, 4,...-1/4*a^2 - 1/2*a + 5, 1/2*a + 3, -1/4*a^2 + 5] @@ -362,7 +362,9 @@ def incr(self, f_out, verbose=False, haltk=0): - ``f_out`` -- an integer sequence, to be written with the coefficients of the next polynomial - - ``verbose`` -- boolean to print verbosely computational details + - ``verbose`` -- boolean or nonnegative integer (default: False) + print verbosely computational details. It prints extra + information if ``verbose`` is set to ``2`` or more - ``haltk`` -- integer, the level at which to halt the inductive coefficient bounds @@ -648,14 +650,11 @@ def enumerate_totallyreal_fields_rel(F, m, B, a = [], verbose=0, a[d]*x^n + ... + a[0]*x^(n-d) if ``length(a) = d+1``, so in particular always ``a[d] = 1``. - If verbose == 1 (or 2), then print to the screen (really) verbosely; if - verbose is a string, then print verbosely to the file specified by verbose. - If return_seqs, then return the polynomials as sequences (for easier - exporting to a file). - NOTE: - This is guaranteed to give all primitive such fields, and - seems in practice to give many imprimitive ones. + .. note:: + + This is guaranteed to give all primitive such fields, and + seems in practice to give many imprimitive ones. INPUT: @@ -663,26 +662,44 @@ def enumerate_totallyreal_fields_rel(F, m, B, a = [], verbose=0, - ``m`` -- integer, the degree - ``B`` -- integer, the discriminant bound - ``a`` -- list (default: []), the coefficient list to begin with - - ``verbose`` -- boolean or string (default: 0) + - ``verbose`` -- boolean or nonnegative integer or string (default: 0) + give a verbose description of the computations being performed. If + ``verbose`` is set to ``2`` or more then it outputs some extra + information. If ``verbose'' is a string then it outputs to a file + specified by ``verbose'' - ``return_seqs`` -- (boolean, default False) If ``True``, then return - the polynomials as sequences (for easier exporting to a file). + the polynomials as sequences (for easier exporting to a file). This + also returns a list of four numbers, as explained in the OUTPUT + section below. - ``return_pari_objects`` -- (boolean, default: True) if ``return_seqs`` is ``False`` then it returns the elements as Sage objects; otherwise it returns pari objects. OUTPUT: - the list of fields with entries ``[d,fabs,f]``, where + - the list of fields with entries ``[d,fabs,f]``, where ``d`` is the discriminant, ``fabs`` is an absolute defining polynomial, and ``f`` is a defining polynomial relative to ``F``, sorted by discriminant. + - if ``return_seqs`` is ``True``, then the first field of the list is + a list containing the count of four items as explained below + + - the first entry gives the number of polynomials tested + - the second entry gives the number of polynomials with its + discriminant having a large enough square divisor + - the third entry is the number of irreducible polynomials + - the fourth entry is the number of irreducible polynomials with + discriminant at most ``B`` + EXAMPLES:: sage: ZZx = ZZ['x'] sage: F. = NumberField(x^2-2) sage: enumerate_totallyreal_fields_rel(F, 2, 2000) [[1600, x^4 - 6*x^2 + 4, xF^2 + xF - 1]] + sage: enumerate_totallyreal_fields_rel(F, 2, 2000, return_seqs=True) + [[18, 6, 5, 0], [[1600, [4, 0, -6, 0, 1], [-1, 1, 1]]]] TESTS: @@ -732,7 +749,7 @@ def enumerate_totallyreal_fields_rel(F, m, B, a = [], verbose=0, if verbose: saveout = sys.stdout - if type(verbose) == str: + if isinstance(verbose, str): fsock = open(verbose, 'w') sys.stdout = fsock # Else, print to screen @@ -859,12 +876,14 @@ def enumerate_totallyreal_fields_rel(F, m, B, a = [], verbose=0, # Output. if verbose: print "="*80 - print "Polynomials tested:", counts[0] - print "Irreducible polynomials:", counts[1] - print "Polynomials with nfdisc <= B:", counts[2] + print "Polynomials tested: {}".format(counts[0]) + print ( "Polynomials with discriminant with large enough square" + " divisor: {}".format(counts[1])) + print "Irreducible polynomials: {}".format(counts[2]) + print "Polynomials with nfdisc <= B: {}".format(counts[3]) for i in range(len(S)): print S[i] - if type(verbose) == str: + if isinstance(verbose, str): fsock.close() sys.stdout = saveout @@ -883,16 +902,22 @@ def enumerate_totallyreal_fields_rel(F, m, B, a = [], verbose=0, def enumerate_totallyreal_fields_all(n, B, verbose=0, return_seqs=False, return_pari_objects=True): r""" - Enumerates *all* totally real fields of degree `n` with discriminant `\le B`, - primitive or otherwise. + Enumerates *all* totally real fields of degree ``n`` with discriminant + at most ``B``, primitive or otherwise. INPUT: - ``n`` -- integer, the degree - ``B`` -- integer, the discriminant bound - - ``verbose`` -- boolean or string (default: 0) + - ``verbose`` -- boolean or nonnegative integer or string (default: 0) + give a verbose description of the computations being performed. If + ``verbose`` is set to ``2`` or more then it outputs some extra + information. If ``verbose'' is a string then it outputs to a file + specified by ``verbose'' - ``return_seqs`` -- (boolean, default False) If ``True``, then return - the polynomials as sequences (for easier exporting to a file). + the polynomials as sequences (for easier exporting to a file). This + also returns a list of four numbers, as explained in the OUTPUT + section below. - ``return_pari_objects`` -- (boolean, default: True) if ``return_seqs`` is ``False`` then it returns the elements as Sage objects; otherwise it returns pari objects. @@ -919,9 +944,13 @@ def enumerate_totallyreal_fields_all(n, B, verbose=0, return_seqs=False, Univariate Polynomial Ring in x over Rational Field - In practice most of these will be found by :func:`~sage.rings.number_field.totallyreal.enumerate_totallyreal_fields_prim`, which is guaranteed to return all primitive fields but often returns many non-primitive ones as well. For instance, only one of the five fields in the example above is primitive, but :func:`~sage.rings.number_field.totallyreal.enumerate_totallyreal_fields_prim` finds four out of the five (the exception being `x^4 - 6x^2 + 4`). - - TESTS: + In practice most of these will be found by + :func:`~sage.rings.number_field.totallyreal.enumerate_totallyreal_fields_prim`, + which is guaranteed to return all primitive fields but often returns + many non-primitive ones as well. For instance, only one of the five + fields in the example above is primitive, but + :func:`~sage.rings.number_field.totallyreal.enumerate_totallyreal_fields_prim` + finds four out of the five (the exception being `x^4 - 6x^2 + 4`). The following was fixed in :trac:`13101`:: @@ -930,7 +959,7 @@ def enumerate_totallyreal_fields_all(n, B, verbose=0, return_seqs=False, """ S = [] - counts = [0,0,0] + counts = [0,0,0,0] if len(divisors(n)) > 4: raise ValueError, "Only implemented for n = p*q with p,q prime" for d in divisors(n): @@ -943,7 +972,7 @@ def enumerate_totallyreal_fields_all(n, B, verbose=0, return_seqs=False, F = NumberField(ZZx(Sds[i][1]), 't') T = enumerate_totallyreal_fields_rel(F, n/d, B, verbose=verbose, return_seqs=return_seqs) if return_seqs: - for i in range(3): + for i in range(4): counts[i] += T[0][i] S += [[t[0],pari(t[1]).Polrev()] for t in T[1]] else: @@ -960,17 +989,19 @@ def enumerate_totallyreal_fields_all(n, B, verbose=0, return_seqs=False, # Output. if verbose: saveout = sys.stdout - if type(verbose) == str: + if isinstance(verbose, str): fsock = open(verbose, 'w') sys.stdout = fsock # Else, print to screen print "="*80 - print "Polynomials tested:", counts[0] - print "Irreducible polynomials:", counts[1] - print "Polynomials with nfdisc <= B:", counts[2] + print "Polynomials tested: {}".format(counts[0]) + print ( "Polynomials with discriminant with large enough square" + " divisor: {}".format(counts[1])) + print "Irreducible polynomials: {}".format(counts[2]) + print "Polynomials with nfdisc <= B: {}".format(counts[3]) for i in range(len(S)): print S[i] - if type(verbose) == str: + if isinstance(verbose, str): fsock.close() sys.stdout = saveout From 980d38f26ffc3ea8682f63b859e0bbf3e970006a Mon Sep 17 00:00:00 2001 From: Punarbasu Purkayastha Date: Fri, 10 Jan 2014 21:58:08 +0800 Subject: [PATCH 038/163] make sure the output for n=1, or m=1 is a sage object when return_pari_objects is set to False. --- src/sage/rings/number_field/totallyreal.pyx | 10 ++++++--- .../rings/number_field/totallyreal_rel.py | 21 +++++++++++++------ 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/sage/rings/number_field/totallyreal.pyx b/src/sage/rings/number_field/totallyreal.pyx index 5ef16299bf1..e6d78290f41 100644 --- a/src/sage/rings/number_field/totallyreal.pyx +++ b/src/sage/rings/number_field/totallyreal.pyx @@ -225,8 +225,9 @@ def enumerate_totallyreal_fields_prim(n, B, a = [], verbose=0, return_seqs=False whose filename is given by ``just_print``. In this case, we don't return anything. - ``return_pari_objects`` -- (boolean, default: True) if - ``return_seqs`` is ``False`` then it returns the elements as Sage - objects; otherwise it returns pari objects. + both ``return_seqs`` and ``return_pari_objects`` are ``False`` then + it returns the elements as Sage objects; otherwise it returns pari + objects. OUTPUT: @@ -356,8 +357,11 @@ def enumerate_totallyreal_fields_prim(n, B, a = [], verbose=0, return_seqs=False sage_free(f_out) if return_seqs: return [[0,0,0,0],[[1,[-1,1]]]] - else: + elif return_pari_objects: return [[1,pari('x-1')]] + else: + Px = PolynomialRing(QQ, 'x') + return [[ZZ(1), Px.gen()-1]] if verbose: verb_int = 1 diff --git a/src/sage/rings/number_field/totallyreal_rel.py b/src/sage/rings/number_field/totallyreal_rel.py index 6711c2b25ac..5276eea1609 100644 --- a/src/sage/rings/number_field/totallyreal_rel.py +++ b/src/sage/rings/number_field/totallyreal_rel.py @@ -672,8 +672,9 @@ def enumerate_totallyreal_fields_rel(F, m, B, a = [], verbose=0, also returns a list of four numbers, as explained in the OUTPUT section below. - ``return_pari_objects`` -- (boolean, default: True) if - ``return_seqs`` is ``False`` then it returns the elements as Sage - objects; otherwise it returns pari objects. + both ``return_seqs`` and ``return_pari_objects`` are ``False`` then + it returns the elements as Sage objects; otherwise it returns pari + objects. OUTPUT: @@ -696,6 +697,8 @@ def enumerate_totallyreal_fields_rel(F, m, B, a = [], verbose=0, sage: ZZx = ZZ['x'] sage: F. = NumberField(x^2-2) + sage: enumerate_totallyreal_fields_rel(F, 1, 2000) + [[1, x - 1, [-2, 0, 1]]] sage: enumerate_totallyreal_fields_rel(F, 2, 2000) [[1600, x^4 - 6*x^2 + 4, xF^2 + xF - 1]] sage: enumerate_totallyreal_fields_rel(F, 2, 2000, return_seqs=True) @@ -744,8 +747,11 @@ def enumerate_totallyreal_fields_rel(F, m, B, a = [], verbose=0, g = pari(F.defining_polynomial()).reverse().Vec() if return_seqs: return [[0,0,0,0],[1,g,[-1,1]]] - else: + elif return_pari_objects: return [[1,pari('x-1'),g]] + else: + Px = PolynomialRing(QQ, 'x') + return [[ZZ(1), Px.gen()-1, map(QQ, g)]] if verbose: saveout = sys.stdout @@ -918,9 +924,10 @@ def enumerate_totallyreal_fields_all(n, B, verbose=0, return_seqs=False, the polynomials as sequences (for easier exporting to a file). This also returns a list of four numbers, as explained in the OUTPUT section below. - - ``return_pari_objects`` -- (boolean, default: True) if - ``return_seqs`` is ``False`` then it returns the elements as Sage - objects; otherwise it returns pari objects. + - ``return_pari_objects`` -- (boolean, default: True) if both + ``return_seqs`` and ``return_pari_objects`` are ``False`` then it + returns the elements as Sage objects; otherwise it returns pari + objects. EXAMPLES:: @@ -930,6 +937,8 @@ def enumerate_totallyreal_fields_all(n, B, verbose=0, return_seqs=False, [1600, x^4 - 6*x^2 + 4], [1957, x^4 - 4*x^2 - x + 1], [2000, x^4 - 5*x^2 + 5]] + sage: enumerate_totallyreal_fields_all(1, 10) + [[1, x - 1]] TESTS: From a4ec8a27113332bfe2e75355d2330de1b0b2a5de Mon Sep 17 00:00:00 2001 From: Punarbasu Purkayastha Date: Fri, 10 Jan 2014 22:02:16 +0800 Subject: [PATCH 039/163] doctest for _rel was incorrect --- src/sage/rings/number_field/totallyreal_rel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/number_field/totallyreal_rel.py b/src/sage/rings/number_field/totallyreal_rel.py index 5276eea1609..da12c531177 100644 --- a/src/sage/rings/number_field/totallyreal_rel.py +++ b/src/sage/rings/number_field/totallyreal_rel.py @@ -702,7 +702,7 @@ def enumerate_totallyreal_fields_rel(F, m, B, a = [], verbose=0, sage: enumerate_totallyreal_fields_rel(F, 2, 2000) [[1600, x^4 - 6*x^2 + 4, xF^2 + xF - 1]] sage: enumerate_totallyreal_fields_rel(F, 2, 2000, return_seqs=True) - [[18, 6, 5, 0], [[1600, [4, 0, -6, 0, 1], [-1, 1, 1]]]] + [[9, 6, 5, 0], [[1600, [4, 0, -6, 0, 1], [-1, 1, 1]]]] TESTS: From d67b6c35baf378c3362f38b8b8c8c8dcc661602f Mon Sep 17 00:00:00 2001 From: Punarbasu Purkayastha Date: Fri, 10 Jan 2014 22:13:15 +0800 Subject: [PATCH 040/163] the doctstring syntax is not latex syntax! --- src/sage/rings/number_field/totallyreal_rel.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/number_field/totallyreal_rel.py b/src/sage/rings/number_field/totallyreal_rel.py index da12c531177..529518832f1 100644 --- a/src/sage/rings/number_field/totallyreal_rel.py +++ b/src/sage/rings/number_field/totallyreal_rel.py @@ -665,8 +665,8 @@ def enumerate_totallyreal_fields_rel(F, m, B, a = [], verbose=0, - ``verbose`` -- boolean or nonnegative integer or string (default: 0) give a verbose description of the computations being performed. If ``verbose`` is set to ``2`` or more then it outputs some extra - information. If ``verbose'' is a string then it outputs to a file - specified by ``verbose'' + information. If ``verbose`` is a string then it outputs to a file + specified by ``verbose`` - ``return_seqs`` -- (boolean, default False) If ``True``, then return the polynomials as sequences (for easier exporting to a file). This also returns a list of four numbers, as explained in the OUTPUT @@ -918,8 +918,8 @@ def enumerate_totallyreal_fields_all(n, B, verbose=0, return_seqs=False, - ``verbose`` -- boolean or nonnegative integer or string (default: 0) give a verbose description of the computations being performed. If ``verbose`` is set to ``2`` or more then it outputs some extra - information. If ``verbose'' is a string then it outputs to a file - specified by ``verbose'' + information. If ``verbose`` is a string then it outputs to a file + specified by ``verbose`` - ``return_seqs`` -- (boolean, default False) If ``True``, then return the polynomials as sequences (for easier exporting to a file). This also returns a list of four numbers, as explained in the OUTPUT From 993fb0fa57a91002a816db20c31ef051fdf568af Mon Sep 17 00:00:00 2001 From: zabrocki Date: Mon, 13 Jan 2014 21:22:00 -0500 Subject: [PATCH 041/163] removed kSchurFunctions_t from the pickle jar --- src/ext/pickle_jar/pickle_jar.tar.bz2 | Bin 627194 -> 623232 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/ext/pickle_jar/pickle_jar.tar.bz2 b/src/ext/pickle_jar/pickle_jar.tar.bz2 index f82ce01e236e9bd2331905411857b7664950c495..12ec884d70fac8d88ace1819a635380c31560355 100644 GIT binary patch literal 623232 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 z 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�{9uf^;ELD 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

(M$5wkZcd&CkPW83 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�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

P7L?OMpfVWX@F31%VA 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�^>@!c1^wP$A5 zt$!`hG}BM+bFwO?08dWu3_~}s%Od(m&T0$a?6fY{AkI|t*QX~X*+!ENDWgU28GcAm zQ069-7@e4|y#e8AS9eW3?5q^mC+BaS>53Sp?+bptOg{boJKG1}O%2#>H=@pQh^clN z1rF;;W+N~|G%J#cvNxXcE}XbbkFcgWnM)JKG&^$KUe{&7x@LpbS&A-h?Dmu`&7Opp zJHi}cr+Wd-p%(dP=}US$^o(4*#^;5dK? z;FtB`2#_;;bTK+%yzJX&Z0t%4H#kYLiT?i8jY3}k^*I1>Htq0oLDQVFc;Byf?c!@% zE^331)%O1G34J-4G;J;SGLJ_Iyl)VQvbp&+Frq!9Xi5PrZialc zkrA1ugRfS6i}b#X!|Yd%&a~bov&Uxo2JwU(OjPEWKigI4R#_Tsl>SM z*gisF#$y?J;>S28Q$M4PS&hcl;lefoHM{_4E>w^kT<(T`q0JB^OguKy{tpI2i8E;2Xce(CwEcC8 z;$CEP2qyY17>^Y+x0#s84R^{+Lyh!+Q?Jh@F@oMK#ntNi8%nLIHgTU^DjJ#$(>{&a*ftX6B)->HRO*``Tjrdo= z?ufqc%`7q~a}9^A(SW~H8GWyRGnawb-Z$03jm(KnUX1ehvGI7d74!Ou1H^*@*N;u$ zaC8*+Bs_#}#EeOWIstWz4vT*O#acfo#waasELd|rlb1n>&}&L{NjPX3n6~1k z08mwiBTP&Xl)axoa?XzyR@=MCxg|%9!Gq5H<`@m!Q`Q1(WZ6@bFPhv)A}J2)^*314 zX<+!T{XN>^FZQAPWT+Zgmb>agcVUc=CM%PA4Ma7xw4a}AIF}FA=ShgHq=&eGjjSEz7bJcWvT8I>L8@*FY3wr|2@K6N^00jyZCrhb~ z2Omjj;dkKVhP*;@SB5;e(RCP>zMg4Y!VM^1Q>lSda72<5X0giKt~W_oh*FzL8f)!= z#I*?hLti>@GIMF>$KRmHl#eJN&oY=r62*!%*Q0KUT{KXONO9d-3E{sRMe1wn@3_4| ze9jIWZx(I)@*QUj;zQ7HR;Z(VJg2f@L9bk0oAx!ce~P#z_)bP2tn#uF03NM7ibMEp zgFTh4bbgK2L*T02I)jb z-acS_?-MX{^B_blU6-;BV>})%zi%=(Zu;QRSkIVCzJq!9V{&*gpDb zK$hptcxR2IT|=|SxGfHfJN9JFxy+iW#A-HAeoTTkEd0u&KmGC1Rq-=T-wnlm2&fxT z?h!IPoYd7~)>UVbf6s;l-M$4@qr5}_iRqvS_;joPM)nyeQN3;D_*bs|4i~)ev-fhT z=YCR>BO>G6-kDufp4T$5GF<=gt*G>%cg8Hv4#yQnWFkwgFnU+si4)Zix#WkN8zk2j zCdWa|@eb$*eIkc>b($|$n&*nSO~A)+oR7HI;bqtz%0>?`an!`0D9VOb3sY6hK(*4PaY=M&egTcYE$g@xXU=+<_Rv|7h~ zrW#Tcm1X$3;bN78=M=gIlw61EiLyY;3&9ZKY|b=H>4+XU_FZ;JHkZjrijm;@%z=;i zZ<9bF5_Zx3V(*S}G)S3wYmrx@N&EoHt(82d>HToZljGRyAQuqfve+=(J4!i&ANRIJ z2k1S1dKRF34yi)9ER4avXg=SdBE;7EmMcV4xW9?7^k5i45lE2lvMn)6P8GNey$ke( z_R7hfvw#tm%W~e^Grw#)s?k( znh5R2^aAp(Tg`Q_8GAq-(N!=+sfgEtrPVx{3GN&?yNnxri-(AyBk@$$#e6DI1`}6o zH(v^wv*{0r14HdKqgR*kb3C7liU(OgRw|c8c_;5u5 zWYaP7IAx6062J-wd`tJictOnPXXppxceSN#0k8~FcGJ{vlU$z(B#H#!%Y?#QNOlnc zOr_2r1S%kiG~)geiR7y7ll!~nUMcn`QUVBuei2L6)QQ~a-qVx^XK$7v3A7<4`60po zh-!H~gPkm|-%9K^E0p-<+h?sF9?7+f0+tW+HCcd;K$%Z|*U)sfia*9C&c27SEl%B- zF>O{La;X!8{lRl-xUVZ+q3K0@6-p!2<*u`b3{1!3nAHcjO+LpD_vpcl!$SOEtKB8_ zdxuGT6~GjO$3@%qn{`84g*6|Avhd-{O@Po<_-$YlQKxq`6;$~cSXQ<1K3pg8VE-6) zwT_qeDKqt~naeIjVnUw+?J>&6J%o*(GEuvQ!`WvUHA_+d@J_yT)NJT}nGW8J?x&}@ z_rs9FzFXA6Zi>~ozQvp!B4GfC|8^{Lj+qT~-0K5%4enc0ZI>KyM22wKEy@cl zA1t#_L$DA5d>_D^z>pJz!bn7buo=R6AKcKE3#XUsCO=F5mXB;FHhHB3;9T@^JnR~0 z@gP$|*T=f&Ds^{yHAxU|yklB4Ohf&RxF^1?aPg!Wjo`g1hrcuL6_BWh>_@L*RklQN ze=i(fWri+D34uj}*Xook>8k_UWGRN+85x^pWUIR~qfs0nprn2qchw@nQ>;c-AwLr0Fprt2T{J z1D_yl^278syi$my*!~1$wMLyUU!RjbTV1J@%^Z+WbCl`TEhXX!6Z^@pX8sHT zxK3!8tTl=3G)x%BiK&v}(dJqdLVj>}QhUgBk$V`-_safW9Yq6XS*IZQ#e(Omom~>a zk%Hw)Y3YBO@PekujW`ox#jMbapi8=QF{|>(+ly%J=d`80-Vxv%cs%Y=?0Ir@U1XA! zt)uwUD!cNwy;7zR1-L(^AjKs9em>sLA>K#>wfAcWMCvUmNU~@}hBUFd8Km|CRtt~F z29INd1;GK8rPe>_9hcHP*I80Q@{|5e5YtkG?>2&UKZU~4@KUw6x9s}xf^EA}R+i)$ zkIX7W0_Maf(Mw3iNaIJr1EjioH$n!625^JTQ{D8{cmb8j;?~m z$tBr+c-QP@!G1xJpRDBKq#tFZ#W7_9I=L}z0=p-aqru6i;@*Hv6qNCq+(X?ZM8gB0 zoq}er+uS4Kyq0BXAjN)hR94%_MF?bh5eId?vaoMI#$sN>MJXdJl39v`pp0a9 zKIlL`EJluX2&44n)4x@~#4%GA_G)2*n6KU%85x+wkwiyo!z$VpxR1T)m2cmOI)L+y zQ`jC6VsBC*g5d8BHyb0NCQ+J{f!j@jp34H|SYPQuOMF2pC-mX4*$00H_m#)hT>2Mh z_ss~#@wuKW4((M6mS<((V@}JPvbg^Nw-YP`#fv*s0~n`OHw|sT7yn*Pdjl!5X41bZ zdAyfbU9+-wE-`h}kXI3>Z~iT7KKr@igt5axdH3E-+t4V1p~1kMW+%!0CHJb1Zk~a) z+`9uY0XsC+ja6-{gX4&3ex)xXEbg+i9C$qQJX~wOSz8PgeSZ3cSFy(hb5b?1@*T#FHN)Y~6DDRNZ zNugNP5?0-9O`VWIUqq2XR5s%kcoWH1n8A%YIm&n_ngbMj+xsjGk82fwJn|l9f`TWY zS%>tQVAc6<=1*nwN~PE)$vB94N1?%nF2j$NKq><;@7> z*cXz0FvB~>@C$AE$2N@BJUaMJYW7O?RH9Af7USz<>(x@wa9950_v%tUQpNd!HZgX` zLAk`++mfy4E^3?jC?m=DH=7Az%A2dh$N>G&w%W(9D9yjWfKSkbc=KN zM|E)*<{dGzvF!YU;WOq4U(qlTZ9mON54!i*;pu^(y zfR3W-tZ-v}d+( z=-X=;As28;vz7ij>5}3S5_Eyod2|-Tm5uZ28h`GI@$G-XyrWM%BQmU$6xrUj;+(1> z`~K4ZF8bfz)gUj%ifWsDaM81Y-Mr9z$SV-)s}2SXQj-fDJ&pLbzzn1AIy zrHYT{vh2-%V?(>vvK64C8xY=HkmxvL>P;g+B*Kw32x0Xa8ePWPX@STZ(ClbjKJh6! zZ3O`wN)&EqtWk@Qh#^7)^!!blHmaL-PqEZ1Svc3h_m zG^`(A5#&v#AQ;4M^P=t%EN_|QA(3g|eBSXzrNy6qJ=PF>_Gk7>NwUu$#5-~l?0il| zzgOpm$ZV7>mRL%;E%#&Fd;*l$1pY@9_99+EEncb5%~~=950T(m3I@J|d8E>-u~40Q6=Rl73i! zM4|Gzm7}(q(EFFc`ylb*v3?4$J?;mHi>0bhHRl(sg<1GDnxy63cDu?d6a?{&-yS}y znlQRCR1&3~k2~x~s?7CaBKrAq@aK9xx0nt3(Y>NAj<$wsMfvFx)I2o_U@4E35`H?JD>T=fuG00Eg2iq5Y}PXV)WuE0lPzYXuUTq=mUi|AJDFj(@DIBp(ml zcwG`VZlB8W-+SGS%&I_uRSOjoJSe}5T(~LdPRu4B8ILs^JX%;FlD z(s2I9MLmH@=iKYG6FFOK%OpN zRcQ9SKuS~~l2_jL9rhA2*&IY@x`OQc+M_XECIUhja*ev_4w2!T`RFM$DPB|KH`{1u zmveTflIVVDPWBv7_MsKxo^C1ioO@em+*CD&|5NWAlzQ{SMglmZA*;9r{;OF>kBxDG zqonCR)_SWF$RbZBNw5Qg0W`2ZLPf~XNx5FnzgtZ3@UrmN->R^yRc?`>KgoLU2=@fc zAL9*tXsRz%FPS78Bbk@2#`{SDX*(aAdYQr_Jfl* zK9)4v7{#4-6<|8xh5SmyF;+OEVtA`8rNuEVji`sC9%Bf0XW9-8v3i@-M3>|pVNBBT zNX+F$BeBPsXgZ@4 zhp0JuMP_=2hHrC8>e}%*FSirnfrlT5Kq${_Y2IUUSurRoEyeh!uXo4|(yp~=|JI;Am$9Bq28OI&$q`QK)W3uj2$ zv#UbJ$s=f^4cVtenX;FpWR8`6r_p$^UVZ<@S68d?v3&4o{r#DtjN9#XgamR$GzvX^E%Pg8pWpfc#5 z9dlN*BK^ighlM)mczdFD?LN2gQ3LQQ#ajvO*1#R12rAX|yX0y1)Ls@dVCU;Fu40@i zX%oMX^(gXIjZFmZO+30xj=lN{YyZ1twA1w*Vt;e8W zb7=?MJ}oNcYEdDi-&!)b1P1bUdaqxH8uk1pzmzK0>f8YkK+A@m%f%>7N)HjNvtNVS z1ibmPA`oz^RP43RRd)ZkWLEofPq(CM;H{uP&1Vo% z)XC&2wu8VtgNjXKG&p01NW&mkAEH+s0JsM#D^(Pg$50PcJ=1Y|DAUbWj)v6R1hUeW zX^1q3pxi5hd!@)1Qf_HPi&W%}Eq3X6;J+>o3dH;yDj>Bc7rAg0VwMl0ULqFqYmUXl)0-zTA(Uqo57q^dk&60}QhN zsZ+q||Hw~jO_{ox+ohI6`kB~3@p71Dh{pb+cqk7|p6#K}#G>*C6_=Oe0O`J5uj~#t zN@E11AywW>D}8*=qESR?eNjxT2f<(jY&`Cf9AfI7lZKIP#@sz`F*h{f$@fZOcm!lc z$=B!*qJ5~6#vz_Mjn?{}p^WlkDyobuT7F8_mBBvf%_-M*rCOQ+*DMVh`nn#X+lBeW zPnd^E4DqeePCP)>)WadG<41@f=8V$r_=z3=ud_IU!ae1K*+WBijexTw z&aZ602nc{2u`o7QBmfz)g9j~P3-vC2W8`xjzS1<`8R0P}dd>8^>g{hMQ3mi@TB>eW z(__vBIxhf2K)k<_4C%DkcOdOo$=ZJ}XV$3jS2Ze(g-bJIqd*gG6fLqxuK#IloN{?H z!6LN|;v)^v>xjz8!Y8f+p)D9aI&LFwEza*!`XamT^*F|Ps(N7IAW4i^Uo?9qR=5^S z(JY2BuwGH96%C-d+Qdy8nc3qkC8JHJr0!sO*{|(~yr-_hW zSph5?n@SN^W1p#tq7Z^yXd&||6BzQPIHEKCk#uZwGH!$xnH$xYG~~>g9Lio^%d}<| z+3KfM1kC7k5O?LMsA&qTEMqk24R0A^agg4%NLbsREgX5)YTicdt-YQ`@#Fga`9c@d zw_)?RYdbRy>1Ml;3c{qMR3sFmxK?aA%rO(>8RazDgV-^EvXQY?d{BCn>zKszI(k6S zs18`x(&ubhL7e$#jwSXo*qR{kmsZyiDbaDdj2FeSF+{C?n6C;$({`;(4WpUL3Xr1B zqP|*++U%#^M%i2HyiV3>r(BOnbM8`U`xUbXGGiOc2!6+HbJwzkgl6pqHJ2FU-zm7X zys%pANQne<2~OZw6P1Ma)s{^+Tp0Cf9@RHEn0JiQCR5PiNFASw2MN=^@6b^{h{f9G zg@PSVtT~r@P^=olz>`_c9rdCXOxYi{?yjc5845 zJ~q3CGeOWVvI3Fm5?^rtJ!TnAZ4bmK0wO6!aDd%d=lJ?)ka#kqLK$5v$fCQKtVx(y zp+{Xt_mk_v!-UVd)Y0@Sy~~@!@X&0U0zA6K&IpPC;9*O)?1zDrqZgwz4itljUDb6a zbg(6oM{Ac``MeVxkA=;eLzan=jY^1+K$f1#(0AfRA?yD08q2P(EjOTv+}x4nueryR z0&QGAXCI0~7ee|DUp}M&_n%OOSA56z1n$3=I}nPAn#20#cllIrjgC~(H-NZbMzSfe__p*t(PXzlEhQ??PT$NrA~#PJM*? zqX3EUA0}Ag4Ar>Mo^wqUd}0jQ`eEsl{v;B7>j>dAY^`nHym6dS!O(r_75<03(9BPS zBg2o?)FuFl*#!@9P*}N!!~^wqu$vj}(euA|_1@DTt&B@$+SHo95~E9sMWfV_xnb@e zfh++Bzz|b^)UUqhexP^p;(0UsgQ-b)i=t(zPSyHuFIOC5KL_z{nK;>!_|v^=JfCtyPfLpKTA&}-h)vt&@@gjHRAZLXTjN_Y zuoPfVpqU1OZPFA%&H(_1_;dELrOG5YC^fUu+?9Xu6+{CLJuy!!U_gNa000KHtnCOs z!0z1To+mu(FU^>hA}fBZ4XR)4=RFF0SfM9FhJ(N9^qRVDYDVI^b+i0fsMLn2lfp+? zcyOFG$tf_XM1wK9q##RyeHgD1UO*{U}%@vCFerUBUEBVhzGYEi&? z+$2r?M9gn`+`DIwWECY%=CcJ1`}4*2&-inNmNUkb^Q4Pws9a(u`sBp zj#^%ffdZ$cF_eHD&n6rNMQmvgDT~>L)4}IAc_jkX{Toz>MIvPhF|x5M2O_z~2?#el znq{)}oMh!~yK5c~xcAs3N4(+Xt}$;PO?nHf08?4TKY{U9g!Nz2(U@%w6O{zf_$v-Q zOu*6Zs%x7?)pk`zv{&-mEg!;alZeXGm=tFUT%dG2%M`wdji^YWHClsd|Eo)u6h{$Q zM2FUPb(fQ4Ja`1N>dI4D23P~b47;yg_5FeCW6-h$#C@799|~ecw@e5(n(<3gh2~W% zHGz(=0WjZO9r2->f}qy0HKz%9I^OtD;^stxmHr=LM!&_p2NLm0C|$~`di>$|#bu&5 zw}}ot%d3WzFFP|{U*Q8Alt&UVp^Nhyf|!uJ+bV@ z1ZF{vns{j`9qv^j*^L)*GoGpppp{y#D<*9ZyLR`V^l88N_D_^W69n1R9HB%0ue4-!iSdFeSBx5e_WT) zs7XnYSX(6@!eeI=Hj1po)VshS6;kn*d>-$gXM1F6@-PHlgEQenI!lvzmV{j}5%$M- zahj`)are{*2;U)qw0ZnodUHH&<`8QU>A8IlE1@8v7u+r%#uUk$Iy$5kp*~d7 zDNFZEWD<(#lep+DY3CS?Y7#<`7_**h$ZHls+;4JC%=&TX z#}~c2tzhr$UHkM5aa?^RETw}+W3XPL?8W20vCLSPXRNeXAVfe4SRX8v|C7xGtoY5X zZHL5U?%*%z%XcQue)E(*y*Cz|-<)r%ESThM&sDm=;77_jgo`3GNmI2^u#(vY+YU=B z-_nTca@qu=iMenK&<8urWmgVFh{sTEl!DJbM$`h)Mo|kMN}o@)$1`^AQlM=%--40; zC=yZnD-k0C^YCFUYk?GREK=~IDwdmV{(rjKi84QrFYc+}JL$<)J|IayDBf5Uhk?Xv z1DL}wjf1DzbIws}#T{hcI*;ksmN>F)8xSpV5}`-#i_gVwH*YP%W_NxdVZ?kPsi=G^c{ z`&vqmEZcx|S5mUl6ttI205)t^x47J#Qwgaehe{jA@kYe)-pZ3>%~G9r?d;w#ezVBG zmJfK|8h3A00r~!xoldd2xsnqfMxVf1VJ(t4+?G!7q9HYwqon#x5z#{z+%JQE-%Do|od|YZM5GfCIse z{HAmxESK!`m`-z17=;6*5G1Tk*tO^I*^Qz0omCm1EM9g3FW{HziF2f7J|I6VYEg_b zHsmrvz}ea>9OFi9ljFqQ!y;Y=m+=-iIN$96;ZI0|yUX1HlpVBV#w?X_XKpb zfc;mnk83Ilnz@C9|H{W z*V|Ypc_0<}m&G0cH?c0cG#~!Jne{vRr9<6-GvtqE%*YSO_i5)1oEP>%(;B=KVupvy zc-mha{yWs;BajZ%p65V?PDNH;mT5?M6aEX~8Cq4dH(Ob;bL0rj;*x1J~9UerY#^ z1z74BY!4J7xpfzO%PZet4vLiVPcVp!z+x|q>QuDPMGdSD!`tsE(Rn^v^)LzdcdTzl zE?H$>{nURcM7&$_sT?1ef%`!wY$4NN^?AFN1JkVHhSvhmW*aJ2QyFyAsvKh9iw!PL z!)88oFJN&hz&(L6fo#Q`3SJayi-$A6)-YCY8}5# z=tAaVv2>k=mjmtQJ{e&*2&eq^$e9|X{>NnrVumEoghVj`)8u<0?lHKvmH;l}gGYn| zXUE<{z1~@vdwUc#%7_ilMUk#8C~g9?s(yU9Bw4<7{ouEfA+SBmkKMovdpL}j&OV4s zsLuNUC>-&KcVK1EV-5(eS{$%DbQLSrG0Sm-eZD$ZUn%fPZ)PHo-R_pV@fXNzqs9@k zAWkwQ2dN|BcB)LRMHqvk;s#ZA^0h7&Do1SeHD5@-?MvAD%N9PEo3SR@oDQ(*Uk*p^ zfjcB$yI#&-cjo*cDa7d{K*>kW-xNuzmD0GB)-MXl3Z`S91+u71vPr9(y3@%|Y;Kq( z;y1JS7+QLpJ!&N>1&x@*NlJv6QY{=H@|Ao{Ns?wS6D!mbbSgEQ*xN}=CFN+TNB1$D z59?OBf9c{M-@e4Oyf?p+j7q>JX(pAi>yIsg8M#oqfP6WA*1wc{X&#B$m~T)fL3;%M z+CBRX@^eukB7@*a?u~on`YaY4$l>f7{|zFAai7CH>@`)G2aC-QT{;JC4P*$cx3rt5 z6G}w(cQZbCD^E3s7S0i2B4$#gb^||hfLuyXcj4fgyc-A<@=?+%QSdOp*xA>%Kg>UjY zeH3uOpvU%PxEX608!kukjT6zQonpjhCW|3W_4#TtZ7-H{SE^xBC}1;gG)oYE?9}#O z)E#BKhFHja#pY_cfi-Z7`)gr)h9uts(s%xOVYPytkf1Re3JPaBKtAfBBh z4TZZ^lfM2Vq!T#t9b8u{v|o*%CIst$()zZTdRV=bJT)ckGP<>g?&4j@pMPRqkxoIY zSp<5#xri)N*wuBeMjm6Q8V*uqPqk%1UODMmw=FZ!ffss1y5P1Eb%DtSH1fB){o7qh zp?uT*tLefsQ7V%+U|@R0I+7J+81-d=XfjB|iC)14N>WprnJggEZh z;LP?_@b5-RoAM!E{o=oDKP&3a2+8h0Q2fL4H1H&th{w2lQOJVs$bEIrc=C}!7#vcY zuyJB$fA#N1LO34dd?U^ChH7~KB(F8B2vLS94chMLbNaj=A_94i2#vJ9Eane95s4tp(p{qYTOk)d>>&$0p?quUNG#u8q zSg^5|7~!&r!TXe%noj%3)6e5wPnXnd!Z#;V*BECs>M#}{K?dL$!J$NX`-ULBbjk1j zHI5&Y*;XLFxgxyAY_;W43xKIucL-o};Ij?kRpoROeMgV)t1pG85sSE$J=Do4=j`Fr ztl2pNmy$}ydAsB)%`9ahr0Q)o%G}lJk(s!yG?fDL%wjxIOAwZHR_KawtM83s;3Tm@ zX6pTQ7G15Kt#LC}nq`zhm)+ig>ICCJj|Ez-VeCa}uT9+)Kj&m?>m?*k1*>$E1?gR5 zojig#~1TwOnkad;%D2oP%p+ z2gGIzy{;B^)PGCzW)HW~F~{sgRd6(^gg6c{dr~3I{QUk1h9GRVXA?Y}Za1NuDu%sE zGQmiGu~}LMZ~@xj!K-YJ1vX(t_^*KPWS|^Am6|7X?kt9IU`~B;G=XCwk?+d{!rf2- zna|o;S0vT}qC5ut@ObBWRMQz9ND)qR)3FXGF9gtlPs^x**LT-A?ya7UPGG?k-;8K|&_c5QO zMhk>+c!WZKEsl@MWw}aV+@+)ND=MWfKEJ~m_E^qzuD4%$qZpYT$aM+6u5CynvUi@` zVqTJNL=3gN+##t{OuU73T&%acwbVgt;-u6se+D*&=$Vv(L=mw*C)myO8-+reAldq6&`RTZQqEO>O8uN`RycQfU7>V)x6m@4l8{WtKdHqO-%6 z38-y~0zCG0rz?K06}ztvIBzq61p%RP66L6|h>8TC=t!qP~Fu=yuSUsGy7JRMwh<>0$Zj z{sT$B!qj}`R7lKZwBizr-m9dde>uJEP{;OJK8i1EPEZ!VPX2Uf`_lQ-nY2k87M_brlA@SSc- z{07&2R)#-yOseG#%h7TkB4_}}v_WYCU2wak0qliA%U{Z$v#eNVwIS22t>9I9B;cbv zo!Q5FZzs^*@{>r6M;cJ1*+sC7S23$VYTrH`jtANL?<&*x2cFuV=+2b6DB#)J)XdenFC-HkcCp&9N3ty@a~4SI zeKx!$zjVZRkBiTn&lOrYP7A%wEgC#1^X*loEi7ah09Abe_`W z9CZk|1;R!bUa%~vI%itBUg*vE@x0m&0B{yIgkF^~mI$v~1S^E&9<6;@(6YUF-!SbJ zg0S2F)2kT@UEd{hSLddCQW!f#;G7=hj};cgZE~}`jPJc5NM97Lgs)jBMyGai+=+DU z{^wJ#^MwGQ9LwaxIL7(*fKFI8IaLTbkCCoJR6CW+aLEm3Ev>#Ma55)NNniE~sJ*uohSgECrMXP#HjF0MV3? zWdO2(SwJkHGJwWQDJq7H(XYF)bKe{Jay>uF{=Gk~{lCkn);k=Z*-1nwj1O!mqw*%{ zp&oo=5)ISKnyj)?OpWZ{pB5Z_FGjPu(N78D(^tZYo1acFn$Qi7dV~)2iqZ~MVgL{X zQpMe~*n+xJaUZn)-pf35GkNq@@{s_D9!@omI;$#-oFDtO59Vn0=hK34x zeWW_8P^9O?^rmz5upgUz_Hrk;gd0Xdy?Re66;w`n%+K>BW4KHSgLvO$*SG#Z$-2fP z2+JEis?g}2vTqSeXCmsM-E}h9901@pw0D_VDh%qr`C(T@fGiBB&BvqZQ^XW+#3GUS zzy<*lPd{WE%7Ym-2ElhjHfab5K@`Gl zv}{6uKx&35He%wPq8Ujs@-R-s~Fai+&OnUu1 z%!*h`Bp*IF5blrb{N=+TZJ_jhn38Sva!9&CVuCuvGBIBm;sQn`V9|%LhXLp3AxaX6a;9)ybdecH^lx&S= z+W%Xf`%xZs|F<`qHAB%rNa)i4(25d`$igvIyRgQkVWn)3=a>EgmL zsw0QNC?y9;%-*y6tJ{sT?=n{6Z7d~(11nnm`mH3-pXA5;QMC2;%dd&yJRhfAH6Gxv z1{mk5nyZ_V!dYohWpgxW^9_hX5lOh&ZC-#k@N@mg_nS3<)sik4A+*z)qQqe9RHPNYY8YQ1s=~IUs|t5eRa{z%C0TokZNZ)guS(PULMFuQZO6tTW%H!JPKpS>-^| zris0FlYd#88K950CbM3pfbB=xA7Q!beG-zvfuKRuSL^ybd(U1ws_062PkwM^(z>=j z|LT}iBX_=vz2B2LviO$6l8Z1f!eYg>pOmJW>!LQM6visCD^v5L@Awwm=gZ|Tz|JL8 z1)6wIA4;;X@|6%v6tg*}V56$n>$o4iqIgdf-TjXR?FyHJN2@f9BPL%;-~CX9;~sja zv#)*-xv4v8X-W<~HrZxq$<+2J&O9Mb||W~IPPtle&Xh#k8z`v0Q@GCa2t45oD!9DTC_*sF1Q&J0pJemQz2unZdzSP-p=dOJ7sFqzn=y(_e z;CyoVoy9*dq5W3RZf^XDhyW6qR^BV)hqOjE5bg4K<9d;hRww~L5G~&?<55e0cM03g zFO6)7hQKxwEkw5?W2SNEKG`99%$qo913)h8T9+9?9byBekt52;(+JQ8fX|^%sCxS7 z|Mzl;RLn(PEGJrJQ$dR%0SFx3xmtBA=8!72Nbl={63~zy<-4M~xCB)CM~LDkNZ{iZ%hTMkfpAAT`$LQ38$l z-kGm>XahiBJ)IHxwH@QG-4LS)%SWv4sn#&_DO!kN^nZsZ62e&Cc75)LxRLw}UKS98 z4T_hw8tlF=Sm26NOP1UI4urv9EBQ6YvGOh|ZPQqPy2P-SQMv__&%%Yzv7F9CIdiu4 zQ2q$T0H7BuXnvZ_2ZcJK5*AV~YoWe0yrj;e6h$9pmZ@c$*`DuisK=SF_|*O6sR!zz zOeu>)oNlpj27#r1MYRmtBX2#E0wmkM8%QN)pqL=guYR|?jP%@3ylAt6Ht zGS^_9(E`J!+A%4Fq2}l2I1#aZ>Wu~&*7=L9g2^kl)D|!gg7pItQ|B5iqlH924Kyc7 z3|aw(#Igd{qDp2N`^RBqHjJ0A?Ug32r9aBl4xI@eX5)D|IHaUf#;&!e&%|=WH0#4V zteP#;;$L~~+X&<3HQeXzeXk11t>__LwV?I=n|;#%>&dyGxqs3iP|+CMiyT4j{5KfZ z#9R}fF&jJFKjh|CPZMm4Jd}M4jM1}%-G@@U%Gc_|y{|6hCvY_nsArH>4)k7-snUw? z*I@iZp94fEHcMAugMk!>OdV*0jk~_X=zBc1TFLBzdS?x-5L*?#%90O1Qud=aG|&Hy zUobIw-+qPTF+uk2?tRYs{d|!!umc)J+6t>5J5G|g$kz$v$4}}(U8%5l;M&z{jm_En z?QZeaa4_TY9FZ^#CkhvW{4@|LsP_gi*`C|c%eQ`cOj2a{n)l5{Cm`E4 zB{}u-v?q5ML%W#5x-6&i1_y0dR|D=|10CHC=}}>Pa%O*U6OQXP!YLCd_O761db?j_#A9swlPKui(}Y=VJPi z8Fk4@G>s3wjB(1V>}!VqyE%__pP~A_cxE~Iw@;xUnQ$_?^*<)Zn45dB*T)&zt><~o zZ7!o4$;Kt_)yE;{L7JgFkM~2#1f=O}o%uM(oxT}?<0x7`GfUe|n>p?`4u{6h#M)oW zcO9{qnYP$*x7kO1%Kv@}S0{E9!hEPgf+B}lgXm<6CiuU)SX>vfO33AIVtrjV(KVp(hgYdKGs$y zY+7s6KKh+pn5xnyhOIWR0oQ`Mh-`?Aq<>moh>cEBV*qRkKt%x@R*5WE*OWR@u9gOU zmdaVVxlLmR@R_f}2H{~2MOoJs&!;#epYaJ+Kkzjtmie1$R~=E-vbiYL<(y~*$i?Mg z=_C0`#M5owe;|7>Iki<7QKCj(nd-QOl_3G;^`ZdlB{u1_GX#Tmt+2rk6X&p8mLu+0 zS&v%dx`g|Cn&|;V+c&hq<1|%2_of)W47|4TQEmfM608|qWaG!F>S<;fs``t!VGbrL z`!gv-n&;_1WM9=E(At((d8+h((6j7u)f%n*PR6~BN<_9!=%7z;Nos$#NPu_m`{y6> zIU`N_7c{nJl2QqPu5HNKT77s8G8SO-uF(Q7zjel6%5!guGKh>|&p3V~tpLpD%KMDR zSz~ZDB6#Xi5Tr^dKIYGtZE*SkTTD(*=W`cOxNKa z)5^_P>#;g|nw|ZLgHdMy6aWzrZhFDzbc(^HdhRea9K|gT)rTjf;bfHsc6$IEf;5#R z;;sh{DJE*0f}Ml3whp}u-D7kk6Znk-Hn`q6GmuN^b8oy+DfRp5qJ;<_@!s-d)Ce#W ztc~_}a5a)|t;5-Sq9`Zrz{;dHMP*8FvWCmJ>0?M}^$!dx#Ugl=B9NB+;i!dpqJmP? z*TD6knY_xM*D*52n13$?Jf ztu=SVikopU(hZrj*dlWqmRy2WM{>TP$)_(U`44x&TG5Q;hc5pI9H%I+c|eyST|z6F zNG3_gq#Zb`%#XCP*-z(E_rS{*JgG5+{|tTFGDJ09hEodhes*?iBY?VMFPGOPg#Lj9 z{YkmzGWV!Im9B^Jgr(~gD?$KhUsvTsPnR8uVJo*kek@4_VC(G2Kv zc=E+K%#VN$C8Iuu(l*`tIgB~P2C=aEJ1admEqHcvPT7jI4p5sBt`M`GoU~bq&&mpl z_9<>FM@|dlb(!C~EUK~hi);Ybt{;9BWC1>9Q+`Bk5`QnM^P-B;I<>%3_-H|^g%498 z2BFp(Q0eiH`1+<##4uMcbWka-|2DKB|Achp>rY}b(@MXwFS38vBfQ8}(cG+4&e7FAQ}2kn+(tIX%Ada#p!x4MX-6J=Yh3#frml=96?&;fS8#5V_ zxOZx@+W1Vk3U1*R!f&df7d*uj!}SFudm)G}VuU%hfWvEawf$3!u({@zxu zVMU99jbHXak>?(i@h0-O--GW4bu2f3H&)Y|;*b=}b~6lbbkYA0isu;QSUb z+}?&OVNKJ8!pg&7yhk!d|ISlnfX)}zIdq>6tVddDvFY0dNFx%}V8y|6q914MKS8!9cqnC5kmA`rNrA1w!lzTUxk%Vzorbo;rO z5|HdD_`63B7O9;vLoJEc9`5u2QQXfKtG_=CpvhC_S|~L{pu3DYa%|}Pf+Fvs1&4oI zsHRGQOn59s@!gj6U~tt=&UODs#OLo?i>lGNBE+cX*h%c^`>1VAo-5wOpj=UGzURkf zI?q>i(!HaWYx4ZGqJfhkJh}(!wkODz-+EgKX7{<*F)TNXO^c#W2wq_F){=D2{smPF zv8HEhE%x(77EZo+Mn+_7*09IsX`ZZQgM&g(Q7&5yM88F9F0QWIWt_GV-L$i=JHNdi zZ8gTf#htD?nTRwZ*%{M?5=BkTIMBO>{8o zIMcO=Q%EOs5XmvI=XFJJEaown$Jado;VMS+*HfS;k!*`7m@bBPqasC=Oa+g<0U5>D;6Ml2(t=4AkB4SaL~ffTxoNT z$pOU5*`FFJ%t`@^9jXQJyf(6Wb;!{+7u6wBnprz?#YJ@h=RIxFC6QllADDnMsabDW zG<4T+Lgj}Cx`Y@QGs`M|yuy}vbQWriDZ}u1abK6`lIbx+5saFGPia5u9Ybhlz98;j zWSy-z;vY3GV?coL0=?jHlBDUwL7dI;`?nTxmVRdVntt)+f)TXv7ahWQEA7bcCnbP8K=`}w*KP?Fn znX0c5&1Zi*_ZEwYuvMNy)eIy5X~*X)HC@-)^0jnxTUT$_1N~z!@l6jKgp|u^bXAr3 zBVjAnKBk%slkk}6P9;Gm)v3nme>mlyL?7@K^1+5!Zj@wwRiKyFdD>p8_uiKZJ%o~IC( ziM}IBuBqE!JKBsW!hKNB%$~i7lohR46RBr`VfgW79t0f{52%(E_hs4Y)Xsh*n~u_V zIQ>MTd9Y7x^@17!hWPpKX~M>xS(B0`{r5Jqi?Bb*`Q6#HL)d3h-5YaNkv#8FIi3KV zUV@3kIRw{Ta*U+w*^kCtwH|SVsmZ>0O4nX08J|H~pL$Z~z=SPEjR6v^WdsTU2H!2yfY zu(oB^cfs;_)}GOis;o`JvVwPxd0#cv{0w2&PKnBO1!5SE16^sd=+11hLy)e>68N8B zmT6JAVg*P4z^?O*QK6Vdor^E5-P8!YHy?TJDiJb#hk+}AS>kS*ie4s{gQo9{w?VTqr1*rb%?u z%iU~E-u^SrELBc@P?!sfa2s{m968?YD~sRxYm?ryWC+qgW=%3u!4h|GA+5S z?e+FLCvYC=0x;?a0tX$}hwzX6d(u6N&woym+t8M-NVO=c{o5Xs#hGOp0tA>z@^v{` z+Hn?=^icG~^a(fNl}wxZC8HR{)^j7fx@$|`_>O)eZ_BmPLAS;N0kgc~2*%Et@@qxl zaoO8X5G#m|YFBd6)t(Sq1>7_Zg^EZoOxo&va(h&K!~h)%*9f+daQO9J(LoYrbV<9^ggE3g^*au5 zVg@r7hA9W)a<9KF4KiS4O9hDZT#Ns@K4W-xQO}>sJ;0jvRV|8h9-4H|li)oBP$cteZ0s zaTIv~!$C6Fk3&nWYH%5ci<#~}Ii_c%R4(Vvv#wQ5DK32_Qt11(bJ}fWE!Oivr7fzx z;hCzJBFl}f(%Ww6PFdL4Jvf-LI=b(=D)pEV_WQSiQ{WnYm#CvmULztPPJ#*^z3TD}*c@*~}EeC6^Zx=`aX zwezLd!9>7t_Z9l%AZ*LGFY(ipvqn_Y-RIwixg5#$7 zV^^=&GgIUt7YmP}8k=YZ>s8pN6?(N>OEA69SvHmL;fPdgw6tMc0*6@hU$ zNVlyrP!lxJaEl?zxbCe*Ea_kh#sHHqyC!B)Q-9IsBO$(%Nv=vagA>qL|6(uGkW}8U z;d$7vECo;WV|9<=czjW?(u0)rzi32!4{zsp6=7X|HR%BxAqek-5X? zkzpVe)&K8)VXxsFfPXlP)bjn~!QEGhcn%K-5O_Qtsv9HXzZ-3(R!S)OP&WqnQZNia z+HQ}s$@GRkB7Q$ffB5Lfa*y6v>94RD(1+u4dNWSf%4R#DANJ(-?=4z*PfLE@(sVcn z$0Zi?llPXZMfJ(iMI;j0-VZL~?{s{BBQ$#{clV>?)4h9H&BAptOx{z-hM;Ynw-a+P z5Mgzllp`Ka4_jQTQt1nqLO*<}FYJpZu2#C(|6`GalqvRYPNu{Ow2gA#v?6lGV0XLz zjM&6?=KJ=oW>RH-90gV(4X<>@oC>gdA72K}(JJqzh-LnNKi|KnkA}QLDft>chKjOV zZh&Z0H2(bWOW|&SbZhD+=T%P#1}|Q(fzX%TAPpT28L{Z)e6x>ETsJAEgh3JB6LTlu zW_(b<(40)Ex;_;?o=T42ASCF*wjvjkGjY!~M}$0v!8G7+d7chYZ|hO(J%)X%K^}YC zIhY!^O_d7((^MtMbm{D&=C7*Oy_}Qk) z!~&Df-FWM)+kWkkk1qa=PET6~e0X}FIFt)ZjJf0@qpj>Rdzh&DsQ83Ec=GJw!0Z%W z+C*Ov0}1R;EeImdyd(t|=?Va0VHTA1O#jTXJq!fWF~z4**y0(Vs($GaX~SZ*HU*@v zwKr&~b>$KYO6s$G=FUG8G}J>rE_1iq(d9H%5{H^0C}+V?i%|syCIG8E7sC>^HzGiL z7OtgZPM_yoc4|B&f08E{JKcy$_&OaiF*XGC3KL2Jse3UW@%t&6w^ANbV=z3 z(EU#=`8)X$(mt4hVCqp%WIvE)9nbmnl{`WrNSv4Dj8U=P#R=;N_U7-#`CZ=zXFmTY z*Gh>IdwjZ6ZSkz7kRfF2H)7Q`SJ#$Pcioi{H0T~jhRPKy#9q7h+Q-1C=Ct0{Iv7em zxE~vTX{KYj!RaP%S_S+bQDn+M{KiBeJR|f8Y`BVzu0H925>qrJg>+E)fVhZGHkrC5 z9ME!WZWx?Wn;IPv8hhqSe2k^zi(q-H4H&I!?;GI28m<6!B$Kj+nF`!vpTIMEEDvq7gJf$)j z?F=mfdD!Mi4eA;(T8pAfh`aAu8ID$W3D~S{ zCwsWJwRFyG5s|}b*?AOV%$5(<^j(X*Z+BEK-pm;o#iX$g?OoP{B|7pHswofyIfsIi zGRVxndRO-dol_5Vdz2Js`!s1@^AGsq8j|i;Vt;B?TmM#vk*7g?jzco^v7^UPLV6dn zipz_2CS!xC_zm60?~Qre*4mw`zzSjOCK)Zv2}(Y{bQ>}?vq_8(q>3_S%D>S6gx7DRekIi@j6KuPe%-kik|QFJ zs~}dlqBsTe4{M7#TblvuXpI(3=Y34X4c=$;7V)LyJ3_w?^TRSYynpDu%e6AL#zSP4 zJYx|F%<9R-1Kmqes{fnRrki2RRXwl-EpI}&+6ju*xxqjO!)m2u)%;&>D83sh*sshg z*bW$nofH1iEe>3nYH82j5g*YDe+g;LW2Wx2f9&v{x}_Im_kQ8gu#n){kfii*#*!<9 ztf7Dfcc-SJQ&4e(*#QxVx$l5t#`3e{#WwDDOZj{q@(bm!v^2naU`+^1&L#joijdeg zY(X?pS|EVBgGSI1nFg<7L!>nW%5|0k_-tyTywzLbXy)1MQK}vdMsJuQ`-iE!JVq&D zE=bB(6AB@B3oL^z%_mYMZEEqxJEE0Q_=%%)lQN>@-WXRK9X$(3l2lXQ@a@IDNRs`1 zMJRYW?>AMM{!|gm*I0fd)H7$U{2$Z>vJH&eJC8p2Tz05#qYuq!oLTSIn(I>OMj}V!{CSK0rZg>QX|PInhQ2218kC#=rYhHi?Hgf+9pJ%t zm(gNbpYX015NQn^bZeO6$p># zV{Tzo1FRsmT2LxrX2J}iRQ#R8%s>toG`q-tWe?)rU`Zm-iBx8gXJnLfG+$U^A81@L zyj4O0C6(osEh0KgPIYs>{w|!^M(#p(e#5%rtzcvT;>zl_Tvu+v&`F zi270PJJS(@iK`ZsUw)hpT??Lup5N{-KKMsxu1=4XC~b4xE@h)S@hjXRvu{hg2ABUs z^x~SW{uu*V^nV^f#$NS{iveV9#hdLq?Zumr z8y-l)O);HXc($3=UBw776IJI-4-!n0nZ3JK4doEz|QpbuPj~*=LV+hqH{-eNqhVmen zNt}SRt4TYFN3BAWSA<1Oj{h@`D3#}-V+wK-)zkW6%Wcp}!hP{Np+AMDSux&bh|LXu zRe)yX{uF57zyoDY>A*^utR@X}xQ8=@1$6!kCA!Pt{Ll2Ss=;E_5BnbP5UT#Jl5Q}> zeqW$~kwUn~zN;yeRsVjLlPAFs{vet+UA6?V=r(cEKi&3FBk>$5#V4Jd7`v6q31X2;M|LS;SSrm8OBUO`kx(;ih1hpP2%>5@lQLq7xnKVi56xZc9(9({U4y) zYn9=@e0}t*w!ix_!3p?O&t#x+C}gjFxSN&j6|`QCs+NPmVD>nIG6b1oVXM7oiHQ8f z!r~OK{wy_=E<`#B*~5JXAG!s^5#AyW+!{27Q-9J6ClCW2y^YXR;A>jM6}+p80rM@kPQ2dBlc>&{P=oR)E}e_BcM zY^R71AJWJ8Qi(wd|pZ>vMs_t3eWf3FS7%C3vpeegCG_`}r<|Sd4PWth~sK4h$Q_)DC zHRAHzxN7ki14sik!9oIb9DocwE4;RF>??#ca>+qZ)X1LBC^}$y!Ggs2{*b_!X2~sD zJgsae^0{_3GJ&xno!Me<{9iXUqiqfxKKRqJNP4o0=WAS! z;C`t;6gl(xVXa`RpG)**X4o#$($xx>E6n^*u~Jm^rxnPS8roZ6Z`6I??FzD#NMv8% z#3Cc?P?oN*m-2_R7EdXs-XR3V#Dt!zHXOe_r1{uXqColXVz@;Mg2C+w1qK67kr4ZCq zq~(;x1H;la@{ za4DcmTN-_lq4F~rI~0COoSiG-PP?0~wCUnbluJgbyR>JeEe*>Y35?>Wk$+0~OF0!T zZ5*z(u^en)GI00Y0a3TZn<63vMCW$$!ofbl%IHHWLHy>o`c8y*x0E5s39+PY%9=)E z*=DE+JUE2mz1?!mktpi#`l+MRi7)t7*z%RVzb^hA7Q~XY>iji(#Hl+cK1hkFd@l3v;N%LFEE04K&$%I1n->lO^v2;wMS4mM zAC~(+tG(UD_J?>?x~o8Sjf^L6e4X3a>|M>uxuNwPiG9)PhmMoRGZygsOqZ=l_h5Um z`{0;pv6|`}n$qVOIHdyU)$6ti(R(x`@;`eE5O>D4!Jba!QO7k}_#kjOj!kITKh;+s zyU*d~k2g+bh%NV|I~~c9P;?4b?OuIjp1#vV{{`@(?h13cPmKNI_-e;riJlrwlBMd$ zA-|z?ox9y&TIh@YR2*E2DvQ9mO($+duHMS=aA)AsAU+cdgPf3z|*DU22-?QJqg&C|*_ zTYT@G{;)X-t+GZ{rpnSG!7u=Q!D#dr-7!RmjGS7qj90NHyD}E3KGGbT;&r&V!Pk4a zFAvJ?lQCya9QvdLN|w8-up5ZyjZdR(lDd8%K!6$T*URQYpY~@Kq-`g7M&RVIzO#3% zI{qhW8-&EwwxOMkU5Wp-uHA_DrpTj4&|vv`Z_cqmNzTc^hfyUlEy@ceJwc=?P)wSN z(fzBJ0UE~Z!}-5ye9l8G&vq>VwY5n|6uf%e;7H(tCN%`qE$%u{sExMD;88AUtD~$V z35d`+P!87-TR@_8a$`KKU;z(QzDmgpiEIp;7d&<^Ig5yPLMhLtX5a^ZmpL5X4I{@u zc(mwC)f^&n17~>!OBs+BkZZFbg#E#Rq^`AVoi4(-3~{g4RR3M39*7aE;oOi}pxjqn z`?jl5qMH!>*OjRe0i(q;eTB9QFP%;wi(KEV!0cA z|2ft7{VFOGUjhx`lKq{pb`%}!i0FSa%NyWhk+?k3!{}O8ua^VcPWr%Keb064-JrI+FRHsC!O54XxG2`J*-*5h)?0 zGRA-8H>b)w)4$W-u$lU95!7)YRF52Ia-5onGo-9@z|P8A`9gPGNl35;|6qlx!=l_8 zWn+;NX9-(Va(qX`0oY6SXYPyZ>nmRihm_^~{517J7!hJ7kgO<9 z;FUkQK;?a1?Q=@C%9bEKC$&ydOkorTATyh2V)x{3FYKYxA=m!UeHP!bUMg)nR;Bkv zeVij%Nz+95@cPGHg3PL9yaq}I2cWvc8pIwK(6dk&ZYtMwqvP>5c@1RUFYc@hPW+I< zVzVhfq&wW~%ff>WRPLq{u}_ZKX`pqQ57PGwp*&?02esj4s8YWWC^Hqct!nTOlVI?( zV5=UpHXFqi^~j%SW4qjaa{L+9&(eVCtr;1F=il-8_l2_Y_1hKa4DOG&FC_>Bt2B`J zJq~I^A?H15fiZ8!ORGlzM78*Q3m&k+C#n7X_GLv^;ClP%hfI1)QXKCXN7jfAK%pFk z%XDuhKvxEHtVAar^QBTz@=O&@Df4nopKc8UnA@Z=JeO@fn20i3*~>00GI{{WRy6F) z@#+0VosMX7F9U59L(t-cGNr|l_P1XM4ZfwO6bp&p-2*nngjjN}tZ&kR?WVBN()3Zv zNIHj%HoJgGa(-bP$1@w+6=h)xeICr}bZ6KKW$Yik$J`uCbJ(WGCy06+1;GTq6{9{5)1? z_u=Dno434$I+r=%-q|aA(Vg3n`jMs~G)rbcIA(HcU9{n-@~ri4YfYyF!2GCTN(~q7 z(PQfj)I(?IqUfg0Wm3atJ$6rzrPYRI#~9jTL0~Dd3R`hqvD&Zw#YUP z`)rX!*`rz~n>5lv-cKwD?Nlbr6mNQ<>&XY$#TD4G?!kQJb(gK5H!qP%(C_jvvoD*OiP#YIANxg47PRZMFuC27eu+b!CagL8r z0!y{R-pDvgHD6_MGrGk;N}i8o>AOHzcnQ3x2sRyR+5+ANoga`d;9N-V+k<$m`xNpn z4mv$gp{(VwpZ$IGt>bX@#P!dCsa(*}8LeB{<(25;qL|$&;QKvD3`b!HT8}sKvMtQ! zCVsSQT^GmIZZb~#d}Vcy0=RI2r`%?vaD~Yp8wCdB_@V}d6|Z1zGlKD}nh4axwE1+O z;#LoM=zMK45Ha+w6u8a7X;12Ejl*?6I~l5uL4&_5jh z9X%oVxcXfeN+Q%|AcEE5=MA^fXE14umg&RnXu>sduYrh+u!Cdio7BaSWe(3GQ@7w| zAzXiT#FsZk7j|4OKr7uBB^rcZY#2{RnYDDaUQmXCo8 zz)Jrq@X9A3hVq9^fGWAK<}4M%>f9tsmwb!9wA?mwlSzVAW{0GkkAoaOXxwtvh=UUP z#9mDK8$5bsn;yTxkRAgO$Th-kN;I7?<^J+HFtPy(du$5Lg+T;0E2;%o%8^Z&yoVG` z*v^I0ls?Lg_r)s&r;{hepzy}%I>0($Uw>PPs?ofz?KI3zQW)IfP%gN_=usA&gG1DR z*2vV^oX}k?j2^=gzxB$=+2NbL6X+7&Xe#kBf$M~if+z$=0=jzqW;fg%Rr7W9#*WNs^<Fmz$5o4knvm=M*BsMEsPe}K3k2iq^ravbiB}234 zi^JMn`DX8GQY?`VJ2jS*t1|DJ_BA7MrRu!r4AGq}A`&&q(AU@~geC?^>&Dc0zO)FV z!6)dr{7V;Ctk5BleL1kG%O>>jjAvFdZI3qhNrS7>M8a8s*l+JvZCuAh3gs|&gomd4 zwj6VGx~x$j$v8u07aSV#dnH6ze`Ld%sS%6mPp2c;v}(;|kPMK(As-{{@RScfUlN|~ zF)Q(x=TDH4*6Mtk^{NVdq{I`G^72^<8MxoBWhmT!)d3GTlTxXtzOaZP2n^Nq zaa=a{#^d_iBT2!3p2~>#UYqZH$|KEB^v?cMlkjYhap?VrSDv1t^O5zTwMIkg^S8uT zNpzrnC`f+qF66DP&k*I??Xa*Az)Dt`t@`jSYjj#$*zG$l*Ddu9Zdi|DulFjmLMg%s zmzg`vha^sfEspDTW$Si@+}>*KyLX+bL7|6&t^pmIJgw#wm=7opJjBs!p40md@U8q@ z+TGd1{-~+!vVge=*9tx~f=jEZP*cbraq>v;Mu5sp=IoGTCI}8N_IXVm|H;UdJp;T_ zt#AIHlTyd&RSv0NRlviU5V(Z3No?tRx~VjUc6WTbcfM2lq^Z+^@SYY8!K}Rc&rLY% zm6b};cC&jN2+9xqUkvJE8~l0Q-jiP_s5$IJZDftT>BysjXV{_g4otOYR(ZuhWm0>V z>T!H$E@iF#vxEAW-2Iq&=#X_QyWj)&0WzVnXe>9(@}Z%w&yyWcW;DljeyTdjn7dlc$AIJ^+$iXaTRa)M+rw_AjPfLrIH5s?9eI>rzxAz*8=0#(rY)M?6~yhX z$Go#K^hYOLWjj)pbn$%gU>&NT-ZCRCXh+q5ro^-Nx-v0L}X{I>D z_haHNnRIj01179x*#~O=kYqyv$ItiO?b>ZOaiZE3ZB1(o%c69J0zGfE?>kp1Na^#8 zg4twKy*TVTTYT=#2i9|a{OS%92PNG?ljJ2$x3f!#_Ql$ z=~wO0Ipq%*!7BP6vac6!jn3!jdk~#*;*@ToNUx|Z#|5rROGEudlt_ZCl-jCK*pSNWE}=C^rH5T z4V`?=UxWwmhGl)3i&rzP?*_INOPy<5HXnHbXv08bHm<3jE^1$~MP}0N;AQF0L%&~T zHj%uUY5k6v+l{c6|}YHiHu1}?C#q|il%5-tt(Z4mRc z>h@mO;~nr$d424BbFEuxW|;WmB_nsIsj!A6I=N<7i+nZM$2(zEm@%`%U`h|uo9b?T zDJx3?1B)+sX)*eAw%JHTegf~O>yzTW=1fOumI6{Pu@9B`RN^Kbgwt9uqPyL022#CD zl5htZVRj-D5{i8nnC|6?W?zI#ULeJi2~!3o)LL=PA0Df?I7Yo7rtjN()W=qa?Ys^nivnT>2h=)K=xGjyshum{^KO`>$gXWgqpFb1oF=qRb<2 z5SjXqDW$$MQ#9j`y?BHm2D`Ouf0{>5>&9i9(?tC#9@W+>X@J^&Z^pP3ZlNT((PE! zFAjs|?b8LqI#!4f?78#2LH`Y1SodM2t|igLMJ-;B-E?pN8D;{uAc_b3cxZ2^5^+Auj$anwWpR!9WH0tV1isWS)|2hZ^_{c#dMwk+&oZJ z&gma>aNN7jIZ&eL9|pwxF{VbJDPaMh{I^T(T*P=@0Ry$X$f|<}V(WJ@AL0$A2-JBM zxuKP)W&niKAg%`g^wxtNd(3NYo|eTME~^jNY6ncXqdFGrQHIg1zekugMB*5n#K~Dd zr3B+Cv#`F$d@Y;&`kzC2-J-z!*tf`AT-!)rkn~8l4K=Kz@1S znZ)~CsPIb|U&agg_o(WAm0?ZJ%_4}g8%N;8=WhCm6DQ?c>gLH2E-;XygTpF^@wC7G z#u#A|ZQW3>=~>4+;p{_#f-Q{!)f8Ao&$=q6*g|D4Wnn)jBIr^b?66d9%jrrU4nVUZ zVq=aO#2wWF>$u-P*e%glzd4yXpy?`)9`o;0tuFRKs&SoFDACB1;VZo2&{DQ13Zpd3 zR;hViW&n$o%DS8CV*R{lGmrQE8gEH?CaX(-<)7QHZhFWyHorRexl~(;C3%rEThcM@ zbB(-l{=m${N93B#R$h`w%Xu?u;OLYI@;Mr~O{~X_i#Sfs_XNm$r zX&O0{!5&MNdj1gXuX`nx3udshUz|6qYlwOI5#@2?y-Yi#Y@sd)VHltBqm_1j{%G0x zu)xJtlYKvwZ;uA@SlTs8cV2|RFGVv{#aB1vgiVVRBG%jH?)1K#uf`d)Jviic_d)EKuq09#8FsSBs?6CL ze}kR9kUB`o2F!a%^(LK5vCo-DAS9Zp{k?^-YJXEN%KXSB!xezL)HzNb2ply^HPP30 zQT7n}JA{+aQ<~eCd*sDbT)1R^B=k6v9Zt3Pk^ngJe&9)Jm8C5`*fD@bv1>G&zpUMk z?jiBdI`d1Uc*$O*_-7uOz(8LRyigJ#*(eQrc5ZC7w_XUK7Yjt8_gHO=e&@S*5=N-n z&wUPlczwLd@{T{@yiBDx%W-05R()X11tdAcxQF{j+MRI(VvhOaZN(>I$^E2rK=7m5 z6>SAh9TbOS>9Bs1B}TI|{EBvG%-S4jZo}G+x*W}l$nsEeEt4%KZ>^T0zf8gF=H?Q= z8wNEEpW7KYs0_yY=A_f`K2dd+#51nGv%f50Q@#Ayd81}oP^8&fyci;x*%`PtSRghSoH63#ti(YR%fiPl|4l#s?l4z`Bg#Rhf(I2JqTGjZrH72^H{iwSPrKsp9 zH$!e{e{rK_Oem%GAE+WYP;@(Bw=$(xp4-3L1CIyiCaqnAoXuWc!aKUmF2OA(yw6v( zlbDe3A*v1)E^GGJ-E$vw9+Dxz;SK{s(i^h@%=mwgXGM0>mWz^%qS1Y@y<69x3&aFI zT2!fPkRE8XKukdn7Vj3FTcCyst^?Dx;U2cct@wn!CL@W9(v9_l?#c2m5^H-Q6(HEl zyiOt_Tl!4pAUX4ZpvShOh(tgU_fDapti^@GqS z`Ao({!PTlWPOkK0Zy0ZQx~D;1a0R8&`J9~sWLq<%aVi}Fa4#El7>6UCGu6Jq-JTvN zY3%92&~4(U#NbDtAAes-0}RUk`cjI47?pHPuK05CS({q)LK#OQ?``u1Ifh?MAqRjop0*6RC+<8J9Mz8VPWjrm6_PFw=03azS$l?gQK0+@j3!$&c|DwBa@ zKo3!aV4YnvPw1)0AsM(PuQ%$EsXC^oMMK7sEnw*id4cA1F50^Ad)#FRA`h z&BMgR_d)!6?Xao*ih6bPCml!yJ)gTy4CKfkBT(9zf3=7X+|aM^GWh)YnJSiFj0E@b z9r+VnJeG6qg{Xb8>z6)DAK06UhxtGed2{AiyKpWym2l~Qs-+IdQ^f0@3h7-cvd=23 zu@D4c1IPk)f={+VII$qRI_X)E$oFEiTq@z!gn}&$C8SL|W_m^K795~=tXgxiPx&z) zuR-36RGkNyu$Z#lN2JIcYrbMe9v^9{L6j3kr_F{{{3TB_!NQ|uR-@VU)R}su+>z2A z(>5C9JDZxhu_3~A_HLl-ZzG>$lqXryzD>o79COquZ_-3!%M!m>aVbeBTCOh4xvrD; zTYpaK!Ptk!wUJ5?P`b&g9ib4nlfE5zh{FdW^_P;V*@K^9)AXHh4u6sJ|r;L9+nyXYsj4KM4c;> zt7^F0YLLxLvApj%;Tx86$UX0&nf9y5-6mf$ti2I?68u3{R7e{d3psHu2-gv<^oA5u zkN7%kZl$bodYvpyvmgD`$CUmYJtttj!S#zfP-T+ zQR37xan24D7WVH{nwbfynbIec{Dx~J*Dq69NdnN;DVhCZ7`eb86zm-9RAzD=+&veG z`tF%S$Kb3Ow{`CtNK-)SBzoqd%n=hpeflZV(iR=rD~0Ya7QJ& zOundE==HS3qFhI6l2mK1!o})N?HLkc)KA3o&4qLLJ*5P%`#Alxa ze*_g#h(=+_aQ~9sV?h#^&5nvdb&}81r1SVK69Aq*-7?}3Ytb>0HKuMtba5e^KDWf}ID*-_VdaKRz?!VlsEXyQ=mfWSTM|D&)N`!H$?Cp@@Us z>7AgE)fvsTTxuP8Mr3umEJM)20SuPF4+u`mP49{nP_}`KP*5ueO2T?+63grP`s_2d zQ2I2qbq+0RBmvvn;q6qJCU?*D^2HblHCP{K*J!bv5FCYisEXL4;-E!bD)XCyV3RI+ z*d__tnon0-(FU*xd~CLc{>BiTd^MslN^<_sFulsxtErVXZNnn=dQjd!3b`XRfEQtD z!uJIT6Lm1&dsmQtT{ydYI-$@l(A=2T_9FQ7FjE)(v8om=kI$#PtjS94MOw&4tMZbKNZg8 z=7#<>5Ig$0o^xZ2+}K)o$8u@8^fcyW_z#8G{$Znp)s3d~8b&M;4s6WUL>v^YwHz8M ziG5wxNB4|J(J<(qCZ1)REci?z-R?P@#>h;93a zW}I0KR>9pH<&jDlSJ#nFuwlZx;56zgEF~2Ibyy-RVrXgu(YiWJhj~@kj&HkO&AnF3XRjRSiiW;))VoRQP>`vD>IQ~0 zHO;PwrOv>);>2iyYxsaJ&UcB7gsPYQh-qe}7NE|B8C-e~9|<&a1dS2PmnW*Cl@`Rx z%!5h-fss-mMKVHPW}75Jg=co%@I!|ps)fQlYGc1=<&U#)yoiq-g4ovhE#h@&$Z1<6 z&*@b@vDr7t`;>$$;Wa-W#Y^9p?MjG)E{DFI>19jKpdpLUJ9v8iV|g!#*LKDo84RGm zQu@}NAf}Hi|1DBI{xC$s12<<>k-1AnbVwi?JD^bNv?=8jXf1ylFBm(&aQwMXPv>$| z{yWiArWzkK>&>_Me%GTK@0*1an^mn`iA!HZ1YlwTC?n1>9H+lZGLhCjn-J8{$(F<} z(x$8~b)9^2BL5loB9fs7Qs7-$>vg@$Sy=Rn@qHc8+5)=3F1NI;4y`$t_afONZWUG`>f3A{P1PA~R|2vXu8q&ER z0X+F1WFZmg2+AMc%6lI|7NO+W<+#zW3aMu{AW#y968i^$B!3e4A*Zj^xGk`=)J4U> z5Y(U$^l1IM(gU(7;4CLz z8ziU;CH4b>s^4qdRJLQO{I=)vCkA7f=-}>oL>9+dx#4PRa$3u7kpj!}(=2jt2)*%W zK^`86Ev^i>S#Lkkd-vOm3AODok5RzmCN~cGuO-VIx(+URRwgl zAn%HW(=8wc(=`A<7+V<3&UK>i<)E~%@(e=_|JA8L7D}G?L9$RAv>2b}A@&LeTlk}3 zr0>lGOr{Hz({X5bdIz5eFw1`AsVBe0^qW6lYJX;f#WGEvlf%h1n zii>F!>h3x6w>Qe;KnZR-W1?7R4dyOcqYoGJJ=}vs8ktZY07J9N_#of}c@dewZi5k~ zn~E3TTR)kN)ceFQ3;-pX5w1;7Dt4rr!xe%abrMbjg~0FvSu1U*;UcCBMWAfY)1jHe z4FDt{Z;Zwathk5*Z^V&X9jkVT5St!nt@B3%SO9bMr z$Dwyw@62WPNA%oh>i|L7=dNcr=g%{5XY0pzyQuK;r^Ak%ttjpvh)~#vxs-`1#uHOZTKaOB_~p-7{ZuG#!rlHaeVM~Lix6h(1uqwseCCs zuhLE_}@;WUIYu@w3I! zHNr!$PrqS28hHo-^{lqRf|9SG`MA!su@Pw^tP;-Qo9A4Sqe`)AlhRAq3!0u)81XVN zt}e2J5yKLI0sr4e?M}{sLl8!(h9~W_Q)+pxmv-RUnD{mT`)%Qe z?str2p?H0C;0me;0hZr1t~>8SXk5%m2p0-Rc)74C6W!oS>p@+l{MKT`z56e!3-R2mea)(?WTxnKmvTK{f~gAUMwn zMK@OzIFG9lNbG|K+J&|WNRch75R*AHScc}A0k0_CJmRu^JXwUnmt&h&z(p;Gip0w4H9 z-e87DG5pn`27Qe(#L&C(&hIftB?<5&&HJujIWka4p%0ld@l@hk;JA|yl8gqpPY~4V zR!7y0&Ds~1pY}HFGZ$c(znA`BoHP4|rILmk@dSNGJ*T}r96)5uCYzeNSR*imK;8i| zWD~&7$szWgaGDH_JB+H&uK0Z;5da3r95Q~{Pa+clvS2t~w#MEPw#^pz^TjxKGCP&< zUmmVCC6PF!6Z8N3bjTZ(iDGH`CNTWBU>_$#$UT z5%O6>;=4!DT`&cxxsQ|3m%n)5woV&AlzlkOECUmj5P!$P5T0AI3{EL}x;~L;)I$op zc%!^Kp=t?4~L(>W|>rQOKFu(;GUDIvB0x0y|!lh~0Y z)jmWI?(4I!v}?WFI{EGY%9hCT zOzs(jRH=*f)p%DC1I%}NU%+Y$P;~?OiAl}^%~JB}f@|>;`Uf7S>wXEP3HaO5lQWf; zIHUZ;Q{F4OBqOBeB8rIuW3~!k>;F~*&Fst1H0npO20sNFf>5Ut1)826mM<6cATE8j zFYky?zM)7k?EElPbe#qF$q*DR@FTW|GR(9QS?ljN|1^qar;*;pnS~oIzjY7AMwRFl zlSZ!-_FRFYe8j&+;2apD=0f7rI*80fCm){++<9pDU2G^it35?Gj!c=(ah>zRSp2~> zqv`RfsrTfv`Ma7~!=sD7vZg?dSVfEJg>;jT5f_&%M2*~XpDo%aiXOkkUE`X29UEj@ zfQCzJ-eEuSq`OE_Vd=@TfkBt8Qnx)PLg1C$zC~aXO*~S4SCYlkeHybF-lO>PO?E+{ zpvUsLEV5IPkYW7lFK1igFe28HiLargDuSApT6W7( zeeR8hcDau30+=IE3YW8oqYECzHq2qpMDpA3OR}Wei+Yo{HLr&mRp;@muP2k`JT`PmDSGWEga4}^UT`z(F7`(S4$YL^41KAw@N|8K zUpWVIe0eqZM!LraZZ+;jtms-^!ZIU`Wg5%Eww>YW(twfH2Pr<4xAK8i4|^}G z4lMYS%I&5Y$bT)FR81mVucRC>t!f0@@8GIiY+6YvrV1pioi9NKLzJo~_TSXNhYBtN z3{x%H?szCp){UO{{Uo;!Qm|n7dzyKh5M_oMOiPr<(}U8UBOz6=x}wudib_}Xwa#%J znE19gdkNZcs<}h1Wj-`c=j3I#{6C~qsv=Kp5NXunmE}$MKF)RkRAg1KJuwY!h)R#2 z(UKxtL?8k5>&hoy@@#OSubJoh%mfDJeWhww7EO)`qM) zkG@9#VyRl&Wj=v&rW&+zAgzoWRH@~pouXBo#Z-HI`)RG7uCl&MOYEcj`a;f} z>D`{&g2?SqE${LJ>|y>{qMHUg1eDihv4Os;1MwNShYi+`zC9~uq>z4pXi3EawKg(~85)Z9 zf^n`ShUn?T^WFci)|2H0@HTPskt=-L(5o!uvRyg(Uz_1l}V5x-2&G6L}}ID>@> zZ`cZ)-XdNiU=yZgwP)VTHPlOdxEB}su>4-8W(3eg;2isQY2+JZlJy}8{#zD@hX*vf zk=>sCw1>jMfn;F~aHA>!ppx)6=}o$%{~!|gpY>4Q_OPdTkB;HLW0w72r$4blw(#&P zxRJ-3+wu||%n)GSyM&~Gg)NF?GYRezCfDkoZ0mIM&u^-M?Gm{o^eb0@N$ab39+kjT)388UP{F2!} z54u@*t{MCv2WZozc?_DOC`_zi=>GhOZKC-RJ+Lqa1Rz*>N&&^bMne&U#+k@`9DCSm zIdXLK2wj_xJO~yLQ1p`s6P~e$lc|Xamp&9)-uF$|Cbi91&vmDiOr=FV?TmaI&Ju22 z#ci(Pq&88qUkVH4huBExt0c?HjKz!_MG*U3A2{wV1e2HKa~;#BiH(ZQl*ipm;_am z%?#h2p(jX+w4z47UN5Asd^ouo;m$$DLh~M0q^p0-V|;W$_J7%AMl80D^1y#R0@wH{ zYQkUPuj@%1B_NP4x-=hM`Cz91RBY(y3F!q*7n-P+c}a8e$ z`g8Y$AiR^{ofnIi*MZ5%j!cbTy|o6G-m&Fkii0dFAk6LFO`zOFgCE5K53K8|Wa-ij z&>l%+ggbP+b1FAKE6=iAx*{ANl6tHUrL$S0LPK8Gq}j0Ro*=xs#YH&Z=661ThNasZ zscYY|wjczZsTNmX*q24WViFF^HVY~GTWCZC6&fj|Gr3#vj2?)-cb_v%p3wE&nvANP8mhXe(_DJSdw-#x;LPFPM(Z}i%^2JYVI zo)Wg=2``UZB{JS$Q5{#RO8(0D)ZyWN+Op|H^Q>Da6@WGeVqg$yC@4Xb(55qg!U8Kq zw>C)+6}9^Lzr;91aN#{M{Frp=Zoah8{Zrq?_oM{~2J&%}>B;hp_x`68_i6;MrdJda zXe%D-mH9p)G0p3r$h(#fFFwon6B5Ob zPX@B>(AF>Ac7{iGQzWof%b_WM82i!RV3|Qxx8-(@^R?VWTw;0h3i4_%bAbFA>`$9Qnp>8W4?xXSMY`@gxO(e_Lh; zI1jMD1OVVHnMRff@@z#Z(e(voGK5=hl!O8a!q75cJE_4)+{h z7lwQ?-#kuQc==IF<+!thOpCZyt98~)5kIV^MlQI1ABa>ZDscGqCWL7l1hs!^U22%$ z3(i6m9X1u^okA>A(SP37H?wg~%hW1i8&&rzGG*zI-HUgU)fjD^mZDgSJq@^py{OXv zxlkwP+jikT4P^k*t6Oyjv(vJxonTS@Zm59H{<_`|NVZAE(<7Qt*64s`%$e#-=L$-H zH0a0flQDngtYb_WN2y8cgJyK!CjTRW+@ba2pgyzDK{kPRtnzGgDE7FeZ7OVcqV^+! z5j2%920|^7@o;gUAygv50h01K;(+KI|Lqe1U>?Ei7}}w(HVXeh_j4Md7R<~@-X;sJ zN_QHmM6X!yHzldIa+SfrSrO@n0%CEia|sGQHQ4a5BG3lZS3>lb&-IFd-tG)IHg?c-X`&L%FG}ZA$rwb77nHR?>aT%_j)b*>W|y4CZWJyUZc5E zi|0%JglEph)IBkyB4ldb_PH-_>|$>@F~JGT+==%4#MDwxls{+Hq@=1g#7k(j+ik43 zpmm|LG{PmJZV!4#%GRjS4bD)bm%Tu_#JjLi=|qUsvU0~ORKhjar>z!9IM9nBo?2kGm zD$ClufvZ}pZrd6wcR0Vb)C=x!fnQ$qR8A*->}lzhh6A%?QBQ2%R{0mwS>kF5PqNd8 zH$S)-i^}2UO`lA<)YWLOA$2KSgF+zXAak{Leg>tiF=&jAlX5}|JOnSq^B3zP8>C6s-Z8QtG@|EtnkbN`zA8^W_gy8u~CkopwR;_|{}ne9kpGhk@gtg##Ka8w3%k?6*O!ZNvsD+K~WazB8&>*Mep4r3U*G%dI7p3wX~9N z;FpSo74Ok>Hv$DrA|=QZ4O_Q6y^9Z}m5KF$;e8+hld>3Jbtrf`%@O)HvEgBA?y3mq z%=+5X^A`2UeTjA```RqujW?9*YK^O;xfccd!PfA#NxZ6xcN%P_*CA#Y zIh0A(!_1AG_K4;VheK8f`!h(@GX;9D*Oy~a;N7-Y)S)^?0!tX7 zR{jSurE;=*^X<6}BHU32Cg@HTGWSO{GO)YpxTAC5bQ`W5ri12okJDq{?j6@Qubc8u zOh0w-12?sqW52;Ye@7O(>8u60a(jJE z*f-*K!m`d!sklI0abL!VlcJ^w_h=Rg-iW8%5})w3(|6>@N(On=-p{`iWcZxDmzNMU4<AF3F77?xC&Zr^SKeUP(QxqH)Vf9Ue+S)g)iRwQT6{ic+zlCca98Rc}IJ@%RAW2UAVpyxLd5Tv|C@QUaE4XpyEV&$GI&mOc+`-}JkgUHfX_;w3-&{Lf z=fV!MVcJO{3o;v8Hmp&{$vD*t&wqYZq6js)Nf^hd%fD*O;L`v{kX1unB+c{rGgPNE zyKoz?vCrVU@y$%%l&+cZN8KqK&}=oyQcKZtzD>KK?S^kF31vp(Lv!6C0ErBsV z9Edqy%4qmVjvfi26Q0AOJV%&Da_;$nY|2AON>)TE_dqrh-n-7B?KeZm59@Hs-tgRy zG}|&33;V=0!d6}e)9;sSvQ<^tn|!vvww5*S6~TBB61L?#$Dbu^s0XgFefK`FFNT-N zB0wg9f|w>%^yOkP*Q4-t@UnRtNe4L~Y^D$RbnIx#~E&T)M0YybdZ>$7sxf@fHa6TM1QHBt1>R1|@P|KT8U+j|SKK zhqmtUfcocLN0tqA`(8DjeTzy+dGkHfWIvM~A5S;?V1IM%h5boICiMecY9uAxQnu6b zS9(ai!4fZ5&j(+$s6Zi5@iQj}0OVRxdmSO5&Xf5k^~S>P1y>g35(xq+Q20MiW0BjQ^C69;rSd)ci(mI&j9U1>zaU1b1gF zO~G6=bLV7$qY!DKD;L``JWwRK;KigMnR!F&+|ZGU<-+pNJMXRw`qmi@SKi28_?cm1 z=L$TG6SJPz}{iH0Y#r>d5x#!GfxrSGhfDeebfnBcw zCchq2IPx+b)^L}>X7e37RkrT4$SRg4Klq;Hzj=H84U3iUnbgod>1+jtsKOVG(fY-A z3-`aQGb{pvNYxN9wI{#QGLFUZ_{(hx9NT$VU(Hm?WB;iTqIgZ(Xjlk2Q*O`YD^5@s zC|c6|-XJ0>x-WL{_5)bgPu_|hfd|!vnNm-xk)>F`r~@J&5hbK{r2y_Oy*Y}QKWWfv zW45y~{q!OpwR!`3P*XL;0<~mjOK4zLAuWqM)ktvz0Po~|&gyMyT z)&J6FAR4}$eA?87i4lxKdJ*IMAiDiE0{6f7YQ4b%GKC;vFjh-EV94ZrUa@?v{p!)t z79ll&g1`Vc%jji^3|VG_@&Z547A^*+lZSjN!-uN}Gd0MtM7%~DzHe^yUhCax2#}Z| zBmg)gA7`(gy`R?#{2e2yLbGu4ZVPLUatLQ7O1bRw@2|zQ@vDxcP0qpaxq~ve=pQ~P zaociu8HEpg>&pu(D`ufeqJcQ$-#UN6g)+CzCIB3{-q5n1*QOUw^6RtcdNw^`h{B+| zx612{&JNZ5Io$Kttv;&J4!uU(m${EB`I{$MUX3+MajZvDoGbnTV~*iG#H2sM`eGZ=x;K{SXm^IAn*Nc%HReb z{+_W^(^)q{d%qpK8rFa^_$m>#d8+cItbM%iFR8!Km08rr~)LQV}0gw8TY zsy7m|eqY83em%klezmHx%REMzD*?pDGhI!?=m>iXB)&7 zYv||Q_>vFD*Lqu&I^U@??;|q91Y|qOrZoA~1CtN6OkxV8Hzr20>ndzC`c)ljr@59B zL_Zp7zxvV4I93S~lA$?0CMy=sG(_zqxc%TXYf!cVUl>JPP_oQswCRmS;F^zDTuHkr7wTc#uy}V z+z20*Bp^W#Uek?|2CAO=DR?|cZ;+b%ew~XxPVl{&>q)H z@+FG7oQHsO7o9Mh?fF6Vd@XaXW>x&WI&{1J?FQjPBG3#q3MF<*nW8vxw7xc~vB}JU z<1v@=S2(&&xF_o(o&ECj5eVej;vVPvphO`^IvHZIv%CL?5{T3UX9z;&xp1mYV2V~} zbV}A%W|zUYd74IgQYQkR%~Gozg$;(Fx593P^3Qzg=q@`2(`~&)Y~DYZjfw(^9|KS_ zkVv+hqtC~_#}*;)%l#D$uCj}*k=ba}{(6_`+kL*(IFmNt7d;P}&a@Le*yEsatqSFw zL=is&46N65h%ps26y!8OgV`Xka%1j){o3XoRpKe(B`t0+qFss{rjF?=Gq^ZtJ3>d2 z*m}J240^Wym~ZAq;brKk-<+YYc)y5d!d1#-6D0uVsZO0Mu1Y%ymBzBMqW`zgR>! zUJR3Z!UUUe#8PH#y?@xz-JPz0E)AMWv%EfmRJ#M)@9@S;X!0<=qOjbs{M&< zg(&!tmg-B3@%{E7lIjSPq{(jI?Q*8!!ImHZ+cPGOdz>6OZ&Ws|zA2^ev$moeS?h$6 z6;MK;;y-Vj>)Aedf$_w}(%+58f#5DkTbtQ*xNpi)f7ppo4%dhii{O1~YYh?S zcyr8V)gAS*-8!uIH`lZS*qDvL#W@Us!K*7dRTX^xwE;ewji^`7pVkXMKn>tdIp)ki zQ2JtI^xh!iiK0cOrRn6$#f2F|Oz_JyXVj253&+S5%@gamNw@9R^lc^NFH|GmbK5G~eiZ03!s3b9+1gb~R^Qc!woD5&AjQ$~<*)m@pE| zO(sbw*7x7Nt@eHZRwomQ)euOM`yH%*fxw9T8pS>sqhys<8#`tJMR58;eD~C(I--hi z!j7Azh`8<0nS4f*vvvvi{;v;-AIu%<%$gg3IhmLw`g0N1&miKmdZzR=CtD$QhWYci zcN#CD!>I^cXjLLO&*=eqKl?YW6{Q%#XC;d&n%R_c1*h7BvuTPXFYnO z@a57i0mbUdN3GMa^4770e7Wl&d%^}pHZ~R z&_KPVIGG3rrtGP*cFb@7SC6Z;7hG)$&?q56ZUVYm0RSZR!ipI2`;}n^;#Ko@jK$&0 zxJQz5Xa}PdCKQj%+KqLKtuPws#!ZNtf6zw>uZ%iI_$yFVxX)$hrz7R|uid}{cQi$$ zS?2|EQyzAuy|9o!+sdY@s;q5-{~7wC)FyD<8N1~QBhY3cs%!a>k^lv2bW(A}q9C{K z)6g9C-nRu*Ga9;LlhMX>5|zX6-ywPRnDGWO0&H4Q6R{fjlQaeB*!J z>z^oo3h_?kGO1FIPYrhN?~>YNu-VLEv_4Y_-T) zk_JvJ9{;$6`c}+A8~60(^Qz?XVIcK@(==_7Cr3cGR?7lO*cFnPeD#4xyeX8TiuH5D zk^$k@8Z&y2Nvd}F?5$s}#il%{aoJVM_7lalzYu2doWrzt_n4j?NZ`Byr~Tu)@)@BV zS%04ZYb2!5qqaOice2dfqA2!YnsPxBTh@knYsth-q51}V*{C%Sy1jvS)*Z#jdO`50 zJudM>pS?yIm^{0XytQ04!^!A={4iuP_0*zarBAUMmof+m3RX(I60EQ38j{FZG;Itk z{*Z;fobA^-0;HZwlTLx_6ETny~@SMH-s74Ko0N)lfApIwwKEI?_I?B&(obB zO#?NsQc;(-SmqnV0hm6|TZJ2jQY7)==mUlz?c7455ak!E|Y!}NPs;b%dYk5g$ z3BWZ<)>rMq=d_J0>r~$o*(fM@uD=_g;s6_mC8Cii?4FWKI8Ff-4MhLtS5AXV1HSX1 zmP-wz-RzJYX@b=KaP=Ui=t^E){?Uv)_?dTtK$IT7@urCEYljX_aOa7^oxm*?6})@m zKeRvum<~5oEjIuqKkCKDY4b`(g7SnQ!gR!1jM5V`oU}|WdpyN5T3PPV#;H4lGselY0hQ= zSZDL#*Q~;)<;sq^8ur9~j$|(T*%` z`FRXS{H*tOE{|#m-v>y6KLTUwk(raJmylc0`SLB6U<32GQxsAqrZlAKrXC-}4%~PFi0Asp#0b4ZbqIL2| zIBi!ag`{ zUtUpK5Vr2+QW+ifKgyrcOeSH)T_lRK5YZo2QbJn>dC5dgK{4Kk5f0;{GX=VtwG-jx z^1$t>ZsOUzk`0uBvEox-mKL5xIOw^2VoQgW2P^PksWH0EwLBu=2#Dnl=KSd z0TU;_WRKt_O_R9TF&@Ws4Bd>f6zy1fEB=PnO_mrU)+7UF6OY^jDzx(<@Wum3!;Lxm z%cw2t1k@$ZZOZ zygO$4G91ecRyuA*9}hVV}G_J9RIDVG1O=&f#E{f z)2vG@f(x#R+EZ~7fbT<^&0A!j2hBnP?YRxVkGd{EMzFVwebax9c}G3Z6iC=Jusbg@ zc5J(Q*&Iu1&4kS1qBG(29JnuOS`AkCK9Oes5+aOWGfAgz95?qc_yi5p{Nq?9t1+LB zt9w54Rj|0D6gLQaZ&nf@u9IYHqvk~%`k0pfZR&v4uh}a@#dBONV49PmXSW8=8;xVCvn%elNVjj{sLrOD@?%ZiM#2XX?TK~FvSP?bRjv(kz zI0js({eXlxr0b8Pz!9LMZ^4~hBy_N(LLdcBv`W9j{7-`Z-ne(U_ZG>1$v zmigLFL?EYws}dG;n26@r^mFG|I*ZBA%dmh1)N(e7b;2qCL|2-x{92Dpzu3IIw-<|c zwS-PNG;%}(Noy%d?D4}V3!PY=(0K$A;WoL2f-0w3tr`=d=1s*s7mtyOZUY$$fti2w zx$VQM6+EynHH$84sMohN5R$U~kHC1;SJpCZkyCgv@=;ml@mpq`@>-C3Y!R|;jz>CLa36v)&bUbz zUDI_}kv^?=Cv5U=(%h)*<`V7%#~meJHEp`QvV{n5AzRb9wViFcrh1hB3M;ytEO z-fDxEkpe#0&x|2UKkf8qZWC(q{EO*5ZRMZNL~!}5dm{xEsu(ltXQkuF8KoLKs}c+i zd2V^?j&CQ~NGYhi-8@i~;r8Qzl}lnUzKSHS)`2Q&*3-H-p-X~$DS@b>8Gtw(qvI^b zL;wq&+%gdFQ2|!*r{0vv3B~i6L|&Tflk3@K|A*NW{dF>dO|lG4m4kF1k+{haE;y+6 zu|ADqjsQ>}kE@K$_6W{lZtN3%5pS}auv1}^Pi?^T5<7*bt2OH}lc#fvnY?yIQgzaxK%Zo8QvE*(n}DOb{-~AEK8LX_2)_Bzy?;=K_U=4`v+><$Q;N ziN~i9lh3`4V(ZiL0C(gwY<7009qI5+UR8e;=ga5jt`iVy^HwNoh4yf95Xy|eT=+xq z8_rM=TjjG=SDoi_Z3T{5hoCFwXG?+qrR=-q-9V&cl1!0E8<&%1iY)+#M>7<_VRhSg{ABfIi1oXS4@_W%jh@J60uo&-kU|W zjvwlaMwG><{HKmsp$3mzLUxE!qY>*tGE9ko>cCr=v1-UuUmBQ6Qv~5k<##c8b^OkF zHj*~S(2!H9RtUmsU#Zhd<8x7jDtp*&g+{{1)Cm_6^Vn|MbVZ4?q=*;drC%dSDGEIPgYFLNJNnm+pHbkBe6AVt+T2 zh!w?ke*XbaOFtR4{`^!TV>Te*LwR9L;(N*xgk;)*Wn}UNynTP zd>~fE{m<#&lJ)}1g0m;oR~THwHb;AV7ZI+AQ}|Nxs{$i{ zNfKv-rAMkHPU~mozxa*rORBIuzBt&UQ&$%jY7WHIUwErYlFX z<0o#Wv5Cv^CYS$=#28Lnq`J9!8lj*H8TTUc5l$nU49-mVn&G_cGQ=RmcEobAx9~mm zxc|{hwaaF$)Kk^Zf{Xwp( zd`LRT0(!X0WbaZJmo_>Ct;OF*Vl=uHr)F}W=7|!L3J$zaN3A`9*R$u7huRQx6*$RW zNBzJ=Xak9*vg&;XP|61L3~16ou~C)cJVbbgOzIjPQ>x{$A%5UhplDKf2>zViK}?~H>OH)D+^Z zYd$xAw-CgD05w8`6;%H?q2Z)b^hCz$Zp|~_{aUhL52AH?0h5Cpi>pai{$n^PmQ`q; z+HrEcUY81cBJuA;WPdaW1uB1>b*m|NXZUO!!z6%#KY?fR`x%LOQcZhnx_4yR9NHh_ z^^F44J8(w2U0TjJ&LLlMLIyhGgMs&si=xQ#uz0V1P67J7rK{s`FFIn^viyj;&?3awfoUMn0MNP znvQ_x@K>`QUxR@Gyv(%vr6$KUc5zo3%$`U{(x7wLk zvlFbp<42F@Wg3?fSG+egkW?iCSE9Y_t=)ip|Fw2GWi{{Uo+vyosS@s~OQfb?07c?_ zegKyQ?(5orL!Myfde$ww*Rdwx*P<9KF7n4Rng0BOU>Xdd|E_9~QsbJrtoRqsbSbkJ zOYPA$^n@KOPe2h-#ayU@ve~fsAi+a2bJj$URkJl^k}Xws6;3*MbGNl!gx)x8RSy!d zhufydn@e|$Cab6|3m-?nKOIP}w;u?2Zc}~RWPpJHkR~iwlDz3Zh39FTj+Hu#_XXN| zf-?GxpZe_uqt5n8L|G+;mRB2(&XCUgi9l#zs`L2d;2OUI@Z(i(0 za_7xltA7`?ZghW}IbEj_P){0kp54`UcM1r+XXO9Ajg7@0`EA=gtgCpm%=DAo*dNEi zrVBlgk}$AC)$3etUSO^;i{MG0l;PA5omzC_sYKSWtsWjxc+3C>K16r`@j%z9cs$Vo zlO7I-lHr>rw)n|x(*NX@S0}P_X6Y`(c!)rMJdFE1k$$KqU;rRfTn}k}(yR4AZj;GT21b~2E#E2=cX0NrZsw-L ziwe0ksHn@SK>}Jx00#5`f9X#jRy{WE-u@R$q}7-?vNb2cx0rdY=@;`#7Eo0DKH$$!)1*RG2j;^Kdz6Ol5M{WPRc4cGNJG zY}l1s7Yx5z&!t8%xYCKcOz&gu(z0;#BhP26vK9+P>(fxN4l5v+VtXPd0t`U|wW_y( z6D9jeAOI>;(?h;P=De##H)(ZHOh@1Z4?4cT__}&d&|-z2E)!V4f&X%6*SiVHTRFL| zg7!K8A1~~n@He&h9(p4`048;YfKlm6D${%urLr?zi=Y!1zmz{ukL^2CUAy4vtFO~P zEZ(}_sxs7kSCa0xv{bN9APTk~UM3JDa9+u~J~*Cu`m8n>`kGJ!hPP663|PvXDOXlR zhFXQuoC8w6@7e>HNsPDhiPV!EOFpo}Y#-lKf4m8~T+Bm&127+FRGgtXCSN)INwT$L ze6XjNgU3oDw^^erbk~&Vz9ZBb%JwVA()^<8Q6~gqr~GpQu|E~A=j^p*vE=Qu^^~Gm zp#Jx*s}b-ams z?i+pIg;E}7KU%E8c6V!>+emK>WOMAaJVV-=#YGA(pLu&KPw%8Vnx8W;Zv_qt0Dy7I zGHkK12JrH`I#-7bs_p{C&m~N}) z_YA+I(;Z>ibXl5HqX$U0a#^2w>oY7C;(pB$v zPo2-YumTdYu{R~`wY1TX?lcsw^^e5y2^JIJjO+HlZ^zt}Sq`CYujH@3dtTB#bi&R1 zmha^~k&Ep{Uw15BzK|`^Pvq&s_+2#7T zZsYA9p0?MQ7?7J=YfTt26UFRyL5_qF3pVA#AvE{|0s*>q4o4TgY_@;((@kwlgRw6s zBk4lm0itBSiWD~5v1?uu=jho$C;$oev^-1%37`rX-D=piLlMn$V6&y5X}SeaJ47|K z`3C(HMhNH!9}Wn?N&jP+0OGDlt0~OOs1Z#?m=REltf#TqkraCD`6L8ds4524027fA z)}EFH$V|U;3q(nQmCuSivsH8UwL?+8A_rPhxwWI{>ZMtgh_VEgW*rE8%N5?Tec*~a zVJEd0Zd*gn#gfSYJbVw_MdevFwupAUBfCJE{2-7_RHWe6@5o)xjkE)m=Me#9keqq> za0=0F%q3H6f>KHh+L#tgymzspMgjZ4gBcTxfB|)hyG$gh4!7RJXDI`M1!NoF`TrXz z!&|LcRhLxMk*6xeR&UMpJEE+SE1U7=zl4x?0bZL_^zjxI*@snuC27&#NZJ0454#m> zkYqkT&{EAPTom^tB&VP}`UI0Tn`=+i&5PE1wa6!ZU~pZGG&Fso2Pm63mh;!Y{biJs z8+wS_zs0WRFd#hG%<~ME(r#&8(h|TO;^C1gjE&`NDOI!t^ND*z7oeK}r`&Wl%#hZS z$T+9*Wm=vebG3LgHfp0Qu}g29lga{3f2KlY0czt3jI=`a4V|}{Z|BP04l|GTeyO?d zd==-XF#(Jvg4PCRGtZTO)$?N)$Tol~reLLZX7x51Nbk=>A+2z=CB?-2KTjO50X%)Q z=I*W)E)ATsE`S1}x&1e>YI=CDx$sq z+IXIVMAE@OTIN5+wK`q0$GL;XJ&M^QegE^{x-MKnp|&f`I_@s7P=SMNw_qb<4LryQ z;+?Fm*!;=}nAZ9dj_5Tw(~KdXuvka$^4Tc;_7$vpzJXg2`@4;-JDew~Cl~r}}*Wg_Qr()0y;RT|7Iq z?)>HqNL#~kCqKRJY_%%zm=}4;Oi`=s8E_I77|_J|Z|fpl2!L@W?$9|P=k(kjrs)Sr zC)Ay^z;hdzGXD1&wTz>syN)Xjw;Lj(?v7)*Rk`Q=wV2Kn(QsOV`@PC%8rtwro}Dy$ z)s6P7ihWk7$!Px1NB4vC%sYr47z07M8?#o8a7}%dbzokgx$f8|-=8nN%{`%jy7m7P zy+r}p!x-~f$^n5>1`2hGT{={(63R6Z@~hUJ(^&n*Ipd2%^FaAM9&*%mgjo0H)G;Kn zof>n1p%{Z3i6)A5KZM&~+G?jlUfHkhdMcwEz z9e^GF-xCQ7zqZS;+*{9LaGTELP}%TKZBy9!v7NnFyB~b#TV<_I{p~UADv%74cA@p} zir@+q4?dE5){)scE;wq!ujl}p;TB~l9cbbcwaISC+#2;p4Z^oe)$QyW9HHoy+2Abb zqqg@2>F=V)xsqI1Yxu!*v{5SxKm;fGG6f;;QF9aLi4yxO!-u(@xo-Xxd;_>^HKPUL8W{%8 zd_tf41?V`BsfxA01StqEMe>8s)>9FQT1^S_EqZ?YI<=Et4!@Mu_R81F;HG#-V~nTr zV7bh$>7FhBE>1flAP50T@63B|b4l}DI~D*H`AX3)G+(fHnm4E+ep0x5FX9W*M*DS zF(<+Mlzs66V#i!}m8n+>F2Feik8BDBY9Dy-)}6I+F0VZAT@}8ALkW;%)Jg$&oxE1r z1J-)GUz<4oFb#W)OQH(T@47%4e=G2`zWy9_F)nvU$!A))&Vb7%bj$d}P8R~@fAQP1 zVR>>4V5D>*%699Hx1Avya1q-&+)8oiHy5G`LfSrKU$alLw@|2k4v${!-=&<66$w>k zO|Yjx5Dv6<2l_CjersA10Q`+rqNFqH{ zM0Nolq-t`~4+Up7zq0Dw9>{O-Q1HbK0%2cMPOH50TFafrpAsz-6fZ$OLC*$) z>uD#D)x$|lMzK6}F-5=8KWSc|OV(WJwuSm~3R<4?=pBXJVlOh~(mzBKmeX!2kj|0# z61fKMO;d5~g;_!qU|LXJO^VoMU8JpSD=b*--(Y*vZ$9~)LGLR=spyb4HvMVZZG8)H zJZxuT*z?p#`xcyl1t85soqBJSJ4GI26`QNbhbe&Dc>pQeX5B7_J7yT_>@%fUp3Kq7 zxz0;g#EGz6Wj(u2ML$D^&DA`16bg17H%D$cVsc|nNy?xAy&JzmZGxXoxc=e5@#?`!zwfQ)Sw_8TBn$Ql)XBF8gJ8Mi`76IijlV5m3^PH?6F5YI zoB$;L;t=^^9uJU!2DcG>J5m01x@Hok^7GIwIg{8F7J6Q_(zdL{Ka2Z z+C6Z*9xluF6fGhZYmeZ%*Lyg|0NOv8p6v_QgI#S4dsbOCJnh;i6spbcK--4Eo(bwO zM&N25c~+|#a>^gZ;|R}}|2>g&)6pXM@zKGCjEo!JK~~}+xr&@N5(_HUWkN_`iFn_& z^>a9u{2N3BdZV7`{A6+U`mq6jdM+BqclTC+b2QNc4gxrY3w4eoG1&HOmUFL<5QiUg z$7hY;vZ-(zYS~b1cPeF5(-0#D(&R7q2Or7$;t}1W$owLj0+-#a$Tz33x3@-)+SJKF zR`>P^n<9V$&Hfm<(`uO+Wij8;{DY#CQgx1~vM7CT_<82#hqCt(J3kE}?|@6jX|EWF zPDrPkFro{YDu>% zAuQ`@^WBPb1}i7}2_N%?S%0G~0^8V+ZpnIWQkAR)A`#Za8!CEID@nXR`;8l-NrvMH zeEdm9XtU(P@vScf>z>0{>jeje+g2ev#p|M~rqIcZirwRty4I`ns;i6WRp!|e#c9{_ zY+&t2S^oR-XE%^Fw%c;*#Gj*TRtR=`E?&F?evxPB*Q&Xnid+0~#!fQ^{PgS$w?BXZ zW~3r~jBV6HT(R$B>P`!LJ10<^x9VM^r?VhlVd*yvk0Y8>e+t=%#vg`P46m}~=gjG5 zlDHE%zqW3qHrD*={FsQ7Dcz}`;34r@r{4GjV2tVSn7I8fn__Ej#!ovZ8Zdxv68tlD zR|^2e*r?hT9Tl|ogNa*f7l36ko&!+cI7rsicWhR*x2C1if28bvQh~aEacTu@1PCs< zHcbq2?o1l(sd{eu(chdW7JnZpym4~d2{xjq47G31`VyqL=JC5g0Q<3cBSkV0Y;e!0 z%fA)mVTfcEa~T-6%`^qE;Wa`))%71KG^!H6rLY7VTrFnPT;T?SuIC^SOOBZ2-xng| zlBfx`!{j&YNIwIb#wA*I20stGf&Y_UjIpc!aaL3KXz<0_LZ80_)SK0!bAuDu30yH; zDSBok4{V{iPp@*{OkbGE&N_I9wlvFcK=*Y9?^PwLGL+g3PPA$k*Q8tclnB!@qX47kjd9`E z6{C;G6M8ZfpRfap=DuDjwt(;M{`wGfe94QeX}k9`_>Jz z9`q0<=h@uczP3*o6aAPts8U1wCIpWn6*t=*i~`aMab_`7$5--{O0l0;3KrW*S~2!n z@UUXOw3k-uK2+U8(_AFK=HCi90Yq0(zr}S(w;e{+miBba_l^&b9?;feY0#T+bw8ae zT1oLC8%Y?PckBjKL>!EGV4Kb5)Grb%@OIu)94M-zN@xC;ykzT!r4#s{6sV{1!9M&Mt3_TZXVSC^Mwvb1H473XE!M z(PlXU-Lje;E-4TRfm}~NE92hnnl$}p!OUON9rLwS*BJnzv8$`B!6NW2sI|zu_!LO? zTRD(SL*${1Jw4|q#R{*l^ssdsu_lhFJ}3?RWBZSNPhyW30T{G+bcZQ5!yLj2y{Nx=z zjIdk%J3>-|m;{u_(ehq#@A^iW`s^@tBl&rKg0G_^R;JtBdHN&Nay(gkmBHySWh0b( z|JI!t?;(rA?2@3P{I+_maT=zQKDTN18YF5D5@1?=g1Z3Fwsupr861yl^uJ3 zC)mx*;)x~i{0eqdi18LF|DF0f?oP{fDKGpa4VWcHd>{ z-35GeRTPFrfWlCG+&lnXp;FV3xXsuS#Jjkl3ogbXHQokMt$ih9(zCqYr$Gq8E&^^ObUjGuS%{SvQJM>N=r zfDVBCx8AzNkE$am07-J#AnMt~F@V6)`7lirjvjO(00JRRsCMxWJ(MZ%kJ=x@%af~k zB-*yORTxw6V@{I*5Yk~QkQzk$zMoh2zAk4>WVl7j8=XsrS8_g64|z_V%4oOiWgs?N zYYzU_6^H_@jreajr`P3|PqJ9|}N9pL^2{0m!6XB-b^nqSzyP2{Th~q|=n?yobkN^no zyWuYr&5&PekI*r($GbA37p|jO-{Y>bzQhvVS=q*EK&$|Q73V39*2xmzNRl80l5f}1 zT5!z-qM2@*4+E=h| zCzK*BVdL5>3TH$)1cpuSb0U<5shkx8TI>cj94WJOcs#NTz!D+#AaQatl@|Suk0U^K z3O$jqoWamWkrGDCh0;Wr01xnLK};TS;Jw=M)ROS@mcIm?53G&>GbSC$&2zcBeh}5s|)3*MTcA+vziA zE-pk9fN(wlA7EECwZiJE7xccwQWl^qEX9rTy-UMBAgx63Z?Pa@O$L_*aAlhP$@>$+ z(8&eSCZGU9Qrsb)VTslt=8u-!8>PzGzvPRr+4v+Bw&P+iTa42u2n#c49`2ruHQ))- zXA){X&FHP{jHqn2_8f}w@I8`ku*Y_Xw7U$LIk=H?GLRIn9!ZY>JVCYU@v^y$%q9SU zI|=}xfF04;fH4rcO(B#SGrb6ub+d>d5QoHus7-!{-pKfW^eJ-oPIYt-<>gSG`yq%Nbyz@ zCt~X#h=bo+G`=xUj2lxZQCapk3-)W=_{;>JxdfBWflhLu0@x3pJoULc6y!wx^K|=> zN4F(j;55CYOO^Ds(oJ_pdK7>GEPL;Gy)j&#pB$mDtGfwb+Bp4<@^pI$fCaGF&ic^n zf9IiS@@!BH zao#49_K97bw$i`=+M^G@h9=WN-ty*JXK9damamd;zEo3D2Xpd(vJfBuK&!7Vc}7?O zfeit`7JyvuwGID)tpbpPqRRU0OYXl`bzRwHUV1>;KAtj804x8k63{^t775^^?ka1~ z2S=F)7WRcdtq%QOGA(&v0))fn`G)oKt2@2Hr{}&@{cj+M0swcq>%lw(#Q=ZhceJMN zo)zu9g=2#?3AvQuN#YNR?FTMhPy)?m*5J^L|98Y}ckt#K8259VzPPNIJ~Yucnxzqt zFhz2g;w>u?K*|0P@%pS|rIvY^RhV7ScR1-*cJ@By<&X(aE9=z0yZ4bC2)*aAO4%P^ z#V`WepmMjOxlTfWQ?9g=J-!sx?g>YlWV`@Cik)IY*=jKF+ey5+{S9X6JO};$7C_t<|L?l!OEwGHsj9+djclFU@TgUQ7Tk{ zjZMeIulyEgY~Jg1=Q{CcFY{;sn)$wQ$-Gr*wTeONzTw{{X!)5H6w4#ma5)QjDGD7{ z_CsHsTr4}!WAvX>=6p<*Rr4PH4R`Ele&>krPT;xX1xr_V&bJLiXzQRJQ=x&KJrO8n zvPqxpFoiD(KFE&ceiRzWDv&2?(5og%BmI#YAr|p{!!6L03u69W6w`=3c!_wQz)6UtX!Qa>%64mfz3OsFp`rJp3C!WtMm(9ZzM zD*ynk_S^h8%xLleg!nLlb4&yP>v%aHZ=8($WM3O)mY{2t$uT+P?K_*x->`zp6LpRT zVY8h}ym6n1sacHt7Hw{1<89$Brw?0?Yu6%vwBy6X?yKEqR~;=k0< zq^9!ubhgB#jPpP1R31+6>wsVknXyYZ#FDyLu$_!u!^!|=NC&oft+q{d`rPOO!51+R z9R#wU!zA@J)%yUH$oYs%L~bGp(^lBWdz~iWC$#7ilwXxLEkO5MG#eb`f%cpgUjuN} z|2V)~I&Bt7YZ|=1jh^yHF_q1tKMp|NRstp|Hk$Fvxmc9C<;9W&3P`{}hSkX>TAFsH zdJ#w2>8JH*G*eZ&dT)n6*1lm%gGwZ3^M@&^j7Osb)Llp3V>+C>;WFc!RpG zodd77A0uhvTE>=gk-1gVL8=`|MZv+8*4r$jTyie7k~n5s`yv9j*WD47d(gJ*LiiRu zZdq^Ioj=1KYG9truQtw|i^GZAfHyzlE+zJl;;~xN7K&HRH=^(M2*?D)i`Q8qS^Ed-Gx#_3_4KyxCl!nFJvTw$f<2(>1#Ev$NJ=eAk=F~MW6Y#OiE<#PVvk*N7Vl-^jN|J zt>4T8R#BMI<;ags{XDZ`z_>)Pr=ADLz9|+j7*raSL-bBC@2o;VRXEZkxFHWTZwQNc zPk37jlw*!8D!nxa!l@gv*vz#8;LA8e$N-bTE*ga@u1>VUC(ZNnIF2AMs_x;jj0U&via{w3%z1tkmS+gPoUy^6})+_f_Ym0TBm-0S6{C zo?sv4g8r-w3_=bai3gCx96Jz?v4s6UwZt{!@0MjGaFlkIAZ4jq`rB{7UhV3&UxzIv zWPHRKC$OcFV@x6dvx0yk<-R{WwDEB=wM&D|o`m-7}4^4@>1hE2;(neJR1=MiH@M1SJy&aPYWGS`T-2e=_F!gzvIboinJ$ zWzyOid6N}6t~M3<)CIdOrIH|h&M@Yu+Bbg`F&z-WgwK3f9 z$(E_3+$VC?YON1>P-#gA$6Pu!kB239&;QdrA6mC`|2fUIW-2cIQxi;@3skE+J1JL> z`TS})F0jwNN=gMpMJx0V)hEoX8<02JA?UjpyRYLt_^_Bb0}D_i^&wpK2CEanqve4HN*$B?6`2^oQskC{vg%ae|LV%eKq}y zga!zd?;$GKX5w)uykqx0KYGLzL3*b*0?*RM3 zOiFV3Be*%i2kB@*$+QW328FH-An95=29S@A(6`1Q0W8Vr0X1Q5ZhfyMk)`le<Sricu<5i@XNlGJDs#G@;v_%G0SwczKn zq)Ee2uZ&T^6{qfv#C6Sn$u$ScaZxCdsR8Zqo*oTr*}$ZFz~4TEa!qRfRc;A7pG;#J z#*rabU^#(`rFw)AF=#dajdd$!v)DZtYqy?4`_r1mqh0LWI_A5&D7|(yv{_r;UlR=^ zcR@fVZ|;WPlr&(rIU`Rhk9=81v<1Wp6e%RI&NH?oH0zs52=M*999LLoCMxtuRoy$k z?wPZGl$%|!yO#nvBRTsPP;ZiCQuX?;e#zkF#0o@1-cvv!o-oZvfocyLUs;!c_Aci~ zV}6rQ>wbvr=#^wqHX3(HwjfT*$zWm+UV?8bJo_N5tQEW?j7oi%cG2ycMz!_bMYq!T zT2Bs+gN!0$Aqzj3@{{A`D%Ek^brbZMg<%)|77)_@Ggx`cJ_2$C2(_nSbcRDoNR|hZ zK6)2E{s!aCq_}l!c6cp53z2-C$E}KJdwuUZfUu9$bO9Q8pXZ+o6E)00<=cNgwXKRq z_Yy~fVm3n+OAL-f!w+UhcviYg{W3Z1ddQBr1QGpf&9(=06mdu#V1Tq50>+=}LITa} zX_B%Hh0i3Dyt1x!>CPhT2O54T7XI@{pw|iOdO>ss`?aR*>CBoj!`lM%S^s0J=uf?@ zy-fTRLn`=`ZFBXmh>?gfqq9FbdXrntPPkdPp$F^W`cAj|ej8P{Ns|&SVR0>7aT3?H zvJc1qnTz=P5@wttx;nW+c4Y{3XMqnV3D z$|J0at0=nPP^O9-M(N#kzok7d%N9dQCBAvSqnOLjSgSY6OiD;&n-!#s)dv0_!N!kFp>q)W+f=mkg$fF=P zL~5J3C{zBOnD?LNtcR_Tl4DVT=P%sc7!9CSam=8HM$8a3Duao?@`Pbhp6_0biu@0K zuHYWeWs9>-I3-ipMWwP;RPEd{`kK9{9$cbdL(j}H;@eLVwbcGdQIZ;a!I!L*iCq$Z$PY2C(QIs z2b9QmP%y;Qv}E%Y3Hd1Yf^2|0Bj1&;vMSzxR5w8jy`j{?*TVA_`|tevFxoqg zb~>;7XZS!{93=(hF6nP*y4-_Z;K-rl%x@N{*Y^S(+?dwm9PTQ(0`x!%_Z)Tw+i zz}Q!zCxFv4B?{iImLWq%B5(YxFhaZCf|J=-Z9t$MohD3e*6XXkWH8&G967C(wk%HQ zy7e3~*eZ|tja2+qov4T8w+*ty;XBgw)xg}Wji0fxuLvpa#B@f@b|(xr8gVj)e@Uos zCEo7Nc+Ra=Pk?BL@su$6hzyT(fPVvWySAn2(}CQi=74i{439A(j#fBi3_CTS3LtC3 z>%Df&2fF+$cQ>S1DtCY-UxC-xl{M(kef)G_7C`L z$qcQUkD7gfJw&2B9gOht=c=u%xjIz;n4ok1U)_`cQ%IuSoKIKaGi|i6f@4OJF}~HT zh#c}3>^ThoWQsJ8VSOL#|IZ@;iL-`-#&7pwd*?~>I)!y*jZh2lAv~Cl~ldgA#|A{qHsS~L>euMqT0xVK8py!@#fc*pPJ9NNs{;C zmbv~95LRw9rnv_~vxuM~|0$3z?*r`Nd5Dg$COb^fpNYI9Oryq>IjJxu8qc%LI7O$z zPuxIcNLH^o7Zl*Gv`7w1{VI@ef2N#xCSJZg%Dd@@T*miMf%x!)jh|-U97TXcdO=}e`g%9t&JIZb1?(xUQy1I0 z{6)GV*cu2%cG2bF;;6jL*V3_lz~7g_OWq`zY#6Vww=}9djL65xRDWu~D>?K+%2~G$ zNaR8^N5eG*Z6dMYlK;&w25&@e#BZ+V~87*nBF-e)<5jz2cf++Bf!Y~(verIf1(Skt}5Qn?jlF@DN5k2Fr| zWPnKGyz@9(-lmBI=LtM$6XjC!pJ{ERBMZ{HI3yFu97WG4BkLFrRNw)jaqM^28NeFm@ za)k9wtVoaQOcgH{;4A*$r=0s`4vr0AVktID%lAsa<;zzJKWisdG_VUnp+2Pf!-;BH zmg0JgdNzNq{MvkqmRKc14rF%Ked-o_9S%X`2N|@C#C)%iNlZQsoVmK^joRZ&x}be^ z{ehELf0TX+#b3Lnb?30D_ZfecM4n^dJejBz;#(bOqj7CiHLvB}{3q?1;XC9D3SfZO`aWw6J}vspXJ=aW z`f2Gpm!IH_Q`h7W_q5-$bo2186>Z*E=ov*7GyVBNrvD`1lM??n65i0*4@ue@t-f}M zPJetwJ!8E#B&8eUlJ6WfehwWE^>wxjYHID#ePIU4vQs=dt3r0s97?fRU5?A!p2 zD=c}+jWky6DV=v!nP!lCX!SIF^}khI*Csv7I;0rdI(EnUcS;r)Z1-Na8{$6)Im>AhlFC;!ck9oV_-(03AVursh+cOP*f*GHNMLO4iWFI z5f>Ep^~*dU0chXL#N5Ky@RgLUr+B(2oFQ0$GMx4GA+9U`e&b~Z*zXU zqQijX?fePKTMlLv!kou&)iAPrvomQ7}i<> zK1`Qvn6iuhiYKbOt0&eX@lW(eOs_WZEbiW8;S83^?q7RrGsrV>?f6H7NNk!^fLIyM zPx8NR#{oOeJUIdG$Sw?4iHlvMtnQ1oGuTk|XD}+PseLluZN_|w>}YAZ^U;zo4UY*m zbqXJ*bXkvK226XdVlsF(hV4?LYPpP15N3TUi}NNZFu{V#wc{Ee?~DJ@>hu&0q=TeUmyGRBF`J3+8jN&G6lSX5!@55nvl*wy#Nfc;;# zsM@L1vsj7E2$F(!xboo=L&b8OMQR4;CVc2^M2DLRLtSZ;jv4btGedd=_x_<6r}N=d z9pc047X`>+zuWAy*vUsgHTH)S(Gi7GQtU!5k}r4HpXQ)oR48;h-W#80$oh5+b5YiG z0kQxbu_#4+dY9(3lVaa!GeB>sc%CFvKVL6-O~rS8vR+O zxxh;eXuG_v{;xE1>OU+fZ?r3(V2A<$HFjTk`PirRF6Xa%5rx!{XkECx;6FvsjN2n_ z75l^Prm=ikm73aZa!G!h23){`vTtU2WI1zp4UwFX_H*LPObag+XaXSxR|pU&P=Npd zp+EpFWDmhy-{+HcN_eDM7*9&qIVcJCD1vmv3Woc!ZV?5ka_UxWRN63aIiO=sKVxas z3^?hvpL{0w_~U{8&H#&bD4Hjvmuq!KVp8(=Q6(1k z-CI=Ohku&{S~QCjZd?&JLC}hW;4=~l;UD8|4d(Q~0`?GB5D7Cl2=)BaR0eF)3Kwf` z*cAxn`)VFkVE>eC;t~SLFZIOus<{Ogxi`==OQ`7X9Y;qIsWW8iUS0+urt^T%6mg;R zpelfvJ$wI1hOEL64x4J2r`M5zQJQ(Ze+Mxd?YwdGkk;+~H;lDOmsokJ5d^B%*z%Ev z*Cxt@aU>rL6phQQaTg19I@6{Io=l&}b0QG=RE9<0D)3ezcpXan;Spl4Jdem{0irGNprQ? zlFzu5u^G0Qn$I`LI#thmz3Ey6V>R-d@RuzQ`!w%Rw3m3>oYd0&-y3sOST@W-gts>S zjSh|U5Wtp1a9JCNw(?-yje+XE@-k;^j6a+r&?uSW^RFVbP3S~wmvXU3rYQsTd;|TK zd$4(kRKUTJ(sW#&r)k#xDvV_5t3p791(2xPu)hg8eBbXb-rNC zZR>0uUam&iDZ7E$gEnW)I(AT|NYrE3>GxJ^2+6s#mt|(vYtbq!BMz~4$GEV#8)W#h zrE3zGyJqlvE3rDdT&qQ>_SED%2g@5W;el~fA-9^3C|GH$VsX$Pu{kEx1r=kmpOYN| z>9pLcQFb?K@_UAO>vcD)h1nqCNt?)JMR-uaD(O9&$i5j>!JxXsWMgvBqKSSM5Drh8 z>2qMq2y8#__?-Z#qPPj6MT$CfI0SaxT@}T+<{ZMZbqx@tu7#|JqpKo*4hi_MOrRZ+Plsw zgzOtHd#v3^D8ycvM zhQ~H?k?spHzOMK_ATowl#l2XVfO>AC1+CU7RGmWC=jh>Z!r`FH;9q2q&|F+F^%!}L z1jb3f?sBM|Ioxvj#HULP9>ktT)#rUQf*arCm!xsMqZlAYxX5a+a3c~iD(Du&?v^V~ z1Lj{Wclz!h3X$m%wGM#Ln!OKLS!X44Y#3{@C0{!V=6reChp?o#Gjsn>)*L`KF=rB4 z7$1p;TPkq{FH8*2FqF~;I|cg|r3>Bw>JHOu$=&f;q2AXwNwq6P7Vb*+Pqf3BY3n?D zV-IZSEl^3wrA#^V_KRSN>}FdzEP(t}Nuq9dQ~?B!p{|EIE1>#oMO&(1O_{u4+w+by zdS8yH)Z*uYdVN&g6Yjg9B=@n38__Wf25|p#D5C;HyY^#bo%w3`?3z-yehoT)mtgWF zw>#{`%uca;eBjxBpm6XLr3v!FKGCi;gbN|4r4Cg2MBp2S`mx`8q_YUY(hK6#%KA#4 zkM5B<&PM35s-L!&e9kP<3vn<4FhVed=x@(d!j&1RqaqOa&ADs*6s1*L$C_A*$W&8< zNgxS=x5irB7#0W@2IJ|z5w`f?pM_cSz^8uKX@Y@>FT3i;_vm;&= z?(sKASp}*-RGpK2YUC7(DL01NC4T*gIJ%zVGdG$}=4Oo-51}+U&wK?uiN8KpaxR)< z)i1d915_U8Q5z!%;*VzA zI%`}d38HcX{xQb)GxD#)J=g}`il#7~Bq=>J_V9ukG;RrPlouT_hh z!*+%N2%3V(6l&QLV#LzEs>Lp$c9(4l<>6AfE)Q^rPTtP_F8}xFU+Kn)^aC~E3Lt5o zX9ivwXr5@YpSReckR%IUd(&&=|I4SJoCsWC%#k0q=G!2EdNAxr6K5~ z?6#S$I!8LtG1S>c{&P=lB1r+CWM~a7cG}>EZFft3w1N&NWqEX4H&v63^< zH-1F1(#+!|V0v}$!r{g{TN4>Gu%V=MB+Lm`EhguRB1^hT8+k1(Nb2Ee6qI~U`M`2d6 z)3(L}Pb4tK5;2`RH+4%&=qbh*(L*N83QhuGHLD9hb-Su4tE6dOYUyFL7^De?=-N^` z^-8~Xd-1Yzi$#==HH=vj6xKIS(FFPL1)42j-C<$MS6cj)?DWtFbbT@kq{*wofD{@l z>%Y+1OTAFRgTc(_0&L6q84xAQooSpI!g^`+M^`J2`Z-X#LJW@JoG`Z)^|l>#DY=uK z-^dT#9b0`9{&A+GM-HpE^j=_3$LZjBU6r+3uZZu%avFRXZ4$y>tSsZh#>}^=P;E*c z3*`Yd5%yMD*);4r$6VR!4A02b`MT57IzRBGJMO>PaG|yuvrjp9eA7%x&XftHm5|CG z6WWZc>_@w~N9~sWSFg)-v+qIx5F!DP!T^X6)&(wRGs@lC#>jKbNr^Q**^ulr!DPHB zUG|+%Z4~`PoW-W;y}1a~cKIL2=3~N}ew!CB=Gp=6mO>eR;DCa=+yICVdg#&FVu(9A zl2>*AUG9E7Si1QM zh0jxz>3!5^L1oj+RLQjv3Lp>*=CL>7rzuOXZKF}TOw)yZwq`-f&8D;f11(6+HYIq1 zNeiBU0%%K#f~RM-Pd?|Ksu=2V711hCi4S?O2QcUsFV*rnbxIQiRt?z_3FttL5C8@w z4VDR`<49X4g}`YWllao?@kv;^nA2$*W?=rd8(v;C+WmwG4AWI~n7J<_}EcqNo!|!!)1K(NP^ag3e5w7S2b`4PUZZruX zUbZQ_F@88Twk4`gktXNB9`ZIEFok*s)<_n*@6q$L70%J=<$oAj2ZbJ$%!>fh{LTs! zR+dz?#+3Mf8bP*?5;}<}DCOPt`wwV}YgI$ZZ3JJbm?D|#YpQ=F$;oxQ|TYpjOKFXqu2jhPbeu0e)7 z*Xq&uBaIaNrsnJe%vlKp)H$5bsIi_-1T|cTj7NB5=y)dF*4w0vvaJCPo@bGABP)zX z1dYDfBA=G>zg~+*@sNM#Mun)hUm*fEcgv@Yz94J?;=8>u`%o39Zsn4Njt91_QftN!=?jqWLo&ks3FCnjR>?|ZB?EMLP|Ez%*``yTh& z`1?v<8KiQ}00H~@j}t)swb0Ec^VFLz{hRpwJ-c6_^LMYW`~A;LuUsGod<6mu8#z5< zAii|7|LoiPM1e9y*%m{u`?_`iJ-0fkCU`w{oPPSlZ152Wdu^Lk4x}qCLWxCYdXV%W zD@U7Z{A@oNXjrV?nHILI1A_Cw>~l`)N_D^=vyFZHtZem-lh(u8aEz&}`-E^zYk_PW zVR&N)zN}o%U0=b$P`t+AV&$MCn67lZB=HB+V}-54_hM`u&l(t6Eb0-|L8eB34(ivF zp*kwJDMmlrkaU0z@y_`17Ha5iyc#T>Z)$5ZFU1CeJ85fs4?(YiYI?v9G!J^-ryHe5 zBr%@s|47PnBajS4te6jgqzoLB`mcL9Z0B0{63TIVAqFJfrY8` z=3OIcP0koMOAj=h0cnpD$e&C2Chvy6t2uYyLJHHNjOio=_oaa8b)HkwN~Pty$x0i4 zE~&S33e7u3Yj4(qg*DObGO~*2G2GxlU|~Cjhc6n0f!tA70p7KH)gZV!4)1qQDhUAoeodjT>jKmuD9m#n;S$qK<1GE3PW$j zh6aZCGRc4fzBt151DPWbSg}#uG%cAu|CYa!~PaB)(S(^0wXJ%;Ebre07}L2x>E1E z@U^J>X7S8Q0W6g2^mI?Oo+t}k+MTjjsVqusWbu_hZ9?$v@;~SaSB%18eX0g5GGkVexVJ@%>0l0X6K7)1>{zQ*S-bmdZO`Dq?xk02pBbs!|Yn zD_qrEJ)saF00{cl?%gMW5XGsu|M9oU!DL627nU2ycOTzZY`QeHR0-V zEer#0_}T~;>@(}K5CiJH+j6ACVFk;rA?>UIT;2wazhq$eK?@(?_U1-X3C>;`GA28px_5hq90q*v znHYogK-s9k=Kz1Coq-&P*b$K8Wvgyr{Er1900>6`jGeL%%ffkcxNxx$0v|hiRir+e z`@O4bCvRbl9af#^Pp9T?dpRVI3BXH#hZtHZpP1OpB%T~}U>De*;jxU+_3_V{HP{`G z!&7f_mf1B$HxM8}gct#8V2Fq|a@7L9p*zV>kp&TUiL=>@<#z#mRcV3$B5Zc z-#(5DJf)D!9?56|d3bNia9$0H~$P+*J~RAmw95sO%xvwlKv?P z#+|u;Qn+1-*Iq=)_g$KJ#PPG9)e*(dDAOT6m+ngJGsc7C*RnS5IYZrgF4qcmnUQCo z#zHP*?n2OeU>m2myn9(If>JL>S=+TXN=c~v3ESmgpD=$5W!C>O3%@+%rkayvm=yBf zUNxNMOTPwELM%A_alxUm6^=)38QP0DZO}u9PQeTS^{rC8kTj%|nDR`spTBSe00?|~ zv3<6^cmollD8vnXh&~kH&o~%`-Ng?`Hq79FsJogQQ9oI^m+))t;A< z{ETq^akmL{qs-OWF$`Jg`X^Nz>!jCzG8AByjc$9G#L9&5i(#_=6mXC20|1^;+1gj} z5!Ot&X7G$7Rn|KQHVIOy2b)w_?($|IBq%%xtI4TGv&(l0Q83pfVnAuWD<@dt@x zKnaf}s0QyIG(rtK@kdK*@7=ym#(4@H-KH$+H9o^@s89vz*fnUDt=-piJw81;Vo-Nj z0wsvn>*%eyn0va_R-qf*SR}w-cwduInQ`e;fd#L(UBxrVGBF1L6Kj5hdHE__x-zeMj5u&97t;f{o=k?PjtF^uMg6wMKa; z6t8jG7ooU~R{mjTT6>n3G@In$TU*YP151r9o<%Nb-EVDKi8YSS2olr|aZG6VIC-SG z>n+}eJ!QLLy-Ng1i^tZfU_~XIrHa?7b=pQ4#tnhM1U>Bar{R3gPdrxzg^)AO^=bxy z6D{`4N$%;@P6i~|kbQlwCmNV6bC)?AxISLgT~aIfB2zml#b}%ho9p||ML=4~Rn8&= ztCj^Yo)-MfHa0ZF>lnBK4({J5xR=*zT8;Z0#_oV%5y_C$5g9vfRtKHTg1`yy=q+2^ zIJT|r6sGmeswa}cUo3X5;Q+bJpd3dSU6)Dq&Wk6wPX%YV_sBcIdQxm!yfW_^c7Dy)gRnEZ zKffVqjg9f4EE2_1}sXmwqPhD61!1QNortHxWIPJ;g zx!7A~@p@m;5Ci~f?8N930c_g*u$MJA@}1<&;;#uPTem6PK}9joLv|ls^h>+!|MF2h z76-o_l-l0((^O?RToi;eOcM}t+BQuW58Z(na1u0ty~b5qwRy9L;=ZPLIyr-NPPf;p zCAv9$_%EuIh1>l7X*n=meRO;J9O5{EJL%MODZn0^6H018qYZ(uCr~utZz{BWp;O^NR$biZF8*b=jS`g^&8`{ z{mp3O;;;NE;!;~z|2BAd>-%7{qkwcu1plz0*%`QkD~&IG0MmN;wUPZw=FcFY#&Z?a z_29rNqo}riK2D#r1oa7G{OKbUNGsZhmT54=HAOO+%xA2xLXIUEMnrps~t6zd+Oqc3Prrl3O}o^4A~dbdV!r|$)PmM{Q~I|MM5bT+)hG|k`1ZR-rn=Ub9d z;4ruyRO^fwYi$|~CfjXH41gi|4gJrSr_iev!SXxLrG&B?zt3hLA=B(HS6FPj$#gn3 zZ!(I;LAg&Ps0t-oocwF>pBw|J{o0&sUF?JlVfLE4x#%&4LPph4d7-cu z#)1O~(daxp66maBf75VWE4Q3i7S-SY$`pknD7ym)k81h;a@f#5ji#loZC|6R|XVwTn9)-oy>9dse#k zABVeZE3G@io7#CJ)*dqVUqA9(w;N+Xxfy)LbmDqYkD?ku_!X}nijByzlPv0ZmczKk z3j$H;B9SkaTz1gluyh8nCjfqrz-BUI=8HNGP-awkLICoPrZUBuhQv2_qS+2U3(tPd z>l@FQe@kth@W{r?bKbnWFEUtg3IV`42Jqe+!Oy27W4`caJ+>SrGFhHG{K;xwy#&8^ z-M4`ho-Ug|e!i_b7)nm19pl^ff~?a=U0}HzNt)yBVJe24kkVxs(I0x3s(}0W#E9LG zh_f5ftr~Ii{m?QDuY3n0YDWdn4XeZhuVLp2 z6^K9`IRxDuN)-lZmT;H)(`2euFrhV`i7Pt|d$QQ)UPH)f4T0o5hmi6=IVP1d$$TcX zY?;o^B08ai4fURK;bWs=;hzZRe~{2@>a2&GXH&)QF_vWIzqetPX@0%-M9M#O|QTsq6BVU0^9Cl`n&E^KDCf;Dtc@NFs3isvUKblbeM<=%8a2mt^Nhk*bE5GaB89*O}17l|`e z1RaURiC*a&n}>p%$%m1(fRjL{&{(G>#RTQBoX_dyrRNL)*t(Bs#)jEFj*b546Z8WZ zf8nJ7YxJ;X5vDEhP*~8t9Z%kneHPIG`8YmaeQeC`n*iWpxZVw^a22%a6QI5Z?Nvy5(YwymHor2YIjW#0gL?`w4iNS z7I=^ab+AW=o1K=*ON@6H*V++R2{rv_BSP%F9)7^RicpWi0`Le@&Ri{st^ zYX*_{FToogWCqp)9a{)l2bc07qlEJp$Ya8J!0|a(hg)e=cH^=)+>1!bC;Z9z-PdFk zw7=~|H!~aUT<)bIjP%j6wnyw8L#TBPVbnT@Q0g^TL(7BIj$Z%2wJ18UPT-t!wdJft zw?70kXQT1@R9Gsx`JEd+Qp((&LmA6GqwM`eLl-Lt+Q}2i9^QtsS7FOz&hI|| zj`w?v$Qy%jZVkb>B?jR@q%qwu`F(2V4)!!8gd&&%R9Q?LaLM9bsHDrxObdBBF6QMh zb13hBN^9DZ@tnA5MRme5GJ)^}KcZ&2AkPvSB-7u0z7ebsh&Dhh0>DN*_L|;k@tskP zU$N`Y4|Yp?oojo!&G3Dsw}Dy9SIG997qtMiB;Hj|Bd;%48e?I z1|VVvAS;YOtz8>!vc8f6X{Wga3{3Y>k027JwTKP|n%Gnt1VprP5HV+zNzDg>%Q55A z6U*0-NF1G?nwCei!Xh7;)xUE+-qY;|3+_CFMiqmIm=B>C_wsY9)yYdbbOJABjjYqm z!TPTsc-mBj%Y^23vfFdTxL$XqtoWWSy&`~Dl6vfT2Av6h@)%!@0)4U1H!%rD?W+_& z?#|OlfVO_DKi>cP_#Xohd=G)}VqZh(OfUAI8aD?4#|a9Z_lD+KPce;6JYB#9qwFfI z1pN)7xB8?AfnVft&jhBIX7kbHOtuNW)P*ljDbz@UHZ`2aU04z>KxzfhZD_du^8OQR zaVvCYy9uNb?Ogp0_-L%48{>vTqAkrL^(fHR8lH`LI{jOhOsIA_(;hY5S*qO|VbO;e zafcXibT|cZ;=QVO^_16jJ0qQ**um@5>3OP>GY&c}^Mwo}s@@%TBYAU<{t*B`3cWWf z4)#hPn{|PzP1trjCP+#v_>~BNbS>}omu4IXoMOiSBpqRh8L8A%IexC9vV;2cWu~w7 z$2j-2`=QrsHF-1%PFgvvrK}oecW{*tj_HZ%yVtR9(TJh`pm=61TMt`a1v3p6rbC{h zJ;XRy;-gjJZhDIQsOkLA!E8SV;QSh2gYbS5QO}(izscJy{;QdX|D$%OI-LzX{$%OK z{GYdX=Z4Uo*JuWU}KZC&97I zz~?nHryot*g-V>T1dr`+Xn&3~RMy~2a1zTagB*U&zMQ)RKKD-h-3f2MKnzyfGM<6EWz zEp-Pfl~owaVMdrRSlv(>_@)ag>8`xf*(OnDMWs z5tvbqk9!l6Csfi8#SO@+CI@nEg#NdTC&&8Mjy=M<(h*=LP^A-TOduuXOOtk)vsb)= z{vJ|Yu77)lG2jwTjPsA~V0^ggtjWpIA4l!zn%*Q;IF&MGC-7YW9EdkaWc7FaDm)2H zs514m!#%&^t(}`%#cc|2 zlkCPnOYlAERtFuTq_WmHbkQ>mq>ubbH+lIjSBPx|EpmD8s->T(&2FjvliLAGL$?tXX66bAdz)iVjk6J1PXP`SaW>q1WxdDvL?<|y)1&nMk-8cZ(0(|zSTo6aA zvgfc&gQWx3HUKiuIXXZAWAwZvW-wRyJ=bjv+V}YtAq>m(E&-Z3Ab#-q(l?oYI_DIj zYwF~~@W7Cc7Vu86eebOtDdK-o+Mk^#ULf4W+k(h2RRDl&4%<|6-GMb)H}U0ocha!D zCa_bB>5J09@see%yU+en9Ee?cnlvkOxQF{Nun))+NNNA8IhqxMP-1o~X<+E6VAb!g z5U{D5%edDm0ZK)>&^PEi*c{7B>Ajxn0!!QIk<1%gkXP~o|AXtvS&?I^L8TFGfc^vr zm?J9sF2Y`t`>J_lbbJg`6_8+?ZbHqhJfKPcNnZ>aG`+8cgXNH);h{oOd*LvN4&;kJg}W@}jb?G3#b z|2ELu(sqrsHv6tswuayH=i6v)`rRvS4Zf%4H>89^f0xfT(B8A*BQ3%oyxmaR8)$rg zh=$PHL+kjoHip_C#NUwG8)$qNu|sHWq57Sj4WYJ&^gY5GLv0WK@8H@SXnQuy4WYJ& z>;4!vhT0!-_rbI_(E1I?8$)dm;`u<@8)$wXpa#&}L+*57+8b!t4G$CLSJS_HoZ);w zk;QsXBY+SIDbuWP09-($zg|0E1y5%8)IQmKI)f5g%XW4#-d3jrQeso0a0CDV5Fk&H zlsjoOgXK=mw$rh-aEGS+Hb;P)Ej8Hp<-0v|Sy3#$QfnXj+b(rF;5Z{D&ZkfM$Z;F+ zRplp(hgGpAeWL!Gu=SoCTunZ0tG>2;p24=3HB8mM;KvKr)(BpBy!rcd#_^0UjT(i`>m^Ush?_3JAG zauW#=y)te%uTiafmYJJ<{eHu-Eb2tqMW#9^c8Qe>lr_WU7%==I49bNZrIZNC0h}VU zZ}T5B)-=*>=K2(J{{VQL>1RUcS!l)tJdQ~$`z-;)A&J+UTPf*&# zuV)6725MY=zi{38=Ii7nI}10e6P|-|N62Y0Jt}=2mM^4$cG`XpEP49kARc(J0BdQa zhX`|P%caA>l0CYzNG(NBbZT1k>O>=}_I05{`vDfV)Y^ys;#@ctB~7+w53_*qS;-Le zi}9=Wx)Bc!*hD}(zRR&U6?(Cw4r7V)9p`5JBPK?-I53f6M-TmC&%e1lTxsBD5IiMC z=F%EIqsNBzgb4cZkj~<>+jDu(=>R6>riZwfr$WClB2rqtGH|QRrb;O z8&E3;muffWHkE)C$Ez3!Na<1>fFcI0EoClya}60ZzNooiRg=of9vIp^>xC)Mk!NuC z|5p6CvPo2(-r7*{e!eCf6WWts9Kv&Y1EFqc(4zQm`r2)CUN|fK^y{ety7t5JaKxfK49W`u}-fj>zK=n3MbyD(=Yzg#~58W z6@Ng<-u7KMh$OJ&^>8Wzb`{(J*`+R}qagcs^HSs$xwN%-Q-Xx0)`e3n_8xvoa#$Zf z?KD>q0mxY4+1AmB3xY;BEE#Cf5`n%3(EBv-!Qj||0C?p@tux~5J60qs%lU9|q8x(G z`^)Q6Lfmya*KnaL3i`{B@;iemd6~NZShouh##ydAsAe^m8qz;%4&wN&eGICzdFfOOw1 zh&xKpF;=F2Gkq2IkM#)X<&SXzy1%P!3pp33lwX+cx|rN;@o5Bd8mBhFKT*fBL6JuG zvX`YP?X(S!Vvinm3=kQ;BSWl8k;{XKVB_`qjW>=)H{7FYgksn5V3$J(d770s7d=uB zBH?VR=|jT;8=kT-N@SHLpH&q_2{iFDt{gcYJ3C&;>QcN8#l!Mwhn|dkx!oACODA}I+(QcRl>Uz z_1T$28E%LG46xYd#2(=&>DuG-D03p0(k1o%uNQR=u(1O_&rI{Bywh=@E35$$vm`m0 zLAb#(i9qezuQY*Px*^ zN6`V#C#2cTNSU*H+xsVIc($iuHY2RVK(Q_qwPcMwD{Mk6B3BBD*hpt?_WRdPW4WMneygqTT|)v%>$$4||*)ujQXwNRca+8+$74S<=!Ny(Lvo zIqn>i%A{&3jh(aS19%RY#rZt%SXQru^a~;9%@7*x`s1s|ZbBdz{5`3THL0zDT6T2b z5$-tbYNE+kt_<-cQo4t3D5kCN<*E=HD_O-PsfVS}J$sb@N|PAYwgu2}Eyl5NoJBM? z#~ko%@t1ZRb>ZqTUMwuUw6*I8QaY9C{3ZwE0$tps`|SJ_xaX{ujK{Sz!>zAO1jKCC zXYCbRxwXh$Ku$T=MvTTuI^|sZ^p<+<6#Zn%Be{EJqRuU~BnnX0uc?o}?C9#1TG9j$ zH!|##2308s0|2&)2dS@|9QfcsfB-;G;58C(ABBzM?@;-6sw{sn^7F4hNSV|)i>-%o zMBSCPbO`6tT16!SCS5RF+k(oN^MvkP&i8|#i`h9S*o7cc`+Pg1ZAzY_3oZ)8>`5ow zWXy5VFT{?XE@q5LkfJUZ#a;2-cSe8#D`YG#%>5^iU{AHHG>v0a8yy!>LF4$CE#lTl zzuDZrnY8$*n&!@`ijXgib!pfYt{+USh24g#NtT?PNp1rPMx;sz7#R2c(};u95iFXA-0Fe3kySSp|*zGL&)m=3wX^U1+X}1 zeOP+&v^LrsXl=AV04g?y+e2*)wuj)0&$Kq$8)$8?&0xoE3Dg`hW%z-d8wrSQ4YW4e z9Rt-FriR-?Z4I`Eofj(5+h}c}w$YyqZ3V$F+CxKjXpW>eQM5MN8)$8`Jm6yup|;T5 zLv5k?@q8wXsD{wnLv5oh(yLyKn+!z_yT+}s>PyX9gz4q0oP-Enq;fRVXCXD0Gd`{w zoz7ShH=48q`Z21(1@O3QMx3|W#cxE>DA??=P&1YQYWPhkPJl1!9ss;)!KMl6)ia&? ze2r`Sf7s)Ur2oh?ZOp|!ZF)_3+8xnmRl(V#MS_~Dl6CfGoZK?6M2RX{IEB%p4=uqse`+gEE|pBlRFSt}46LO(xw)e%&L(+dFftkm@5s zs;qfI(*HL9Y)tkSB!!~L;olM|V_ExGRrY#bK17$oFyi#N+%GTMdV3SY8Jj}VIa>rb z_cXX#1Q_#-=o~tJMTvI+-;c=f4*HKZGqLQ9DjyL4)%8)KqCYW^WB-VQ-Oz&N2!ssH zr7zF`kgL{SaWO|hw@{m~&f)W5S7w16Jx|7MZ!s^BHOU1u!_ug zK~Gt(jG}gPjeC5tZQW241TPQ*E4FDcg&>&!k#+XHZh)_7)qn*+gK#05N*`H74u*L# zCWkBw#i`I%3xYM);j(zE{kfSMzu)L?zgqdoWzPAr(NqX=KDNdqOy>Kg!DkYy6)cza z!pjr+u5A-v zBb+WJdx&DtGoH#4?RVYVgc4nKe)*(&|E1|XtdDi^y+7LbKR@1a+fT>#yk7}S_xvEF z{4cTYxI3zgfwgd1P3@K{F*SWk{cVgIY#ST8E^1R%#3-0zd?BX^hAS}?;$o&Yn3!N1 zfu^rtfV>6uLgi(8^%KCPvj(WpMOx&~JgX2i+QednQX(T27|cwgfrDYx{CU!JoVJTY z*{vz#+MW&O zGU0Sw3?XsbUMxX3$$a-7w3)F?$BXX1ba^@}GP|rL=Iq1T`dFF?X=P^W?s#$!C!cR% z`7`q*gbFi6U@&xh{OB`@e;(1XuIHM^PciV&kY>@Wd6lo)c$mZ_AiK*s3;IXwH&qOZ zVRXNEf+F~XVN}6To4x%20H%WXbDnNZW4+$ym5dTfzIJsCN4H^6BK<=#*}tA~UJZ|6H;7=x`H!cHB-ISZLO$)cIMqd;hk zGrG-6BkX4+vTdjr8E1^l{xc6AAJ5mjaQ!ek?okGObN;N5$^A$!<+!?R!w1u>tXI@P zU9HBDz80%v2n)`_K^&za8Ej?xuep^;x=W@xgB2#uv-AQ~vI+iBW|@*x=z%gGs%UkO zllF`Gb^hY<{Jfnuu(nvk-a<(*M+AyNbxNZ-$dQp{`}^Es{MCnL4o=@niUG}}b0?SJ zbN?h6oQ6M7a@nxk;zBl&^1Qw8=;%UV6H)DPvQD5NGm>r~ogBXmM0pIDVqbPQ#@_Y@ z1m}`cAM804jT;c0K=K^`a-o176iM8PQe#HX{AXu25vD*l3)z83NO?`!#H zLUbO`&Zr(7m(Q(~2kD7I6?v!3zjf>Ui;)*P^W(QAp^X-ET}Gg&m3TvOoMlf4o~|O` z4e^}KgQYW-84ydwMr8E?_C1>nh-h0%5mj!P9dQK%%eUkB&039)U}-wF%#lb&6mf19 z>-`WLxlp*7<|kOOj@>P@>AN*5IQG$6BloD!(oLT)L%Cl+2mU>us-_|?Evzl8mwZ?x z0KBX>&};T|YLj1HqqS@ffW^wuMXX`VZH+3`3M$XxFm#DGAuB~0z82K);#rCJ@if)i zIN@f@qU#mhuufM*^2skkOKpktZ&Kzi+Aw=QpARnsEsalt^pKCP&LzB%*AQDm28f2b z(Y%6T3&JVDo8h$mdb9?cECiWwR;UsMtyzrXK#=o(~2S zFhf>DLP2zf_=li`Ne?*+Z|&22G@LVsCvMHVLDAYdJx=zV+MLkfj&;;ldVQx;k(r9j z$=tKQH5WmxLt(!=u$oSA1EB{mZzB%2-ahN^E!fi2j9ioK8X*Z zdtH@R%VWhck?e6kRS4MA!zC0_1r~iASu_?*B?!GWgr;+YowK7f|K^Cdxcu=iFfS?h zc+RfHCX8Ak9zVeUwjwU9TvrM_ArzWAvZybZYZA;Nv}Sg@Eint@VnNGS9x>JDF^9F+ zRM<~8bdd}#i`wQ;hD6tM#`Pr&jRg4~%Y+`}#mFZ_KbKfuZ(m~)FMWMhXLO$;K|k7*X~1w1S)lxUx)V-;eWeY{Rcy# z#|a9Q(1x4!kGJKX4WJ*UjRlKU|H!WQdRx<;D-Gv&z$n|DhJyK!%lK<6$1wxMZ8B`Z z?k2h@>L9w_`1(m@#Jdxqx0M<&i%gAv*|~jv6B0ydk(g}XVw}}Hu=1&~?v7k2-Cv#s zS#7ewv=n*r%7B};lJ$KU`$g1(-I0b2EWx852+yDI9g_BNUX8So>td%&J zIXXl`wb;0J(S`a^ieKTTZK2(wSa=HL1t?j++@+FgG>`?k9g(-Jp(>xS|6@peW!-eL z^I77)oC^{&pE;od?=pwwzGJeeQKC00SiI!m%Uk^&_ozzw0R4Pn+MZEe@61?Go%H8(;m3OJa+a5L4^)#bY*LLR6@hFM&_mYnlEa1eg)Aj(j71kG9pT>p z9{Xv%`uzOW{U%XmVE;eB>7?L~;E^7YN)y8PO%UV$58-T80o)jXj|Ule(K{?)+?r@# zH4B6KxA6a3Kgk!)!GWrXiD99QcJj6b$^+S}z_q($5?dn4WwIT|7uhKH?3~s0ojf5C zw`ln(N9h|&%`so(yN2R$Zye4;U0U#9K!)Yf05wFGI=kE)+|>IVur&qhLT#FO`Oiwv zNs8cH?pR@_0!i7hwbj8oQdQQ#fi(%5YnDx|Tt)alnMt2Px!QPNt-chrHYt1WRmjl4F$KQvU6F* znCzrhq;qZaJ7@oPatk-Ne|noa00R_BV~iw_Yjw+Fnq9 z7|OZf>={dKEGW5R9wIgbMcOan0Yn^^=kW10^$+MbERvHA4vDuoZd*>Iv!}za_G*cj zn&KK0IE1KZn=!gQ!`8V^s@A1^YHV4#LEdh7J?$lir=0JC?u7KBMrp~^NZ>_X`jtsht z?x%MSRc9mg)Uj}z9ij{6_{l8XYo>cvLE6XeLhJH zp#=H8;SZSv%2A3P5!20$2+fOyn|S>l$cy^%ZDU?rv0672Lbv4Rmt^x7DR4Og&Bt#z z8@0#rUXjfp6Q`H<@GK(S)+ty;Uu?e8TF&r>=c5^zIB+E({Pw?nzyk3eNWI!<4K{f! z%lzQ}63isBNY(LAtU5|BJ}3N8NjGKloa(H&y+;;f6mfvMKZeVrg8e8nDQJ-<*$9#D zPSPXMlSa|NrzihIdTYlp+m&Ro(UL5UF`%lQSTe3`p3PvFZZ7-1^Qo$l&pWC&z3tZg z4K8|2*%f^nCKNmTuGfCb(j0NP#ojSj3KK{>aL4VZPXQ!cpY(OZNCb3$#gVK0* zr+59O+zVuNnW+yJV4aeUQ4z4S`@E=>rIqH!11bzr&}2hEW)pL7VZyQgy~F|h>YB{= z?NVUKPT)@B;^H!W3~t(%*+Ovc<(S@O(BkKcuec%MA*~_#AqYbVhaiU_ghD#_W}Vi= z>&Nx4ESsgZcZYbzJu#<$du-jeuvV&-nJV%vW6DOQ_DL1nIKF?SbAm*`$m(lcvHc5x zAWAX&!}h&YmB;^0*aL751st{z8k`jrr#m&gVh~gKE;^E+TZX?6O{n5shE8~#!Q6BNo>uCKt~Jw? zr)HI-z6&7{WvELub!LBR4STm|%b-Bbq%Q8^;WB7>3N-l#A-5X_E`uO&0DYQa55z^l zxNFo39(R!AWr>J;#jx1&7NrpL6ekdU80PngfdJ+nTknQ|L^^b*<)9bn_pwCPVZL~s zgYV%kv5g+Z)z6*G|9MZK&*T!&+qTYiDuD8kU@<1Hp6<&px&4PXg8yD z*ZIle+v9zcJ*JfjMbXZ%&U%Q2edAOOF6H?Xf7dXNU(tCI&p?(BfNgys-J$sKO-HH+%zQ-@yR;U|d6@wRHk za!Kaf&-W{U3G1PN#wfz2AKQZO;&1XF9_8o3mV3gRzAH5vo^7lk?qV%{MK2dz_1aci z8GV~l$V9+VXST>W{RKVpeGP(TeF(U^(8G&js;$|+KDdz9dVBpOE+?2qC{gdjJn=|b z{Q7?Qa>xYP%G1Q@oKqIlh#vN_4&QdM3)Nw#;*a|f>%!;-*e&!V=BWP%{c&09S8Xz9 z)^nCj&pC+p(Im8*-NNQBe0Mz4p0zl|FiyH36=6;p#i{0@hKT?R?Ezg9jdHW#FC48h zu?O}F>naB%tCffAiF2vMu;4dTw-MURWA`z2EF(JS@z=mM#k*Mo7)pg$u6J>}XIh_9 z(GLZg7=}W1TseHH2lZ9Q4`YIe>rfbH(#RTO6axv&ngth+avOgv^1UN1Ci%lxcfB zTFAtORv?%3py8+dj=drDE?6U}&9f8s!YZI6C7GKc2@j3W=Np0qF3Q97w*KxrV^P4o z#%9Y-YE-SO|IeM%zEkyw%~mAl)~8MJYHKK){Fd_bH@w5EPH0dbM#zI}VMX2#H^g*_ zTVWIvG!})zgVu6>77Ih<8uq_zLvy?24xWp&$luvPm)Z3I2@K*33#z@@OpTn}V+sfi(O%o2aE&tAE{nFE% z9BEp((QLsDTKs8y=R0oR#k1OF-=f(y?Twk8JKxe-GLDPM{O|yXz^f^LzuJckM+^5U z@l-py$yG2G`g!EG5lES%^ylo;$oAjJFB?}J>5{YdpX$THWcE72Bw_;QN1c(P8C#kw z<>`Nr^a3ar0r3E9YXB)sY!!8$*uRq?W7X$wKU!uqk6H<6cEFkeMF1Em0|gEY7yu<< zz+56QFcL#mR!~f=upCP4HO0|#khNWm5Ot6j3?@$=TToKA>uKu3sE-pxyCBZuk+qea(kw`wC{MdqNZSxFQ*|u;fBqYNfW> z5quyIN@&;015&-sMkPz79MdT+utKZG&HL`rxc&YV+-H$GPwI zIDY3-OhcKn#>w}{Igr)R#1K#+z+;*rlp(^zg0WHD_Cyk>WgQ@cF1j)vZ$%8BZ4O%* z+;f%1#@*w$#=2On=_?MR#QSR}DC!-an5Vo28kQ;riW$xZJsk8@3mof6zA*JoU1Vyq zEd`#iA^j)9saPL8D|;DDOl41P6%t;dhdS21llT0v(KM6+dAa(=ubngyYsvIAbM=|6O*sq(fbR z)*Iq?RB!97gDfkVy?qU1d4LCRe&sn1=?{`V;{V6#$~qE6cqM7v2w>oW?3|d&HG0C3 z+hvF3F4t=zb}6AKCR&{fvqTEqQ$wk;c`fX*aOcNv=@6zJx$gQM_hhO!1 zP6mkdS!t@?SqZq(lftx4ZuPSib9QFFsPX$JdMEOJR;dq*Ufo zSTT01z9Zu1&*DL&d(!oH5$rEfIS=gA`L%0 z=*Z(^+*l^S$5{pibpa~IM5D?h$+9Jg$k8Y#^CGH7G*y}#?32vF0KHvxklz9NhlL;d z{ucXofsSwZ{|x`0elDA+p7Kf57xcE}T#p~SS8KCtU3J>O9hC#6QR#M51CPyMW>6Iv zD-dc}!nLL%p+;e+9r{AAjapnrP)o&PH4SWkV*6*y(C!`h((>zI{bnHNAD8k92Qq7uwu? z>&E8f@hlT}r!H*ND~!c~lmhKpquIV@E}LP-!xTt27yhI>D9-yM3dcU?aIXh!K7>!a zm>WEBB*_acrRXn#Xoz2M2W#cE(x(Js(Z^j}CMgLu#C4_vMp*W)JS0`ty(Z``O4U0W zx=035=LNVftA>}fmp8hK-C}(ks+NHZgSg$Jvy=TRKsWRpv<^RXpF7-U1gEgON4WPX z7Fy*_*wRX|(p58mNx2wHb%rR!=O?G_aG=TTsMvuFMU|cy0=1l)C@b=I1Mq3>&A;<) zTKDyx&zou(a@Y1+O}k21!5a$~%w6MQ8GOAZ12{OjiKSYzB=0Zk9Bx-Zl!%+>CaXiS zX6#-_c0FRkWZa%(Q(Ea65ZNgLh~!{q1k`Tqe^@>ePceR0UV1VKMJ841s*QVDbBWQp>d82d#xa3cgSV7F(Shy{byfIw=|<7HT3`HM{gmtNan^S zX}USXSYW@MMGrMm4h|TIac!uU#pVjf)7W8ZeM2`Fc{@~$(6X{bQ z4IOy-fnfd%5k*4p6D+YV_BF1DkCLYTZ&!3V&~GTj>&uMlH#?pzU03G&s6Zra$MFC; zwZynLQXtzSq|ZY*f06c;i3+i$(_kvtiKQ(QfJr)3?D30XC&&Epv)^DM7;vty9044{T z4;sH)w$uBR;st#*F8<*_re@7{#GA?|iYK%6Px zZK0QtLP&Mr>+LH`HaZanDx|gulsB);RV+jTU&B9s#v-hV7s|(wZ>9`ND;*d+1NL<+ zp$YM-4v%9DUo`C`ULohlL~IZ7oz1y6@|-=o{?z~ffvKx30zq?l<&hS1#hEKp^*6sr?*n#svU(#y`W5_&h z_#{2VI(U1+4dfNEV$@oTZ$MTOW5d+6XZv}#@=#(2B$8I)&)ZTlR}=9T0qhxX6&j$c z8dBmE(VJwi;LnOpLa21&tXeP>*VB2ZLY$N6P(kNv5_({KF1#qY^G~R4q^iaU3?xDm zJ#j6L=U6LCfgBR8v0+!%Th&ORF>&=FY@bXwGZ`!_tdtGUo8{xDdhM}2uVXP;WDyTl zwt4~(h66?eW*A|G6w<%uXYzrkI`;3=>2_SQ{!WWx zH}&Ts$7QpS-)txvu~N7%o1nzG+kCoD(JdOpI8Nn$y|xU+bRJdNZw)4S9KwyCo0ifA zD(UB@Ja^jjQuY5RGLRvn@7PEFUC3|`BC(5B)$9Hrg;T${;Yv`HYBCWitvgtbP=2n# zF7W@b$*abSO8X8VJ25dSFzajUE7W<^d5oHN*2IKK4T%d96@)BEIS}HIfyrU4XWncz z@S39klWe>54var64kN1$$*{Y*JbM-DIU?8D#f$@zfq~d_sp}q-T{ev~_%0b*4Qfvt zkGa5Y)gy+eQh6`>RN_YV9C>eAn@$2mZMG{qQ-SJW*)BWCL9wutF&#a=o8Ugad zFVprZEswfQj{{Fs@7ojn_VMNQes5`^{qW@n^6-4O!96&BePItQZNG#4fSd-eq19IJ z252Tx?5mDy%D=lii7(7rmyb z1>xaw@{f&!@5gi2;|~Z7j98ah#@?ROIz?f7X+|a_QCBmm?^`Bd>9|S(XR}_LE2zGz z=ktcQpUfD8Hbym=Lv`ze!!Ujv@z8;N5j$;YeQ!`=9b!Myk?yp4VSX=d1r z^eTtmQo2X~SLWe8j|OrV4^svU-YpxpjA3J5ZMvQsW?NHWo^;Je(_;4!9p)!(V^&X*Rysa%ImLL4>v{&#{WjoQ`F#eY z_)X-7EYB%A4mkSp@?y-l=tKTui=xr5-^QcxS}g?31wueIry`4fik$}m4>T0b}}rg^C2cx0+k_l;M#&oq~U2Wg;`>^;^PnFfseZ4(s zLVX>SSWH~-)BBeyTBgH0@IPf5qB%6=y75F&s?srCzYXQdIUb}@%&-+EHVdS1NWdc- zi;5r|anKB^0O`im)hAm~5y5)u_cCK%(aID=i!`~;qYiz&UzbZxtH(C1BmfCoy!^fP zO60m9U2XbWoD3k6@BI*}DsaSJt2m++cOCrTTI zld+r9oKuOg>*yF-Pmz6Cfemm+8;h}s;uAZQU~iE=tVX^PyvFcm8D%ffw=+cbD%_?(0;(N}J-D*Ew2F{#ea&fSXj@cAgUV9X0pS1z# zz$`avD&-`TsLdZ^+;W#|P`+@RAE80$2zQqBO++7qJian$GYa0S17C?&rK5;+PFoaT z^3)uNlRV+v!Rr`yMs3y;;H1v&l143YA)nKJ$J+J%g~zPHErDx};ouBD#^fQD?eEIw z;*i2^3$g!s_F%O0JK9Vqq(l_P>$r|3ATK{hf`ttqi}{uI^iS=io>#tXtCQkzZUSK0 ziJ>|hhe$9s1_AXMVAe8Y*JEu%wOa~u@j34vtKZbD_oRoyWUw7qX9_%KCEpx+(B5tQM@=A*n&|;uFLzc$D>j*1Hu7!+(lKD#Wh=cI`o*B|)S!vF;hop7r3P`y2bWdSqmaQvn}kv1BmmjZB7q6!jo7yf?X@FUT#ca(l$2w!K)51kfK`0f`WhVkZ*!>K{? zeXki*zBYFnrx_F#30P{=+=yu}8^|pDV;u5GJ3MoEB62p^Jt0 zGqP);e<>Gm>BTwEXvKlNP`>|w-X;z7X8D|Crw zuC*S2IsETr02CJSm6U`{n7BoOg(#w7rgrXvbb3rB@cnwDxwG{)${deIm8~ESi!vbq z0Z!ILxjlC?tbvAX12;m^0#H;Gyq%3AK~oV(nv5w$B1XV3>P!|wh_;UjKVw1esHmtt zdfcYye2klH*dlt)ZF2y$upW(76Rr#P&~0A!j2MNE;cQ=&r^M`kPQuLBe83z?KGvy| zQ*hGDADhjg#$W>Km>a=_RJsml(MNOei*lEPvC6V%ZRl1!r>J>tun*5|9F#9aCWuVr zXGl-bbBHYPF##!e%*HGSy`V&n__heKe+G<~_VNr{a}@0J>j~pjuk$?vw$d2zzhLkMeN&{3MN)YQ;ATIq#%EBWes2wO);O= zhKK=V>+BZGWqx|VRw$e64Lm0`s-2Ne>)e1NzMre$HTuH6Izp1lTrGUYfpX6ZRDNg2 zGE#9dn&$$#txZ^Ui(#-5Xu3Mo31CT2Dd-gLRM!3m;`UH;{acGv%9LQ$^7-dMJ$Ps4 z<}8!D%({PIxd|606O{I$9UAnE-9evWAuU5iZcE6{?<7gq8w?Y&_j~t@I2>8{U+B@y zPke1GtSyh{Wg5-Tu{qSaC^QgQCm*;7512r8DEVl_M^=qeGf4Qz`>5&>okz(=Z5whl z2=;F8C>xVpcrS}Pp5DlU7>`TfPT_rBoQ(FTwwpT+qyh}Nb1GFkV; zl4#GYV$+v_7cO=ZKTc);S@8UD!W z!NVoDZ7Ma~gVTnh&bvLtBKtT-cC!O>U^RiEtRiz@M#d4EV09)G-1HM!(J}yTNx2%+ z^NRWZe;0g7zQcTN)%S^GQSP~8$Yaw+s6mVI>p1`%{T0Kftl$a3Hb zv_UgP3J;;5g-tTz=x?{FUquG>a89YOS&*(!=$eW~xdF}w?n8~)_HX?LN-JA^N$y!= zo7EIe4w%jGxb~~-*q&FsuTUBqfr{5si-m&7&waM-l!svtkN|*ypBs;}v*dEri*(HX z#6JIOPL?+6FeKH@@-p4*kgR~4om5Tmja$Rc9^A0F93p{`7oQlT5J7DCFVg27E0>LmR@0b?e{6er7 zPFUGP>Sl7ZeN`w|gnuH&^C5R7WM#;?$Z%!Z{&gU=`e!i>U*>!>+1CtBPIeQt*;Vo; zKBCR=%zD=K>#h>l7zPViWw@7#K$d0G=6`@43dzbTh(R+3%BHiqDYg0F5kLi~4lAY3 zwmbJ(SH8Xh=coxjvV#3utb*%(fvUIRph&eN$`)R*K%;1>)&9@9J*4Mgsb@D!NL@2; z&UXses%yA0x#|(z>ZV$4@WAYswL@0aQx;JW?vWIHG7OEg#5Soi*9MIj_+lA2&m&AC z$B&<-T#TBSQjfUxAyli?qQo-5pprgz6|vdNKX2DkysY1ozYXc(raCx3DLh68Upgp} zBa6vot^}N_h0RtVyk2*KFY8)3$jF;Hku zK8|&tCWLCbn%ihkKpAGPz{H&-1F4aeMype9X`Ez59F^e5((97UJR%v!pBWI+093*w zw7~JHr6=uuFv-?2>>U7_!N+P99g8cSTFSceLGK=A1TZY+qWG)r^;YUNZ~MidimEPJ zhK*7MDgMTuoHdBFWd~63?^x9`nmO&G`W93=b7zF{1>^8=T+yD_ixwV|ecM*|Z>$^kjm*Xzy>~p}mue$OaCs#(?b`C4T3)rH~BF02S(LP)}MN%Gw?QKJPdw0w*JZJ8Tbzr7pQ+(dwVa8(c2iDYDC>MCG75Ooii9RG=i*pM1%U5X?{ zd_e-IwhUlb9BW%q_$6GV#Kl}iQRbhCMtXP994a6!$(FHkS-Zi}?OoMrI5LY)i7>j2Ih8> zluT%*p<9r+3_92aK9l0?s%Nh_s4yEtEEDOpzc&(Er9?XJ;THI2tAXo$nXkAq4#jF9 z-G42IK21Z7U6Y%#-;VoUS6IZ#p_r*OSg5hg`4TO@S z37^ra|1dRuq(#c6aT70Pqip~XAQw{P9$F1xj2$cr{0;%Ga_buPba;d$uZgur4!mtq z$Q7-Ese+MWMW63YoQPoaQ=gKQ;-Hn2!WYJ;IW_HP^Xrrcteo6 zRu+Q%7?W++^-k&iGEU*RHb?gH)Vh2_mL(A*%1OjOY-V7PXnK=OJZwI*gR5h+Ta+67 zR(sXc?6z0RdvU(OnpcfItLC4`6K#-v2Rvu0W92p%vG}c9H3FS|*UD8b&1zUcT?`F{RhGti^4aL{LvWv6eeMN%%%D)ef~JEQ_}PyGI0`nfZ`BbQfV+l(c5ss zDuhdODhrF>X0^YYDKSssuceC%4${yjz<1k1|7q@^WQ+S$@OU^WS5;Wpf$kh+tWi-B z*1~!X`YCuNQxHc6*us*MDJ+3W6VOm8DHY6#WS1uPY{{w=OX;kCSlEkCMcjH_O)qMm zV;{)(#GmMQyS*O}jUI8g7vdB~jzE7GLy{DS^gxe(*tdf4NDl8G_3mBmWO*5w3>EnV z00-A$rg4}EHcNx`1n?&Ckq&entBQ)cJDF0I$+s)9Zw$fmIwCMyf}RRvm0$GgovpH% zzK!-J6bwmjFEcQJZ!Zop=787{AQou-nPX^;2o>1HX$ey(_C=o|wmS|s;FGYL>Um^# zl{fLjGkYO4aIHmw);}1a{I%*#U)Q>Qa9x~wI;^)~WB`vVM?r+vBm-63W1ExRoilv!oF&f%2R+1yjD zTCFlft_E%!t1OWsr|u)J*ZtIdBH^ZS25%Z1Q`s*e8FRyrsy=(>eQHDo2_Nml9f$tWTE3qH1jhQ?Z;XW2OC_R)Q;Lpcc zEgXN({~Fe9gZ0HO5YhW9f2|Rn6Ylp629+Nl+kJMCRdrV2s%c#WK*ij*6G^*WLxjV< zD2j=b0~_CjhRuO#eU5-T@bSzR7N6COV)0f?(@F}MS@^hhw60HRg==lR-ixKz{}I<7 z0LHG(G{g9|e=Qwkk)Jz+0ssL7>Es~~qw*LQm6wigFlYxI54S;#GCL}c#Md`&owZmP zVcYMqU+Imzl{#vNBFZcC5m0owH#ZLHDE(4VKI|o9Nl$M1SfJ%Ik|$Jovxngr4~cDc z5c8{>iv1AXsMK@t?b&^ad)@KZsLvf**-s2yFTdW;idHUYxA50V#vT;ML#4Xp(}zs` z5?2CT3N%*0;DPxB=+*_PfY8PIs4!LWam~2Gjx3{Jx;0AvXcu_qY$c3G`%u+*{(7Pn zWVp{ONDkfc{~EwP-DF#m_J`mFIs6hlGG<*E>f6TG7-FOOCVCm+UFjdk-W*ezt&|^m ztu88;P7MXWQXb3KEtA9Pb-DgRsCftnd_4`w(TkCW3;`HwR1*Wgvh!r9|`8*@Lw+?s0=8L&?}wqPvFV?4xn`EGBG^w9&n2Y01=?!y_A9bKPhGZp3kI)ge9m|JPu+X79Ee6NFroV%^g#$6-n`1a>Y5{0 zxn$ucPRs;ykMee?zvLk{1-K5qfno|B9)GZ&jzc0Lyr0%R?W_;qy#I~2&0H$%PSY!^ zKdrI3t#b&Cx#@hkbD)N{iy}-$I3yisvU>3Gvhh!^42>nY$g67OG^0qSSl#RPBb3yy z3PJatV}X3iV%1=)PxgphC!mIkolwleh{15ijt4WesZIFLH?o5+-_0Iv4-Gaje^7^0 z;&o!NRj4V@{{Tfmy1!)sRI!&UCR8_k46yVC;pnds6M2+(LB$7^&KP|@WPaEq?o#G- z=}=?n$+o`~v@`N32q-ceNKUm+rc-O-F0rM)t}#DQTMnccnLKkjcX77J|2~4)Y@<-@ zYB$H^@|xmyikHU%HxyPIy#*13xx%V*Q==&N%SkvM-3`NNz;R!;2||3v@;?X3EVNd^ zEVGDy$CJicB6YZ`IT%S9)qYxKl3yI_@^}inFoiqJn_#6d{q=2pczYxzwmXml3khYU zf3Iu~{c3cR+e>t#GBP(9da3q3NjKb+u|F4ZB#DEDuywn*bD&rB=Fhp zWb33{b6)xq`KBg;Th3DuX^o|XHW7rizBO!(Us*|~%>&eEOq zq5@<4#&_Ev@V)do(Q-_HyJFkt1DDvG@Wr{cHOm$CIhX5acjmcIIkp`78_=+Og9{<{ zyfeoO9-j>?y_Q{+yyXC~Bx0=Eg-q*)GnM+U4c!zihO)1HgO%MwzJO?ZB?LD8D4V9f z@8OvF;+KjS3g9hvuQp>pcH1Ia>6sh}hVWY|qL}1W6Az9EQ-C1`2giS8Y&-;kM1TQ0 z0136uO}XdokCl*S+H;QAwuLTk614R@kCA)jADyP-O< zZm;@hUVjbojX8?6L3IW91D=`2w;|({@}+ZEPwd>9KD9GJtNjRN`9?foK?#2Jd7se3y=J6CsNJU72luanY zj6Bj&aw8%Z3Po(3qFF^M{}ZPVv$U>P%+%n$KRV9nTW<8!auXM;wDw#SOs57rY3pQr zcFz6q;$Ut@kY9`k(YOnP2rLZnQRzGCv_jTgnO$^q|Z_Vn%`v~xw8$i&g)#*?M-X#3pxKr)n zSues`M-k5FWlKm8SpK@%MBqV;nm5RZs_6dj0<&~K;wZW=XYE3#yBl)Sgg@g@S1mN% zDNq?7_Hv!?Ub!N1o||J|E4jN@u`1Zy$)0kxwphr1SS!)%IfYk$evX}~`iNPEKZfIZ zO1NDx$E<=H$u*FadU{Z`iPq>lH|D>(7yBGgMnj)5B{=d5Y_w&xRMOhVKy6)5sKqa> zrLN|N|914dH8cfyf$MoSr4t}T#4yXuKSX*G&Ee(V-HExVTP+MTc8Y>RW{GMxUnSg$<_>etPE zCVMJn)8BG>&i=V4u+T@)?X7_JjdBaXQ4`n#grYTpI0;+vjb$}@eQjN6De6?L&reFb zI?#$qOi{U;RlAteA+%I*l6+?`UBcWRgbY9c1`HqB3kO#4oq)KrHs1v3y40--yv|%LD3o2^8uYrLof9##$4j9 z4VC_b>c;-DoY=wdmuvKgAG-+}-%{OT2{s3L3Cl&pVo#&yzuu$$hNCURfk+JKtV#>; zD*VrUzJS#Fk8bE%)N;L%FQ3O`18Z))k8{6-y)S;_fA4;$>*^X4AoRzO3DA>^yvIt? z)uyf%=1m$Io@HxbT28deI=ErDj1U;y52?l);M$8@^Hw*W$Xrx=bFlZ_k~E5)u#K6_~Urz<41K6%3n77jBKERAE?D|n41wq>w3 zs7P1Jt9m^rt}f9z3^rs6ZaX(rWn#D45dG?ruXjiYrMvYmHDh@@Y%9oE7L#xkwzivS zOuJqq&3&By4*Fm$j;PQ%@gaYaUD)(ionsg-wZ{8)&3y#8ieJALo(|&Mvh~~fB&bon zqV1lCzZ)r5TwlRD0jV&AKXPO!lI0@oDXkcRT5Hqfy7}QJ3+|Gz)HOp-(*pN7EAqTi^u`z4VM_E#@vulR`R(J1H;UN_k$$+Qd{m_Oel<)zj5 z)4O12ZmzpU(j@2An0FVpq0alvxpo^-mP6c-T(MT&ZgC;2L0IQgKcSd?$*_XtB~Qa@ zO)vmFP%F89wbZOIGQFdiBFCC1xy_0jCiH}(VeL9s!cBqJLw0-7Z^4mKTm4%%1IGvx zJhe)6b&eZun!ok_r+FKH_iDzlS+c8Tk+$v1c(^-PS+~nBD!Q?7;w#a%R$i`f^EV^1 zFhY3X3X$d=P`D-rEN@5fdO~RHgg$>yOGvZN$KzHit1l+5FEILTmpe{5k8yb{1FIjn z+)AOC6i)zFAR#&Ue8bOI3}{oguN#G8c)O|%3= zLX$>Q+NZ5|;iwD{_&LFFmvy8LcSvj6P6cQxwHt7Lx zTCX4b6VU?r!=vvqjoF^RkekfR%E@fHjpU|<#}9p({`Uq)41M)>$aHnp%yz#}{k&c4 zA}Fn`=KrY{xu4ZMEw_xQdmPc`7|DH`9rDSt(Oj=%Uh_)OdxJP6>1T3GhBpQqGFANf z;!>Rhq(9gc45pF56KkB(8PC<{G#0&+D7K%!D%dA{M`o>dQdFrtgFt_`Hku0flzm3W z*%5U@hM&C!npH|{YBK&WWc5BP5-ZWET1pfQ#C~(NLI#ctsCY<$?Ctdxc`^fm zSQxk7oDYnA$G}}zd;a|oNQC^Ep5<29XLy=&8iF6*>ChY`NOo_P{$q03E`>yhTor@R zGP%LZJjbM}Jr*!}&ykQnv%v?y^QYI}p8rng)(Jwk?2~+{{Nd@TBwqaG^UzzY@|g4K zBHepq)x#%NS78DJ$YSDtq?WzLeAGj(#;qKNIAnfe4@H&9u%YE+tDLt;?dqh`qJ=VT zf!zEx&((oOXG9v_UZu+HB9k-K1T2B`9-LM}w8sUe&{E34(Kh3wk}W% zx%SC}h(0_9+}LG3NuIuG(88LDV9Zxn#VeHlNQDJd;-=$d_93Y!G_jTthQ}jRZzQJ{ zaB(P6rs`83eme0_vMf{Iemfqcv_wQ@-R{NCEfhX;Pah75MO0V{%`H|+W@4|2$k$w5 zk&d>e%uhg;QMl(%(hqDs&4%7Juak|)^u0eEM=Jm*j7WVP(UKLTA$GkzTD|11;W-Re zWsW+&y^?OWQ-N~E;L*WneHJ}5GX|4z@h?OLEQs>f6g@utD$*+=&Yedb-+V>PmLjsU z|GHL`E3z2l`b;tI5rTc?~h0S-i~1mMY0&c9xSRUdI|Z^8IuK_YR~`V()hT2gNLE zL?JxME6k2O;M?^3@D;O%hh{GSHxk)r)fkZ`E=KHehp0r3czhXQ(hndW1;8_Olt5VF z5>H!4FlgFD?Vs0X6J8Ov`g$Ilhifl;8s4BO<2{3Y|HJuP7f_b ze}>%0HgxG(FN~HT+qk}<`Th?}R?*Kn!b;_w&GC73QsmasG~3Ft>6)1X;P+w@Mhnt|}!)e7jL#iXxg zSE?wEqYh}0$T~5?>tS0yro)+%XB9RQS2yD`@?`s*3-Fzy)Z%=%P+(P8ewfei?c&(PPi zk1%wr1;#Heb{X>5Byhcqo_Q2oYv)xw@V}xQ6NvE~MDBw!O~R&{bk>vXCsVSN zQ{NO)WAYAVjc(W1Rk8WbDPQ7;GU`qV4SzlxkQF-V%D6Alb^e+?gQTL`R(cMqm2d`^ zeiMy*pZ$G^UEZ^iueffhuXj7*k({;5vOq5)VWdr>-bmHo^1bEVsP9~YgX z>v~Vctv${w9cvNffxI{GF7&QLz2?R@FQ)<3xL&FF`qt7?kKGWc5Ky-Dc8E&b{Q|=c zNQazKyw_prmB-e9R8?%o7ya=phZUxDe=rgqKgF>^%VhX^izzPxNR8mYbUGpH4nAFt z%hlBwp4I*w8+Sbi~!Fpn>4`bPpi}xE4I};awlHxsgNjzyh_=w z!(2MeEw;`8A*<(%ZDDnYNJEy}A|$FxtdJMCIAyQ@Mw~T9eAFZxRL3?&?QlY~taECn zhdn&k153{s-sQuFK@Z7ef67S$6{14g(ne@(kz|l`cnizDqbDVbN`vZ|?{Jc?NiLsG z%mH4?3;i2y-A~w56qfwwQome}&|_6yK*$M$`AD{phr$#z#|&H}@2I}N71~^=hN4z3 zq7g!;t%Z0Zu`r`yK;Vbwr?kLUZij(gZoh7|8bEA2>-0P~%l5KWPH>XX5aW?ZJRx7W z2Bs)(Nv1>R^c)|;4)qEPA9^ki!2&`Xmwfi>AR)#pJRu>W`ltEO5N|w~O;nmGqvSsv zR0s*aj*A5zmMt~i@2tQRNIB_KXOp2THMc0QeJKcFqeS^J_RPsMF~hOP=sSBDCXXKm zcVkHU03Tda-ck4*8^^B!nDzZ@5{2DX$kP#3VNQkVZ@N)fMU8mAbMowYsy%CCm-}vB zAI+Nz0WRLI1R5BRISJco$(VuFfN-%5{lL6ocFGVyQ%jH$V6Gbrr+Vj1fclHz4rZ2r+0Z zL$JCRd_iP1Bh~BwvDHa~)!{ofhk>#nN#r@GI}K=yA|v)m4LYS4x%|fDodw&8(U!m- zHGpjHr7_1>XE|0x3vBCG8S0X@C5;`dJ(1uA()t_a&L$<<*rE<15{AK z|9tDc(3j`Q#&%1e^0dyt6cmfyetj$*pZipj5Xq056qU>jQ8HLT?Z`1z8e-&|shg~F zc(ZJZTBg2;ru^JvLtbV5@69jY#>vb-7CP6p^kmQDyEoh=xnLB^v>=%a$(-AVtO;+r3Pc+;5E+fCw!(IzM> z8a}G=lOfdsLPzjWVbnjV`gP9Ic>hKe&P_fROG!YOoK6>I6MTp346CSVaw#0$KHor0 z1}qsqNa*_>%KU_#xbNxPfe;`7mrCCP=hE zRgw3*JBDNB@U*1j)++tSsbar2Cvzs(4iHB#LW*ZcxKR+jlrbyfHTrDWT|#OF_2gBI^T9mwvYZ;8?oQSpwWfB zZ#U#I0kmwB-MJ)-FPk-a@$b#>oU(;|*p_5Q1!2Eing5R?FpqN>=*2(qWu>Zs(9W;K zN~UoA$GDjm6 z*1wX&-QRP z!xtWzzAo8I%uOur2&x!=ko7@Dzrc^<-IRpeUU!gKXZk??L1W1uDny~ua#k+WFbEIB zelaHuqMGYe&rr_TX>s|Gubp7zFpYYdVfHiU69}m!pFqv{sab4vwheyYN$nx1()!*i zC+0V6Bj6XLi{QZ5a=Q~sUO>6`0%AwH3^h(yXiFwu_%y*QrEED@;$8iymZR@l3IUH* zWL?t3uJ~pL-5-`@RJwo1QH2mhvfY4Nr2G>5s4(RMa*}(6SHS>zFk^~md&Zl_aqeiG zSCY5r6_;ji=M-ANF|Tj9K1+ieQ>GhsP9Dq-Nj^oN%X3J7<$S=WoTR9jR-?5>V~dHy zXrurTvf+j_8axC`tJM_nT8aFWio{i7sN1IBEXr%T9JyUra) z9QQR8;E4KjiC}%pin@7AUam=Hn1hlOTlsx}#}28u{9eDkP9*T@1FfoSY(KK3aO}Q_ zcbWktcCA_pkctQiE{VHaR;5$xpYq`3U5O@9ybdTsj$J*qh#Jtv1%`La)Pom_Wr$V=$$p!OWe)fu&ph@X|h z?=e5xd)oV*GG=7%Y!cqp0PPr(|4%|^^GE!ZYbj|jI-u!QC*vuH&G zOO7q*-bbKzqB}vbWn$N)oy08F^%R(oh>g-z;fhy2kqtM#A+!%g>srlBcij7|p5$k7 zC1l|~tSl4#YGN%mJtm`_qp2rN>j z6anxMQI=iughernhb0FcDO{BMEixlzJxPXW5t3{P@~MnvRYL94**jr>(b^`DH7pM* zXMnXq+lZDpPTIl5$GvM9GE$oEe2qlR7{hWHiwQV9xQD9+|IbymGCfA=_(2vq^1iMs zFbkmBpbeX6&F=?>O9vV~cvD<6G0qY)kK1N68`4hgdJ6^)DR+dOxRHsR=WRZ3GH8fZ zgwJHrZnVW+EF=8)zv{~j&7B`9a`>$gJ>0RcreP?Te>S;Q$K!fsUayF$%LQY|G?`>; z{v|!HxYc7-{dOgWQZ?SQ?cGNhI&Zn)_U*1dUT&!iYBvDbU*8YI7iMw+y!v*za(|$g zMqPx=&lJMz+YZ+1zd4V67y5;6<-+yuRwt+D{)SIz;+?Gw%#6?r{xVV*To~r6by*ED z@-|ISA|O*NRxE?mDaF;%M#t|moY?YBT8~IMb6?j>J3F7l-ztAXIj6jyE~ne%slsN z&a+C{S`5!upy}h2Mz54n?~!+?66Qn_h&FT&+kQKd`!rh{FRdw}z{9Q3IVWNBI zdNjogspCMrrDq5l3y-xs?83U1Yrcd{_q<32r$P}&{B&+JYfR8NC$zfv z9pkxZRX3+J-KX^2QV?>7AuOS6j>Q1qWAXh!+JAgu@u2>H-c?<};zK3YaEdxOOooR` zAAdg6BzS%`v$>w-q(zVZ(X|@F7M`2!Og8*fndj{ej3-WR+M^5JFhh2N|P>%N6DtdRgpnN@GJYrQ-p^uKO zhr(*{%YQ+(LNk#@i(3G(7`a6-)PQ7-<2Xq2Kb(>QA2EyJoD#39?OeT;x3vLDVWxP7 zzC2^WcfI}9WsZ-9rMoum9vTS%oYU$tugc!yjqT!ju73J{q5<%u?^kaQhlb2)?GOF@ z?rAfMh{C)(Gr{~-OVR>)3EoJHZT7#=fFKCbD{gGMtH=j&){E`QUpzm%57i#K_|m9= zq&VK*rym`I(m*XLDZca+7F;9(5|^d*I29fq=8hJ^PV$TIZohFRgt}AElFVF{e&Ui4 z-M#m~<8yg_L5Ko`#v|6+$-{J+&E&ic3q*gpp{SsEGWk+e*OE>w*dMfX=ZLC zbxxhZKs&lE9?hdAiGH%`Nz7ytigh^eqp`~Sf0@qf*RbgZdk-!csyZg=X;2L&4&s69 zarTBlC_Pkqxm;A((4Z?5cDbX2Z_Q?QqRc1rgm&LX<+NyI9u(2*fsThjxweVi`tX@} z8ZPQ!tm|(-e9fhF2ckpW%t%dA-VmVk>~fvS$WkK{n~my}6z@TKZ~XF_h4e~Iim z9|M0HhF28K|%B{$2vdBwQ+{RKg*d8BEm-W2C#ongl;*g9%^pv`2{j;h7 z`Ee$uaKBS~Ghy4yC)l<+HIAOuR)+nYEW$0NDex2v+%VByQ>KeGQd3tOiuPJ^#JG>mc5@2 zsoMeibb6wdc*eQx2H{;u(EPv06i^xiNDP7iZB9x~Kp=Bj6avrUYcfGYBDm>k;>2JD zN{wN8`9IJ{#bg6w;%7UWub)C4+O?-WQ_N-E=U+|ik_z?i;JMZ@viF^{$c7_H<2Et7 zD4cv-yV3D0iIg<8AO494!?yO#>Ip{ODFE)+_>GK*mQ&Sv%l=!vjBfR*Aj(cY$idlz zR7sV~y7mS`XLNV$dEf-68os?exDC`Ku}~xJJSw-X396rp0^&IFojLrd_^IgIRO300 zr^3|ro$R=A?;jlP^}1UYpGM_=txuWPcq4X6WQ*+PV835&h zn~}NecFyfmR4)9|#qW$R<&-#5@0!-J6l zB&A@UsC+9ofK&*mI{ahfJcN0}fXY-b4SLq)*AgmlVeS*!#hjZ)fibWjjFj)qkU8hF0Uj^u@%0{P6!j=S($x>m>hHVG0!f;7VMe=^w2ZDE2ROYPcg1M5t^PLkg7uGVKgxrHjsKvxB8XDlq!r)o zzQ8;WPg{NI&Q~{bcAZ* zixkAk@A1zd8#A#dds$_64bl;W{ibY)@E#j{ii20nrv3DV+3CV~NDV3DMrdfHPYsl7{*nXmJ z9i;G&zRlP8PK^Zr2QAF+Z%!W=?10X;(y1OAG^fcYX&?J4fO75+)SNf8xt)aL_=Zsx zXGC89zFNmrBUjm#`{j;>H~kNzKE)G?#CK5-8-jyo{}OmVf86iW0nx+gzB*VP88?m= z?Gkq(`K=00^ir{h2KTKQux|LiTWPHk2Se737O#0D;}8-wf0hMRubXFpxw>Rbh4dM}|HU z=F84d7-Qm4=b-KGCS%5cKk93=Ipd=7mtb#mT$ijkI^DmH(@18H!gq>&qGze^#&xWmODtvTqgM7d@oDwTN$S2bwQb4u4R?f)UPC%@#Se{c03Qa0WBwM8yb@Y}v|27JoF_(P3OcQBX=I>&~ z`j|(>Eo@~U6MgrE4I~8fr$_b{MDf}KG@CSE&G#9@)JBb=Lwm{i{HoJRDcWijhQR=x z%opRPfwQ+~(M`t%56l5;)FC5zI0AHmBqjprAu}a1zb0pmXXXkM1n_3W(`4Ykj0H;> zccOrekA6KR<-u%UV^~jq`gRxG^V`2f!Xlo{H7Y-nk7H7hEpnXksp4{-y!$FV9H%=S z2(#I2yu-Sfev{v5&gK@%rFVOEhD!0It{i6$W08|spK$B`@W01`fX={!$I`MoLPT9o zf712a{gZ9Sdnpraz?W;Zbh8Aj8LqamP$-4~1h^Z4PY(zaM49Oj#8&>z!1bFxXMWAY z&|KwRUTk8>K~7n&>mLWlQhMM--Jc3u+WRh~D$KNPK}mi88QN@8Ia_=+%OWH_5R+pX z96-M>4HMU&Wn!X$Zf>H^KjtVr4eqwk`rN4JkQQ>G`LL6=R#um$+x{Z?i0`xq%;ut_ zr(~HMO?udg+;f**g7j+V!=il)JpIMJ`|+dKOaSvSgKT=u`ffIeI~}9Vfy40jjyQfyB2C$>1g$z>db>M^LM4d?m^@}!6e zNh3zcQ~D0}wBvXiGcvVSScg+O_m* z2+B56b_<&GA0BS!e3^9#kWtgD+i(#ETVRHCQx+U;JiZrbIGhx4wl$tjmJz=^XZ3HX z8E)^rXK%`nEn|e>?tA@vD7HrHd|KU7e9SUL<^A0UDv0ZYGLBCHJm!38Aqc10=%617K}o&)YXb35Wj#P07|f)8rz=fTzXkw0HS zE6x1)>bM$$2m#%wC3hkqKyo!dz38?sw$3ZF5)RH zb$Vd}g|O98fwI1k!A?yoezY$y_o7JhzCH}Af>)&UAErD(VuEXl$^Em@!?(Xz&y|`{ z>aVZr<|w|HM%Gps6V;=W)F!L{%rfsejS^Z4%9bn+1$AbvINKvF9QsrQP%|*5mos3J zY8x%s%Y1b(uB{-Ds5w|J%C9XThsUUuN4P$@@1-hROOy&SG{bg{h_+z)>qXjul!#5C zO$!8Pj5!OWlGNdi=1NpO_WAiMA&*!`{`d+R)1t;Yr#LSwNLjXc@I`x_uA~& z&wli-L^|0Mbz-k6VH~`6ykaS^q1))j9W5SttWIAt*n6br(}6rovh%~LeO6%u zlqP%Scuq^hJumK_jzu4Lm2%Lh?B_ZUAyzQA>NuOULV?tNA^;f|nbVQEr2-MGuyr%` zC2bF%#E4#6%zlIGH<^M^@pztJy^mYu$#_kgMk!d;=xU(ZQ5hQ3V*j&|H%+998j`!G{@R7%d+3UdKbW&T;*HWbUXDglj z@T+}I$mZyMK5xuWKM-4`S?7Mb()5RW%M1~*jgt((%Q+d^t+%rM#LmY;_DJ^IcBY<^ z=W8x1X%M?bKjxl!%VNI{2_9#H+5H#mVw7EAGIx8X z5l+E)R4kTCQ{hET!Qz*~;p7m5Bk4EEj7@GZWdgXt zDl38hbH|W4)oL&Yp#x6+JDqp>2akY{JcECp*$Kw6A*)+77wozq^_`CagDbM=w{tb< z2Aj6(zA{_zrb8CF?|6zM7C z16?l$q%HR5l!wMH*Ve%cgYJvo_-dqy8!yI80XL?893zBY8E zkLnwlID^bboPzoHP0WQJTOshZ#Er%2FbPdF;pcFQB+B8rJIcBJeg)!Z0B1tZZZBff za{!vA$rCg)KixB3G{2B3x*lJ_Z^n+VJm?ii%67yd;OCZ-NQ!3u%6IzgbT-v_v*YQG zJ+For;UEAC;Bu`v+4RMo;gL-U426qoa@k`S2W-;0HVTX~Kl7~P=y74?udV-fuOK5m zJ$#~BbWdsU(zng0$m*gdtEzqlr-2DK$wKyE=5o6BG$je=n*9rXA3_i9gNR04UU{Ox z(rRVaTw|$e<31?K6J%FMZtk1kKvWZJ-Br`2!Q0dS-R@RcOd~%T?Tmp1CRU+KZy>-+ z`ji>-S*PJJj_*_#Vl26ui2ut4Wf72#eSGjY;vqXF+SlHfXtGM)&+0-(e% zSv68}P)lM?FBJwwOT%Hhui0l}AW#E7cNnCe9A^_>=|m#1%C_eQUrXsjrZ#j#axp^}Y{T85DSiqf& zffoX}6hZ(yhc0a@V)S&)6$PnlO0@`wE|DpnXw?$P5v!gxnwb+V{Or5J+Brzkg!nnY z|9(4STY-3dg~dR{vU-+f>U%c7`}UjXj$HUQ%DzJAYX)b{;a025ZtuT(L6}DhxIKTvuqB#FXD6!1$78hMELD1OU!kE z5Ys$)u=VoXEj-$L5#KVho54v(-2##r%+I)z^ISsI>E|4u>Tp{=?X|~%NZa1&X$w$` zv$LJc{54sRHDW;!f_+l*O;fbz)jYU_VrtO*ml^l^StKfY%2l{wuEwtw5zK9jX`?+( zwI>?Jo;a}h@0(h86|^CFfjz8=n?B}}NbU*0%OX?B*{J;GCU<$U&*mOXZ{DC8*mi<< z7t3aNaS(RmzD1ln2pOsVPdC@*xym*h#bb>uf#Zm2nBHoXsguLA*PSS*h}NM#jVN!x zyq_m&1fkoR!2b30BthIJm&&G{)x(V|@dg5ioYA{c{_etD#4?oW6DxmG_a`Vbs9alI zt=QW0x4($*gQ0SkQzI_{Jgd;Ef!JA^X zub<@(?V+avvN)`y^!ENp-p%?pxE?>S+o9BAF0(@uY*6>GYPZcQNZ3-C#?@;| z(51;pv4FROn3A&~VS~Q=3V6U^7x6< zcT`FV%*wJIlqHW7Z8lCkYk>yI7^{?yiuRFl8yXXFtEQqi1b>)9*$KWjB(kx z!S+qAQnZVS*p+&jYWe6kQQzho1OOC(6aioZb$h9b7)4*?tVv0f&bP!BP6(kaSB{A; zeij~6kq5Wfx2U;T7h{#7zLbev7az7)dc9_Zby0{T|Hhx~LVWs{ zp_R)S3hLf=X^hpmap7-qcYEJkio?Qa8C%4zx%RZCC5rvYRh1*%h^BI<8`dT%r(&BNqa%v;Q-*!xd0J*o8%?1zD%@83KPNl^6|7-Bn{iKtd3^t%(jU-=!4SBEkUEk!= zddfCZ)_E`kSRHeu2d7CVIJ^HEa`3>?7AkquNwN zAHe;;^T6EWH5Q6CC7mrTK2dDdM4qedvI3;i+Y=T&RBUN+-AAa0KA9Rk*9?M zW1E6+>~1uQo#-8>B2*raT1E0SBe{BGFD(t2iHaDlI}i@wA&~pf=N-zCR`NiP| z7nQDZ&Ojk!u8g3FErR3HiP>6EKNiZWWocJQ^kG~I(?BPqkpZ(zHf82%YL-kig_N4{hdp<{6jm(=~U`+mbs`c zOJXt@getV><+iB;0vlVD=lTf^e`O=TP8lHz?p_sI^+~*!OC&m$mgxv*=RY+@Xm(it z`4SQp=vX!RlgEfjY5H<}_H9bHvt53XAp<6SN>_gq(0n#l^&_!yxknw>W(67u&I_~M z)8&V?RSN#^@^Elt(s^$uS5Bipj9OUcFtsG5hUke-xo1Tsh{cB#UReiJfqsNR${g#xmK)83A?_)Qct4i!Trg7M3%p7$(1zkT z9g%UEeyLRC+Pk=^S7vD!TohJpy!T(#DGMtEdNS8Xc^O{nl_2(4@q_A8my7JJw zyRnM-#oEUl40daq%31{L4uOROexBHqJgk=t6I-Vj#gOLy+4C?MGpjZgu1kIew=uZNPY6J_1C+%0+yDp3v)MqFsl(ZI(chsiF8Z`jNABqK0IJy#)4@UP;_-#l)s zP`I0g$*85U`>7b46hVC6`sQw8arTOINsN|GY_>7mCPsvG#zO-0Uf1BhU!7MR-C8#y z@!*JUX=9q7Qo=VG9@Mli@IFI}G(p_bI!9)$UrVk%U&I4b#oc39#7mOr@SiSrC?@s& zucH{g`EwW9ou70YP{VW-k7=g?FtQOo>Bhikz)YtGs>|@#VnDiQNw+i0nLTxaEn-#$C$^Vi z)PV*&zhvsb?;&Y{c@f6`l(Aj!^f^Mu$+r$T^j4IuxS~3Vf=#qdE9K@PARiw(CDa0S+W zFwoLS`k7RT`vM5N0GE6y7`I{v&U6jm19`p~AcJCvJz>fs2C0+jxnM=ErajnPa5^PO z0)N&rzl5BAg!fsYVvm!)L^eB0uNS|k?Wpl=3+xxfA+KRFN*`NRkuTh8nuxsSKs_~> zY7&wRI>-jC5^#WRv9qTMPJL{5zOS;B&R@bAfz#>Xg@FTp>MlOE!K&%Kq)ip5uP0_% zfft&+&9W*&1CAV!eT%(Z){a-6)++L!_%ZI$VIiisJhn}FdUh-ODy6i4)~T01L#ExA z4ELL_Qj!y{SF7IDZGn1R1$zp>_=;~IKc-fa0I3*%`gS^r$JLu_YbIj%^xERI^oDk( zV+yU%E;*&qUqBTSZCgN$3|M3z({1nwn|dH$OL1UZu_>9YS9sRPE*=aaf~&|j2L7;h z%`7iu07S{;+aptTkiqy+ai9@FJe@Z5BLcp(Pmq;*MTk|@cr$oNnlx?+#u2Kh#va^Y z{_b{$+i0`H0)b;t;BUQ#C6LYV^mP)(#eEA!6IkIe>3D>4z3Y*qG}#muzLmt1>7o8s zd!0U5tXOvSCA+}MUK^fPGH>xX=L_3;M2nCKjjX3i+9vTAl?2JAxLF#k7Zsh`y z1TM3HR(KD!2!E60NUN6;1R5&Ex3C{NeGWy!-K*aBwGWSseK={qh%${Ay@7gQbB=B; zh2CS_7~HJA?ti=2)X@}jtt8m3M2^C;*=U(l+RkEJMXWtz#6!dZBi@C!UVLCBqz8MU z-*+pD%V#gk~eVR~9BzXIyW*f>qL5p@o4IAk#UjYs}7%g>fF3=i|`KfU9gs4M5>|H$}> z30LW%)D+Lv(x@)IVy}%)UqeRCEj6s6GwNJ9*3<=|ThY&pU#=ksvYWr{IX@J*WrIXQ zBHP&M4Ig;C9xNMp`0aG!L7YOmL2$|*M3l}4*%=4WrtXO*&xH?X4jwBgvy>CVN)|LaO;=@B?GnlECAZifGQer zaJ`z?cmYlgvx^m)bnoJYMFRwXPT5BT#8YYC8B zxI8+fGY*4!30yMKOZ{SsoIQIHPR6u{YGqs2)}FlI;j72s(BOME-HP-c#bjS=i{q(R z@(pZzRH0(<*DHHTLD8?saiV(#&6XI2I!!XUaYyYl;;3a$E8}K{MLRQkmvPzKvj>`D z%Dm-M^?JKU!yoKl+C=r!R;H!+=!rWjahQD7@_`JImVcehsrbYy<0wIp(N(8vLA^fQ z7w($jGEH<9EGRH->L1Z;8I!bAP?H0$^Gtz`xF9`!l;&>qT9`re$u8o%`LbZDY^iiC z-DDb8PoA$x?xZC;YBKB#?@-R2x6*EoKdt8QT2weHcVHdHZ1pf*0W=IJB7-g`n z0_gf5nm+0JI96Uw?^D_;t=?+Kw?eVMJM9xp^A%;esx5go=I5hBDFH01; zit`I2BOMC!JIeX<6g%Yr;h|o?v#rE;VawO=1KK5}t>t`a8a%H&>f*~Vk!jj0{lZ<& zwX7BuB!lPQ4iDObqQzd9E9v-Y8-_H9-C3M%Y6gWA;&JSbof%4Z045mDTpE-pYjZo3 zX80N}uzY`462gK5751nZ60NXnd2Zko*>&atN+f+PanD5cOvC~qezC`X!ai=D-2mp~ zvvhe{0n+kmwcIqaNqjV?( zKTYE}2M#GqAe0RV|I33ocuj7B>jq$*IwyC2{1y${zPy;OL?di3cN0=}l>U*FBE zE-E1ie;G{FdI2E&Oy-ju#l%VAkhYP=>|J)z|$tn)B-uzWW zxcHCd8?=BYi|jUUQTGvXehB0VO%<3<$s7mA$k%F^tf{KP-j&I6^TSFiyNZ1$E%?;Y z&dP`*={0$U_;`=@SJY8zgujFmxvCObzp^GuAx1gENbk=X=9dPmW*$kE z0$wig=`h<$xqk8FzGV!l-91KfR2tD=aG*J~mC~f_f)oEbpeuwi?}p zSF$})8QEwybL#vdRquJ`2K0Ypj<4D$l)QR36u>(*xVh=R=b~W-S|>IC8HIZG31Kb? zcOWrm5QvB!b7ND@D~YnBG1;Qio-D)3TOfg3p^M(eR>@fjj(xFCiv!(V^akfn6bu-4 ze~CNIzRn9R4Py#$+}WZ>dj>Jyt0tY7#(5k)Z7-B!zfuVdEFUK>s-iPhZ0!fK#;q{m zuuz}`h25LE!ULR`)CwWY_CVvITxTyP-Sn0$lTV5#d`W6=g1L^_HS(NS_#kly@=qlz zMG41^T?er`nqw;+rmgm#S8l!)mG8!8uZ!9%gQ%%s~D&yb{}L9noqofBxBQLghbECiMv z&p9}8`oxK!l5`GpG;;?5`^InKT>n6|MOiN7uD6C7XxH>QeYF*feFmcEDSDJcC&bi} zH=u#~eVF8)&C*ZUwa8W&Tg|(4k3MvGcoP}z%iY42-n~|onO&iYbGgaqVOR_RnZJ*% z3c>P~522kfgHM3Z>#|v2D%%UbKf;%44JQ}WwP-xJoobYo@W*XoKF*$z=&zuihedNj z^YY*OUeB*dm>4VD7dSJhNZoambr(6v5D(nQ$ohaU>gu@3_YBbK>-*SxA#0EfWfSaz z==WBa0z4f4cY2bsf1S2i#wnFH6JL4Y(>;MXx4es`Vbrzaq_Nbu;Ty|0oK)PdKD%Ms z>Zj)goMy7E9MJ7aO6}8xJ2Wbj)O?}jHw1r;kH^jrJWT^v7H(DY?Tz^N+HT{B^zEd_Ii>?tJ{iEhhr%V$q!8uV$FJP2Q z;E(-G-FqIYp{{WND6o^%8nrY|gQA5S@)TkH>NKUq%89i47G6+x)6As@3*aw1;U|xCYqz zzd80ROg}#tSk#SRD5@>8Q6TfeA;5DN=ta+mA5Rq%axW(;xhQnE7OodK2r=&ukYJdc zup_};JTihK8pus;9L_rwyukCCENVmLAuQZIO^bf#f-NfXO>x#59x;H&ejMp!>-mfi z*A_*`h`kx`{PJ%dM{uhQJ*bh7&qLN?zap@PrSc=#j-GdyK#Wj(c-1Xr ziYGgFYjjF|iPRA|~HT`d#SPVnY9!hVo6 z1F?nej&a0cA!hn>z5F%hcnPFO#&G{IE3<4+a8Z{Qr3>X%i_$Q{<`)?Fh@+CRpqHti z7fA!9T1$Qp2d9Y4b1s;999Cb6?1Trpr|(9ltGlX%Zq|ylj$uW~EgyeEQDwiY%fBK1 zZ<S_+uU;p1v#5D?}>@{O>VrMa@5o4{M{f8sn9s(?6P;$h4Y z;W~#vsm9w8ZX^xX8j>HeeB*{17NalzZ-tKd{%lK|;<&|?HrkezB40mnXK{?K_AU`0ff?|Qg{~+Dkg|0*GG%K^TG?uE zUa{e~_LT)^i-Q(8-8h@Ri};EdKle&ek`eR6z9SsZ_RxB+05WsG-{5bp-JeP8pW1ZuEl#iO%{68BvVZW{HyfMr^PQd|!P#T6M8 z;7y>r0w8rm?hVM%t6?}jOlZ9a1QY)zgy4{{aoXz}pjB>Ajoy>fjITN-cs=(&EnPRp z50z)afn>zd%Py!pa!fyKkh5fa65JH;@)j5hV+$D~0|5)N1UsbPaeNM|je-tnRjT?b z!#uWMB$Cw|CpARhNHRkD*JJ{=Q7zKqvSyE)t$L<_?+z=pqIP_5@N!imDsA>bUD74} zkLZcdQkr`0MbT8wVCk#}S*2X|z@A8kn%sH5Ux44=t#VfK$2Ub6} z(xSjP-Be-}E3T#IyXb_hgYX)5);6->=wizyaSeYDS_Tuw-DM@)LG(6XWKzAQOi*t@ z3Ox+ALNB84bSWmhijZcrS_GM4gefGxoC{TKYiMsDbOyJfmO_9sTJ2^Ki|t&nAr#?S4L1UDl}?``2BRdO=p3Q-u6ZV zm}@^xQD(92a$~SWV_Gp5(1ghw&g%=|Q_RyiMYY&D3ZIS?K7e!GFl(hWVk#qP-A@_B z#-ctOg4e@}+EgNg0MN^`mNIF@kpT;eF~UiAJN5PX#Wx-Oi94iXE=r(VPU+wLNCT=| zap6?@ndbeD-0m7jhjjyy8(rN>5m(zo$b|#VRBU}atxGnvun9 zo4zrGZ;EW<%?T$G%_WyL<>>S%9dYKG(^20u6;ok~VH(CJY3z1~?XTKsv;4S|L>}}7 zI|BSQx(*klX*F$GJ5M*{q%~!lgf?i^9^8!+7+yye5aDN#iQtP@RIyYh+-B4oCJy+; z5lZn)<4Lc}dx}F>qSVPdb-rCpSb{4k&BM%F#gSF;W}WI?A_0`Y+e^85k!(vGLNO}0 zS!?cm{=eI^DrCkxchDjEw2AJ{fclrjv`*Kj|NnmI9Gk^wiXY|~eI z;aihB>fi{GJqHOmWOyRid4eY1k!#84`k0cRxqp>8hN73YPSrb&#>7V*E z()^APxTvZ1pHxYK)X{MKi17H$RcCHj)Mu_>P=I|Ae;3W707xfvOn~jqPkkTt?2U=T zdRjVre`REZNng(WGkND+kabxh+6mtDdj%Gcy0Fz>hDfY<%Zslc! zurIqCu&DP4+E>6Lp{4IvIjL0!(rujyLpnVdoL@1_{($_*#=JQ@pWV0{BjPfH9Q3rl z=wU!AQez$xSteV(3V>*GMolXWgiH)>F^#QCvV4DfkLcrGuAm@f+S84ql4~ zzIZKCf`V#QOJ|`*%18l4M)F&6IOF@7Q zlAyju(-&%JhsVlklr>xEL;U0T;r?U#Litsnu3zx=kosnavFLoCa>~ZUzux$s7qI{t z9zm7WrK-a$Mm!}3v&|gw=26$V^6jr05YJVhd5sK=#cLJl7Rzd@mlF`jc!8bheub+s zqC}i%=1??T&hQ7j*-B*G!^X0H@;Ae<(t)p73Sw-0ccNEm)bz$2mVK!%#;+)bi;X7E0ai!#3Xov{DCdYA8veWlYBrs=FJ*Eq6Q zb14WfwGmoQ5>$8U2yZ7$)R;EX|x6iWE}*2^SzY2c;^h$)vfG>M&UyazazSKhYVGhb}UDYjL2|p znQ#1O>f6~aGOjBx-8s5Xm)v|fY6Kg7Eo|((Eu??vDWaljgiZ;BJ1-@Q!r^(N>T@WA z!Zcs6(vLnaRy_hBmTC#ru}3M@m&>5*qB(JpuF!Q&AkTSK*Kv+~x@?BC!j8!j%~!}A zI&`yPi0M+tG2C#kT`9LUY{i%txZQp-&`mQN5!(nsLL7516inYWoYO`+cb3xP5zA7q z$SP+C&~JI{d9*QT>Xe#_OEFscO7S^f&D)lNiq)G!ncJ+7=r{Dpuwqp`5 zNma0fEhXe$gV$y-@$`hW4!E-!n>`%~r^LRdqU}%&d*$=uLLnBOw_bHcLEAu5Cxbzd zE)W6F4aY<3M&jx9rJ}l2ta1(V$lsxzq2MAFtluh|L{#$PzKMZ{My*`XW$0=zx(a9N zV4(2}r8Vr$G@w#BpUoJ}lgoqd^k%*zP4w@9```|1rO{O{XDzQ1&SL}tP0#AMJ%sFV zNi^NCw$QGy&MPfaRYeM0_#`fuAzc-hCql)5Vyd{?(|M0j_O%eClzov zU|PhaI_FHVsLa{Nn3vsTM;JSB6zjza6ontdqeXGf>%*$`Nd^Wl3`Fz*eMA>?5{MfI z#B@0du2-YT>nU$&@X~<{nfR1Il(W)jw?3Rq zSN9Wo1DO!L>}E_9vc{feikr)+nqMN2JZM80tppbp#HoqA{~U1n$;YW1pnA*;t-*C5 z{-5+cI+l%{F@tA23_{^HFG%HA2eR_fMtzPyGc?CLYxHs)m=lss=wMp1Sqt4p2L}NvZ z-xyRpRSf#rmx8xeS})TRv6*IAV$}oEzhURXum{^AlwqLpJTwzD6VUdm!nc49MOy#1 z0b0`8FHt~yFH~fh2r^`302YKhFaIPrISO;l^O#epPqNfO>8L0?^cal)EAh_(d-@&4 zsuRReR^&!23q*{1-bOv_dC6fb&*h<7M&ZU8b5dP$O~|*OZ%Lz1o`$#H#;N$9U@SV$ z)qb!r=>aaab|-7$%RYi2yJ77LbT`S|&ldnKj41*aA#Y<02^tU@?Xjt;HJ&CN6R9^> zcgdnurVK5-vsgNF7xX{UU_BkHravfG>Xl=0q$EhQ_)e zx;|z`^k5AE_oC#XBWFzsu!l2;srRVPiZdtO4ldWO#xq?*g>#H?m9pX@F`&>)sVa8d z=q|1{2g!Oa3$dcQ&tOVxA&|NBXOf`eL><=4k{cY(t%T18@L%0d>?_Ut%8yzxsvk@Q zq57oplnClIOvb`D8qJ7|SkNh*3C?+#BWPM*{+Z^S82^ zLoi|&(>zWCuaq@58$FhYj=pt&IeAcRt@g zw|2zgBgQS0_k)htbnHw?R@N_fq$V23j7_~#)M_+8`b!hyQocJHbuM|_vB zxUO?@qBlE0F~cc8%u;2rUZFr6t(pdS;r7AtR^^-neSGkT#2c|ggU z%K#Ye!Q*H7-SRT{2TQ7T?1cL`IA;Jeilq^k|Hzog&mzvR23b9cTFwgLmONbc)CY@1 zfB>~X>X;+XVI)zOf7~`I*`3kap}}TSuU*aZM|4XwHEE^u(Tji&WqTpnRGT9?oXs$D zXV#(_1^2GWR$gA6{k@Qc7SG$N0jKGih(vB8@$_uNXCAin6q)GW8xicBHL^J6C_u*Xu1>h`2WRzpl zkbGgtu4SlZ+#<i5PNT)7v|{!X*_iDz!k%etSe{c}3Fqy#@2nr#4d9Z=Br+e@ES zyyQY{*Z+gsa|vx;o>J@grnPoam|lmX);Kcbv1BjDaj+I!VTg>=pxbq<`wzQ5l< z<3y2hgA`nl!{WF0Y(|A~!m=3%l*sR!~4$0Mebft@$zG_4(#E?y|3n+YCqjB?21N+4iO&UQ9|Uw2FQzX%ER-cwR{q{9pPJsGz)ZX;QBKe`kh)tzfIO zQ9f~`JjfQ}O=F59iN{NeTc6+(HoJ+=&GCYJv_a$m>)_sq;*%8RXpL=4bK;>zseKP44$t42q zkngcx1THd}r?{$s$#h+tjv$UK`oF!r0PfpS{%n{zq6l4c)xjNC}AUd$S%wBmHtV@~u%bJ4uYo6f?=c<3i_QCu4G;^bbj??UAJK zM<1lNg;~oeuqTRGW&f+xe-CAccH$|Y+8*~5(zR?@mp6^_h>>Dz5;kP8__EJ>3%27z zt)f&M*Kt=Xy;Z&_nEkKovClpPo^BP7^5PKANQR*Z6?xDUxTPob>8L4$QK^TARUN zE3*opxsq_@G=Z#8v#2W>Ovy=B^iEI79>c&=MH~;mF4?7<@DVZu#1M*VPWy5S*&R|KmppFDKg<0g*()7 z$b5o?{Ej*QlPb%rue;Hzi)S7;TrinkAp3_O@1y24S6$T8?3aFZE87J12e?tbPn!SC zj#34$!PXub=!3HUr%mZPemdBCHDbBp^glxfU2Ck>mGS{dJ?RCLrY4YSyk2zIl&V%j zOzAU5zU{;v1eD>_v6z{nfPpeKsxbuf{;G8L3dsysTwyH$w{1Rp`ZMJNNLRBz{VlRiG7fyZ(L8{D$^_ z6kpYzegV;b&3RAJKI!im6>9Pb(hT1@tDMc=V+%kNX#2zxU))6}E-!$HC3k;q*R3AZ zG<_rjAE{`CUbj_r>bm>^fPiER)Y#MIR_MF^VChn-WdYZ(KCn>rqvUd2v?`|+oH~$} zdLa=xt9GmW=2fv2*v~@Oc%dB#LsCGsb=D}Y${ltG5oLcHghEhx6e?++#cTP;xa5=o z(Js1b>)+VsG+Mqd8+1}Y(4wvRlj#g_wfP4ml}|RdXsWBRT&8NV4IFruE;PgkB>)73 ztq)X-NQmeeMik_msSKMN-KUuy&jJF6K2~bg%jyIBo)i_i;NdPFs3};gkLmuCl;Icx zd?10jD&K<4aQqB+2}J*(ytNm0xRCv?{xnC z;FUpY@U$S@8p72Xk6FDzv*=nQxaFr4^8YENls9QuXv$IK!Kaw-gU-PYg z)k*sgt`NhBvQd>u&6Z%*>)6Ej+=u~jSTF$c%{ken22Ij6-G;n&x&5=T2Y#lyNO6Dx zWenxAz>a3jKwqkQAT*9RqP(~e1Irh6Y%=_jxXCd0)RQ@-U~uokbvOkdhvu3fFoeP5$U6aB}Vh&*nd39T$T|60E9NEWs zs4b<=JYWFCv;)(wyc4*r#Yy=4PSO<}A`a{s%rBc{C4+<#v1Ol2VIVrrxLE|HaUSPB z3vN1I041Y+Gkf7lwCAfweFOXJ40^^~^A<-z-Q4S+pSv@cnN{48Psj1_L7sLAB=hq0?AN7b_Gst z^0${UC`{_?-%uunN@(ZKG9Cf`PW6&zq*{ z4(oIA(4Mo=tEGD$m1kDZW(ab{EIR7)ux5q8Uxc&fcu1R$TboLkvUl=jb}tU)Qk&X! z=7&~IOW=Sh2oR}fNEC&>#NZ*nbjixUy}4EtXrSep_SdCKO_sH7eVqoCcT#2s_o$2j z1kbBAEEl$yCnN~x&kQ_DXIX_zk*~uwkksS5Lj1$IOGB-Ekv@6S03$%Ded}U^$o=M` z+YjR0hH{qb=WrJX)w<1m-FdYN)Eni#z=!It{`keB*`1K#qHJJf&`m$t!$Tum$%}RI z{=&zS1I3)xkx##?nUJ}1clsw?)$?9neH*0o3PGDr-CI+tRlkc8obJTO1uu(a)0)!G zYmEiNc6;MUiK*H;UyyU^u3zJ*nCNqc2SnI;ys*P*D96cJi61lG@0kA;yfXo407{eO z>U%fR43WXyCncDnr}w=cRKH}{XFdJV(hxWC{qImX4vGHzGVS~S37X!sb;bI&VIB!xX z6=h#|2AxpY?Gvf&*FB99dyOEto2zU_M);nA+H>rgDIN$H5iqfz?SvRSK|bVlh|}xC z9(30fz-EqUlkl+taL5O@IO_Ori{uSECGdBF)NvBA%#4M5n=w);Vftaus9qXZq0Rlo z3lXnIyEqFOC_}auii_8?y}(VVR5kaE`_x=Q^PFFX&-8zT^bp~elT|aS24-7@?SZ&6 z-q!$v03kTXz)}@+w_l?@Lo?qg=7c1!MiD|~4J$SRl)=OTpZk~|XMUn82!H`hx(ZRd z6e5apyGo)aUka|VFZ%MS@Xwx;ex!+<0KEe>ZaqN>vppO*s7;~L51w&lWzUXB{i#|d zvlnP^S^d}!!k!TJM)Tk)%v)f)NG9Td29%IcJ0A=C5^>@9``HqWC94?dxX@q~ z$$p}*`eTOEU&Q&o^{fCIj~IaKp$Huw}B1K5Li^ zCa}0G!q@Ncj*HV_=BBCt&i}&h0T`$JzdkPN3+02`U`(DBH&>M8 zoRQrx6T9H8(15$L9$+!15gD&;<-tWMKkbmzs7Zj@>%l;nSeihbY!D5htFRM-Lm;|T z+81r;`z39TFN(DLLS_B-QM<%MY)pkYB+?$Q`X8hTH#_9K#Xg7{73&mQ4x$ZcU*E{W zre!(C7RErsgImdH=C8$i#%lGP47OJ`fcWhWkUO8xbhFJCi%VLaIm88guO!Q1cFvrR*I%3{zS zR{W@@sh$!YCnS}!KW*(s@;o(*DqFSCs-JduNisIN6|a{?m%~DSt&4!mcM&OFAYblu zjt{&lRgIvf&ei6s_mh6|mAe7Q_W+nQ6F`=T4&6O)d$$3I&tawZmfLvRcrK>#l_ z$x07YeM*aX9;oE2156Eh{VvDOaAn6k|GUOay-R+mtatc`XqRs~kCPkxwpiWyU=!WTG zIvnre#Qr6D-@8e~uUQCREqjaNTZaK62L>#GSl=q9vG&47jvJd94D5B$jGF8E3>;pq zIc2XYalvHEhbZH*c`vOfM5rC5bL}_hkU!kt_A4b1E@14;Jah?96*1&E07gV=Y#I3I z;0`jVjSs)S2=P@W4UC;&Ps9lgf3rqi~$L&&)*=F zB9fkB33g;1LUtw`vKB~x@U2KN^IbV37elk?E_oJCf#d4hoO zli#QHuNML#OxuquCR4MO9^D5x8U+rw$fl><9PXVP>pfG5-YJ?Vyjk*#~W&MSqq@`{Cg}5T9Xg@wtjq{ zgA0Z+)VsSq3BeLRShqhYeS6XB+ii|QHm8~V_(`n7nvKf)z+}+KLgcqhjSoZ1@yH7*#kHTi!vFwHVmdfM<Bq-jGh1A zFryxc&G6pvxtw>4S|8x#({6%UFpPeqtAwr=M^@$XXzRmxMS%k%jxo*Y|AFQOhw#d_IRX?xvC&nylZDt-onMjpuQhE9k!LsHRIbC{D8a zBpaz}hJZ!;rSe2>q>2XY}_Id`c-A*?T={(Pju?3(LWqs~y8oS-%k@3&|RK6<{d5?^m z)qj+KtN>Y~k!c0igLk=Iky34aDg4N*j1&ghkL8VO7{d>~wPLHgnA47h1wJz|^_T0Z zR0VY8&>d8R4|~Qtwo;z6Uak3ga`ltMR~kmEb7xDrvXbNlt6hu(0zV- z_QQK4t^b|_lBFjz#c7voMQ{HY6Ghk72yXN3JncxTYPohBDw+p=(uq}=W;*-g)l8ag zs$IJ(E)%YF=0E@teF`_m6J_<pFh(fLgh%sW>48#`lpl}_~JRJ6u2YH0hF{wrI4FRSL! zZZWuDO|_^d$j&^h*e4aq>Zt*#6vled;>14B5z{q0Wsl&h`f!B-5GvpAy5SVN~}(l2-1w`TIA-8>Cv)!RgM57-9vCQdV?&EMw03UVtTRO20_yY zu!3$2sF$@Z$RV5|a0LD(Z>oY>+F4*o9zKEE3`V`Wu=YWX{9Pm7>umCHEk;9;AJNlU z`23O~5vSup%ZaXF6dk^eMqhTop?!tG%Ja6qeCFLq6p}55Hno%wKIsqyi9I*yml9E@^B`qFxO0 z!c+=%pl;lbfFoxMOE+l}m>()4#szlv3XNhIhVk56^)RyxfC^4EVZa1AUjs~2RUd2V zrq`pqgcLx~GH>Uuv*g~02(_{H{(dGpqhJWTxa_5yXM>NhA~F#!@1j;li?AZEjjKco z&z^NLC<1(`I*Z;gzp`qz(<}zf1HKq!;80E(WbvRJhO=Q>riSP2u^;rmM4BzLs$C1V zoi(om&y&@@t7B6EU{4H(i7zy|mxbJ!u=BR>b`B}Q^MBt^>X7B~8GdNgyvYGpuqyl} zMrt*yZ^f#Jafrc84)b|WxVNa>ge95K$Uc(L?SemKmOA191oH&-St3pX9#F8RQhz?l z|J8ODneui4yJxvzz*?4$6ykMu|7fY7Rv0IFE53gzy0s8GH%Nlk#bb1pJ)qX{(1Ox` zHe8q=%?^KNpNKkblP`)pAt{%%+9(26^S0|e-lo|GrrzdWsVIu3Ifq=M*{u6sITU%$ z{c_LqF`T{ifbxv>I*`j)bhZB3fD^}wdZUuUf{DZrCGjWMJ9N5Ev{2EqnWSJ7+yg++rALEcm;!xv z)%RXG8lYr|T)m_BB})dm*K`aCptWM z_x->~3-{09b#YxSgBQl+*mvtnTW~xdR6V8To)VB`#`hCBk0(flIBb7x#k~G9;AaAMSSjXJTFN9so!FS@|r5sLN2# z-ax4`@qK90dEJLG2HdG-IPjZHs zcs0=1JsH$Bj;41KUNMjF@*)67anN}uaA)7lFT6gSxGCF54gic2D`td`)sNp*X8GnI zFp=QqZ<`-XkAwu_$6yypZn|}nvbKd%*$QAl2b8I;{H6D|CCnGVzfx|1>(%FB@K0WW z#e!;PAzQb-rPV=#&{uufC+tz@tTe~-X7!<$sSE^)a0a8-5}Gb zg61~SxMnXfd=T2@h(U#dY+C0HCXj!Z_RnH=bJ-`Z;vsP(m66!HTz!yNyIT$~MgUhiSM4|UpjC6Did{45W| zF!r+TucADVMb782b`!$OV7gV)<#iAU0WmptI5IxJ7pX~`$N(gp!15Xe;SBt|);(1> znsBHBXsXqdS|YIuZ!+@TI@@A*YuGv++kObD?vblH%0tO{%v@Q#A5_LHuf+fCzHJTt-7@~MJyJG3nvHdMr|~2;rmkvn(LF2!G1n+-A}xp zJl!VJiDRtESjk?R3sd0U@igP3$38CBv+w);GFO?v=;9&;+woJ43jJ@VQz_tDMhX9L z?VBss<^t@p*%vU)=Km=)wjAOFgaIhqiHRo3j)^qovJ4*_zZtoWL!greTDevq!$w56 zw(Ft=kSTpra)Td4U(AenKbjiQcNVXt^Z3!!`c*uyRs{|f`mU@v8+7fb-`45J zw^ULED+;$02RW0m2nV;@=7+XMcoYu&XP7QG%;DuoC?Fx5*XX!4Y3K(_3p)Oy5+wH^ zv^l-d9L#nxh=F%997YwdpV|hJzhskXG?qUlt^M0g6WCpxGg5vdbdd}wek0F5(uX@-?iV4j>4-{hYS2R*jd319NZCRrmX zD`}J}Ew-o-RUfFw!T>Fo(_;)sta4zWkG)LLR1FwBjTmK)x*d!b$r9Ib!$Thz8&v&B zb&^-3{M(p=55rDJpvF{Qt9SYW&mX&=L^kFSH!egw9MDv#Pmva#?VyH)IgZRe5Sde0 ziv1sO%j5qz3~Y0SuE{8g)OQh4&-G>EznW1_A>@+sYr3>=w2yS@+iXIB+?!M+L{rer z&k%M3Qbv+M0mJNufm*UlIpzc~3aoE#;ptCj;F1GajbjPdo9s%Q+Bt31d{C$b1BA@Z zB{7F`>Q|-u36*QykmLD!cnT>=m#*yM1wLorCY8Xs*@B_eYuD|;&&tT>eJU*!xx8lAP4nLIt};J6RIk8rkT2HZAp&lX1nt8K>>!KYXJ}p)G z=iVBvW$&tfq8=0WWV`#J|0q-qt2mNhY^%5;N>PbL1+}N?yl9;0$j%ptE7g`34xX%< zQ?UOK?q&ZE-IeCsWQw{R>Q(VYW6EGSD^a}B&D}!nPlj`HaGfNE`lR2egQEYylVwXs zL3h{lyuL6DC3WF`;veKIi^wwz3SV-Tc17+ClHhP27H;z%p9$x7X-=>%K;{{?o0MxKa@^TK{2XccI~|HcUnF$Q?NmRJyL6SE z<%BKdMurW=2YF?+IAyANV+XiX1)-Kiiu+&`4jxcIvS5%Gxu!Kv-N%f_0C|`t>Q6!6 zAGhdH05yv2eBXvRW7L&aTmPCZIyV88GgNGS3W2;Nw>2|-ynaG6$d}l zek|!*Z^hWa4l}t<&Z;6A&9q^$W4wz$wsN$SAkuJT#)|FB{U#+Pl-3oqZzlSVH371= zT-XUh2v(^IAG!fZLG_bE-|FmRs!N_qoRwWhM+ciW)!7;hyuMBSR)tUzalfy%Qmww% zx3g?e@D-esgp(yn0YEzCg-^km4;b}0AQg+aHx3gnn@Y;SL{ZIn4VsfrLOD$#gPA)# z*&?C_nL3q^FgxNmQ)Rq{pU&-Fcy zwD zIHN~vJiGAEy8&BniSL_>{2ofh>}&R{luKht_W}^Wk`IP(m{ue-xXsnW;x@xgNcRHY z9*Hk(Ucm^h31pwj8W%;68b(hZ5o~g zU3^k!Q}FpPdLwaRs*^v^Et_(YU9c(YcUQhU%W;@SUmv>&j~T#4Pm*OhotCEW)UU`B8U307mz8;eUBbi|BHW2<*7a2n5zq zK?fS08EvTcuOzZtPIH=>QfLT5Cycp891}Q`EGh#@d2{Ztxkp&?{X2El0(1;(H=2eX z3F`w+|8ki(4aaCG6(!bi0`fI;FFI9h-$1JsXm3lNL;EtGEvJ;T|1X?fTxB`#JVN<* zJVgiAZYeg(uO(>-R> z9x==vf%j(yuh%I6&^@%bsXJm5V>3B&s^c75*&6oG7!`yh z6*?k{$dIHck?v<`DWPLJ+iN6Pt9_7NI={JkVp>u&L^wWJd$nsxPkVd%r5H&l^RD{` z2Bn7+t>c$R{z{;Z=qyW-4>vC()r{>$SX-uB;GewXn{kndH_qboo|K^z`B^OM(Rdun zD_HBZ^x8wIJ0AAEiM;20sq<;dy%V^v;2qtT(4^{;z-gbwG&e5WsNU5La@MFl~1GjGl`GR@Fa%-8nJje@%e;{TfS%a)@vHi}gHV3BO; z%-u^CQ43V&$k^l!e>_(*RJ+8cfxVKCxg0o4Dwu^*#kotz1T0G>rPO)mcJl!s+}}J< z%I*lEfR#*b`n0nc(&65^d8ku2?fi&O@C;q}|N;>c(+h#>Kus zOnEol?#gXUavg=^z>reVOKWMNBgF4av=1HBTfS{FIPyF4D*ymLz8D8k_&K^o+9^pY zNOeWlYyz6lF>e`Qk=jTh36fNqLz=oZGlj9RKp?KQ&ap zhX-dbJ-xf6;>PrysMI)>C&+!jPsvsPHK!;?4=Vo4u#)q+r-iBL_ z?HcDi6?MUG4eRIS+2&sHeju!)dIj0#5nwmVFfBk+SBg&Wh*J-RQ})O>8da%$5IMlRZYokreCxrza? z4a}(<%Eal3>X@iRG@asbMaq$PMd+)0fG!=u1c+Nu>FkdtfIp19{mHV{8e?6h9S88a zQ8(@BhCexyk;51+!yrs`Mu2(%;uHj1MlfgxCKjJw8>L#o;8}!ok`N|D%9l-_qx*T~ z+y@4@PW+$FPz8Re4CyJ>IWU8aV43uks-=6s?&lXfLN@qu4K%?$ zas<~`dolRAYl8UlByj9CY;WDngJaUdsB;C$y;dI=RPYb!;!^tz%qUy9yf<^fi zgm=6H4~Vk4+vx3Xi&{KOoMprSW;{VMa!C8WhI{?W8 zvhJ1yce{$w2{=MN^(issd)%eVp4BDuyQ4DCgYjcc->@c|U!kwE?6K~+TIs5i`Tju+Pzn(N(URk1etfIvn z1PF+m>G3>Y9X+}QUJ$Z(r8mRZyinSq*)_0dq$JvPt(uwoGftDd5C;!qv}dGn2>pu(Qep{X8c%;6k6Tu>DUgyE^#b=(ijP zM9siU$}9>-MNn4syN**z6-rv>xR z`y+yHd+L!N&|@v?W1Mn#eh{IkCeKa>$_GQxJ9D}aaOMmt%UQQB>0C{XD^#Swmh^I+ zS$8-e*P!?wYLfX7ZF<|_8D(9~UHu)=EzHz8UtEP-1BIy_a*%(BEtVtUq0~w(L=-2># z7LW_SXh>e8BNyM5umUnApK|StuA{!0J_u`U>%z-U9j-zEFazpnHMbhGyRj&wwK4a_ zDsj?FlV92nd^Xjl?;rvA-x5DZFYXw1srWnF{o7SOP2|v*)*YP={&?8~a%s4Oeb|t! zeJ)ye>oSf799%2~FTWY=z$`5TllWLl&GtTwa+0_TE$El~OonX51ElZc*bUu{s0tfCfT~`tvkX@i) zbV!Wd(sEm<&}nUMZKQj@`=70lu$Y)_-FKP%@)l+^9gMG!^Y7MQ-c(IqLw)>d#VotKW7L$>G6;WK zU7i;ISIu1WaGpNX&F@J%{VoPBCCVhj(~g~5;-VWbA675K^OL|gDafHn~S^awaaKuEzCqp7r>El(#sk#Yk7w%4B2CV z^pb)bEueQ(0XYE&?_-IzHBGPURb7qz!gs40%PhC>`5>7m(QPzr0`bjMmT2R}V;8uA zpACvIO?d1!C{M8w*ID!APt=6~tg^$+*IGL`SqakHSd)KCrC99YyLLVNy&Z3z*bs2L zr`Iok--js0gUdCs3{3}j;@h>-l*FB-OiOV=SvE74Xb01Rm}@K(9`;d5V3ur`{ z*gqZ^nDkgYmTiXk3>a<-SBKg3K7j!WMZnS8$w^2dK~vr|#K(GczU zd#p;VU4Vb{i2eJvZwY7ci~5ioAx?m5ZMxcM%Q*1gj7CF0-;d~Lr7U>Tk-F{ob^$Ez zK`V~79htdFZ^*kd8LU715DsORJm^SfbPwnT#p7U(G?0+WAJ*bp67xs`4W=8dmqsda z2T$PUR(G6FdWEkkA|e*Aynd|}7`)3(c}^k(`6Zut2R%PInLF!`&)O^6r?N{*j=xOO z;d7*iPdS{}e+OkKhC7m2cNgOl_EQi1Q76ifq zcq$2UGnwiAxQ(UF=d_D+^Lg-@kXXuI>^xnc$sFGW5FNZ#i>cG39CS%$;qEbZap*zj zDdbhsScB);Ps&><*1}C70~f03YW~mDORRh8x^of`$y7-PyX7)Hm*MP+*Mbwv+^f+Z zo-7`<=YpB|=fhEA^V+=H0t?>y=HZq)Lx04PH`<l} z_b_^sgg&_)lM?ouakg5>BIBRm#ZY2>@)$nJ`L_Fv;%6$8pEhs|HkLgx7QJ|Bl9YOT zP#98(K{wGdeSN=VBz@l;sQAKc*U~!(~7UUgi4-w`di4DNe-_ z>CRNI->Fj~0GjNM%P4%feCOVC@G-CQ<|qvqFKnc~$C%kh{wD_6=ib6zTqH{{#c;B9 z)yK|)h4sZ@2Pa{(b})xu_vhMBPNLtoco`tZBPxA6EVwp3vFKFQNT3f5DD;&Gy;-J2 z2l{Y^=Vvxkm{#iOx7w;2`6c~xyBZ`+b5C5pN$WLq8XO59hW5tk_t1ydFF2s{cdg=| z0I(-Gwfl_QQ^7XyiOVq_p_W#87Z8~ck<AQ)O$d;-8(jD=-fZ@=e0+aBv2Y> z*4ob=9XNy)EVG^tBVSYsQig`#+9oA%P$u>I1|1POqr#>b@#@Tdj1+n9dQvz&=8o5^ zq)c?gZEspxpA(QpZ(oy>!Uev{J#=C)@3%FV1OX5&#b59$1FH8e+#4{d&xc|Ot=1bP zuDo}U$Gu+D>#O0{a;Me8Ri^Uj7nhvuK>dTLASeM+zK-FG4YicG5Q3ZikYT%t*ZR}z zM~;Ld;)u4H)_I*G0CFD+n{W1vBR;34$w6oybXwWqg-QFPu6kpe(itp-IJeL z0F3SCsiZvyPAdcqX&ux2mksCw3;GU~@yZ9L^u=>ER1Ujk4Ko} zsA_WGt(#jQnJdki^Dop?X4FogzZEDs1>WW|ErPPkkW3&LDq(ZH#Tsk)qf5npFd6fe z{xPlsLGI4^R`LyN#T#dB1B3?0gS})|2Xb)ut!mcukl>s*rBJS!t)#)3(3kBz&2&H@ z8u$s)tY>}|DEr3M9uHCfd>RE)xQIY+@ZY99LrrgK^Mj1}|HvF~5Ay_HCRqNTlc1;E zoAjfVK@jbOdPD=Sr11`(cA+cd#ND5=rN1{1dv@2(I^)2lD6cLi5^k4$uUkk$-7G`= zC62)c-^%uUN>m@zQ)tt@IdjKhXZa5JyZZzLF^6FN7_+97@OJyNw@MtpGyY@C7v||u z$~z@?p?$+$rq<56?zirU$bLTg{N%Hq0=Ah8*~Zg-KWzkI5YDF_@b)o$uYds;4EYRC zpRv!L@N=|!R40a!S3Yxh0_tzhnpUlTh+EuVT3!ykd4F(_ z$-y^@f<2G=rRvVp(l+ICdYvj!1E{)OIq7^+{l`M*%zOHKk3Cxwzf^kZr9zLobc8c! zymOQm@p$AHhv|Yh(Lr%~fi{fSeS)j$qG~)tzp!}zZ_cjzco#psuhae0yG7s7O-XWd z44fmT$I%Yd-NX7%BO&q)2smGyrG~R@4|0A59Ll1DH{-;je(FAL!(f2(a|a5Q$@OJ- zfoz#p@6byima3iNr27Ngf{34OienNo7A{LI0;GtW(193mfIWwDQb4-X6VdknX$WwR zyz$D2jAx2iZXvO07m9=eWA-kBQ&n>7ZP=x>pEaOyYc2y3O{Xdc?#75$_lXOg2`81> zBoG<5Z#d7!OY`ydT2~F zyz?Vxj5s6^8FwW2dt3kQ;VX!SMNUFqYw<4|uZeXq(+cpHeoUvJiuKTlKs0^`=GG4B zxj20e{O<27;UWM4BO_H0Y_^R34KGyj2U)f(O~$jG7J}_e;{jnrc#Q5Kghy_-aCR5m zW3sWt?6M8zGbQ4#ul$IFcM1!IYj)%KL41;LgAwV_l1LE3aBD^o{dwXD(= zzNCkA#9J3V@l1{=Ydc*GffE8n{`D#jb1?M1|3Z0Oe~LwnuU0}2G`Cy-;3wKK*d?xJ zH=o2e$lSw_pE3BjK?c@O@NCqlMj+kDRMEu!Tej%#PZw*6?6fGF#lC$}Dgl*R2#7FZNwqv1|Ld} z-?czm-ANHWGSl2=?f?>`Wje&JyLYi_l9C?&b<1jkv;d~uq?GVM9`>qm)qbT*_aH3| z+z1(mjU@z&jbbP=MXw6ytD(7!0LGniKAW{*NDK1{1=0+*b#``x-5MUpt!Yj>IUnpg+vB>WQ&S0n@1>mn!uk?(Gg7MkFMD8Rk^FYX&tSQW*QC^#D@_lW4 zt?BuI<@nN?SrJkZZPE5#^N{lXU3SALboH(`pmYe8x9yW}6(zP=MLBk6AVD$>GR{`xI#$fFu#6M}Y=y*HDTBKmoe-2wQ=_C(yzzSV3^I zsf*-Pmee{^e^qM=PYF^@E+2)~ceW#pqd+{{mHGR*xWv1jUb6p|CAGNW%JtILGrMkv zsm2B2)hkvL5J-T0T_y_IYpn)yHh~_K9^!_t3E1mx9dY6GXHd~c^QGW z?ck1oDL9>}7jhCh`Js_hkO9vVu-cfw(y?ZWcrNz{ch8)nCjF5@$Bex%kS8r%;&c;1 zo@5b_+8S@CVjx1!1cUZekcbQ^cgq6m`eV`n0$_)G_wl)vAm3QRV8K!z)4Q$JS7N`54UCc$+7Rl7viTG1P>@i;@|OebTF+3wS9 z-zNYHG@|%KSYuSKEArB^UMb$5?z%Ah3JU|`g+?yQLID+NT=*1-#EH6R?`B9Rw|isLfqljqD~J*JB4m*4j){vG{t)E zS;8zpp@OWEMKZQ~0oUky7J84^f4k8P_A&8#c01lb_>nBntroHr3|FM)XHUP+ws+KC z+!9d*ie$yN2UZId635W{1`#XHOzxjC6j!a(>no+_>yqUYAusEm-{mXsB|KyYU^t3r2H6Ji3F>rMZMGNQbw^5L?WiAP_6m;7W#AAdkj9Qvq_TL5Q5m0(( z<|A5Pz0m4!o2lB|_*#8ejXg(!FylU!#A^4vB^EYV;X%Y$Mxbn+5_amokh;p$AHQ@< z@XMY7HmYs+GDAO_)JJMhEMgWObNIXB=}@(vDiZjj_1`Wk0d z+*UVN^(%DnNYIDo6~2s4J9a!4rWqAOPsy9heSZp;x*EKz84jA${P%Ha@eRT0)_06@ zt%pGg1tdB!Z(-B6YB1pkGv~)fAMXI2hC_g!h=%PRS0zx+)#WNL<}3g(H?Js&%iak! zw2KD@`feh`il){HfQ%si`7rF@Tq^sATLJYfJp-h+FA-4;g7!Of&@!n-|AYlH1k!T!7J!?c;{TE7^)BGkvbZQ!uZISs6-B z7J&6AhGI(g{D2G7qBlHPbf&36FvV5mt&??Nn}oswFv&(Oh{;Ie)2?V4TqO53S^S&x zKzdq85cwJ-4P?Y=wM0LY_RxfyVy<4^u?MN&LX3UQ$lm&aO8Qwtcl^1CdDWwm-ydf1 zW~a8Jg_251aV{W!$|-!F$1d@ylMa&)K_|^W=A8=>3%tNB^obv*3??ZpH-bF&@eh@H zEw+Cq$Q_6x(XTe^WR_G80L0AhF4wlsqroUb@>N(aP&>g#Vx}=7`ytM(*}yKG%hR6j zt=NTpyj$(7UdVb>fUAycvHPkPNr6>tdwJy6Qc7I3U@qxH7tr`bM7Z=2RjB+;=e@0< zk!H}y&@F<#X@(F)rZ}aBPd(wu9d^gG6wtL6JY`HdRieirHF@)NoNWOO`5!9Lt~MhB z&7o-M>lYxMqZvd6Fs=39yh<(d9@mCKL^)*m;y3BJfCP3;&noK`cZBwvxgzOdsjEc* zxDEyp3soq4+U4>*k8wAC8rfg%^z3%*%=jq5MCG@X?74E=^dH-a$ZPNkE;O@vubj@pejOhZza zQz*AY6ndE>jyxFWL7XKHV#78l@-$@^Ek1}GoH9;{rpC-!&k|}L$rz|F7c&NIBL!q*JEKtue7mP|-8E=FGA_#tP zM>A=v*Zb?Mz?V`KuCUQPTD&B1f^>5gU^mYf&iz)iWM`EwfOPev-uXgp0nyF? zI;#ID2;s7^oJ%a6Z>5m5rcVEa1MuO}vok=5MyVYf@~iW^N3W|?7U4+1Fp7_oO z&Rgj-o|q?gpFY=B!4GH!mwFC9T}Dd3o~X8Dh-SeKv{ZN&CMiPYm7T+tdG1;T>+~}t z<|A0MLsK~*y;LZV7#zhs>3+~Jz>Nc(l?S;TI|hpD_ap=qo4m@T;tc^84G@-?`XM@G z%A>C)AwngIXU)ny^|ey|JI)9=fl#8xW@SF!#}A-FG@`wZ@_bMz3qtB~29$?OOS^U# ztFcJP5I*8-42{Ls7tu1-Y8TFD&mF3tpRk)?rrP`$&cZt*(wP17!&`&A0`vvDBUM0g zi^b1498e(vH(G+r?2C;s_Ez5Cln%$rl-0^@Y z#hJ}9U%<5gSHJB|y5dwKbs6k_i*3-ww6K0AWoi>sr%g6%lJf#+YQaqcs{`bl$hFhe z3x5}&7pWI?W(yQtA^A>N-H)U6cLTUK(v=QyT98kmn?Y{@dI2qh-2zx$4&o3o3Gt~A zp#Ba!>9o(~b$)4jAs=b}l#M;cAY2Asqh?q_z||5!{;JQXOHA#$EM_~uPG+qWcyYu~SCF8v3+5Jo8h^4+ zt%wi}jgt9?8qyC#`A{%!%eu#F5oUu@=dRK8*oA4YMmQY)@G7hM)M)tdP*{Lhc_Mq7U~k`WmEUrr7V zpMkVeIbf439oC}X5!1zh|D!s`?Mrrqb&qMg+jv(^jWV^{lr;HJyC)4PV2TVM;AYXl zz?S*JnZa-6TjC2FN&|e%=Sq87Tfupmfe3RvuCy5=wjcbjxNGBt3jV#+OcTq&&FX1{QMvvp6StRD=rhc zRI*@w;)_pxQEo7%ALY7*kE*O_{HzNsD>gdyKUKeyzVg*rpw%+C|G46Cs7QIYc<>d~ zfr0O>^s8pyl)cy^ZXy}0trZDrpL{zVU+X%4XypaFAK^x_asCN- z%Ne+%-8*?cC%Nu{xF`q$o`wKmfkO7NUBlP{V+Yq_)tLRJJuOlqvO2ReS`d3xCr{^( z-sdlC>nzC;Taaz$p8!8E*S7!`w+>sSSadyET910@@=TD3NI<&thBaD1fe@Vi4i1zw zKiCJkMmI5S&l*ZB#c(CC#oA4UfB;Yy;<0Z-0fUh?mUkfANy@zoyzR}6?WcG)=ABQh zM)=>{oHuQ?%@UK>IPmM?Z3<@%MGHObJld08=yO#bu*ib-LKU1|`Ge}N$J$L3tYMfM zfxFlbdoB)SIrj4Ld3+@s_?oGUzvC?0*E^TD-Y2&!>Tj0A5YAKDY#^ai6z15um_tt+Si#6R} zRM@`pS0KyI1UMYPB1mtDHxTa-pdhkCC_`F81cf;V0t$p4E;1PD=Sq1m^R7Lf>Z0?V z)qe2a!~6#f9dbVkJ>obdb;$WB^$6#Y!K1`R?v61IowK`JddW8nd@sFvJxyKz0FhM8 z{|nVAR_c=r_g~YS-(8k3ea7VqiWDr8=+DT6q_zYq}+)PRF+|i zPC`N;nPf5sMsZF{_4Mq)pWl-PC9!*?C`l+754*<{W-771tCow-!LTsR4&QD+%i_KQ zui-vWE^OB~x=5W0wLA}8k(bht|bwg)l64gTs zC`7greqWdhjECa=6J-1VjBVJ$ydqt4TQ5uGMU^6zwl^u%HixIbdte=1Q z&E~?$Jg-g3L($6OUSs@45lfk?9QjONeUuME8!bMK2};(zNIQOMx^Gj53b0OS?A65wtN_L*%SDEcGD3f;3%I z@{0{4W2j1LrQdH&9l4rI8=7}kBS0U}*Q{GgY_%O9oPZwFD|i!(@aTVorl{@FDrYJ4 zDv@d?>y*!B;3m(-uGq!Ivq6pK%eO!OBbxqO-l)jEX7Fx&TCNxHCGVw_`xYjH|t;F~>eyXy5=O5g$-J z5k!z*xQv^Ffa0Z5c*LZI0lq9H#$1JY{DN#kevfd|H=O?aVDJM6&R!L`Ji@Ly)ZI0*Ug<&s6kL}@N2p@R-tA@5l{;FC6MQwiMzL9f@wV$g;NmA@O# zl65Y1=$5p_?{6w2sHDJh32S8DlW&CuiFW9Hj^BmX=@Es}Tu1|3fLCcWsv_8~*+bc7 zdgtGUmn*3rWY07`?)kcvY0=`27HyMZp~#}XWl`(#xUj+6=K0%G5UhIgg$NKD=L`vX z+3%-o^W2Z^PPD7g?>2KK%Cy;C*vP)%xoOM|*PBABWIK4}?JO{HszfXX%AwL&nG(VW z2`jAPjRpnOYP?njgC;|;L4`Cqzz@|jrvQ5gBj8F=7m9NVkr|SQbkfc7=O^_NDt_%Q zksWNn75w(8ps~47`j}<0K#@6JKUD?zhcEnx=g>K1u=O{!<1sS)ZD;x2?_O6`3%J!H z&Qv}+)TMxu#I9sQwoJ=8VEJoXwf$~Sy>gr}p12P?bTV%Q3w(zKPKv0OqC_XOIw-5p zQ^p{xv_wiqDnYx%IW|6R?WpI=Nm=YQ_&wtva(UpW6o>$nC~~SKQ0+dirwg7!POgJJ zP%UY2bgsG#3-PJ((diRp1P4RpFG_E>o?LAXolBXFyJJlvNB>3b^K=ytCc2GfLPg1H zpV`#SgmLqT-yFhM5+McAh8Mk5yY!e!L0qwnyW(n=yhs!y$|0V)Av?EA-!cbaV4)Uo z9%gc%8#QdT<_FgNPGF7ov_s-ScPRiLdVOHw)w5rKmEMGsW$Rl@>vVP#Feo<+J&Ib( z1>YFH1==?S3UDq9kPtf)F1FPE90s5x;wM;p^pY?}NQXs5-;Jh8mwc*}`;{%!r-B+$ z4+~-Zm{j`Hho*taG4_%U?>N`Lo3-H?=OYI-d(*BT2bQ%*aSU!5cDh_j&h+)G|9)7U z08Y;<)ed^%{$rR9zKGLBuVzZ&>UiHK zjm==E(Anzcw{W@ou!|FVd}`Q*4>;;FX|p*9B4B|^t7_sGbiw^bSTt!R6KTnLK0*Qw za-}oMH#U2*(D^|k*Ldu1Md!IQaXR>x2*w6gA^FOmqiz!qQh%oOG(U95?(VvF8Gzw5 zmbl%z)@`C~@=QnW2ONc2!}=_r4%U>Ro>f|oo|U`zNzBfC$l7rG`=)b= z!HpqoLF9)tgi#7oA7UC(8Hc)B`g}|W3&$^mtH7RvxVy+-?|iloJ^NA?J>5}Oi$yNwN6dHOTB0E*Aa2ljcUIgSOVr^DRNFe3dj(OhgErU^DA2R!Rx zu;ozC&p)apu8|}N|HzWI&&jyRFKjy z`MyWfAyrLJP>-m;aAi*%%l$o6RNUZ-ZfEWkGcA9kmE z3#$_GLe1OO9iZK}W*xfA$#0A6kIf@5QRPJ;4_)#hg?u#d+YgQ5vaSWix zvOW+$YeEQ%1`z@5P&tFzG<)&c`g*-7u%^JJ!#?7&#jc4ziuYn+Y)s;Y=0eHw$fZ>Q zPYJs~Pjs|Oi6U$6E-2C#ogW;G;E4`&7A)ths2yIlQ}IWn$rL4?%dXlMaqsB!V#Ir? zGAaMwqd6){w=we7-Wud=EKqkCN70Hqu?zSLJ^U-A2rSNj0FXl|2Jm>CLDUOFN#Fb1 z)IDD(L7Y2{N}_UQDRVh-$-2qONW%o%XwEzRQToJL$77z~9V#JHAxxW_t+X!v{_~UT z_t5CPg`Agq7SMlTi~MCYVQm*K@^){z^%eQJNTngjZjrDhucWlt7Jtc$6H!d7=P82`F!ut9XGd=leP)^l zJmK)&gl%dZ&P47mbU+TIGXjC95Ww0uP)o#J%MQPewSV*fFhTQd9sXWck6xH^!wAri z(8ULl)dPeENO(bbfkp!0f;u1pO9HY4%p

q&{N^Q46rb8g^X&2FFzE^0)NQ#UbLF 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 literal 627194 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

3Z%q249m472j3)FY`=-Hx(Aw@WE@u%?zM5DC?T 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

Jgzo;Q;{ERng2HvEZe2`?cv&oXy`R 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 Gu}i?r$q!Tj From 5f55f5b15aeccc3c40f62585639b3ffa61852490 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Thu, 16 Jan 2014 14:56:59 +0100 Subject: [PATCH 042/163] Clean up cliquer package --- build/pkgs/cliquer/SPKG.txt | 94 +--------- build/pkgs/cliquer/package-version.txt | 2 +- build/pkgs/cliquer/patches/Makefile.patch | 49 +++--- build/pkgs/cliquer/spkg-check | 35 ++++ build/pkgs/cliquer/spkg-install | 201 +++------------------- 5 files changed, 89 insertions(+), 292 deletions(-) create mode 100755 build/pkgs/cliquer/spkg-check diff --git a/build/pkgs/cliquer/SPKG.txt b/build/pkgs/cliquer/SPKG.txt index f4309cc8109..4b1557c587a 100644 --- a/build/pkgs/cliquer/SPKG.txt +++ b/build/pkgs/cliquer/SPKG.txt @@ -6,7 +6,7 @@ weighted graph. It uses an exact branch-and-bound algorithm recently developed by Patr Ostergard. == License == -Cliquer is licensed under the GNU General Public License v2 ( June 1991 ) +GNU General Public License v2 == SPKG Maintainers == Nathann Cohen (nathann.cohen@gmail.com) @@ -18,92 +18,8 @@ http://users.tkk.fi/pat/cliquer.html == Dependencies == * None -== TODO == - * A MAJOR cleanup of this package is required, see #9870, #14349 - == Patches == - * Makefile.patch: Patch the Makefile for Sage. This custom Makefile - contains Sage specific compilation and linking flags. More - importantly, we're building cliquer as a dynamic shared library, - instead of a stand alone program. - * cl_c.patch, cl_h.patch: Hook into cliquer to access internal - functions. Could probably be done better (see TODO) - -== Changelog == - -=== cliquer-1.21.p1 (Volker Braun, Felix Salfelder, 15 July 2013) === - * Trac #14892: Track all patches, remove unnecessary graph.c.patch - -=== cliquer-1.21.p0 (Nathann Cohen, 4 May 2012) === - * Solved memory leaks reported on #12905 - * Incidentally updated Cliquer to version 1.21 - * Incidentally removed Sage's code that was formerly directly - inserted in the original files. This code is now inserted during - installation from patches located in the patches/ folder. A bit - cleaner. A long way to go. But God this code really is messy and - full of global variables. - -=== cliquer-1.2.p11 (John Palmieri, 23 March 2012) === - * #12311: Remove explicit path to testcc.sh in spkg-install. - -=== cliquer-1.2.p10 (Karl-Dieter Crisman, 28 June 2011) === - * #11547: Make sure that libcliquer.so is copied as both - .dll and .so files on Cygwin - -=== cliquer-1.2.p9 (Jeroen Demeyer, 4 May 2011) === - * #11227: Apply workaround also for versions 4.6.1 of gcc, not only - version 4.6.0. This is to support pre-release versions of - gcc 4.6.1, the bug should be fixed in the final gcc 4.6.1. - -=== cliquer-1.2.p8 (Jeroen Demeyer, 25 April 2011) === - * #11227: When compiling with gcc 4.6.0, add compiler flag -fno-ivopts - to work around a gcc bug. - * Use `patch` for patching the Makefile and put patches/Makefile.patch - under hg control. - * Some minor cleanup of spkg-install and Makefile. - -=== cliquer-1.2.p7 David Kirkby, Leif Leonhardy (14 September 2010) === - * #9871 Change flags passed to the linker on Solaris to avoid problems with the - link-editor believing the shared library contains text relocations. This - problem can be seen on 32-bit builds of Solaris and OpenSolaris using - /usr/bin/elfdump, but the problems are much more serious on 64-bit - builds of Solaris - in some cases stopping code from building. - * Added the linker flag -ztext on Solaris too, as -ztest forces a fatal - error if any relocations against non-writable, allocatable sections - remain. This will make it easier to catch any similar bugs in future. - -=== cliquer-1.2.p6 Nathann Cohen, David Kirkby (31 August 2010) === - * #9766: Additions to SPKG.txt - - URL of the original website to the SPKG.txt file - - "Special Update/Build Instructions" section - - "Dependencies" section - * Added an entry to SPKG showing when this package was first put into - Sage. The first mercurial log is dated 17th July 2009. - * Added a note on to the cliquer-1.2.p0 entry in SPKG.txt that 'scons' - was no longer used. - -=== cliquer-1.2.p5 Mike Hansen (15 February 2010) === - * Fixed Trac #8279 to make the cliquer spkg work on Cygwin with the Sage library. - -=== cliquer-1.2.p4 Mike Hansen, William Stein (12 February 2010) === - * Fixed Trac #7308 to make the cliquer spkg work on Cygwin. - -=== cliquer-1.2.p3 (Peter Jeremy, 2010-01-25) === - * #7824: add FreeBSD support - -=== cliquer-1.2.p2 (?, ?) === - * changelog lost to history - -=== cliquer-1.2.p1 Karl-Dieter Crisman, Georg S. Weber (7th October 2009) === - * fix trac #7115: Re-add support for building cliquer on Mac OS X 10.4 - -=== cliquer-1.2.p0 Minh Van Nguyen (16th September 2009) === - * Support for building cliquer 1.2 in 64-bit mode on Mac OS X 10.5.x - and 64-bit openSUSE 11.1. - * Add custom compilation and linking flags on top of the Makefile of - cliquer 1.2. - * Removed dependancy of cliquer on 'scons' - -=== cliquer-1.2 Nathann Cohen (17th July 2009) === - * First release put into Sage. - + * Makefile.patch: Patch the Makefile for Sage. Remove hardcoded + compiler and linker flags, allow flags to be set from spkg-install. + More importantly, we're building cliquer as a dynamic shared library, + instead of a stand-alone program. diff --git a/build/pkgs/cliquer/package-version.txt b/build/pkgs/cliquer/package-version.txt index 0986e116b06..52e40c7ff6e 100644 --- a/build/pkgs/cliquer/package-version.txt +++ b/build/pkgs/cliquer/package-version.txt @@ -1 +1 @@ -1.21.p1 +1.21.p2 diff --git a/build/pkgs/cliquer/patches/Makefile.patch b/build/pkgs/cliquer/patches/Makefile.patch index d17505d5a45..f773ecce3eb 100644 --- a/build/pkgs/cliquer/patches/Makefile.patch +++ b/build/pkgs/cliquer/patches/Makefile.patch @@ -1,27 +1,32 @@ -diff -ur src/Makefile src.patched/Makefile ---- src/Makefile 2010-02-16 05:26:57.000000000 +0100 -+++ src.patched/Makefile 2011-04-26 09:46:41.000000000 +0200 -@@ -1,14 +1,17 @@ - - ##### Configurable options: - -+# Don't need to set any of these compiler variables. They have already been -+# set when running SAGE_ROOT/local/bin/sage-env as part of installing a -+# package. - ## Compiler: +diff -ru src/Makefile b/Makefile +--- src/Makefile 2010-01-22 08:53:21.000000000 +0100 ++++ b/Makefile 2014-01-16 14:55:51.977047191 +0100 +@@ -1,24 +1,3 @@ +- +-##### Configurable options: +- +-## Compiler: -CC=gcc -+#CC=gcc - #CC=cc - - ## Compiler flags: - - # GCC: (also -march=pentium etc, for machine-dependent optimizing) +-#CC=cc +- +-## Compiler flags: +- +-# GCC: (also -march=pentium etc, for machine-dependent optimizing) -CFLAGS=-Wall -O3 -fomit-frame-pointer -funroll-loops -+#CFLAGS=-Wall -O3 -fomit-frame-pointer -funroll-loops - - # GCC w/ debugging: - #CFLAGS=-Wall -g -DINLINE= -@@ -29,14 +32,14 @@ +- +-# GCC w/ debugging: +-#CFLAGS=-Wall -g -DINLINE= +- +-# Compaq C / Digital C: +-#CFLAGS=-arch=host -fast +- +-# SunOS: +-#CFLAGS=-fast +- + ## Program options: + + # Enable long options for cl (eg. "cl --help"), comment out to disable. +@@ -29,14 +8,14 @@ ##### End of configurable options diff --git a/build/pkgs/cliquer/spkg-check b/build/pkgs/cliquer/spkg-check new file mode 100755 index 00000000000..3c6fd5964f0 --- /dev/null +++ b/build/pkgs/cliquer/spkg-check @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + +if [ "$SAGE_LOCAL" = "" ]; then + echo "SAGE_LOCAL undefined ... exiting"; + echo "Maybe run 'sage -sh'?" + exit 1 +fi + +OPTIMIZATION_FLAGS="-O3 -funroll-loops -fomit-frame-pointer" +# Work around a bug in gcc 4.6.0: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48774 +if [ "`testcc.sh $CC`" = GCC ] ; then + if $CC -dumpversion 2>/dev/null |grep >/dev/null '^4\.6\.[01]' ; then + echo "Warning: Working around bug in gcc 4.6.0" + OPTIMIZATION_FLAGS="$OPTIMIZATION_FLAGS -fno-ivopts" + fi +fi + +CFLAGS="$CFLAGS `testcflags.sh -g $OPTIMIZATION_FLAGS -fPIC -KPIC -Wall`" +CPPFLAGS="$CPPFLAGS -I$SAGE_LOCAL/include" +LDFLAGS="$LDFLAGS -L$SAGE_LOCAL/lib" + +# Compile for 64-bit if SAGE64 is set to 'yes'. +# On 64-bit hardware, we don't need to set this variable to true. A +# 64-bit cliquer library would be built on such platform. +if [ "$SAGE64" = yes ]; then + CFLAGS="$CFLAGS -m64 " + LDFLAGS="$LDFLAGS -m64 " +fi + +# Export everything +export CFLAGS +export CPPFLAGS +export LDFLAGS + +cd src && $MAKE test diff --git a/build/pkgs/cliquer/spkg-install b/build/pkgs/cliquer/spkg-install index 360baae8bdf..86b445883ad 100755 --- a/build/pkgs/cliquer/spkg-install +++ b/build/pkgs/cliquer/spkg-install @@ -6,12 +6,7 @@ if [ "$SAGE_LOCAL" = "" ]; then exit 1 fi -# This tells Bash to exit the script if any statement returns a non-true -# value. -set -e - -# Add a sensible default optimisation flag. Change if necessary. -OPTIMIZATION_FLAGS="-O2" +OPTIMIZATION_FLAGS="-O3 -funroll-loops -fomit-frame-pointer" # Work around a bug in gcc 4.6.0: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48774 if [ "`testcc.sh $CC`" = GCC ] ; then if $CC -dumpversion 2>/dev/null |grep >/dev/null '^4\.6\.[01]' ; then @@ -20,158 +15,36 @@ if [ "`testcc.sh $CC`" = GCC ] ; then fi fi +CFLAGS="$CFLAGS `testcflags.sh -g $OPTIMIZATION_FLAGS -fPIC -KPIC -Wall`" +CPPFLAGS="$CPPFLAGS -I$SAGE_LOCAL/include" +LDFLAGS="$LDFLAGS -L$SAGE_LOCAL/lib" -# Most packages do not need all these set. But it is better to do them all -# each time, rather than omit a flag by mistake. - -CFLAGS="$CFLAGS $OPTIMIZATION_FLAGS " -CXXFLAGS="$CXXFLAGS $OPTIMIZATION_FLAGS " -FCFLAGS="$FCFLAGS $OPTIMIZATION_FLAGS " -F77FLAGS="$F77FLAGS $OPTIMIZATION_FLAGS " -CPPFLAGS="$CPPFLAGS -I$SAGE_LOCAL/include " -LDFLAGS="$LDFLAGS -L$SAGE_LOCAL/lib " - -# Compile for 64-bit if SAGE64 is set to 'yes' or '1'. +# Compile for 64-bit if SAGE64 is set to 'yes'. # On 64-bit hardware, we don't need to set this variable to true. A # 64-bit cliquer library would be built on such platform. -if [ "x$SAGE64" = "xyes" ]; then +if [ "$SAGE64" = yes ]; then echo "Building a 64-bit version of cliquer" CFLAGS="$CFLAGS -m64 " - CXXFLAGS="$CXXFLAGS -m64 " - FCFLAGS="$FCFLAGS -m64 " - F77FLAGS="$F77FLAGS -m64 " - # Some packages may need LDFLAGS and/or ABI set here. LDFLAGS="$LDFLAGS -m64 " - # ABI=64 -# else -# echo "Building a 32-bit version of cliquer" -fi - -# If SAGE_DEBUG is set either unset (the default), or set to 'yes' -# add debugging information. -# Since both the Sun and GNU compilers accept -g to give debugging information, -# there is no need to do anything specific to one compiler or the other. - -if [ "x$SAGE_DEBUG" = "x" ] || [ "x$SAGE_DEBUG" = "xyes" ] ; then - echo "Code will be built with debugging information present. Set 'SAGE_DEBUG' to 'no' if you don't want that." - # Actually anything other than 'yes' or '1' will cause - # no debugging information to be added. - CFLAGS="$CFLAGS -g " - CXXFLAGS="$CXXFLAGS -g " - FCFLAGS="$FCFLAGS -g " - F77FLAGS="$F77FLAGS -g " -else - echo "No debugging information will be used during the build of this package." - echo "Unset SAGE_DEBUG if you want debugging information present (-g added)." -fi - -# Add appropriate flag(s) to show all warnings. -# This test of a compiler is not perfect by any means, but -# is better than nothing. -set +e -if "$CC" -flags > /dev/null 2>&1 ; then - CFLAGS="$CFLAGS -KPIC " - SUN_COMPILER=1 - # The Sun compilers are fussy, and adding extra - # warnings will just show too many. -else - # Assume GCC if not the Sun C compiler. - # Add -Wall to show all warnings. - CFLAGS="$CFLAGS -Wall -fomit-frame-pointer -funroll-loops -c -fPIC " - CXXFLAGS="$CXXFLAGS -Wall " - FCFLAGS="$FCFLAGS -Wall " - F77FLAGS="$F77FLAGS -Wall " - GNU_COMPILER=1 -fi - -# Determine if the C++ compiler is the Sun or GNU compiler. -# Just to check we are not mixing GNU and non-GNU. -if "$CXX" -flags > /dev/null 2>&1 ; then - SUN_COMPILER=1 -else - GNU_COMPILER=1 fi -# Determine if the Fortran compiler is the Sun or GNU compiler. -if [ -z "$SAGE_FORTRAN" ] ; then - echo "No Fortran compiler has been defined. This is not normally a problem." -else - if "$SAGE_FORTRAN" -flags > /dev/null 2>&1 ; then - SUN_COMPILER=1 - else - GNU_COMPILER=1 - fi -fi - -set -e - -# Checks that the user is not mixing the Sun and GNU compilers. This problem -# has been seen on code built with the aid of SCons, but in general could -# happen with any code if the user has specified a C compiler but not a C++ -# one. This problem is even more likely to occur with the Fortran compiler. - -if [ "x$SUN_COMPILER" = "x1" ] && [ "x$GNU_COMPILER" = "x1" ] ; then - echo "You are mixing the Sun and GNU C/C++/Fortran compilers." - echo "Such a combination will lead to problems." - echo "Check CC, CXX & SAGE_FORTRAN carefully." - echo "Exiting..." - exit 1 -fi - -# These are all used by GNU to specify compilers. -echo "Using CC=$CC" -echo "Using CXX=$CXX" -echo "Using FC=$FC" -echo "Using F77=$F77" - -# Used by Sage in connection with Fortran. -echo "Using SAGE_FORTRAN=$SAGE_FORTRAN" -echo "Using SAGE_FORTRAN_LIB=$SAGE_FORTRAN_LIB" - -# Flags which may be set. -echo "The following environment variables will be exported" -echo "Using CFLAGS=$CFLAGS" -echo "Using CXXFLAGS=$CXXFLAGS" -echo "Using FCFLAGS=$FCFLAGS" -echo "Using F77FLAGS=$F77FLAGS" -echo "Using CPPFLAGS=$CPPFLAGS" -echo "Using LDFLAGS=$LDFLAGS" -echo "Using ABI=$ABI" -echo "configure scripts and/or makefiles might override these later" -echo " " - -# Export everything. Probably not necessary in most cases. -export CFLAGS -export CXXFLAGS -export FCFLAGS -export F77FLAGS -export CPPFLAGS -export LDFLAGS -export ABI - -# End of pretty general spkg-install file. -# Now do the specific things needed for this package (cliquer). - # Flags for building a dynamically linked shared object. -SAGESOFLAGS=" " -if [ "$UNAME" = "Linux" ] || [ "$UNAME" = "FreeBSD" ]; then - SAGESOFLAGS="-shared -Wl,-soname,libcliquer.so" -elif [ "$UNAME" = "Darwin" ]; then - MACOSX_DEPLOYMENT_TARGET="10.3" - export MACOSX_DEPLOYMENT_TARGET +if [ "$UNAME" = "Darwin" ]; then + export MACOSX_DEPLOYMENT_TARGET="10.3" SAGESOFLAGS="-dynamiclib -single_module -flat_namespace -undefined dynamic_lookup" elif [ "$UNAME" = "SunOS" ]; then SAGESOFLAGS="-shared -Wl,-h,libcliquer.so -Wl,-ztext" -elif [ "$UNAME" = "CYGWIN" ]; then - SAGESOFLAGS="-shared -Wl,-soname,libcliquer.so" else - echo "Cannot determine your platform or it is not supported" - echo "Since SAGE_PORT is set, setting SAGESOFLAGS to Linux defaults." SAGESOFLAGS="-shared -Wl,-soname,libcliquer.so" fi + +# Export everything +export CFLAGS +export CPPFLAGS +export LDFLAGS export SAGESOFLAGS -cd src || return $? +cd src # Apply all patches for patch in ../patches/*.patch; do @@ -184,51 +57,19 @@ for patch in ../patches/*.patch; do fi done -#Do not exit script if there is an error, but instead print an -# informative error message. -set +e - -make -if [ $? -ne 0 ]; then - echo "Failed to compile cliquer... exiting" - exit 1 -fi - -if [ "$SAGE_CHECK" = "yes" ]; then - echo "Compiling and running the test cases of cliquer..." - - make testcases - if [ $? -ne 0 ]; then - echo "Failed to compile test cases of cliquer... exiting" - exit 1 - fi - - ./testcases - if [ $? -ne 0 ]; then - echo "Failed to run test cases of cliquer... exiting" - exit 1 - fi -fi - set -e -if [ ! -e "$SAGE_LOCAL/include/cliquer" ]; then - mkdir "$SAGE_LOCAL/include/cliquer/" -else - rm -rf "$SAGE_LOCAL/include/cliquer/" - mkdir "$SAGE_LOCAL/include/cliquer/" -fi +$MAKE + +rm -rf "$SAGE_LOCAL/include/cliquer/" +mkdir "$SAGE_LOCAL/include/cliquer/" +cp *.h "$SAGE_LOCAL/include/cliquer/" -cp -f *.h "$SAGE_LOCAL/include/cliquer/" if [ "$UNAME" = "Darwin" ]; then cp -f libcliquer.so "$SAGE_LOCAL/lib/libcliquer.dylib" - # On OS X 10.6 at least, the above does *NOT* work at all. - # So I'm also doing the following, which can't hurt. - cp -f libcliquer.so "$SAGE_LOCAL/lib/libcliquer.so" elif [ "$UNAME" = "CYGWIN" ]; then cp -f libcliquer.so "$SAGE_LOCAL/lib/libcliquer.dll" - cp -f libcliquer.so "$SAGE_LOCAL/lib/libcliquer.so" -else - cp -f libcliquer.so "$SAGE_LOCAL/lib/" fi +# Copy this in all cases, in any case it doesn't hurt. +cp -f libcliquer.so "$SAGE_LOCAL/lib/libcliquer.so" From 368ff90554ceabcfa2ebc55874ff5c69df46f31e Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Thu, 16 Jan 2014 14:14:04 +0100 Subject: [PATCH 043/163] Remove support for SAGE_FORTRAN --- build/install | 38 +----------------- build/pkgs/atlas/spkg-install | 16 ++++---- build/pkgs/rubiks/spkg-install | 64 ------------------------------ configure.ac | 2 +- src/bin/sage-env | 5 +-- src/doc/en/installation/source.rst | 12 ------ 6 files changed, 12 insertions(+), 125 deletions(-) diff --git a/build/install b/build/install index 2519646839a..32cb8af45e2 100755 --- a/build/install +++ b/build/install @@ -65,32 +65,6 @@ mkdir -p "$SAGE_SHARE" # Determine whether to install GCC (gcc, g++, gfortran). ############################################################################### -# Give a deprecation message whenever SAGE_FORTRAN or SAGE_FORTRAN_LIB -# is set to something. See Trac #13349. -if [ -n "$SAGE_FORTRAN" ] || [ -n "$SAGE_FORTRAN_LIB" ]; then -cat >&2 </dev/null 2>/dev/null; then + if command -v gfortran >/dev/null 2>/dev/null; then FC=gfortran elif command -v g95 >/dev/null 2>/dev/null; then FC=g95 @@ -264,12 +236,11 @@ fi # Create the sage_fortran script. ############################################################################### -# Don't use FC and SAGE_FORTRAN_LIB if we are installing GCC or have +# Don't use FC if we are installing GCC or have # installed gfortran, as that can cause compatibility problems. # We want to use the Fortran compiler that we build as part of GCC. if [ "$need_to_install_gcc" = yes ] || [ -x "$SAGE_LOCAL/bin/gfortran" ]; then unset FC - unset SAGE_FORTRAN_LIB fi # Write sage_fortran script. @@ -301,11 +272,6 @@ fi EOF chmod +x "$SAGE_LOCAL/bin/sage_fortran" -# Make the fortran library symlink if requested -if [ -f "$SAGE_FORTRAN_LIB" ]; then - ( cd "$SAGE_LOCAL/lib" && ln -sf "$SAGE_FORTRAN_LIB" . ) -fi - ############################################################################### # Create $SAGE_ROOT/build/Makefile starting from build/deps ############################################################################### diff --git a/build/pkgs/atlas/spkg-install b/build/pkgs/atlas/spkg-install index 61bd7ab7212..c0b6395a5e2 100755 --- a/build/pkgs/atlas/spkg-install +++ b/build/pkgs/atlas/spkg-install @@ -136,16 +136,16 @@ if 'SAGE_ATLAS_LIB' in os.environ: sym_gfortran = 'gfortran' in symbol_table sym_g95 = 'g95' in symbol_table if sym_gfortran and conf['fortran'] != 'gfortran': - print("Symbols in lib77blas indicate it was build with gfortran \n") - print("However SAGE is using a different fortran compiler \n") - print("If you wish to use this blas library, make sure SAGE_FORTRAN points \n") - print("to a fortran compiler compatible with this library. \n") + print("Symbols in lib77blas indicate it was built with gfortran.\n") + print("However, Sage is using a different fortran compiler.\n") + print("If you wish to use this blas library, make sure FC points\n") + print("to a fortran compiler compatible with this library.\n") sys.exit(2) if sym_g95 and conf['fortran'] != 'g95': - print("Symbols in lib77blas indicate it was build with g95 \n") - print("However SAGE is using a different fortran compiler \n") - print("If you wish to use this blas library, make sure SAGE_FORTRAN points \n") - print("to a fortran compiler compatible with this library. \n") + print("Symbols in lib77blas indicate it was built with g95 \n") + print("However, Sage is using a different fortran compiler.\n") + print("If you wish to use this blas library, make sure FC points\n") + print("to a fortran compiler compatible with this library.\n") sys.exit(2) SAGE_LOCAL_LIB = os.path.join(conf['SAGE_LOCAL'], 'lib') diff --git a/build/pkgs/rubiks/spkg-install b/build/pkgs/rubiks/spkg-install index ad198c4e78c..da74c86d9c3 100755 --- a/build/pkgs/rubiks/spkg-install +++ b/build/pkgs/rubiks/spkg-install @@ -92,76 +92,12 @@ else echo "Unset SAGE_DEBUG if you want debugging information present (-g added)" fi -# Add appropriate flag(s) to show all warnings. -# This test of a compiler is not perfect by any means, but -# is better than nothing. -if "$CC" -flags > /dev/null 2>&1 ; then - SUN_COMPILER=1 - # The Sun compilers are fussy, and adding extra - # warnings will just show too many. -else - # Assume gcc if not the Sun C compiler. - # Add -Wall to show all warnings. - CFLAGS="$CFLAGS -Wall " - CXXFLAGS="$CXXFLAGS -Wall " - FCFLAGS="$FCFLAGS -Wall " - F77FLAGS="$F77FLAGS -Wall " - GNU_COMPILER=1 -fi - -# Determine if the C++ compiler is the Sun or GNU compiler -# Just to check we are not mising GNU and non-GNU. -if "$CXX" -flags > /dev/null 2>&1 ; then - SUN_COMPILER=1 -else - GNU_COMPILER=1 -fi - - -# Determine if the Fortran compiler is the Sun or GNU compiler -if [ -z "$SAGE_FORTRAN" ] ; then - echo "No Fortran compiler has been defined. This is not normally a problem." -else - if "$SAGE_FORTRAN" -flags > /dev/null 2>&1 ; then - SUN_COMPILER=1 - else - GNU_COMPILER=1 - fi -fi - -# Check if SAGE_FORTRAN_LIB is defined, that the file actually exists. -# SAGE_FORTRAN_LIB does not always need to be defined, but if it is defined, then -# the file should exist. - -if [ -n "$SAGE_FORTRAN_LIB" ] && [ ! -e "$SAGE_FORTRAN_LIB" ]; then - echo "SAGE_FORTRAN_LIB is defined as $SAGE_FORTRAN_LIB, but does not exist" - exit 1 -fi - -# Checks that the user is not mixing the Sun and GNU compilers. This problem -# has been seen on code built with the aid of SCons, but in general could -# happen with any code if the user has specified a C compiler but not a C++ one. -# This problem is even more likely to occur with the Fortran compiler - I've done -# it myself when building Sage! - -if [ "x$SUN_COMPILER" = "x1" ] && [ "x$GNU_COMPILER" = "x1" ] ; then - echo "You are mixing the Sun and GNU C/C++/Fortran compilers" - echo "Such a combination will lead to problems." - echo "Check CC, CXX & SAGE_FORTRAN carefully." - echo "Exiting ..." - exit 1 -fi - # These are all used by GNU to specify compilers. echo "Using CC=$CC" echo "Using CXX=$CXX" echo "Using FC=$FC" echo "Using F77=$F77" -# Used by Sage in connection with Fortran -echo "Using SAGE_FORTRAN=$SAGE_FORTRAN" -echo "Using SAGE_FORTRAN_LIB=$SAGE_FORTRAN_LIB" - # Flags which may be set. echo "The following environment variables will be exported" echo "Using CFLAGS=$CFLAGS" diff --git a/configure.ac b/configure.ac index b782de6d078..7aff8cfd9d2 100644 --- a/configure.ac +++ b/configure.ac @@ -205,7 +205,7 @@ fi # Check the Fortran compiler accepts free-format source code # (as opposed to the older fixed-format style from Fortran 77). # This helps verify the compiler works too, so if some idiot -# sets SAGE_FORTRAN to /usr/bin/ls, we will at least know it's +# sets FC to /usr/bin/ls, we will at least know it's # not a working Fortran compiler. if test $enable_compiler_checks = yes then diff --git a/src/bin/sage-env b/src/bin/sage-env index a9021b7d401..38caa37aa13 100644 --- a/src/bin/sage-env +++ b/src/bin/sage-env @@ -479,10 +479,7 @@ if [ -z "$CXX" ]; then CXX=g++ fi if [ -z "$FC" ]; then - if [ -n "$SAGE_FORTRAN" ]; then - # Deprecated, see #13349. - FC="$SAGE_FORTRAN" - elif command -v gfortran >/dev/null 2>/dev/null; then + if command -v gfortran >/dev/null 2>/dev/null; then FC=gfortran elif command -v g95 >/dev/null 2>/dev/null; then FC=g95 diff --git a/src/doc/en/installation/source.rst b/src/doc/en/installation/source.rst index 70c2ed5c143..df087f65e9c 100644 --- a/src/doc/en/installation/source.rst +++ b/src/doc/en/installation/source.rst @@ -1089,18 +1089,6 @@ Some standard environment variables which are used by Sage: The same comments apply to these: setting them may cause problems, because they are not universally respected among the Sage packages. -The following Fortran-related environment variables are **deprecated** since -Sage 5.3 and support for these will likely be removed. -They are still recognized, but should not be used for new setups. - -- :envvar:`SAGE_FORTRAN` - the path to the Fortran compiler. - Deprecated, use :envvar:`FC` instead. - -- :envvar:`SAGE_FORTRAN_LIB` - the path to the Fortran runtime library. - Normally, you don't need to set this. - If you really need to, you can add the directory containing the library to - :envvar:`LIBRARY_PATH` and/or :envvar:`LD_LIBRARY_PATH`. - Sage uses the following environment variables when it runs: - :envvar:`DOT_SAGE` - this is the directory, to which the user has read and From ac731d2558e25e322bc0e68c5e146ec71b7a8dad Mon Sep 17 00:00:00 2001 From: Johan Bosman Date: Mon, 26 Dec 2011 19:58:58 +0000 Subject: [PATCH 044/163] Trac 12141: finite algebras over fields --- src/doc/en/reference/algebras/index.rst | 5 + src/sage/algebras/all.py | 2 + src/sage/algebras/finite_algebras/__init__.py | 1 + src/sage/algebras/finite_algebras/all.py | 1 + .../finite_algebras/finite_algebra.py | 711 ++++++++++++++++++ .../finite_algebras/finite_algebra_element.py | 526 +++++++++++++ .../finite_algebras/finite_algebra_ideal.py | 207 +++++ .../finite_algebra_morphism.py | 144 ++++ 8 files changed, 1597 insertions(+) create mode 100644 src/sage/algebras/finite_algebras/__init__.py create mode 100644 src/sage/algebras/finite_algebras/all.py create mode 100644 src/sage/algebras/finite_algebras/finite_algebra.py create mode 100644 src/sage/algebras/finite_algebras/finite_algebra_element.py create mode 100644 src/sage/algebras/finite_algebras/finite_algebra_ideal.py create mode 100644 src/sage/algebras/finite_algebras/finite_algebra_morphism.py diff --git a/src/doc/en/reference/algebras/index.rst b/src/doc/en/reference/algebras/index.rst index ed613983fe5..297f1c38127 100644 --- a/src/doc/en/reference/algebras/index.rst +++ b/src/doc/en/reference/algebras/index.rst @@ -4,6 +4,11 @@ Algebras .. toctree:: :maxdepth: 2 + sage/algebras/finite_algebras/finite_algebra + sage/algebras/finite_algebras/finite_algebra_element + sage/algebras/finite_algebras/finite_algebra_ideal + sage/algebras/finite_algebras/finite_algebra_morphism + sage/algebras/free_algebra sage/algebras/free_algebra_element diff --git a/src/sage/algebras/all.py b/src/sage/algebras/all.py index 9642aa0d8df..bf67be53c86 100644 --- a/src/sage/algebras/all.py +++ b/src/sage/algebras/all.py @@ -32,6 +32,8 @@ from steenrod.all import * +from finite_algebras.all import FiniteAlgebra + from group_algebra_new import GroupAlgebra from iwahori_hecke_algebra import IwahoriHeckeAlgebra, IwahoriHeckeAlgebraT diff --git a/src/sage/algebras/finite_algebras/__init__.py b/src/sage/algebras/finite_algebras/__init__.py new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/src/sage/algebras/finite_algebras/__init__.py @@ -0,0 +1 @@ + diff --git a/src/sage/algebras/finite_algebras/all.py b/src/sage/algebras/finite_algebras/all.py new file mode 100644 index 00000000000..93fb73ea455 --- /dev/null +++ b/src/sage/algebras/finite_algebras/all.py @@ -0,0 +1 @@ +from finite_algebra import FiniteAlgebra diff --git a/src/sage/algebras/finite_algebras/finite_algebra.py b/src/sage/algebras/finite_algebras/finite_algebra.py new file mode 100644 index 00000000000..7230dedc71c --- /dev/null +++ b/src/sage/algebras/finite_algebras/finite_algebra.py @@ -0,0 +1,711 @@ +""" +Finite algebras +""" + +#***************************************************************************** +# Copyright (C) 2011 Johan Bosman +# Copyright (C) 2011, 2013 Peter Bruin +# Copyright (C) 2011 Michiel Kosters +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# http://www.gnu.org/licenses/ +#***************************************************************************** + +from finite_algebra_element import FiniteAlgebraElement +from finite_algebra_ideal import FiniteAlgebraIdeal +from finite_algebra_morphism import FiniteAlgebraMorphism + +from sage.categories.all import FiniteDimensionalAlgebrasWithBasis +from sage.matrix.constructor import Matrix +from sage.matrix.matrix import is_Matrix +from sage.modules.free_module_element import vector +from sage.rings.ring import Algebra + +from sage.misc.cachefunc import cached_method + + +class FiniteAlgebra(Algebra): + """ + Create a finite `k`-algebra from a multiplication table. + + INPUT: + + - ``k`` -- a field + + - ``table`` -- a list of matrices + + - ``names`` -- string (default: ``'e'``) - names for the basis + elements + + - ``assume_associative`` -- boolean (default: ``False``). If + ``True``, then methods requiring associativity assume this + without checking. + + - ``category`` -- Category - the category to which this algebra + belongs (default: ``FiniteDimensionalAlgebrasWithBasis``(`k`)). + + The list ``table`` must have the following form: there exists a + finite dimensional `k`-algebra of degree `n` with basis + `(e_1,...,e_n)` such that the `i`-th element of ``table`` is the + matrix of right multiplication by `e_i` with respect to the basis + `(e_1,...,e_n)`. + + EXAMPLES:: + + sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A + Finite algebra of degree 2 over Finite Field of size 3 + + sage: B = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: B + Finite algebra of degree 3 over Rational Field + """ + + def __init__(self, k, table, names='e', assume_associative=False, category=None): + """ + TESTS:: + + sage: A = FiniteAlgebra(QQ, []) + sage: A + Finite algebra of degree 0 over Rational Field + sage: type(A) + + sage: TestSuite(A).run() + + sage: B = FiniteAlgebra(GF(7), [Matrix([1])]) + sage: B + Finite algebra of degree 1 over Finite Field of size 7 + sage: TestSuite(B).run() + + sage: C = FiniteAlgebra(CC, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: C + Finite algebra of degree 2 over Complex Field with 53 bits of precision + sage: TestSuite(C).run() + + sage: FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]])]) + Traceback (most recent call last): + ... + ValueError: input is not a multiplication table + + sage: D. = FiniteAlgebra(RR, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [-1, 0]])]) + sage: D.gens() + (a, b) + + sage: E = FiniteAlgebra(QQ, [Matrix([0])]) + sage: E.gens() + (e,) + """ + n = len(table) + self._table = [b.base_extend(k) for b in table] + if not all([is_Matrix(b) and b.dimensions() == (n, n) for b in table]): + raise ValueError("input is not a multiplication table") + self._assume_associative = assume_associative + # No further validity checks necessary! + if category is None: + category = FiniteDimensionalAlgebrasWithBasis(k) + Algebra.__init__(self, base_ring=k, names=names, category=category) + + def _repr_(self): + """ + Return a string representation of ``self``. + + TEST:: + + sage: FiniteAlgebra(RR, [Matrix([1])])._repr_() + 'Finite algebra of degree 1 over Real Field with 53 bits of precision' + """ + return "Finite algebra of degree %d over %s" % (self.degree(), self.base_ring()) + + def _coerce_map_from_(self, S): + """ + TESTS:: + + sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A.has_coerce_map_from(ZZ) # indirect doctest + True + sage: A.has_coerce_map_from(GF(3)) + True + sage: A.has_coerce_map_from(GF(5)) + False + sage: A.has_coerce_map_from(QQ) + False + """ + return S == self or (self.base_ring().has_coerce_map_from(S) and self.is_unitary()) + + Element = FiniteAlgebraElement + + def _element_constructor_(self, x): + """ + TESTS:: + + sage: A = FiniteAlgebra(QQ, [Matrix([0])]) + sage: a = A(0) + sage: a.parent() + Finite algebra of degree 1 over Rational Field + sage: A(1) + Traceback (most recent call last): + ... + TypeError: algebra is not unitary + + sage: B = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: B(17) # indirect doctest + 17*e0 + 17*e2 + """ + return self.element_class(self, x) + + # This is needed because the default implementation + # assumes that the algebra is unitary. + from_base_ring = _element_constructor_ + + def ngens(self): + """ + Return the number of generators of ``self``, i.e., the degree + of ``self`` over its base field. + + EXAMPLE:: + + sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A.ngens() + 2 + """ + return len(self._table) + + degree = ngens + + @cached_method + def gen(self, i): + """ + Return the `i`-th basis element of ``self``. + + EXAMPLE:: + + sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A.gen(0) + e0 + """ + return self.element_class(self, [j == i for j in xrange(self.ngens())]) + + def basis(self): + """ + Return a list of the basis elements of ``self``. + + EXAMPLE:: + + sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A.basis() + [e0, e1] + """ + return list(self.gens()) + + def _ideal_class_(self, n=0): + """ + Return the ideal class of ``self``. + + EXAMPLE:: + + sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A._ideal_class_() + + """ + return FiniteAlgebraIdeal + + def table(self): + """ + Return the multiplication table of ``self``, as a list of + matrices for right multiplication by the basis elements. + + EXAMPLE:: + + sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A.table() + [ + [1 0] [0 1] + [0 1], [0 0] + ] + """ + return self._table + + @cached_method + def left_table(self): + """ + Return the list of matrices for left multiplication by the + basis elements. + + EXAMPLE:: + + sage: B = FiniteAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1],[-1,0]])]) + sage: B.left_table() + [ + [1 0] [ 0 1] + [0 1], [-1 0] + ] + """ + B = self.table() + n = self.degree() + return [Matrix([B[j][i] for j in xrange(n)]) for i in xrange(n)] + + def __cmp__(self, other): + """ + Compare self to other. + + EXAMPLE:: + + sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: B = FiniteAlgebra(GF(5), [Matrix([0])]) + sage: cmp(A, A) + 0 + sage: cmp(B, B) + 0 + sage: cmp(A, B) + 1 + """ + if not isinstance(other, FiniteAlgebra): + return cmp(type(self), type(other)) + if self.base_ring() == other.base_ring(): + return cmp(self.table(), other.table()) + else: + return 1 + + def base_extend(self, F): + """ + Return ``self`` base changed to `F`. + + EXAMPLE:: + + sage: C = FiniteAlgebra(GF(2), [Matrix([1])]) + sage: k. = GF(4) + sage: C.base_extend(k) + Finite algebra of degree 1 over Finite Field in y of size 2^2 + """ + # Base extension of the multiplication table is done by __init__. + return FiniteAlgebra(F, self.table()) + + @cached_method + def cardinality(self): + """ + Return the cardinality of ``self``. + + EXAMPLES:: + + sage: A = FiniteAlgebra(GF(7), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [2, 3]])]) + sage: A.cardinality() + 49 + + sage: B = FiniteAlgebra(RR, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [2, 3]])]) + sage: B.cardinality() + +Infinity + + sage: C = FiniteAlgebra(RR, []) + sage: C.cardinality() + 1 + """ + n = self.degree() + if n == 0: + return 1 + return self.base_ring().cardinality() ** n + + def ideal(self, gens=None, given_by_matrix=False): + """ + Return the right ideal of ``self`` generated by ``gens``. + + INPUT: + + - ``A`` -- FiniteAlgebra + + - ``gens`` -- (default: None) - either an element of `A` or a + list of elements of `A`, given as vectors, matrices, or + FiniteAlgebraElements. If ``given_by_matrix`` is True, then + ``gens`` should instead be a matrix whose rows form a basis + of an ideal of `A`. + + - ``given_by_matrix`` -- boolean (default: ``False``) - if + ``True``, no checking is done + + EXAMPLE:: + + sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A.ideal(A([1,1])) + Ideal (e0 + e1) of Finite algebra of degree 2 over Finite Field of size 3 + """ + return self._ideal_class_()(self, gens=gens, + given_by_matrix=given_by_matrix) + + @cached_method + def is_associative(self): + """ + Return True if ``self`` is associative. + + EXAMPLES:: + + sage: A = FiniteAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1],[-1,0]])]) + sage: A.is_associative() + True + + sage: B = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,1]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,1], [0,0,0], [1,0,0]])]) + sage: B.is_associative() + False + + sage: e = B.basis() + sage: (e[1]*e[2])*e[2]==e[1]*(e[2]*e[2]) + False + """ + B = self.table() + n = self.degree() + for i in xrange(n): + for j in xrange(n): + eiej = B[j][i] + if B[i]*B[j] != sum(eiej[k] * B[k] for k in xrange(n)): + return False + return True + + @cached_method + def is_commutative(self): + """ + Return True if ``self`` is commutative. + + EXAMPLES:: + + sage: B = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: B.is_commutative() + True + + sage: C = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,0,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,1,0], [0,0,1]])]) + sage: C.is_commutative() + False + """ + # Equivalent to self.table() == self.left_table() + B = self.table() + for i in xrange(self.degree()): + for j in xrange(i): + if B[j][i] != B[i][j]: + return False + return True + + def is_finite(self): + """ + Return ``True`` if the cardinality of ``self`` is finite. + + EXAMPLES:: + + sage: A = FiniteAlgebra(GF(7), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [2, 3]])]) + sage: A.is_finite() + True + + sage: B = FiniteAlgebra(RR, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [2, 3]])]) + sage: B.is_finite() + False + + sage: C = FiniteAlgebra(RR, []) + sage: C.is_finite() + True + """ + return self.degree() == 0 or self.base_ring().is_finite() + + @cached_method + def is_unitary(self): + """ + Return ``True`` if ``self`` has a two-sided multiplicative + identity element. + + EXAMPLES:: + + sage: A = FiniteAlgebra(QQ, []) + sage: A.is_unitary() + True + + sage: B = FiniteAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1], [-1,0]])]) + sage: B.is_unitary() + True + + sage: C = FiniteAlgebra(QQ, [Matrix([[0,0], [0,0]]), Matrix([[0,0], [0,0]])]) + sage: C.is_unitary() + False + + sage: D = FiniteAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[1,0], [0,1]])]) + sage: D.is_unitary() + False + + .. NOTE:: + + If a finite algebra over a field admits a left identity, + then this is the unique left identity, and it is also a + right identity. + """ + k = self.base_ring() + n = self.degree() + # B is obtained by concatenating the elements of + # self.table(), and v by concatenating the rows of + # the n times n identity matrix. + B = reduce(lambda x, y: x.augment(y), + self.table(), Matrix(k, n, 0)) + v = vector(Matrix.identity(k, n).list()) + try: + self._one = B.solve_left(v) + return True + except ValueError: + return False + + def is_zero(self): + """ + Return ``True`` if ``self`` is the zero ring. + + EXAMPLES:: + + sage: A = FiniteAlgebra(QQ, []) + sage: A.is_zero() + True + + sage: B = FiniteAlgebra(GF(7), [Matrix([0])]) + sage: B.is_zero() + False + """ + return self.degree() == 0 + + def one(self): + """ + Return the multiplicative identity element of ``self``, if it + exists. + + EXAMPLES:: + + sage: A = FiniteAlgebra(QQ, []) + sage: A.one() + 0 + + sage: B = FiniteAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1], [-1,0]])]) + sage: B.one() + e0 + + sage: C = FiniteAlgebra(QQ, [Matrix([[0,0], [0,0]]), Matrix([[0,0], [0,0]])]) + sage: C.one() + Traceback (most recent call last): + ... + TypeError: algebra is not unitary + """ + if not self.is_unitary(): + raise TypeError("algebra is not unitary") + else: + return self(self._one) + + def random_element(self, *args, **kwargs): + """ + Return a random element of ``self``. + + Optional input parameters are propagated to the ``random_element`` + method of the underlying ``VectorSpace``. + + EXAMPLES:: + + sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A.random_element() # random + e0 + 2*e1 + + sage: B = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: B.random_element(num_bound=1000) # random + 215/981*e0 + 709/953*e1 + 931/264*e2 + """ + return self(self.zero_element().vector().parent().random_element(*args, **kwargs)) + + def _is_valid_homomorphism_(self, other, im_gens): + """ + TESTS:: + + sage: from sage.algebras.finite_algebras.finite_algebra_morphism import FiniteAlgebraMorphism + sage: A = FiniteAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: B = FiniteAlgebra(QQ, [Matrix([1])]) + sage: FiniteAlgebraMorphism(A, B, Matrix([[1], [0]])) + Morphism from Finite algebra of degree 2 over Rational Field to Finite algebra of degree 1 over Rational Field given by matrix + [1] + [0] + sage: FiniteAlgebraMorphism(B, A, Matrix([[1, 0]])) + Morphism from Finite algebra of degree 1 over Rational Field to Finite algebra of degree 2 over Rational Field given by matrix + [1 0] + sage: FiniteAlgebraMorphism(A, A, Matrix.identity(QQ, 2)) + Morphism from Finite algebra of degree 2 over Rational Field to Finite algebra of degree 2 over Rational Field given by matrix + [1 0] + [0 1] + sage: FiniteAlgebraMorphism(A, A, Matrix([[1, 0], [0, 0]])) + Morphism from Finite algebra of degree 2 over Rational Field to Finite algebra of degree 2 over Rational Field given by matrix + [1 0] + [0 0] + sage: FiniteAlgebraMorphism(A, A, Matrix([[1, 0], [1, 1]])) + Traceback (most recent call last): + ... + ValueError: relations do not all (canonically) map to 0 under map determined by images of generators. + sage: FiniteAlgebraMorphism(B, B, Matrix([[2]])) + Traceback (most recent call last): + ... + ValueError: relations do not all (canonically) map to 0 under map determined by images of generators. + """ + n = self.degree() + B = self.table() + for i in xrange(n): + for j in xrange(n): + eiej = B[j][i] + if (sum([other(im_gens[k]) * eiej[k] for k in xrange(n)]) + != other(im_gens[i]) * other(im_gens[j])): + return False + return True + + def quotient_map(self, ideal): + """ + Return the quotient of ``self`` by ``ideal``. + + INPUT: + + - ``ideal`` -- ``FiniteAlgebraIdeal`` + + OUTPUT: + + -- ``FiniteAlgebraMorphism``, the quotient homomorphism + + EXAMPLES:: + + sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: q0 = A.quotient_map(A.zero_ideal()) + sage: q0 + Morphism from Finite algebra of degree 2 over Finite Field of size 3 to Finite algebra of degree 2 over Finite Field of size 3 given by matrix + [1 0] + [0 1] + sage: q1 = A.quotient_map(A.ideal(A.gen(1))) + sage: q1 + Morphism from Finite algebra of degree 2 over Finite Field of size 3 to Finite algebra of degree 1 over Finite Field of size 3 given by matrix + [1] + [0] + """ + k = self.base_ring() + f = ideal.basis_matrix().transpose().kernel().basis_matrix().echelon_form().transpose() + pivots = f.pivot_rows() + table = [] + for p in pivots: + v = vector(k, self.degree()) + v[p] = 1 + v = self.element_class(self, v) + table.append(f.solve_right(v.matrix() * f)) + B = FiniteAlgebra(k, table) + return FiniteAlgebraMorphism(self, B, f, check=False) + + def maximal_ideal(self): + """ + Compute the maximal ideal of the local algebra ``self``. + + INPUT: + + - ``self`` -- ``FiniteAlgebra``, must be unitary, commutative, + associative and local (have a unique maximal ideal) + + OUTPUT: + + -- ``FiniteAlgebraIdeal``, the unique maximal ideal of + ``self``. If ``self`` is not a local algebra, a ValueError + is raised. + + EXAMPLES:: + + sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A.maximal_ideal() + Ideal (0, e1) of Finite algebra of degree 2 over Finite Field of size 3 + + sage: B = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: B.maximal_ideal() + Traceback (most recent call last): + ... + ValueError: algebra is not local + """ + if self.degree() == 0: + raise ValueError, "the zero algebra is not local" + if not(self.is_unitary() and self.is_commutative() + and (self._assume_associative or self.is_associative())): + raise TypeError("algebra must be unitary, commutative and associative") + gens = [] + for x in self.gens(): + f = x.characteristic_polynomial().factor() + if len(f) != 1: + raise ValueError, "algebra is not local" + if f[0][1] > 1: + gens.append(f[0][0](x)) + return FiniteAlgebraIdeal(self, gens) + + def primary_decomposition(self): + """ + Return the primary decomposition of ``self``. + + INPUT: + + - ``self`` -- ``FiniteAlgebra``, must be unitary, commutative + and associative + + OUTPUT: + + -- a list consisting of the quotient maps ``self`` -> `A`, + with `A` running through the primary factors of ``self`` + + EXAMPLES:: + + sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A.primary_decomposition() + [Morphism from Finite algebra of degree 2 over Finite Field of size 3 to Finite algebra of degree 2 over Finite Field of size 3 given by matrix [1 0] + [0 1]] + + sage: B = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: B.primary_decomposition() + [Morphism from Finite algebra of degree 3 over Rational Field to Finite algebra of degree 1 over Rational Field given by matrix [0] + [0] + [1], Morphism from Finite algebra of degree 3 over Rational Field to Finite algebra of degree 2 over Rational Field given by matrix [1 0] + [0 1] + [0 0]] + """ + k = self.base_ring() + n = self.degree() + if n == 0: + return [] + if not(self.is_unitary() and self.is_commutative() + and (self._assume_associative or self.is_associative())): + raise TypeError("algebra must be unitary, commutative and associative") + # Start with the trivial decomposition of self. + components = [Matrix.identity(k, n)] + for b in self.table(): + # Use the action of the basis element b to refine our + # decomposition of self. + components_new = [] + for c in components: + # Compute the matrix of b on the component c, find its + # characteristic polynomial, and factor it. + b_c = c.solve_left(c * b) + fact = b_c.characteristic_polynomial().factor() + if len(fact) == 1: + components_new.append(c) + else: + for f in fact: + h, a = f + e = h(b_c) ** a + ker_e = e.kernel().basis_matrix() + components_new.append(ker_e * c) + components = components_new + quotients = [] + for i in range(len(components)): + I = Matrix(k, 0, n) + for j in range(len(components)): + if j != i: + I = I.stack(components[j]) + quotients.append(self.quotient_map(self.ideal(I, given_by_matrix=True))) + return quotients + + def maximal_ideals(self): + """ + Return a list consisting of all maximal ideals of ``self``. + + EXAMPLES:: + + sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A.maximal_ideals() + [Ideal (e1) of Finite algebra of degree 2 over Finite Field of size 3] + + sage: B = FiniteAlgebra(QQ, []) + sage: B.maximal_ideals() + [] + """ + P = self.primary_decomposition() + return [f.inverse_image(f.codomain().maximal_ideal()) for f in P] diff --git a/src/sage/algebras/finite_algebras/finite_algebra_element.py b/src/sage/algebras/finite_algebras/finite_algebra_element.py new file mode 100644 index 00000000000..571403f6f59 --- /dev/null +++ b/src/sage/algebras/finite_algebras/finite_algebra_element.py @@ -0,0 +1,526 @@ +""" +Elements of finite algebras +""" + +#***************************************************************************** +# Copyright (C) 2011 Johan Bosman +# Copyright (C) 2011, 2013 Peter Bruin +# Copyright (C) 2011 Michiel Kosters +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# http://www.gnu.org/licenses/ +#***************************************************************************** + +import re + +from sage.matrix.constructor import Matrix +from sage.matrix.matrix import is_Matrix +from sage.modules.free_module_element import vector +from sage.rings.integer import Integer +from sage.structure.element import AlgebraElement, is_Vector, parent + + +class FiniteAlgebraElement(AlgebraElement): + """ + Create an element of a FiniteAlgebra using a multiplication table. + + INPUT: + + - ``A`` -- ``FiniteAlgebra`` + + - ``elt`` -- vector, matrix or element of the base field + (default: ``None``) + + - ``check`` -- boolean (default: True) - if False and ``elt`` is a + matrix, assume that it is known to be the matrix of an element + + If ``elt`` is a vector, it is interpreted as a vector of + coordinates with respect to the given basis of `A`. If ``elt`` is + a matrix, it is interpreted as a multiplication matrix with + respect to this basis. + + EXAMPLES:: + + sage: A = FiniteAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) + sage: A(17) + 2*e0 + sage: A([1,1]) + e0 + e1 + """ + + def __init__(self, A, elt=None, check=True): + """ + TESTS:: + + sage: A = FiniteAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) + sage: A(QQ(4)) + Traceback (most recent call last): + ... + TypeError: elt should be a vector, a matrix, or an element of the base field + + sage: B = FiniteAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1], [-1,0]])]) + sage: B(Matrix([[1,1], [-1,1]])) + e0 + e1 + sage: B(Matrix([[0,1], [1,0]])) + Traceback (most recent call last): + ... + ValueError: matrix does not define an element of the algebra + """ + AlgebraElement.__init__(self, A) + k = A.base_ring() + n = A.degree() + if elt is None: + self._vector = vector(k, n) + self._matrix = Matrix(k, n) + else: + if isinstance(elt, int): + elt = Integer(elt) + elif isinstance(elt, list): + elt = vector(elt) + if A == elt.parent(): + self._vector = elt._vector.base_extend(k) + self._matrix = elt._matrix.base_extend(k) + elif k.has_coerce_map_from(elt.parent()): + e = k(elt) + if e == 0: + self._vector = vector(k, n) + self._matrix = Matrix(k, n) + elif A.is_unitary(): + self._vector = A._one * e + self._matrix = Matrix.identity(k, n) * e + else: + raise TypeError("algebra is not unitary") + elif is_Vector(elt): + self._vector = elt.base_extend(k) + self._matrix = Matrix(k, sum([elt[i] * A.table()[i] for i in xrange(n)])) + elif is_Matrix(elt): + if A.is_unitary(): + self._vector = A._one * elt + if not check or sum([self._vector[i]*A.table()[i] for i in xrange(n)]) == elt: + self._matrix = elt + else: + raise ValueError("matrix does not define an element of the algebra") + else: + raise TypeError("algebra is not unitary") + else: + raise TypeError("elt should be a vector, a matrix, " + + "or an element of the base field") + + def vector(self): + """ + Return ``self`` as a vector. + + EXAMPLE:: + + sage: B = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: B(5).vector() + (5, 0, 5) + """ + return self._vector + + def matrix(self): + """ + Return the matrix for multiplication by ``self`` from the right. + + EXAMPLE:: + + sage: B = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: B(5).matrix() + [5 0 0] + [0 5 0] + [0 0 5] + """ + return self._matrix + + def left_matrix(self): + """ + Return the matrix for multiplication by ``self`` from the left. + + EXAMPLES:: + + sage: C = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,0,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,1,0], [0,0,1]])]) + sage: C([1,2,0]).left_matrix() + [1 0 0] + [0 1 0] + [0 2 0] + + """ + A = self.parent() + if A.is_commutative(): + return self._matrix + return sum([self.vector()[i] * A.left_table()[i] for + i in xrange(A.degree())]) + + def _repr_(self): + """ + Return the string representation of self. + + EXAMPLE:: + + sage: A = FiniteAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) + sage: A(1)._repr_() + 'e0' + """ + s = " " + A = self.parent() + m = A.degree() + coeffs = list(self.vector()) + atomic = A.base_ring()._repr_option('element_is_atomic') + non_zero = False + for n in xrange(m): + x = coeffs[n] + if x: + if non_zero: + s += " + " + non_zero = True + x = y = repr(x) + if y.find('-') == 0: + y = y[1:] + if not atomic and (y.find("+") != -1 or y.find("-") != -1): + x = "(%s)"%x + var = "*%s" % A._names[n] + s += "%s%s" % (x, var) + s = s.replace(" + -", " - ") + s = re.sub(r' 1(\.0+)?\*',' ', s) + s = re.sub(r' -1(\.0+)?\*',' -', s) + if s == " ": + return "0" + return s[1:] + + def _latex_(self): + """ + Return the LaTeX representation of self. + + EXAMPLE:: + + sage: A = FiniteAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) + sage: latex(A(1)) # indirect doctest + \left(\begin{array}{rr} + 1 & 0 \\ + 0 & 1 + \end{array}\right) + """ + from sage.misc.latex import latex + return latex(self.matrix()) + + def __eq__(self, other): + """ + EXAMPLES:: + + sage: A = FiniteAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) + sage: A(2) == 2 + True + sage: A(2) == 3 + False + sage: A(2) == GF(5)(2) + False + """ + A = self.parent() + if A.has_coerce_map_from(parent(other)): + return self.vector() == A(other).vector() + else: + return False + + def __ne__(self, other): + """ + EXAMPLE:: + + sage: B = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: B(1) != 0 + True + """ + return not self.__eq__(other) + + def __gt__(self, other): + """ + Raise a TypeError as there is no ordering defined on a FiniteAlgebra:: + + sage: A = FiniteAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) + sage: A(1) > 0 + Traceback (most recent call last): + ... + TypeError: there is no ordering defined on a FiniteAlgebra + """ + raise TypeError("there is no ordering defined on a FiniteAlgebra") + + def __lt__(self, other): + """ + Raise a TypeError as there is no ordering defined on a FiniteAlgebra:: + + sage: A = FiniteAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) + sage: A(1) < 0 + Traceback (most recent call last): + ... + TypeError: there is no ordering defined on a FiniteAlgebra + """ + raise TypeError("there is no ordering defined on a FiniteAlgebra") + + def __ge__(self, other): + """ + Raise a TypeError as there is no ordering defined on a FiniteAlgebra:: + + sage: A = FiniteAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) + sage: A(1) >= 0 + Traceback (most recent call last): + ... + TypeError: there is no ordering defined on a FiniteAlgebra + """ + raise TypeError("there is no ordering defined on a FiniteAlgebra") + + def __le__(self, other): + """ + Raise a TypeError as there is no ordering defined on a FiniteAlgebra:: + + sage: A = FiniteAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) + sage: A(1) <= 0 + Traceback (most recent call last): + ... + TypeError: there is no ordering defined on a FiniteAlgebra + """ + raise TypeError("there is no ordering defined on a FiniteAlgebra") + + def __cmp__(self, other): + """ + EXAMPLES:: + + sage: A = FiniteAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) + sage: cmp(A(0), A(1)) + 1 + sage: cmp(A(0), A(0)) + 0 + + sage: B = FiniteAlgebra(QQ, [Matrix([0])]) + sage: B.basis()[0] == 0 + False + sage: B.basis()[0]^2 == 0 + True + """ + if self.vector() == other.vector(): + return 0 + else: + return 1 + + def _add_(self, other): + """ + EXAMPLE:: + + sage: A = FiniteAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) + sage: A.basis()[0] + A.basis()[1] # indirect doctest + e0 + e1 + """ + return FiniteAlgebraElement(self.parent(), + self.vector() + other.vector()) + + def _sub_(self, other): + """ + EXAMPLE:: + + sage: A = FiniteAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) + sage: A.basis()[0] - A.basis()[1] # indirect doctest + e0 + 2*e1 + """ + return FiniteAlgebraElement(self.parent(), + self.vector() - other.vector()) + + def _mul_(self, other): + """ + EXAMPLE:: + + sage: C = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,0,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,1,0], [0,0,1]])]) + sage: C.basis()[1] * C.basis()[2] # indirect doctest + e1 + """ + return FiniteAlgebraElement(self.parent(), + self.vector() * other.matrix()) + + def _lmul_(self, other): + """ + TESTS:: + + sage: C = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,0,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,1,0], [0,0,1]])]) + sage: c = C.random_element() + sage: c * 2 == c + c # indirect doctest + True + """ + if self.parent().base_ring().has_coerce_map_from(other.parent()): + return FiniteAlgebraElement(self.parent(), + other * self.vector()) + else: + raise TypeError("unsupported operand parent(s) for '*': '%s' and '%s'" + % (self.parent(), other.parent())) + + def _rmul_(self, other): + """ + TESTS:: + + sage: C = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,0,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,1,0], [0,0,1]])]) + sage: c = C.random_element() + sage: 2 * c == c + c # indirect doctest + True + """ + if self.parent().base_ring().has_coerce_map_from(other.parent()): + return FiniteAlgebraElement(self.parent(), + other * self.vector()) + else: + raise TypeError("unsupported operand parent(s) for '*': '%s' and '%s'" + % (self.parent(), other.parent())) + + def __pow__(self, n): + """ + Return ``self`` raised to the power `n`. + + EXAMPLE:: + + sage: B = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: b = B(vector(QQ, [2,3,4])) + sage: b^6 + 64*e0 + 576*e1 + 4096*e2 + """ + A = self.parent() + if not (A._assume_associative or A.is_associative()): + raise TypeError("algebra is not associative") + if n > 0: + return FiniteAlgebraElement(A, self.vector() * self.matrix().__pow__(n - 1)) + if not A.is_unitary(): + raise TypeError("algebra is not unitary") + if n == 0: + return A.one() + a = self.inverse() + return FiniteAlgebraElement(A, a.vector() * a.matrix().__pow__(-n - 1)) + + def is_invertible(self): + """ + Return ``True`` if ``self`` has a two-sided multiplicative + inverse. + + EXAMPLE:: + + sage: C = FiniteAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1], [-1,0]])]) + sage: C([1,2]).is_invertible() + True + sage: C(0).is_invertible() + False + + .. NOTE:: + + If an element of a unitary finite algebra over a field + admits a left inverse, then this is the unique left + inverse, and it is also a right inverse. + """ + A = self.parent() + if not A.is_unitary(): + raise TypeError("algebra is not unitary") + try: + a = self.matrix().inverse() + except ZeroDivisionError: + return False + try: + self._inverse = FiniteAlgebraElement(A, a, check=True) + except ValueError: + return False + return True + + def inverse(self): + """ + Return the two-sided multiplicative inverse of ``self``, if it + exists. + + EXAMPLE:: + + sage: C = FiniteAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1], [-1,0]])]) + sage: C([1,2]).inverse() + 1/5*e0 - 2/5*e1 + + .. NOTE:: + + If an element of a unitary finite algebra over a field + admits a left inverse, then this is the unique left + inverse, and it is also a right inverse. + """ + if self.is_invertible(): + return self._inverse + raise ZeroDivisionError("element is not invertible") + + def is_zerodivisor(self): + """ + Return true if ``self`` is a left or right zero-divisor. + + EXAMPLES:: + + sage: C = FiniteAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) + sage: C([1,0]).is_zerodivisor() + False + sage: C([0,1]).is_zerodivisor() + True + + """ + return self.matrix().det() == 0 or self.left_matrix().det() == 0 + + def is_nilpotent(self): + """ + Return true if ``self`` is nilpotent. + + EXAMPLES:: + + sage: C = FiniteAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) + sage: C([1,0]).is_nilpotent() + False + sage: C([0,1]).is_nilpotent() + True + + sage: A = FiniteAlgebra(QQ, [Matrix([0])]) + sage: A([1]).is_nilpotent() + True + """ + A = self.parent() + if not (A._assume_associative or A.is_associative()): + raise TypeError("algebra is not associative") + return self.matrix().__pow__(A.degree()) == 0 + + def minimal_polynomial(self): + """ + Return the minimal polynomial of ``self``. + + EXAMPLES:: + + sage: B = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: B(0).minimal_polynomial() + x + sage: b = B.random_element() + sage: f = b.minimal_polynomial(); f # random + x^3 + 1/2*x^2 - 7/16*x + 1/16 + sage: f(b) == 0 + True + """ + A = self.parent() + if not A.is_unitary(): + raise TypeError("algebra is not unitary") + if not (A._assume_associative or A.is_associative()): + raise TypeError("algebra is not associative") + return self.matrix().minimal_polynomial() + + def characteristic_polynomial(self): + """ + Return the characteristic polynomial of ``self``. + + EXAMPLES:: + + sage: B = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: B(0).characteristic_polynomial() + x^3 + sage: b = B.random_element() + sage: f = b.characteristic_polynomial(); f # random + x^3 - 8*x^2 + 16*x + sage: f(b) == 0 + True + + .. NOTE:: + + This function just returns the characteristic polynomial + of the matrix of right multiplication by ``self``. This + may not be a very meaningful invariant if the algebra is + not unitary and associative. + """ + return self.matrix().characteristic_polynomial() diff --git a/src/sage/algebras/finite_algebras/finite_algebra_ideal.py b/src/sage/algebras/finite_algebras/finite_algebra_ideal.py new file mode 100644 index 00000000000..597614b76d3 --- /dev/null +++ b/src/sage/algebras/finite_algebras/finite_algebra_ideal.py @@ -0,0 +1,207 @@ +""" +Ideals of finite algebras +""" + +#***************************************************************************** +# Copyright (C) 2011 Johan Bosman +# Copyright (C) 2011, 2013 Peter Bruin +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# http://www.gnu.org/licenses/ +#***************************************************************************** + +from finite_algebra_element import FiniteAlgebraElement + +from sage.matrix.constructor import Matrix +from sage.matrix.matrix import is_Matrix +from sage.rings.ideal import Ideal_generic +from sage.structure.element import parent +from sage.structure.sage_object import SageObject + +from sage.misc.cachefunc import cached_method + + +class FiniteAlgebraIdeal(Ideal_generic): + """ + Create an ideal of a FiniteAlgebra. + """ + + def __init__(self, A, gens=None, given_by_matrix=False): + """ + EXAMPLES:: + + sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A.ideal(A([0,1])) + Ideal (e1) of Finite algebra of degree 2 over Finite Field of size 3 + """ + k = A.base_ring() + n = A.degree() + if given_by_matrix: + self._basis_matrix = gens + gens = gens.rows() + elif gens is None: + self._basis_matrix = Matrix(k, 0, n) + elif isinstance(gens, (list, tuple)): + B = [FiniteAlgebraIdeal(A, x).basis_matrix() for x in gens] + B = reduce(lambda x, y: x.stack(y), B, Matrix(k, 0, n)) + self._basis_matrix = B.echelon_form().image().basis_matrix() + else: + if is_Matrix(gens): + gens = FiniteAlgebraElement(A, gens) + if isinstance(gens, FiniteAlgebraElement): + gens = gens.vector() + B = Matrix([gens * b for b in A.table()]) + self._basis_matrix = B.echelon_form().image().basis_matrix() + Ideal_generic.__init__(self, A, gens) + + def __eq__(self, other): + """ + EXAMPLES:: + + sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: I = A.ideal(A([1,1])) + sage: J = A.ideal(A([0,1])) + sage: I == J + False + sage: I == I + True + sage: I == I + J + True + """ + if self is other: + return True + if self.ring() is not other.ring(): + return False + return self.basis_matrix() == other.basis_matrix() + + def __ne__(self, other): + """ + EXAMPLES:: + + sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: I = A.ideal(A([1,1])) + sage: J = A.ideal(A([0,1])) + sage: I != J + True + sage: I != I + False + sage: I != I + J + False + """ + return not self.__eq__(other) + + def __contains__(self, elt): + """ + EXAMPLES:: + + sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: J = A.ideal(A([0,1])) + sage: A([0,1]) in J + True + sage: A([1,0]) in J + False + """ + if self.ring() is not parent(elt): + return False + return elt.vector() in self.vector_space() + + def __le__(self, other): + """ + EXAMPLES:: + + sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: I = A.ideal(A([1,1])) + sage: J = A.ideal(A([0,1])) + sage: I <= J + False + sage: I <= I + True + sage: I <= I + J + True + """ + if self is other: + return True + if self.ring() is not other.ring(): + return False + return self.vector_space().is_subspace(other.vector_space()) + + def __lt__(self, other): + """ + EXAMPLES:: + + sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: I = A.ideal(A([1,1])) + sage: J = A.ideal(A([0,1])) + sage: I < J + False + sage: I < I + False + sage: I < I + J + False + """ + return self.__ne__(other) and self.__le__(other) + + def __ge__(self, other): + """ + EXAMPLES:: + + sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: I = A.ideal(A([1,1])) + sage: J = A.ideal(A([0,1])) + sage: I >= J + True + sage: I >= I + True + sage: I >= I + J + True + """ + return other.__le__(self) + + def __gt__(self, other): + """ + EXAMPLES:: + + sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: I = A.ideal(A([1,1])) + sage: J = A.ideal(A([0,1])) + sage: I > J + True + sage: I > I + False + sage: I > I + J + False + """ + return other.__lt__(self) + + def basis_matrix(self): + """ + Return the echelonized matrix whose rows form a basis of ``self``. + + EXAMPLE:: + + sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: I = A.ideal(A([1,1])) + sage: I.basis_matrix() + [1 0] + [0 1] + """ + return self._basis_matrix + + @cached_method + def vector_space(self): + """ + Return ``self`` as a vector space. + + EXAMPLE:: + + sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: I = A.ideal(A([1,1])) + sage: I.vector_space() + Vector space of degree 2 and dimension 2 over Finite Field of size 3 + Basis matrix: + [1 0] + [0 1] + """ + return self.basis_matrix().image() diff --git a/src/sage/algebras/finite_algebras/finite_algebra_morphism.py b/src/sage/algebras/finite_algebras/finite_algebra_morphism.py new file mode 100644 index 00000000000..4178d992eb2 --- /dev/null +++ b/src/sage/algebras/finite_algebras/finite_algebra_morphism.py @@ -0,0 +1,144 @@ +""" +Morphisms between finite algebras +""" + +#***************************************************************************** +# Copyright (C) 2011 Johan Bosman +# Copyright (C) 2011, 2013 Peter Bruin +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# http://www.gnu.org/licenses/ +#***************************************************************************** + +from sage.categories.homset import Hom +from sage.rings.morphism import RingHomomorphism_im_gens + + +class FiniteAlgebraMorphism(RingHomomorphism_im_gens): + """ + Create a morphism between FiniteAlgebras. + + INPUT: + + - ``A`` -- FiniteAlgebra + + - ``B`` -- FiniteAlgebra + + - ``f`` -- matrix of the underlying k-linear map + + - ``unitary`` -- boolean (default: True) - if True and ``check`` + is also True, raise a ValueError unless `A` and `B` are unitary + and `f` respects unit elements + + - ``check`` -- boolean (default: True) - check whether the given + k-linear map really defines a (not necessarily unitary) + k-algebra homomorphism + + The algebras `A` and `B` must be defined over the same base field. + + EXAMPLES: + + sage: from sage.algebras.finite_algebras.finite_algebra_morphism import FiniteAlgebraMorphism + sage: A = FiniteAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: B = FiniteAlgebra(QQ, [Matrix([1])]) + sage: f = FiniteAlgebraMorphism(A, B, Matrix([[1], [0]])) + sage: f.domain() is A + True + sage: f.codomain() is B + True + sage: f(A.basis()[0]) + e + sage: f(A.basis()[1]) + 0 + + TODO: example illustrating unitary flag + """ + + def __init__(self, A, B, f, unitary=True, check=True): + """ + TEST:: + + sage: from sage.algebras.finite_algebras.finite_algebra_morphism import FiniteAlgebraMorphism + sage: A = FiniteAlgebra(QQ, [Matrix([1])]) + sage: B = FiniteAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: FiniteAlgebraMorphism(A, B, Matrix([[1, 0]])) + Morphism from Finite algebra of degree 1 over Rational Field to Finite algebra of degree 2 over Rational Field given by matrix + [1 0] + """ + RingHomomorphism_im_gens.__init__(self, parent=Hom(A, B), im_gens=f.rows(), check=check) + self._matrix = f + if not (unitary and check): + return + if (not A.is_unitary() + or not B.is_unitary() + or self(A.one()) != B.one()): + raise ValueError("homomorphism does not respect unit elements") + + def __call__(self, x): + """ + TEST:: + + sage: A = FiniteAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: I = A.maximal_ideal() + sage: q = A.quotient_map(I) + sage: q(0) == 0 and q(1) == 1 + True + """ + x = self.domain()(x) + B = self.codomain() + return B.element_class(B, x.vector() * self.matrix()) + + def _repr_(self): + """ + TEST:: + + sage: A = FiniteAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: I = A.maximal_ideal() + sage: q = A.quotient_map(I) + sage: q._repr_() + 'Morphism from Finite algebra of degree 2 over Rational Field to Finite algebra of degree 1 over Rational Field given by matrix\n[1]\n[0]' + """ + return "Morphism from %s to %s given by matrix\n%s" \ + % (self.domain(), self.codomain(), self.matrix()) + + def matrix(self): + """ + Return the matrix of ``self``. + + EXAMPLE:: + + sage: from sage.algebras.finite_algebras.finite_algebra_morphism import FiniteAlgebraMorphism + sage: A = FiniteAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: B = FiniteAlgebra(QQ, [Matrix([1])]) + sage: M = Matrix([[1], [0]]) + sage: f = FiniteAlgebraMorphism(A, B, M) + sage: f.matrix() == M + True + """ + return self._matrix + + def inverse_image(self, I): + """ + Return the inverse image of `I` under ``self``. + + INPUT: + + - ``I`` -- ``FiniteAlgebraIdeal``, an ideal of ``self.codomain()`` + + OUTPUT: + + -- ``FiniteAlgebraIdeal``, the inverse image of `I` under ``self``. + + EXAMPLE:: + + sage: A = FiniteAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: I = A.maximal_ideal() + sage: q = A.quotient_map(I) + sage: B = q.codomain() + sage: q.inverse_image(B.zero_ideal()) == I + True + """ + coker_I = I.basis_matrix().transpose().kernel().basis_matrix().transpose() + return self.domain().ideal((self.matrix() * coker_I).kernel().basis_matrix(), given_by_matrix=True) From baf61f12b15b12bf7d782724d0f938feaff6d114 Mon Sep 17 00:00:00 2001 From: Ben Hutz Date: Sat, 18 Jan 2014 12:31:32 -0500 Subject: [PATCH 045/163] Improve documentation of projective dynatomic polynomial --- .../schemes/projective/projective_morphism.py | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/sage/schemes/projective/projective_morphism.py b/src/sage/schemes/projective/projective_morphism.py index e4de291ae68..168bc392023 100644 --- a/src/sage/schemes/projective/projective_morphism.py +++ b/src/sage/schemes/projective/projective_morphism.py @@ -365,7 +365,7 @@ def dynatomic_polynomial(self, period): For a map `f:\mathbb{P}^1 \to \mathbb{P}^1` this function computes the dynatomic polynomial. The dynatomic polynomial is the analog of the cyclotomic - polynomial and its roots are the points of formal period `n`. + polynomial and its roots are the points of formal period `period`. ALGORITHM: @@ -504,6 +504,36 @@ def dynatomic_polynomial(self, period): sage: f = H([x^2+ c*y^2,y^2]) sage: f.dynatomic_polynomial([1,2]) x^2 - x*y + (c + 1)*y^2 + + :: + + sage: P. = ProjectiveSpace(QQ,1) + sage: H = Hom(P,P) + sage: f = H([x^2+y^2,y^2]) + sage: f.dynatomic_polynomial(2) + x^2 + x*y + 2*y^2 + sage: R. = PolynomialRing(QQ) + sage: K. = NumberField(X^2 + X + 2) + sage: PP = P.change_ring(K) + sage: ff = f.change_ring(K) + sage: p = PP((c,1)) + sage: ff(ff(p)) == p + True + + :: + + sage: P. = ProjectiveSpace(QQ,1) + sage: H = Hom(P,P) + sage: f = H([x^2+y^2,x*y]) + sage: f.dynatomic_polynomial([2,2]) + x^4 + 4*x^2*y^2 + y^4 + sage: R. = PolynomialRing(QQ) + sage: K. = NumberField(X^4 + 4*X^2 + 1) + sage: PP = P.change_ring(K) + sage: ff = f.change_ring(K) + sage: p = PP((c,1)) + sage: ff.nth_iterate(p,4) == ff.nth_iterate(p,2) + True """ if self.domain() != self.codomain(): raise TypeError("Must have same domain and codomain to iterate") From f66afcc9a249d951ca839bb58fc8d3faee766cfb Mon Sep 17 00:00:00 2001 From: Punarbasu Purkayastha Date: Sun, 19 Jan 2014 12:50:23 +0800 Subject: [PATCH 046/163] Fix order of output for m=1 The output for m=1 was in a different order compared to the output for m>1. Thanks to Xiaolu Hou for pointing this out to me! --- src/sage/rings/number_field/totallyreal_rel.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/rings/number_field/totallyreal_rel.py b/src/sage/rings/number_field/totallyreal_rel.py index 529518832f1..6cd5aebf730 100644 --- a/src/sage/rings/number_field/totallyreal_rel.py +++ b/src/sage/rings/number_field/totallyreal_rel.py @@ -698,7 +698,7 @@ def enumerate_totallyreal_fields_rel(F, m, B, a = [], verbose=0, sage: ZZx = ZZ['x'] sage: F. = NumberField(x^2-2) sage: enumerate_totallyreal_fields_rel(F, 1, 2000) - [[1, x - 1, [-2, 0, 1]]] + [[1, [-2, 0, 1], xF - 1]] sage: enumerate_totallyreal_fields_rel(F, 2, 2000) [[1600, x^4 - 6*x^2 + 4, xF^2 + xF - 1]] sage: enumerate_totallyreal_fields_rel(F, 2, 2000, return_seqs=True) @@ -746,12 +746,12 @@ def enumerate_totallyreal_fields_rel(F, m, B, a = [], verbose=0, if m == 1: g = pari(F.defining_polynomial()).reverse().Vec() if return_seqs: - return [[0,0,0,0],[1,g,[-1,1]]] + return [[0,0,0,0], [1, [-1, 1], g]] elif return_pari_objects: - return [[1,pari('x-1'),g]] + return [[1, g, pari('xF-1')]] else: - Px = PolynomialRing(QQ, 'x') - return [[ZZ(1), Px.gen()-1, map(QQ, g)]] + Px = PolynomialRing(QQ, 'xF') + return [[ZZ(1), map(QQ, g), Px.gen()-1]] if verbose: saveout = sys.stdout From 44c49ca9f4f43622e42acc3772c5f32d345b4360 Mon Sep 17 00:00:00 2001 From: Erik Quaeghebeur Date: Wed, 22 Jan 2014 16:43:28 +0100 Subject: [PATCH 047/163] first try for trac issue #15686: Improve documentation of constraint_generation in MixedIntegerLinearProgramming --- .../numerical/backends/generic_backend.pyx | 14 +++++++------ src/sage/numerical/mip.pyx | 21 +++++++++++++++---- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/sage/numerical/backends/generic_backend.pyx b/src/sage/numerical/backends/generic_backend.pyx index 7e79451decc..47573de0592 100644 --- a/src/sage/numerical/backends/generic_backend.pyx +++ b/src/sage/numerical/backends/generic_backend.pyx @@ -980,12 +980,14 @@ cpdef GenericBackend get_solver(constraint_generation = False, solver = None): ``"CPLEX"``, ``"Gurobi"``, ``"PPL"``, or ``None``. If ``solver=None`` (default), the default solver is used (see ``default_mip_solver`` method. - - ``constraint_generation`` (boolean) -- whether the solver - returned is to be used for constraint/variable generation. As - the interface with Coin does not support constraint/variable - generation, setting ``constraint_generation`` to ``False`` - ensures that the backend to Coin is not returned when ``solver = - None``. This is set to ``False`` by default. + - ``constraint_generation`` + + - When set to ``True``, after solving the ``MixedIntegerLinearProgram``, + it is possible to add or modify a constraint, and then solve it again. + The effect is that solvers that do not support this feature will not be + used when ``solver=None``, + + - When set to ``False`` (default), this is not possible. .. SEEALSO:: diff --git a/src/sage/numerical/mip.pyx b/src/sage/numerical/mip.pyx index 8045c3ad889..051c710d9c5 100644 --- a/src/sage/numerical/mip.pyx +++ b/src/sage/numerical/mip.pyx @@ -216,8 +216,14 @@ cdef class MixedIntegerLinearProgram(SageObject): - When set to ``False``, the ``MixedIntegerLinearProgram`` is defined as a minimization. - - ``constraint_generation`` -- whether to require the returned solver to - support constraint generation (excludes Coin). ``False by default``. + - ``constraint_generation`` + + - When set to ``True``, after solving the ``MixedIntegerLinearProgram``, + it is possible to add or modify a constraint, and then solve it again. + The effect is that solvers that do not support this feature will not be + used when ``solver=None``, + + - When set to ``False`` (default), this is not possible. .. SEEALSO:: @@ -273,8 +279,15 @@ cdef class MixedIntegerLinearProgram(SageObject): - When set to ``False``, the ``MixedIntegerLinearProgram`` is defined as a minimization. - - ``constraint_generation`` -- whether to require the returned solver to - support constraint generation (excludes Coin). ``False by default``. + - ``constraint_generation`` + + - When set to ``True``, after solving the + ``MixedIntegerLinearProgram``, it is possible to add or modify a + constraint, and then solve it again. The effect is that solvers + that do not support this feature will not be used when + ``solver=None``, + + - When set to ``False`` (default), this is not possible. - ``check_redundant`` -- whether to check that constraints added to the program are redundant with constraints already in the program. From f22017298b9d44268a686e3e75f00c327a94204d Mon Sep 17 00:00:00 2001 From: Erik Quaeghebeur Date: Fri, 24 Jan 2014 15:26:31 +0100 Subject: [PATCH 048/163] second try for trac issue #15686 --- src/sage/numerical/backends/generic_backend.pyx | 5 +++-- src/sage/numerical/mip.pyx | 15 ++++++++------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/sage/numerical/backends/generic_backend.pyx b/src/sage/numerical/backends/generic_backend.pyx index 47573de0592..01d3b190d60 100644 --- a/src/sage/numerical/backends/generic_backend.pyx +++ b/src/sage/numerical/backends/generic_backend.pyx @@ -983,11 +983,12 @@ cpdef GenericBackend get_solver(constraint_generation = False, solver = None): - ``constraint_generation`` - When set to ``True``, after solving the ``MixedIntegerLinearProgram``, - it is possible to add or modify a constraint, and then solve it again. + it is possible to add a constraint, and then solve it again. The effect is that solvers that do not support this feature will not be used when ``solver=None``, - - When set to ``False`` (default), this is not possible. + - When set to ``False`` (default), also solvers that do not support this + feature may be used when ``solver=None``. .. SEEALSO:: diff --git a/src/sage/numerical/mip.pyx b/src/sage/numerical/mip.pyx index 051c710d9c5..7a53d7e0e8b 100644 --- a/src/sage/numerical/mip.pyx +++ b/src/sage/numerical/mip.pyx @@ -219,11 +219,12 @@ cdef class MixedIntegerLinearProgram(SageObject): - ``constraint_generation`` - When set to ``True``, after solving the ``MixedIntegerLinearProgram``, - it is possible to add or modify a constraint, and then solve it again. + it is possible to add a constraint, and then solve it again. The effect is that solvers that do not support this feature will not be used when ``solver=None``, - - When set to ``False`` (default), this is not possible. + - When set to ``False`` (default), also solvers that do not support this + feature may be used when ``solver=None``. .. SEEALSO:: @@ -282,12 +283,12 @@ cdef class MixedIntegerLinearProgram(SageObject): - ``constraint_generation`` - When set to ``True``, after solving the - ``MixedIntegerLinearProgram``, it is possible to add or modify a - constraint, and then solve it again. The effect is that solvers - that do not support this feature will not be used when - ``solver=None``, + ``MixedIntegerLinearProgram``, it is possible to add a constraint, + and then solve it again. The effect is that solvers that do not + support this feature will not be used when ``solver=None``, - - When set to ``False`` (default), this is not possible. + - When set to ``False`` (default), also solvers that do not support + this feature may be used when ``solver=None``. - ``check_redundant`` -- whether to check that constraints added to the program are redundant with constraints already in the program. From f61aa06f654e031d3f5a3e58470cca81504e2554 Mon Sep 17 00:00:00 2001 From: Erik Quaeghebeur Date: Fri, 24 Jan 2014 15:58:02 +0100 Subject: [PATCH 049/163] first pass at #15722 --- src/sage/numerical/backends/generic_backend.pyx | 2 +- src/sage/numerical/backends/glpk_backend.pyx | 4 ++++ src/sage/numerical/mip.pyx | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/sage/numerical/backends/generic_backend.pyx b/src/sage/numerical/backends/generic_backend.pyx index 7e79451decc..70ca29d1f5e 100644 --- a/src/sage/numerical/backends/generic_backend.pyx +++ b/src/sage/numerical/backends/generic_backend.pyx @@ -141,7 +141,7 @@ cdef class GenericBackend: * 1 Integer * 0 Binary - * -1 Continuous + * -1 Continuous EXAMPLE:: diff --git a/src/sage/numerical/backends/glpk_backend.pyx b/src/sage/numerical/backends/glpk_backend.pyx index 8d57dcb13f0..e537eafe3e0 100644 --- a/src/sage/numerical/backends/glpk_backend.pyx +++ b/src/sage/numerical/backends/glpk_backend.pyx @@ -805,6 +805,8 @@ cdef class GLPKBackend(GenericBackend): The user can ask sage to solve via ``simplex`` or ``intopt``. The default solver is ``intopt``, so we get integer solutions. + EXAMPLE:: + sage: lp = MixedIntegerLinearProgram(solver = 'GLPK', maximization = False) sage: x, y = lp[0], lp[1] sage: lp.add_constraint(-2*x + y <= 1) @@ -820,6 +822,8 @@ cdef class GLPKBackend(GenericBackend): If we switch to ``simplex``, we get continuous solutions. + EXAMPLE:: + sage: lp.solver_parameter("simplex_or_intopt", "simplex_only") # use simplex only sage: lp.solve() 2.0 diff --git a/src/sage/numerical/mip.pyx b/src/sage/numerical/mip.pyx index 8045c3ad889..55075c1c990 100644 --- a/src/sage/numerical/mip.pyx +++ b/src/sage/numerical/mip.pyx @@ -202,7 +202,7 @@ cdef class MixedIntegerLinearProgram(SageObject): - Gurobi (``solver="Gurobi"``). See the `Gurobi `_ web site. - - PPL (``solver="PPL"``). See the 'PPL'_ + - PPL (``solver="PPL"``). See the `PPL`_ web site. - If ``solver=None`` (default), the default solver is used (see From bdb4ee9f5ba593ea1e5203c6a654d2a5c673bd4c Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Mon, 27 Jan 2014 10:43:11 +0000 Subject: [PATCH 050/163] Initial additon of the pkgconf package --- build/pkgs/pkgconf/SPKG.txt | 26 +++++++++++++++++++++++ build/pkgs/pkgconf/checksums.ini | 4 ++++ build/pkgs/pkgconf/package-version.txt | 1 + build/pkgs/pkgconf/spkg-install | 29 ++++++++++++++++++++++++++ 4 files changed, 60 insertions(+) create mode 100644 build/pkgs/pkgconf/SPKG.txt create mode 100644 build/pkgs/pkgconf/checksums.ini create mode 100644 build/pkgs/pkgconf/package-version.txt create mode 100755 build/pkgs/pkgconf/spkg-install diff --git a/build/pkgs/pkgconf/SPKG.txt b/build/pkgs/pkgconf/SPKG.txt new file mode 100644 index 00000000000..87332165df9 --- /dev/null +++ b/build/pkgs/pkgconf/SPKG.txt @@ -0,0 +1,26 @@ += pkgconf = + +== Description == + +Pkgconf is an implementation of the pkg-config spec with minimal +dependencies. + +== License == + +BSD + +== SPKG Maintainers == + +* Volker Braun + +== Upstream Contact == + +https://github.com/pkgconf/pkgconf + +== Dependencies == + +* C compiler + toolchain + +== Special Update/Build Instructions == + +None, standard autotools-based project. diff --git a/build/pkgs/pkgconf/checksums.ini b/build/pkgs/pkgconf/checksums.ini new file mode 100644 index 00000000000..be8a24c0949 --- /dev/null +++ b/build/pkgs/pkgconf/checksums.ini @@ -0,0 +1,4 @@ +tarball=pkgconf-VERSION.tar.bz2 +sha1=2d353227f5dfbcaa2c0f48f045f828dac2abcff0 +md5=88f34448e9c5c20b23c328824043a239 +cksum=997423134 diff --git a/build/pkgs/pkgconf/package-version.txt b/build/pkgs/pkgconf/package-version.txt new file mode 100644 index 00000000000..a602fc9e283 --- /dev/null +++ b/build/pkgs/pkgconf/package-version.txt @@ -0,0 +1 @@ +0.9.4 diff --git a/build/pkgs/pkgconf/spkg-install b/build/pkgs/pkgconf/spkg-install new file mode 100755 index 00000000000..85f2d8a4416 --- /dev/null +++ b/build/pkgs/pkgconf/spkg-install @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +cd src + +./configure --prefix="$SAGE_LOCAL" --libdir="$SAGE_LOCAL/lib" +if [ $? -ne 0 ]; then + echo >&2 "Error configuring pkgconf." + exit 1 +fi + +$MAKE +if [ $? -ne 0 ]; then + echo >&2 "Error building pkgconf." + exit 1 +fi + +$MAKE -j1 install +if [ $? -ne 0 ]; then + echo >&2 "Error installing pkgconf." + exit 1 +fi + +# pkgconf is an alternative to the "official" pkg-config, and does not +# automatically install a symlink. +ln -sf pkgconf "$SAGE_LOCAL/bin/pkg-config" +if [ $? -ne 0 ]; then + echo >&2 "Error creating symlink to pkg-config." + exit 1 +fi From 5407a163df0f9be9c96050a1fd9428487e1887c1 Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Mon, 27 Jan 2014 11:03:50 +0000 Subject: [PATCH 051/163] Initial additon of the pkgconfig Python package --- build/pkgs/pkgconfig/SPKG.txt | 26 ++++++++++++++++++++++++ build/pkgs/pkgconfig/checksums.ini | 4 ++++ build/pkgs/pkgconfig/package-version.txt | 1 + build/pkgs/pkgconfig/spkg-install | 9 ++++++++ 4 files changed, 40 insertions(+) create mode 100644 build/pkgs/pkgconfig/SPKG.txt create mode 100644 build/pkgs/pkgconfig/checksums.ini create mode 100644 build/pkgs/pkgconfig/package-version.txt create mode 100755 build/pkgs/pkgconfig/spkg-install diff --git a/build/pkgs/pkgconfig/SPKG.txt b/build/pkgs/pkgconfig/SPKG.txt new file mode 100644 index 00000000000..123ab851e9d --- /dev/null +++ b/build/pkgs/pkgconfig/SPKG.txt @@ -0,0 +1,26 @@ += pkgconfig = + +== Description == + +Pkgconfig is a Python module to interface with the pkg-config command +line tool. + +== License == + +BSD + +== SPKG Maintainers == + +* Volker Braun + +== Upstream Contact == + +https://github.com/matze/pkgconfig + +== Dependencies == + +* Python 2.6+ + +== Special Update/Build Instructions == + +None, standard setup.py diff --git a/build/pkgs/pkgconfig/checksums.ini b/build/pkgs/pkgconfig/checksums.ini new file mode 100644 index 00000000000..75d85b5045e --- /dev/null +++ b/build/pkgs/pkgconfig/checksums.ini @@ -0,0 +1,4 @@ +tarball=pkgconfig-VERSION.tar.gz +sha1=aaf00b11dc3e8e167e59a0efab05efd9cb19f882 +md5=15998b487c15c5954feb79443b5a937a +cksum=1411102530 diff --git a/build/pkgs/pkgconfig/package-version.txt b/build/pkgs/pkgconfig/package-version.txt new file mode 100644 index 00000000000..9084fa2f716 --- /dev/null +++ b/build/pkgs/pkgconfig/package-version.txt @@ -0,0 +1 @@ +1.1.0 diff --git a/build/pkgs/pkgconfig/spkg-install b/build/pkgs/pkgconfig/spkg-install new file mode 100755 index 00000000000..cd75613d25f --- /dev/null +++ b/build/pkgs/pkgconfig/spkg-install @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +cd src + +python setup.py install +if [ $? -ne 0 ]; then + echo >&2 "Error installing pkgconfig." + exit 1 +fi From 550204b5315bb40445dd61802d6009dc696dcf05 Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Mon, 27 Jan 2014 11:39:18 +0000 Subject: [PATCH 052/163] Make pkgconf and pkgconfig standard packages --- build/deps | 8 ++++++++ build/install | 2 ++ 2 files changed, 10 insertions(+) diff --git a/build/deps b/build/deps index 0764bf72b02..a4437fbf3df 100644 --- a/build/deps +++ b/build/deps @@ -81,6 +81,8 @@ all-sage: \ $(INST)/$(PARI) \ $(INST)/$(PEXPECT) \ $(INST)/$(PILLOW) \ + $(INST)/$(PKGCONF) \ + $(INST)/$(PKGCONFIG) \ $(INST)/$(POLYBORI) \ $(INST)/$(POLYTOPES_DB) \ $(INST)/$(PPL) \ @@ -496,6 +498,12 @@ $(INST)/$(GCC): $(INST)/$(MPIR) $(INST)/$(MPFR) $(INST)/$(MPC) \ $(INST)/$(PILLOW): $(INST)/$(PYTHON) $(INST)/$(SETUPTOOLS) +$(PIPE) "$(SAGE_SPKG) $(PILLOW) 2>&1" "tee -a $(SAGE_LOGS)/$(PILLOW).log" +$(INST)/$(PKGCONF): + +$(PIPE) "$(SAGE_SPKG) $(PKGCONF) 2>&1" "tee -a $(SAGE_LOGS)/$(PKGCONF).log" + +$(INST)/$(PKGCONFIG): $(INST)/$(PYTHON) $(INST)/$(SETUPTOOLS) + +$(PIPE) "$(SAGE_SPKG) $(PKGCONFIG) 2>&1" "tee -a $(SAGE_LOGS)/$(PKGCONFIG).log" + $(INST)/$(NUMPY): $(INST)/$(PYTHON) $(INST)/$(ATLAS) +$(PIPE) "$(SAGE_SPKG) $(NUMPY) 2>&1" "tee -a $(SAGE_LOGS)/$(NUMPY).log" diff --git a/build/install b/build/install index 7c4ac43169f..25aa3f1a017 100755 --- a/build/install +++ b/build/install @@ -410,6 +410,8 @@ PARI=`newest_version pari` PATCH=`newest_version patch` PEXPECT=`newest_version pexpect` PILLOW=`newest_version pillow` +PKGCONF=`newest_version pkgconf` +PKGCONFIG=`newest_version pkgconfig` POLYBORI=`newest_version polybori` POLYTOPES_DB=`newest_version polytopes_db` PPL=`newest_version ppl` From c86f67876e1117f7d5add0a224edfca50d3d33c9 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Mon, 27 Jan 2014 15:17:32 +0100 Subject: [PATCH 053/163] Speed up MPC multiplication --- build/pkgs/mpc/SPKG.txt | 4 +- build/pkgs/mpc/package-version.txt | 2 +- build/pkgs/mpc/patches/mpc_mul_faster.patch | 124 ++++++++++++++++++++ 3 files changed, 128 insertions(+), 2 deletions(-) create mode 100644 build/pkgs/mpc/patches/mpc_mul_faster.patch diff --git a/build/pkgs/mpc/SPKG.txt b/build/pkgs/mpc/SPKG.txt index 34366cd7e34..7ac0fa10baa 100644 --- a/build/pkgs/mpc/SPKG.txt +++ b/build/pkgs/mpc/SPKG.txt @@ -33,4 +33,6 @@ The MPC team can be contact via the MPC mailing list: == Special Update/Build Instructions == -None +* mpc_mul_faster.patch: Patch from Paul Zimmermann to speed up MPC + multiplication (for small precisions) by reducing overhead in MPFR + operations. diff --git a/build/pkgs/mpc/package-version.txt b/build/pkgs/mpc/package-version.txt index 6d7de6e6abe..b0df6e09260 100644 --- a/build/pkgs/mpc/package-version.txt +++ b/build/pkgs/mpc/package-version.txt @@ -1 +1 @@ -1.0.2 +1.0.2.p0 diff --git a/build/pkgs/mpc/patches/mpc_mul_faster.patch b/build/pkgs/mpc/patches/mpc_mul_faster.patch new file mode 100644 index 00000000000..5fc59a1bffc --- /dev/null +++ b/build/pkgs/mpc/patches/mpc_mul_faster.patch @@ -0,0 +1,124 @@ +diff -ru src/src/mul.c b/src/mul.c +--- src/src/mul.c 2012-07-22 17:40:22.000000000 +0200 ++++ b/src/mul.c 2014-01-27 15:12:37.449617411 +0100 +@@ -170,6 +170,10 @@ + return MPC_INEX (inex_re, inex_im); + } + ++#define MPFR_MANT(x) ((x)->_mpfr_d) ++#define MPFR_PREC(x) ((x)->_mpfr_prec) ++#define MPFR_EXP(x) ((x)->_mpfr_exp) ++#define MPFR_LIMB_SIZE(x) ((MPFR_PREC (x) - 1) / GMP_NUMB_BITS + 1) + + static int + mpfr_fmma (mpfr_ptr z, mpfr_srcptr a, mpfr_srcptr b, mpfr_srcptr c, +@@ -183,33 +187,68 @@ + + int inex; + mpfr_t u, v; ++ mp_size_t an, bn, cn, dn; + + /* u=a*b, v=sign*c*d exactly */ +- mpfr_init2 (u, mpfr_get_prec (a) + mpfr_get_prec (b)); +- mpfr_init2 (v, mpfr_get_prec (c) + mpfr_get_prec (d)); +- mpfr_mul (u, a, b, GMP_RNDN); +- mpfr_mul (v, c, d, GMP_RNDN); +- if (sign < 0) +- mpfr_neg (v, v, GMP_RNDN); ++ an = MPFR_LIMB_SIZE(a); ++ bn = MPFR_LIMB_SIZE(b); ++ cn = MPFR_LIMB_SIZE(c); ++ dn = MPFR_LIMB_SIZE(d); ++ MPFR_MANT(u) = malloc ((an + bn) * sizeof (mp_limb_t)); ++ MPFR_MANT(v) = malloc ((cn + dn) * sizeof (mp_limb_t)); ++ if (an >= bn) ++ mpn_mul (MPFR_MANT(u), MPFR_MANT(a), an, MPFR_MANT(b), bn); ++ else ++ mpn_mul (MPFR_MANT(u), MPFR_MANT(b), bn, MPFR_MANT(a), an); ++ if ((MPFR_MANT(u)[an + bn - 1] >> (GMP_NUMB_BITS - 1)) == 0) ++ { ++ mpn_lshift (MPFR_MANT(u), MPFR_MANT(u), an + bn, 1); ++ MPFR_EXP(u) = MPFR_EXP(a) + MPFR_EXP(b) - 1; ++ } ++ else ++ MPFR_EXP(u) = MPFR_EXP(a) + MPFR_EXP(b); ++ if (cn >= dn) ++ mpn_mul (MPFR_MANT(v), MPFR_MANT(c), cn, MPFR_MANT(d), dn); ++ else ++ mpn_mul (MPFR_MANT(v), MPFR_MANT(d), dn, MPFR_MANT(c), cn); ++ if ((MPFR_MANT(v)[cn + dn - 1] >> (GMP_NUMB_BITS - 1)) == 0) ++ { ++ mpn_lshift (MPFR_MANT(v), MPFR_MANT(v), cn + dn, 1); ++ MPFR_EXP(v) = MPFR_EXP(c) + MPFR_EXP(d) - 1; ++ } ++ else ++ MPFR_EXP(v) = MPFR_EXP(c) + MPFR_EXP(d); ++ MPFR_PREC(u) = (an + bn) * GMP_NUMB_BITS; ++ MPFR_PREC(v) = (cn + dn) * GMP_NUMB_BITS; ++ MPFR_SIGN(u) = MPFR_SIGN(a) * MPFR_SIGN(b); ++ if (sign > 0) ++ MPFR_SIGN(v) = MPFR_SIGN(c) * MPFR_SIGN(d); ++ else ++ MPFR_SIGN(v) = -MPFR_SIGN(c) * MPFR_SIGN(d); ++ ++ mpfr_check_range (u, 0, GMP_RNDN); ++ mpfr_check_range (v, 0, GMP_RNDN); + + /* tentatively compute z as u+v; here we need z to be distinct + from a, b, c, d to not lose the latter */ + inex = mpfr_add (z, u, v, rnd); +- +- if (mpfr_inf_p (z)) { +- /* replace by "correctly rounded overflow" */ +- mpfr_set_si (z, (mpfr_signbit (z) ? -1 : 1), GMP_RNDN); +- inex = mpfr_mul_2ui (z, z, mpfr_get_emax (), rnd); +- } +- else if (mpfr_zero_p (u) && !mpfr_zero_p (v)) { +- /* exactly u underflowed, determine inexact flag */ +- inex = (mpfr_signbit (u) ? 1 : -1); +- } +- else if (mpfr_zero_p (v) && !mpfr_zero_p (u)) { +- /* exactly v underflowed, determine inexact flag */ +- inex = (mpfr_signbit (v) ? 1 : -1); +- } +- else if (mpfr_nan_p (z) || (mpfr_zero_p (u) && mpfr_zero_p (v))) { ++ ++ if (!mpfr_regular_p(z) || !mpfr_regular_p(u) || !mpfr_regular_p(v)) ++ { ++ if (mpfr_inf_p (z)) { ++ /* replace by "correctly rounded overflow" */ ++ mpfr_set_si (z, (mpfr_signbit (z) ? -1 : 1), GMP_RNDN); ++ inex = mpfr_mul_2ui (z, z, mpfr_get_emax (), rnd); ++ } ++ else if (mpfr_zero_p (u) && !mpfr_zero_p (v)) { ++ /* exactly u underflowed, determine inexact flag */ ++ inex = (mpfr_signbit (u) ? 1 : -1); ++ } ++ else if (mpfr_zero_p (v) && !mpfr_zero_p (u)) { ++ /* exactly v underflowed, determine inexact flag */ ++ inex = (mpfr_signbit (v) ? 1 : -1); ++ } ++ else if (mpfr_nan_p (z) || (mpfr_zero_p (u) && mpfr_zero_p (v))) { + /* In the first case, u and v are infinities with opposite signs. + In the second case, u and v are zeroes; their sum may be 0 or the + least representable number, with a sign to be determined. +@@ -312,15 +351,14 @@ + mpfr_set_exp ((mpfr_ptr) c, ec); + mpfr_set_exp ((mpfr_ptr) d, ed); + /* works also when some of a, b, c, d are not all distinct */ +- } +- +- mpfr_clear (u); +- mpfr_clear (v); ++ } ++ } + ++ free (MPFR_MANT(u)); ++ free (MPFR_MANT(v)); + return inex; + } + +- + int + mpc_mul_naive (mpc_ptr z, mpc_srcptr x, mpc_srcptr y, mpc_rnd_t rnd) + { From b82c7193792137337f5bc3356f9d5cf08fcd2757 Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Mon, 27 Jan 2014 17:35:19 +0000 Subject: [PATCH 054/163] Do not use ln -sf --- build/pkgs/pkgconf/spkg-install | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build/pkgs/pkgconf/spkg-install b/build/pkgs/pkgconf/spkg-install index 85f2d8a4416..938e6d9022c 100755 --- a/build/pkgs/pkgconf/spkg-install +++ b/build/pkgs/pkgconf/spkg-install @@ -22,7 +22,8 @@ fi # pkgconf is an alternative to the "official" pkg-config, and does not # automatically install a symlink. -ln -sf pkgconf "$SAGE_LOCAL/bin/pkg-config" +rm -f "$SAGE_LOCAL/bin/pkg-config" +ln -s pkgconf "$SAGE_LOCAL/bin/pkg-config" if [ $? -ne 0 ]; then echo >&2 "Error creating symlink to pkg-config." exit 1 From aa6237ec471f87675c7f21e79910f1c35d8559cd Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Mon, 27 Jan 2014 17:45:53 +0000 Subject: [PATCH 055/163] serialize python install to avoid race --- build/deps | 1 + 1 file changed, 1 insertion(+) diff --git a/build/deps b/build/deps index a4437fbf3df..0f46f447d7c 100644 --- a/build/deps +++ b/build/deps @@ -529,3 +529,4 @@ $(INST)/$(PYGMENTS): $(INST)/$(SQLALCHEMY) $(INST)/$(JINJA2): $(INST)/$(PYGMENTS) $(INST)/$(SPHINX): $(INST)/$(JINJA2) $(INST)/$(SAGENB): $(INST)/$(SPHINX) +$(INST)/$(PKGCONFIG): $(INST)/$(SAGENB) From 2419f90d9368682cbe7d8534f5d39c3aa86227d8 Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Mon, 27 Jan 2014 20:02:42 +0000 Subject: [PATCH 056/163] Install pkgconfig first instead of last --- build/deps | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/deps b/build/deps index 0f46f447d7c..45637a097ce 100644 --- a/build/deps +++ b/build/deps @@ -524,9 +524,9 @@ $(INST)/$(CEPHES): # setuptools forgets to update easy-install.pth during parallel # builds, so we build the relevant packages serially. +$(INST)/$(PILLOW): $(INST)/$(PKGCONFIG) $(INST)/$(SQLALCHEMY): $(INST)/$(PILLOW) $(INST)/$(PYGMENTS): $(INST)/$(SQLALCHEMY) $(INST)/$(JINJA2): $(INST)/$(PYGMENTS) $(INST)/$(SPHINX): $(INST)/$(JINJA2) $(INST)/$(SAGENB): $(INST)/$(SPHINX) -$(INST)/$(PKGCONFIG): $(INST)/$(SAGENB) From 9a08f971289efb49abaea1b3419f180a82c1ff1f Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Mon, 27 Jan 2014 22:04:28 +0000 Subject: [PATCH 057/163] license clarifications --- COPYING.txt | 2 ++ build/pkgs/pkgconf/SPKG.txt | 2 +- build/pkgs/pkgconfig/SPKG.txt | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/COPYING.txt b/COPYING.txt index a47c964a074..4e4ad135a24 100644 --- a/COPYING.txt +++ b/COPYING.txt @@ -88,6 +88,8 @@ pari GPLv2+ patch GPLv2+ pexpect Python License pil Similar to MIT and modified BSD (see below) +pkgconf ISC License (equivalent to Simplified BSD) +pkgconfig MIT License polybori GPLv2+ polytopes_db None (database) ppl GPLv3+ diff --git a/build/pkgs/pkgconf/SPKG.txt b/build/pkgs/pkgconf/SPKG.txt index 87332165df9..c5b7ee75145 100644 --- a/build/pkgs/pkgconf/SPKG.txt +++ b/build/pkgs/pkgconf/SPKG.txt @@ -7,7 +7,7 @@ dependencies. == License == -BSD +ISC License (equivalent to Simplified BSD) == SPKG Maintainers == diff --git a/build/pkgs/pkgconfig/SPKG.txt b/build/pkgs/pkgconfig/SPKG.txt index 123ab851e9d..3dae19b21b2 100644 --- a/build/pkgs/pkgconfig/SPKG.txt +++ b/build/pkgs/pkgconfig/SPKG.txt @@ -7,7 +7,7 @@ line tool. == License == -BSD +MIT License == SPKG Maintainers == From 9052b7cce2301671c8ef5333849be7e67093ab17 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Mon, 27 Jan 2014 15:50:15 -0800 Subject: [PATCH 058/163] Partial work on refactoring morphisms. --- .../finite_algebras/finite_algebra.py | 117 +++++----- .../finite_algebras/finite_algebra_element.py | 203 +++++++----------- .../finite_algebras/finite_algebra_ideal.py | 53 +++-- .../finite_algebra_morphism.py | 94 +++++--- 4 files changed, 240 insertions(+), 227 deletions(-) diff --git a/src/sage/algebras/finite_algebras/finite_algebra.py b/src/sage/algebras/finite_algebras/finite_algebra.py index 7230dedc71c..90cc6ac1272 100644 --- a/src/sage/algebras/finite_algebras/finite_algebra.py +++ b/src/sage/algebras/finite_algebras/finite_algebra.py @@ -15,7 +15,6 @@ from finite_algebra_element import FiniteAlgebraElement from finite_algebra_ideal import FiniteAlgebraIdeal -from finite_algebra_morphism import FiniteAlgebraMorphism from sage.categories.all import FiniteDimensionalAlgebrasWithBasis from sage.matrix.constructor import Matrix @@ -116,14 +115,14 @@ def _repr_(self): sage: FiniteAlgebra(RR, [Matrix([1])])._repr_() 'Finite algebra of degree 1 over Real Field with 53 bits of precision' """ - return "Finite algebra of degree %d over %s" % (self.degree(), self.base_ring()) + return "Finite algebra of degree {} over {}".format(self.degree(), self.base_ring()) def _coerce_map_from_(self, S): """ TESTS:: sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) - sage: A.has_coerce_map_from(ZZ) # indirect doctest + sage: A.has_coerce_map_from(ZZ) True sage: A.has_coerce_map_from(GF(3)) True @@ -159,12 +158,22 @@ def _element_constructor_(self, x): # assumes that the algebra is unitary. from_base_ring = _element_constructor_ + def _Hom_(self, B, category): + """ + Construct a homset of ``self`` and ``B``. + """ + if isinstance(B, FiniteAlgebra): + category = FiniteDimensionalAlgebrasWithBasis(self.base_ring()).or_subcategory(category) + from sage.algebras.finite_algebras.finite_algebra_morphism import FiniteAlgebraHomset + return FiniteAlgebraHomset(self, B, category=category) + return super(FiniteAlgebra, self)._Hom_(B, category) + def ngens(self): """ Return the number of generators of ``self``, i.e., the degree of ``self`` over its base field. - EXAMPLE:: + EXAMPLES:: sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: A.ngens() @@ -179,7 +188,7 @@ def gen(self, i): """ Return the `i`-th basis element of ``self``. - EXAMPLE:: + EXAMPLES:: sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: A.gen(0) @@ -191,7 +200,7 @@ def basis(self): """ Return a list of the basis elements of ``self``. - EXAMPLE:: + EXAMPLES:: sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: A.basis() @@ -203,7 +212,7 @@ def _ideal_class_(self, n=0): """ Return the ideal class of ``self``. - EXAMPLE:: + EXAMPLES:: sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: A._ideal_class_() @@ -216,7 +225,7 @@ def table(self): Return the multiplication table of ``self``, as a list of matrices for right multiplication by the basis elements. - EXAMPLE:: + EXAMPLES:: sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: A.table() @@ -233,7 +242,7 @@ def left_table(self): Return the list of matrices for left multiplication by the basis elements. - EXAMPLE:: + EXAMPLES:: sage: B = FiniteAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1],[-1,0]])]) sage: B.left_table() @@ -248,9 +257,9 @@ def left_table(self): def __cmp__(self, other): """ - Compare self to other. + Compare ``self`` to ``other``. - EXAMPLE:: + EXAMPLES:: sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: B = FiniteAlgebra(GF(5), [Matrix([0])]) @@ -270,9 +279,9 @@ def __cmp__(self, other): def base_extend(self, F): """ - Return ``self`` base changed to `F`. + Return ``self`` base changed to ``F``. - EXAMPLE:: + EXAMPLES:: sage: C = FiniteAlgebra(GF(2), [Matrix([1])]) sage: k. = GF(4) @@ -312,18 +321,18 @@ def ideal(self, gens=None, given_by_matrix=False): INPUT: - - ``A`` -- FiniteAlgebra + - ``A`` -- a :class:`FiniteAlgebra` - - ``gens`` -- (default: None) - either an element of `A` or a - list of elements of `A`, given as vectors, matrices, or - FiniteAlgebraElements. If ``given_by_matrix`` is True, then + - ``gens`` -- (default: None) - either an element of ``A`` or a + list of elements of ``A``, given as vectors, matrices, or + FiniteAlgebraElements. If ``given_by_matrix`` is ``True``, then ``gens`` should instead be a matrix whose rows form a basis - of an ideal of `A`. + of an ideal of ``A``. - ``given_by_matrix`` -- boolean (default: ``False``) - if ``True``, no checking is done - EXAMPLE:: + EXAMPLES:: sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: A.ideal(A([1,1])) @@ -335,7 +344,7 @@ def ideal(self, gens=None, given_by_matrix=False): @cached_method def is_associative(self): """ - Return True if ``self`` is associative. + Return ``True`` if ``self`` is associative. EXAMPLES:: @@ -363,7 +372,7 @@ def is_associative(self): @cached_method def is_commutative(self): """ - Return True if ``self`` is commutative. + Return ``True`` if ``self`` is commutative. EXAMPLES:: @@ -494,7 +503,7 @@ def random_element(self, *args, **kwargs): Return a random element of ``self``. Optional input parameters are propagated to the ``random_element`` - method of the underlying ``VectorSpace``. + method of the underlying :class:`VectorSpace`. EXAMPLES:: @@ -512,40 +521,41 @@ def _is_valid_homomorphism_(self, other, im_gens): """ TESTS:: - sage: from sage.algebras.finite_algebras.finite_algebra_morphism import FiniteAlgebraMorphism sage: A = FiniteAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: B = FiniteAlgebra(QQ, [Matrix([1])]) - sage: FiniteAlgebraMorphism(A, B, Matrix([[1], [0]])) + sage: Hom(A, B)(Matrix([[1], [0]])) Morphism from Finite algebra of degree 2 over Rational Field to Finite algebra of degree 1 over Rational Field given by matrix [1] [0] - sage: FiniteAlgebraMorphism(B, A, Matrix([[1, 0]])) + sage: Hom(B, A)(Matrix([[1, 0]])) Morphism from Finite algebra of degree 1 over Rational Field to Finite algebra of degree 2 over Rational Field given by matrix [1 0] - sage: FiniteAlgebraMorphism(A, A, Matrix.identity(QQ, 2)) + sage: H = Hom(A, A) + sage: H(Matrix.identity(QQ, 2)) Morphism from Finite algebra of degree 2 over Rational Field to Finite algebra of degree 2 over Rational Field given by matrix [1 0] [0 1] - sage: FiniteAlgebraMorphism(A, A, Matrix([[1, 0], [0, 0]])) + sage: H(Matrix([[1, 0], [0, 0]])) Morphism from Finite algebra of degree 2 over Rational Field to Finite algebra of degree 2 over Rational Field given by matrix [1 0] [0 0] - sage: FiniteAlgebraMorphism(A, A, Matrix([[1, 0], [1, 1]])) + sage: H(Matrix([[1, 0], [1, 1]])) Traceback (most recent call last): ... ValueError: relations do not all (canonically) map to 0 under map determined by images of generators. - sage: FiniteAlgebraMorphism(B, B, Matrix([[2]])) + sage: Hom(B, B)(Matrix([[2]])) Traceback (most recent call last): ... ValueError: relations do not all (canonically) map to 0 under map determined by images of generators. """ - n = self.degree() + assert len(im_gens) == self.degree() + B = self.table() - for i in xrange(n): - for j in xrange(n): + for i,gi in enumerate(im_gens): + for j,gj in enumerate(im_gens): eiej = B[j][i] - if (sum([other(im_gens[k]) * eiej[k] for k in xrange(n)]) - != other(im_gens[i]) * other(im_gens[j])): + if (sum([other(im_gens[k]) * v for k,v in enumerate(eiej)]) + != other(gi) * other(gj)): return False return True @@ -555,11 +565,12 @@ def quotient_map(self, ideal): INPUT: - - ``ideal`` -- ``FiniteAlgebraIdeal`` + - ``ideal`` -- a ``FiniteAlgebraIdeal`` OUTPUT: - -- ``FiniteAlgebraMorphism``, the quotient homomorphism + - :class:`~sage.algebras.finite_algebras.finite_algebra_morphism.FiniteAlgebraMorphism`; + the quotient homomorphism EXAMPLES:: @@ -585,22 +596,22 @@ def quotient_map(self, ideal): v = self.element_class(self, v) table.append(f.solve_right(v.matrix() * f)) B = FiniteAlgebra(k, table) - return FiniteAlgebraMorphism(self, B, f, check=False) + return self.hom(f, codomain=B, check=False) def maximal_ideal(self): """ Compute the maximal ideal of the local algebra ``self``. - INPUT: + .. NOTE:: - - ``self`` -- ``FiniteAlgebra``, must be unitary, commutative, - associative and local (have a unique maximal ideal) + ``self`` must be unitary, commutative, associative and local + (have a unique maximal ideal). OUTPUT: - -- ``FiniteAlgebraIdeal``, the unique maximal ideal of - ``self``. If ``self`` is not a local algebra, a ValueError - is raised. + - :class:`~sage.algebras.finite_algebras.finite_algebra_ideal.FiniteAlgebraIdeal`; + the unique maximal ideal of ``self``. If ``self`` is not a local + algebra, a ``ValueError`` is raised. EXAMPLES:: @@ -623,7 +634,7 @@ def maximal_ideal(self): for x in self.gens(): f = x.characteristic_polynomial().factor() if len(f) != 1: - raise ValueError, "algebra is not local" + raise ValueError("algebra is not local") if f[0][1] > 1: gens.append(f[0][0](x)) return FiniteAlgebraIdeal(self, gens) @@ -632,15 +643,14 @@ def primary_decomposition(self): """ Return the primary decomposition of ``self``. - INPUT: + .. NOTE:: - - ``self`` -- ``FiniteAlgebra``, must be unitary, commutative - and associative + ``self`` must be unitary, commutative and associative. OUTPUT: - -- a list consisting of the quotient maps ``self`` -> `A`, - with `A` running through the primary factors of ``self`` + - a list consisting of the quotient maps ``self`` -> `A`, + with `A` running through the primary factors of ``self`` EXAMPLES:: @@ -661,8 +671,8 @@ def primary_decomposition(self): n = self.degree() if n == 0: return [] - if not(self.is_unitary() and self.is_commutative() - and (self._assume_associative or self.is_associative())): + if not (self.is_unitary() and self.is_commutative() + and (self._assume_associative or self.is_associative())): raise TypeError("algebra must be unitary, commutative and associative") # Start with the trivial decomposition of self. components = [Matrix.identity(k, n)] @@ -687,9 +697,9 @@ def primary_decomposition(self): quotients = [] for i in range(len(components)): I = Matrix(k, 0, n) - for j in range(len(components)): + for j,c in enumerate(components): if j != i: - I = I.stack(components[j]) + I = I.stack(c) quotients.append(self.quotient_map(self.ideal(I, given_by_matrix=True))) return quotients @@ -709,3 +719,4 @@ def maximal_ideals(self): """ P = self.primary_decomposition() return [f.inverse_image(f.codomain().maximal_ideal()) for f in P] + diff --git a/src/sage/algebras/finite_algebras/finite_algebra_element.py b/src/sage/algebras/finite_algebras/finite_algebra_element.py index 571403f6f59..9c5daa50c81 100644 --- a/src/sage/algebras/finite_algebras/finite_algebra_element.py +++ b/src/sage/algebras/finite_algebras/finite_algebra_element.py @@ -1,5 +1,5 @@ """ -Elements of finite algebras +Elements of Finite Algebras """ #***************************************************************************** @@ -15,6 +15,7 @@ import re +from sage.misc.cachefunc import cached_method from sage.matrix.constructor import Matrix from sage.matrix.matrix import is_Matrix from sage.modules.free_module_element import vector @@ -24,20 +25,20 @@ class FiniteAlgebraElement(AlgebraElement): """ - Create an element of a FiniteAlgebra using a multiplication table. + Create an element of a :class:`FiniteAlgebra` using a multiplication table. INPUT: - - ``A`` -- ``FiniteAlgebra`` + - ``A`` -- a :class:`FiniteAlgebra` which will be the parent - ``elt`` -- vector, matrix or element of the base field (default: ``None``) - - ``check`` -- boolean (default: True) - if False and ``elt`` is a + - ``check`` -- boolean (default: ``True``); if ``False`` and ``elt`` is a matrix, assume that it is known to be the matrix of an element If ``elt`` is a vector, it is interpreted as a vector of - coordinates with respect to the given basis of `A`. If ``elt`` is + coordinates with respect to the given basis of ``A``. If ``elt`` is a matrix, it is interpreted as a multiplication matrix with respect to this basis. @@ -49,7 +50,6 @@ class FiniteAlgebraElement(AlgebraElement): sage: A([1,1]) e0 + e1 """ - def __init__(self, A, elt=None, check=True): """ TESTS:: @@ -61,8 +61,9 @@ def __init__(self, A, elt=None, check=True): TypeError: elt should be a vector, a matrix, or an element of the base field sage: B = FiniteAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1], [-1,0]])]) - sage: B(Matrix([[1,1], [-1,1]])) + sage: elt = B(Matrix([[1,1], [-1,1]])); elt e0 + e1 + sage: TestSuite(elt).run() sage: B(Matrix([[0,1], [1,0]])) Traceback (most recent call last): ... @@ -155,13 +156,13 @@ def left_matrix(self): def _repr_(self): """ - Return the string representation of self. + Return the string representation of ``self``. EXAMPLE:: sage: A = FiniteAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) - sage: A(1)._repr_() - 'e0' + sage: A(1) + e0 """ s = " " A = self.parent() @@ -179,9 +180,9 @@ def _repr_(self): if y.find('-') == 0: y = y[1:] if not atomic and (y.find("+") != -1 or y.find("-") != -1): - x = "(%s)"%x - var = "*%s" % A._names[n] - s += "%s%s" % (x, var) + x = "({})".format(x) + var = "*{}".format(A._names[n]) + s += "{}{}".format(x, var) s = s.replace(" + -", " - ") s = re.sub(r' 1(\.0+)?\*',' ', s) s = re.sub(r' -1(\.0+)?\*',' -', s) @@ -190,8 +191,8 @@ def _repr_(self): return s[1:] def _latex_(self): - """ - Return the LaTeX representation of self. + r""" + Return the LaTeX representation of ``self``. EXAMPLE:: @@ -218,10 +219,8 @@ def __eq__(self, other): False """ A = self.parent() - if A.has_coerce_map_from(parent(other)): - return self.vector() == A(other).vector() - else: - return False + return (A.has_coerce_map_from(parent(other)) and + self.vector() == A(other).vector()) def __ne__(self, other): """ @@ -235,105 +234,60 @@ def __ne__(self, other): def __gt__(self, other): """ - Raise a TypeError as there is no ordering defined on a FiniteAlgebra:: + Raise a ``TypeError`` as there is no (natural) ordering defined on a + finite algebra:: sage: A = FiniteAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) sage: A(1) > 0 Traceback (most recent call last): ... - TypeError: there is no ordering defined on a FiniteAlgebra - """ - raise TypeError("there is no ordering defined on a FiniteAlgebra") - - def __lt__(self, other): - """ - Raise a TypeError as there is no ordering defined on a FiniteAlgebra:: - - sage: A = FiniteAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) + TypeError: there is no ordering defined on a finite algebra sage: A(1) < 0 Traceback (most recent call last): ... - TypeError: there is no ordering defined on a FiniteAlgebra - """ - raise TypeError("there is no ordering defined on a FiniteAlgebra") - - def __ge__(self, other): - """ - Raise a TypeError as there is no ordering defined on a FiniteAlgebra:: - - sage: A = FiniteAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) + TypeError: there is no ordering defined on a finite algebra sage: A(1) >= 0 Traceback (most recent call last): ... - TypeError: there is no ordering defined on a FiniteAlgebra - """ - raise TypeError("there is no ordering defined on a FiniteAlgebra") - - def __le__(self, other): - """ - Raise a TypeError as there is no ordering defined on a FiniteAlgebra:: - - sage: A = FiniteAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) + TypeError: there is no ordering defined on a finite algebra sage: A(1) <= 0 Traceback (most recent call last): ... - TypeError: there is no ordering defined on a FiniteAlgebra + TypeError: there is no ordering defined on a finite algebra """ - raise TypeError("there is no ordering defined on a FiniteAlgebra") + raise TypeError("there is no ordering defined on a finite algebra") - def __cmp__(self, other): - """ - EXAMPLES:: - - sage: A = FiniteAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) - sage: cmp(A(0), A(1)) - 1 - sage: cmp(A(0), A(0)) - 0 - - sage: B = FiniteAlgebra(QQ, [Matrix([0])]) - sage: B.basis()[0] == 0 - False - sage: B.basis()[0]^2 == 0 - True - """ - if self.vector() == other.vector(): - return 0 - else: - return 1 + __lt__ = __ge__ = __le__ = __gt__ def _add_(self, other): """ EXAMPLE:: sage: A = FiniteAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) - sage: A.basis()[0] + A.basis()[1] # indirect doctest + sage: A.basis()[0] + A.basis()[1] e0 + e1 """ - return FiniteAlgebraElement(self.parent(), - self.vector() + other.vector()) + return FiniteAlgebraElement(self.parent(), self._vector + other._vector) def _sub_(self, other): """ EXAMPLE:: sage: A = FiniteAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) - sage: A.basis()[0] - A.basis()[1] # indirect doctest + sage: A.basis()[0] - A.basis()[1] e0 + 2*e1 """ - return FiniteAlgebraElement(self.parent(), - self.vector() - other.vector()) + return FiniteAlgebraElement(self.parent(), self._vector - other._vector) def _mul_(self, other): """ EXAMPLE:: sage: C = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,0,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,1,0], [0,0,1]])]) - sage: C.basis()[1] * C.basis()[2] # indirect doctest + sage: C.basis()[1] * C.basis()[2] e1 """ - return FiniteAlgebraElement(self.parent(), - self.vector() * other.matrix()) + return FiniteAlgebraElement(self.parent(), self._vector * other._matrix) def _lmul_(self, other): """ @@ -341,15 +295,13 @@ def _lmul_(self, other): sage: C = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,0,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,1,0], [0,0,1]])]) sage: c = C.random_element() - sage: c * 2 == c + c # indirect doctest + sage: c * 2 == c + c True """ - if self.parent().base_ring().has_coerce_map_from(other.parent()): - return FiniteAlgebraElement(self.parent(), - other * self.vector()) - else: - raise TypeError("unsupported operand parent(s) for '*': '%s' and '%s'" - % (self.parent(), other.parent())) + if not self.parent().base_ring().has_coerce_map_from(other.parent()): + raise TypeError("unsupported operand parent(s) for '*': '{}' and '{}'" + .format(self.parent(), other.parent())) + return FiniteAlgebraElement(self.parent(), self._vector * other) def _rmul_(self, other): """ @@ -357,19 +309,17 @@ def _rmul_(self, other): sage: C = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,0,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,1,0], [0,0,1]])]) sage: c = C.random_element() - sage: 2 * c == c + c # indirect doctest + sage: 2 * c == c + c True """ - if self.parent().base_ring().has_coerce_map_from(other.parent()): - return FiniteAlgebraElement(self.parent(), - other * self.vector()) - else: - raise TypeError("unsupported operand parent(s) for '*': '%s' and '%s'" - % (self.parent(), other.parent())) + if not self.parent().base_ring().has_coerce_map_from(other.parent()): + raise TypeError("unsupported operand parent(s) for '*': '{}' and '{}'" + .format(self.parent(), other.parent())) + return FiniteAlgebraElement(self.parent(), other * self._vector) # Note the different order def __pow__(self, n): """ - Return ``self`` raised to the power `n`. + Return ``self`` raised to the power ``n``. EXAMPLE:: @@ -382,7 +332,7 @@ def __pow__(self, n): if not (A._assume_associative or A.is_associative()): raise TypeError("algebra is not associative") if n > 0: - return FiniteAlgebraElement(A, self.vector() * self.matrix().__pow__(n - 1)) + return FiniteAlgebraElement(A, self.vector() * self._matrix.__pow__(n - 1)) if not A.is_unitary(): raise TypeError("algebra is not unitary") if n == 0: @@ -395,6 +345,12 @@ def is_invertible(self): Return ``True`` if ``self`` has a two-sided multiplicative inverse. + .. NOTE:: + + If an element of a unitary finite algebra over a field + admits a left inverse, then this is the unique left + inverse, and it is also a right inverse. + EXAMPLE:: sage: C = FiniteAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1], [-1,0]])]) @@ -402,50 +358,45 @@ def is_invertible(self): True sage: C(0).is_invertible() False - - .. NOTE:: - - If an element of a unitary finite algebra over a field - admits a left inverse, then this is the unique left - inverse, and it is also a right inverse. """ - A = self.parent() - if not A.is_unitary(): - raise TypeError("algebra is not unitary") try: - a = self.matrix().inverse() + self.inverse() except ZeroDivisionError: return False - try: - self._inverse = FiniteAlgebraElement(A, a, check=True) - except ValueError: - return False return True + @cached_method def inverse(self): """ Return the two-sided multiplicative inverse of ``self``, if it exists. + .. NOTE:: + + If an element of a unitary finite algebra over a field + admits a left inverse, then this is the unique left + inverse, and it is also a right inverse. + EXAMPLE:: sage: C = FiniteAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1], [-1,0]])]) sage: C([1,2]).inverse() 1/5*e0 - 2/5*e1 + """ - .. NOTE:: + A = self.parent() + if not A.is_unitary(): + raise TypeError("algebra is not unitary") - If an element of a unitary finite algebra over a field - admits a left inverse, then this is the unique left - inverse, and it is also a right inverse. - """ - if self.is_invertible(): - return self._inverse - raise ZeroDivisionError("element is not invertible") + try: + a = self.matrix().inverse() + return FiniteAlgebraElement(A, a, check=True) + except (ZeroDivisionError, ValueError): + raise ZeroDivisionError("element is not invertible") def is_zerodivisor(self): """ - Return true if ``self`` is a left or right zero-divisor. + Return ``True`` if ``self`` is a left or right zero-divisor. EXAMPLES:: @@ -454,13 +405,12 @@ def is_zerodivisor(self): False sage: C([0,1]).is_zerodivisor() True - """ return self.matrix().det() == 0 or self.left_matrix().det() == 0 def is_nilpotent(self): """ - Return true if ``self`` is nilpotent. + Return ``True`` if ``self`` is nilpotent. EXAMPLES:: @@ -505,6 +455,13 @@ def characteristic_polynomial(self): """ Return the characteristic polynomial of ``self``. + .. NOTE:: + + This function just returns the characteristic polynomial + of the matrix of right multiplication by ``self``. This + may not be a very meaningful invariant if the algebra is + not unitary and associative. + EXAMPLES:: sage: B = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) @@ -515,12 +472,6 @@ def characteristic_polynomial(self): x^3 - 8*x^2 + 16*x sage: f(b) == 0 True - - .. NOTE:: - - This function just returns the characteristic polynomial - of the matrix of right multiplication by ``self``. This - may not be a very meaningful invariant if the algebra is - not unitary and associative. """ return self.matrix().characteristic_polynomial() + diff --git a/src/sage/algebras/finite_algebras/finite_algebra_ideal.py b/src/sage/algebras/finite_algebras/finite_algebra_ideal.py index 597614b76d3..f368a8765f3 100644 --- a/src/sage/algebras/finite_algebras/finite_algebra_ideal.py +++ b/src/sage/algebras/finite_algebras/finite_algebra_ideal.py @@ -1,5 +1,5 @@ """ -Ideals of finite algebras +Ideals of Finite Algebras """ #***************************************************************************** @@ -25,16 +25,28 @@ class FiniteAlgebraIdeal(Ideal_generic): """ - Create an ideal of a FiniteAlgebra. - """ + An ideal of a :class:`FiniteAlgebra`. + + INPUT: + + - ``A`` -- a finite algebra + - ``gens`` -- the generators of this ideal + - ``given_by_matrix`` -- (default: ``False``) whether the basis matrix is + given by ``gens`` + + EXAMPLES:: + sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A.ideal(A([0,1])) + Ideal (e1) of Finite algebra of degree 2 over Finite Field of size 3 + """ def __init__(self, A, gens=None, given_by_matrix=False): """ EXAMPLES:: sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) - sage: A.ideal(A([0,1])) - Ideal (e1) of Finite algebra of degree 2 over Finite Field of size 3 + sage: I = A.ideal(A([0,1])) + sage: TestSuite(I).run(skip="_test_category") # Currently ideals are not using the category framework """ k = A.base_ring() n = A.degree() @@ -47,13 +59,12 @@ def __init__(self, A, gens=None, given_by_matrix=False): B = [FiniteAlgebraIdeal(A, x).basis_matrix() for x in gens] B = reduce(lambda x, y: x.stack(y), B, Matrix(k, 0, n)) self._basis_matrix = B.echelon_form().image().basis_matrix() - else: - if is_Matrix(gens): - gens = FiniteAlgebraElement(A, gens) - if isinstance(gens, FiniteAlgebraElement): - gens = gens.vector() - B = Matrix([gens * b for b in A.table()]) - self._basis_matrix = B.echelon_form().image().basis_matrix() + elif is_Matrix(gens): + gens = FiniteAlgebraElement(A, gens) + elif isinstance(gens, FiniteAlgebraElement): + gens = gens.vector() + B = Matrix([gens * b for b in A.table()]) + self._basis_matrix = B.echelon_form().image().basis_matrix() Ideal_generic.__init__(self, A, gens) def __eq__(self, other): @@ -69,10 +80,21 @@ def __eq__(self, other): True sage: I == I + J True + + sage: A2 = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A is A2 + False + sage: A == A2 + True + sage: I2 = A.ideal(A([1,1])) + sage: I == I2 + True """ if self is other: return True - if self.ring() is not other.ring(): + if not isinstance(other, FiniteAlgebraIdeal): + return False + if self.ring() != other.ring(): return False return self.basis_matrix() == other.basis_matrix() @@ -179,7 +201,7 @@ def basis_matrix(self): """ Return the echelonized matrix whose rows form a basis of ``self``. - EXAMPLE:: + EXAMPLES:: sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: I = A.ideal(A([1,1])) @@ -194,7 +216,7 @@ def vector_space(self): """ Return ``self`` as a vector space. - EXAMPLE:: + EXAMPLES:: sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: I = A.ideal(A([1,1])) @@ -205,3 +227,4 @@ def vector_space(self): [0 1] """ return self.basis_matrix().image() + diff --git a/src/sage/algebras/finite_algebras/finite_algebra_morphism.py b/src/sage/algebras/finite_algebras/finite_algebra_morphism.py index 4178d992eb2..70ced77cabe 100644 --- a/src/sage/algebras/finite_algebras/finite_algebra_morphism.py +++ b/src/sage/algebras/finite_algebras/finite_algebra_morphism.py @@ -1,5 +1,5 @@ """ -Morphisms between finite algebras +Morphisms Between Finite Algebras """ #***************************************************************************** @@ -14,36 +14,37 @@ from sage.categories.homset import Hom from sage.rings.morphism import RingHomomorphism_im_gens - +from sage.rings.homset import RingHomset_generic +from sage.matrix.constructor import matrix +from sage.matrix.matrix import is_Matrix class FiniteAlgebraMorphism(RingHomomorphism_im_gens): """ - Create a morphism between FiniteAlgebras. + Create a morphism between two :class:`finite algebras `. INPUT: - - ``A`` -- FiniteAlgebra - - - ``B`` -- FiniteAlgebra + - ``A``, ``B`` -- finite algebras - - ``f`` -- matrix of the underlying k-linear map + - ``f`` -- matrix of the underlying `k`-linear map - - ``unitary`` -- boolean (default: True) - if True and ``check`` - is also True, raise a ValueError unless `A` and `B` are unitary - and `f` respects unit elements + - ``unitary`` -- boolean (default: ``True``); if ``True`` and ``check`` + is also ``True``, raise a ``ValueError`` unless ``A`` and ``B`` are + unitary and ``f`` respects unit elements - - ``check`` -- boolean (default: True) - check whether the given + - ``check`` -- boolean (default: ``True``); check whether the given k-linear map really defines a (not necessarily unitary) k-algebra homomorphism - The algebras `A` and `B` must be defined over the same base field. + The algebras ``A`` and ``B`` must be defined over the same base field. - EXAMPLES: + EXAMPLES:: sage: from sage.algebras.finite_algebras.finite_algebra_morphism import FiniteAlgebraMorphism sage: A = FiniteAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: B = FiniteAlgebra(QQ, [Matrix([1])]) - sage: f = FiniteAlgebraMorphism(A, B, Matrix([[1], [0]])) + sage: H = Hom(A, B) + sage: f = FiniteAlgebraMorphism(H, Matrix([[1], [0]])) sage: f.domain() is A True sage: f.codomain() is B @@ -53,29 +54,36 @@ class FiniteAlgebraMorphism(RingHomomorphism_im_gens): sage: f(A.basis()[1]) 0 - TODO: example illustrating unitary flag + .. TODO:: An example illustrating unitary flag. """ - - def __init__(self, A, B, f, unitary=True, check=True): + def __init__(self, parent, im_gens, check=True, unitary=True, f=None): """ TEST:: sage: from sage.algebras.finite_algebras.finite_algebra_morphism import FiniteAlgebraMorphism sage: A = FiniteAlgebra(QQ, [Matrix([1])]) sage: B = FiniteAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) - sage: FiniteAlgebraMorphism(A, B, Matrix([[1, 0]])) - Morphism from Finite algebra of degree 1 over Rational Field to Finite algebra of degree 2 over Rational Field given by matrix - [1 0] + sage: H = Hom(A, B) + sage: phi = FiniteAlgebraMorphism(H, Matrix([[1, 0]])) + sage: TestSuite(phi).run(skip="_test_category") # Currently ring morphisms are not using the category framework """ - RingHomomorphism_im_gens.__init__(self, parent=Hom(A, B), im_gens=f.rows(), check=check) - self._matrix = f - if not (unitary and check): - return - if (not A.is_unitary() - or not B.is_unitary() - or self(A.one()) != B.one()): + A = parent.domain() + B = parent.codomain() + if not (unitary and check) and (not A.is_unitary() + or not B.is_unitary() + or self(A.one()) != B.one()): raise ValueError("homomorphism does not respect unit elements") + if f is None: + if is_Matrix(im_gens): + f = im_gens + im_gens = f.rows() + else: + f = matrix(im_gens) + + RingHomomorphism_im_gens.__init__(self, parent=parent, im_gens=im_gens, check=check) + self._matrix = f + def __call__(self, x): """ TEST:: @@ -88,7 +96,7 @@ def __call__(self, x): """ x = self.domain()(x) B = self.codomain() - return B.element_class(B, x.vector() * self.matrix()) + return B.element_class(B, x.vector() * self._matrix) def _repr_(self): """ @@ -100,8 +108,8 @@ def _repr_(self): sage: q._repr_() 'Morphism from Finite algebra of degree 2 over Rational Field to Finite algebra of degree 1 over Rational Field given by matrix\n[1]\n[0]' """ - return "Morphism from %s to %s given by matrix\n%s" \ - % (self.domain(), self.codomain(), self.matrix()) + return "Morphism from {} to {} given by matrix\n{}".format( + self.domain(), self.codomain(), self._matrix) def matrix(self): """ @@ -113,7 +121,8 @@ def matrix(self): sage: A = FiniteAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: B = FiniteAlgebra(QQ, [Matrix([1])]) sage: M = Matrix([[1], [0]]) - sage: f = FiniteAlgebraMorphism(A, B, M) + sage: H = Hom(A, B) + sage: f = FiniteAlgebraMorphism(H, M) sage: f.matrix() == M True """ @@ -121,7 +130,7 @@ def matrix(self): def inverse_image(self, I): """ - Return the inverse image of `I` under ``self``. + Return the inverse image of ``I`` under ``self``. INPUT: @@ -141,4 +150,23 @@ def inverse_image(self, I): True """ coker_I = I.basis_matrix().transpose().kernel().basis_matrix().transpose() - return self.domain().ideal((self.matrix() * coker_I).kernel().basis_matrix(), given_by_matrix=True) + return self.domain().ideal((self._matrix * coker_I).kernel().basis_matrix(), given_by_matrix=True) + +class FiniteAlgebraHomset(RingHomset_generic): + """ + Set of morphisms between two finite algebras. + """ + def __call__(self, im_gens, check=True, unitary=True): + """ + Construct a homomorphism. + """ + if is_Matrix(im_gens): + return FiniteAlgebraMorphism(self, im_gens.rows(), check=check, unitary=unitary, f=im_gens) + if isinstance(im_gens, FiniteAlgebraMorphism): + if im_gens.parent() == self: + return FiniteAlgebraMorphism(self, im_gens.im_gens(), check=check, unitary=unitary, f=im_gens._matrix) + try: + return FiniteAlgebraMorphism(self, im_gens.rows(), check=check, unitary=unitary, f=im_gens) + except (NotImplementedError, ValueError): + return RingHomset_generic.__call__(self, im_gens, check) + From bc527f273168bf1be3aeaf01d43db0f3b6582fc1 Mon Sep 17 00:00:00 2001 From: Robert Bradshaw Date: Tue, 22 Jan 2013 06:25:18 +0000 Subject: [PATCH 059/163] Faster int -> ZZ coercions using a pool. --- src/sage/rings/integer.pyx | 86 +++++++++++++++++++++++++++++++++++--- 1 file changed, 80 insertions(+), 6 deletions(-) diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index 07fd798c781..ee09702e9ba 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -5951,17 +5951,91 @@ def make_integer(s): return r cdef class int_to_Z(Morphism): + """ + Morphism from Python ints to Sage integers. + + EXAMPLES:: + + sage: f = ZZ.coerce_map_from(int); type(f) + + sage: f(5r) + 5 + sage: type(f(5r)) + + sage: 1 + 2r + 3 + sage: type(1 + 2r) + + + This is intented for internal use by the coersion system, + to facilitate fast expressions mixing ints and more complex + Python types. Note that (as with all morphisms) the input + is forcably coerced to the domain ``int`` if it is not + already of the correct type which may have undesirable results:: + + sage: f.domain() + Set of Python objects of type 'int' + sage: f(1/3) + 0 + sage: f(1.7) + 1 + sage: f("10") + 10 + + A pool is used for small integers:: + + sage: f(10) is f(10) + True + sage: f(-2) is f(-2) + True + """ + def __init__(self): + """ + TESTS:: + + sage: f = ZZ.coerce_map_from(int) + sage: f.parent() + Set of Morphisms from Set of Python objects of type 'int' to Integer Ring in Category of sets + """ import integer_ring import sage.categories.homset from sage.structure.parent import Set_PythonType Morphism.__init__(self, sage.categories.homset.Hom(Set_PythonType(int), integer_ring.ZZ)) + cpdef Element _call_(self, a): - cdef Integer r - r = PY_NEW(Integer) - mpz_set_si(r.value, PyInt_AS_LONG(a)) - return r + """ + Returns a new integer with the same value as a. + + TESTS:: + + sage: f = ZZ.coerce_map_from(int) + sage: f(100r) + 100 + + Note that, for performance reasons, the type of the input is not + verified; it is assumed to have the memory layout of a Python int:: + + sage: f._call_("abc") + 3 + sage: f._call_(5) # random, the Integer 5 + 140031369085760 + + In practice, this precondition is verified by the caller (typically + the coercion system). + """ + return smallInteger(PyInt_AS_LONG(a)) + def _repr_type(self): + """ + TESTS:: + + sage: f = ZZ.coerce_map_from(int) + sage: print f + Native morphism: + From: Set of Python objects of type 'int' + To: Integer Ring + """ return "Native" cdef class long_to_Z(Morphism): @@ -6265,8 +6339,8 @@ cdef Integer zero = the_integer_ring._zero_element cdef Integer one = the_integer_ring._one_element # pool of small integer for fast sign computation -cdef long small_pool_min = -1 -cdef long small_pool_max = 1 +cdef long small_pool_min = -5 +cdef long small_pool_max = 255 # we could use the above zero and one here cdef list small_pool = [Integer(k) for k in range(small_pool_min, small_pool_max+1)] cdef inline Integer smallInteger(long value): From 6dbeaa1df723103a3b1014fd1195c20c6ca878f7 Mon Sep 17 00:00:00 2001 From: Robert Bradshaw Date: Mon, 27 Jan 2014 21:08:23 -0800 Subject: [PATCH 060/163] Small refinements, clarification. --- src/sage/rings/integer.pyx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index ee09702e9ba..300b372bef6 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -6339,11 +6339,16 @@ cdef Integer zero = the_integer_ring._zero_element cdef Integer one = the_integer_ring._one_element # pool of small integer for fast sign computation +# Use the same defaults as Python, documented at http://docs.python.org/2/c-api/int.html#PyInt_FromLong cdef long small_pool_min = -5 -cdef long small_pool_max = 255 +cdef long small_pool_max = 256 # we could use the above zero and one here cdef list small_pool = [Integer(k) for k in range(small_pool_min, small_pool_max+1)] + cdef inline Integer smallInteger(long value): + """ + This is the fastest way to create a (likely) small Integer. + """ cdef Integer z if small_pool_min <= value <= small_pool_max: return small_pool[value - small_pool_min] From 6b18661787e2d518fca76d0a22c4eb5a6ab49a08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20M=2E=20Thi=C3=A9ry?= Date: Wed, 29 Jan 2014 10:30:58 +0100 Subject: [PATCH 061/163] Implementation of 15759 --- src/sage/misc/cachefunc.pxd | 2 + src/sage/misc/cachefunc.pyx | 82 +++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/src/sage/misc/cachefunc.pxd b/src/sage/misc/cachefunc.pxd index ba08a5603cb..183c511531d 100644 --- a/src/sage/misc/cachefunc.pxd +++ b/src/sage/misc/cachefunc.pxd @@ -24,6 +24,8 @@ cdef class CachedMethodCallerNoArgs(CachedFunction): cdef class CachedMethod(object): cdef str _cache_name + cdef public str __name__ + cdef public str __module__ cdef CachedFunction _cachedfunc cdef int nargs cpdef dict _get_instance_cache(self, inst) diff --git a/src/sage/misc/cachefunc.pyx b/src/sage/misc/cachefunc.pyx index c8ff5ce72f1..60c1b61ea4c 100644 --- a/src/sage/misc/cachefunc.pyx +++ b/src/sage/misc/cachefunc.pyx @@ -1425,10 +1425,12 @@ cdef class CachedMethodCaller(CachedFunction): TESTS:: + sage: from sage.misc.superseded import deprecated_function_alias sage: class Foo: ... @cached_method ... def f(self, x,y=1): ... return x+y + ... g = deprecated_function_alias(57, f) ... sage: a = Foo() sage: a.f(1) #indirect doctest @@ -1444,6 +1446,29 @@ cdef class CachedMethodCaller(CachedFunction): sage: a.f(5) is a.f(y=1,x=5) True + The method can be called as a bound function using the same cache:: + + sage: a.f(5) is Foo.f(a, 5) + True + sage: a.f(5) is Foo.f(a,5,1) + True + sage: a.f(5) is Foo.f(a, 5,y=1) + True + sage: a.f(5) is Foo.f(a, y=1,x=5) + True + + Cached methods are compatible with + :meth:`sage.misc.superseded.deprecated_function_alias`:: + + sage: a.g(5) is a.f(5) + doctest:1: DeprecationWarning: g is deprecated. Please use f instead. + See http://trac.sagemath.org/57 for details. + True + sage: Foo.g(a, 5) is a.f(5) + True + sage: Foo.g(a, y=1,x=5) is a.f(5) + True + We test that #5843 is fixed:: sage: class Foo: @@ -1457,7 +1482,14 @@ cdef class CachedMethodCaller(CachedFunction): sage: b = Foo(3) sage: a.f(b.f) 2 + """ + if self._instance is None: + # cached method bound to a class + instance = args[0] + args = args[1:] + return self._cachedmethod.__get__(instance)(*args, **kwds) + # We shortcut a common case of no arguments # and we avoid calling another python function, # although that means to duplicate code. @@ -2039,9 +2071,18 @@ cdef class CachedMethod(object): sage: sorted(dir(a)) ['__doc__', '__init__', '__module__', '_cache__f', '_x', 'f', 'f0'] + The cached method has its name and module set:: + + sage: f = Foo.__dict__["f"] + sage: f.__name__ + 'f' + sage: f.__module__ + '__main__' """ self._cache_name = '_cache__' + (name or f.__name__) self._cachedfunc = CachedFunction(f, classmethod=True, name=name) + self.__name__ = self._cachedfunc.__name__ + self.__module__ = self._cachedfunc.__module__ def _instance_call(self, inst, *args, **kwds): """ @@ -2084,6 +2125,47 @@ cdef class CachedMethod(object): """ return self._cachedfunc.f(inst, *args, **kwds) + def __call__(self, inst, *args, **kwds): + """ + Call the cached method as a function on an instance + + INPUT: + + - ``inst`` -- an instance on which the method is to be called + - Further positional or named arguments. + + EXAMPLES:: + + + sage: from sage.misc.superseded import deprecated_function_alias + sage: class Foo(object): + ... def __init__(self, x): + ... self._x = x + ... @cached_method + ... def f(self,n=2): + ... return self._x^n + ... g = deprecated_function_alias(57, f) + sage: a = Foo(2) + sage: Foo.__dict__['f'](a) + 4 + + This uses the cache as usual:: + + sage: Foo.__dict__['f'](a) is a.f() + True + + This feature makes cached methods compatible with + :meth:`sage.misc.superseded.deprecated_function_alias`:: + + sage: a.g() is a.f() + doctest:1: DeprecationWarning: g is deprecated. Please use f instead. + See http://trac.sagemath.org/57 for details. + True + sage: Foo.g(a) is a.f() + True + """ + return self.__get__(inst)(*args, **kwds) + cpdef dict _get_instance_cache(self, inst): """ Returns the cache dictionary. From 823c33878cc7d0385f4d99702e74e2884f72a22c Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Wed, 29 Jan 2014 16:14:56 +0000 Subject: [PATCH 062/163] fixing building of R extensions on ARM --- build/pkgs/r/patches/install.R-arm.patch | 31 ++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 build/pkgs/r/patches/install.R-arm.patch diff --git a/build/pkgs/r/patches/install.R-arm.patch b/build/pkgs/r/patches/install.R-arm.patch new file mode 100644 index 00000000000..6ca5128ddf1 --- /dev/null +++ b/build/pkgs/r/patches/install.R-arm.patch @@ -0,0 +1,31 @@ +diff --git a/src/library/tools/R/install.R b/src/library/tools/R/install.R +index 5d55ca8..b654cd6 100644 +--- a/src/library/tools/R/install.R ++++ b/src/library/tools/R/install.R +@@ -110,7 +110,11 @@ + SHLIB_EXT <- if (WINDOWS) ".dll" else { + ## can we do better? + mconf <- file.path(R.home(), paste0("etc", rarch), "Makeconf") +- sub(".*= ", "", grep("^SHLIB_EXT", readLines(mconf), value = TRUE)) ++ ++ if (substr( Sys.info()["machine"], 1, 3) == "arm") # arm has broken regexps in libc ++ sub(".*= ", "", grep("^SHLIB_EXT", readLines(mconf), value = TRUE), perl = TRUE) ++ else ++ sub(".*= ", "", grep("^SHLIB_EXT", readLines(mconf), value = TRUE)) + } + + options(warn = 1) +@@ -1676,8 +1680,13 @@ + mconf <- readLines(file.path(R.home(), + paste0("etc", Sys.getenv("R_ARCH")), + "Makeconf")) ++ if (substr( Sys.info()["machine"], 1, 3) == "arm") { # arm has broken regexps in libc ++ SHLIB_EXT <- sub(".*= ", "", grep("^SHLIB_EXT", mconf, value = TRUE), perl = TRUE) ++ SHLIB_LIBADD <- sub(".*= ", "", grep("^SHLIB_LIBADD", mconf, value = TRUE), perl = TRUE) ++ } else { + SHLIB_EXT <- sub(".*= ", "", grep("^SHLIB_EXT", mconf, value = TRUE)) + SHLIB_LIBADD <- sub(".*= ", "", grep("^SHLIB_LIBADD", mconf, value = TRUE)) ++ } + MAKE <- Sys.getenv("MAKE") + rarch <- Sys.getenv("R_ARCH") + } else { From 47fa84600b5b09478f1474cb52c7c9906e71a056 Mon Sep 17 00:00:00 2001 From: Robert Bradshaw Date: Thu, 30 Jan 2014 04:02:12 -0800 Subject: [PATCH 063/163] Fix mutation of cached Integer. --- src/sage/matrix/matrix_integer_dense.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/matrix/matrix_integer_dense.pyx b/src/sage/matrix/matrix_integer_dense.pyx index ea697552364..9537e02eba7 100644 --- a/src/sage/matrix/matrix_integer_dense.pyx +++ b/src/sage/matrix/matrix_integer_dense.pyx @@ -3348,7 +3348,7 @@ cdef class Matrix_integer_dense(matrix_dense.Matrix_dense): # dense or sparse # Use generic special cased code. return matrix_dense.Matrix_dense.determinant(self) else: - det4x4 = ZZ(0) + det4x4 = Integer() four_dim_det(det4x4.value, self._entries) return det4x4 From d3e730d9ff3b8249f3e02283f9c06b78bbe882d1 Mon Sep 17 00:00:00 2001 From: Xavier Caruso Date: Mon, 22 Oct 2012 13:31:21 +0000 Subject: [PATCH 064/163] trac #13642: modular exponentiation of polynomials --- .../rings/polynomial/polynomial_element.pyx | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index 2b9f3bcd381..e47474a8dcc 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -1705,12 +1705,6 @@ cdef class Polynomial(CommutativeAlgebraElement): sage: f^3 x^3 - 3*x^2 + 3*x - 1 - sage: R = PolynomialRing(GF(2), x) - sage: f = R(x^9 + x^7 + x^6 + x^5 + x^4 + x^2 + x) - sage: h = R(x^10 + x^7 + x^6 + x^5 + x^4 + x^3 + x^2 + 1) - sage: pow(f, 2, h) - x^9 + x^8 + x^7 + x^5 + x^3 - TESTS:: sage: x^(1/2) @@ -1724,6 +1718,18 @@ cdef class Polynomial(CommutativeAlgebraElement): Traceback (most recent call last): ... TypeError: non-integral exponents not supported + + :: + + sage: k = GF(5) + sage: l. = k.extension(x^2 + 2) + sage: R. = l[] + sage: f = t^4 + (2*x - 1)*t^3 + (2*x + 1)*t^2 + 3 + sage: h = t^4 - x*t^3 + (3*x + 1)*t^2 + 2*t + 2*x - 1 + sage: pow(f, 2, h) + 3*t^3 + (2*x + 3)*t^2 + (2*x + 2)*t + 2*x + 2 + sage: pow(f, 10**7, h) # fast + 4*x*t^3 + 2*x*t^2 + 4*x*t + 4 """ if not PY_TYPE_CHECK_EXACT(right, Integer) or \ PY_TYPE_CHECK_EXACT(right, int): @@ -1733,9 +1739,12 @@ cdef class Polynomial(CommutativeAlgebraElement): raise TypeError("non-integral exponents not supported") if self.degree() <= 0: - r = self.parent()(self[0]**right) + return self.parent()(self[0]**right) elif right < 0: - r = (~self)**(-right) + return (~self)**(-right) + elif modulus: + from sage.rings.arith import power_mod + return power_mod(self, right, modulus) elif (self) == self.parent().gen(): # special case x**n should be faster! P = self.parent() R = P.base_ring() @@ -1743,13 +1752,9 @@ cdef class Polynomial(CommutativeAlgebraElement): v = {right:R.one_element()} else: v = [R.zero_element()]*right + [R.one_element()] - r = self.parent()(v, check=False) - else: - r = generic_power(self, right) - if modulus: - return r % modulus + return self.parent()(v, check=False) else: - return r + return generic_power(self,right) def _pow(self, right): # TODO: fit __pow__ into the arithmetic structure From 9917b2806836f24e9fe233b429df6f16fae1016f Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Sat, 1 Feb 2014 23:24:17 -0800 Subject: [PATCH 065/163] Reinstated doctest. --- src/sage/rings/polynomial/polynomial_element.pyx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index e47474a8dcc..e908d23478a 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -1705,6 +1705,12 @@ cdef class Polynomial(CommutativeAlgebraElement): sage: f^3 x^3 - 3*x^2 + 3*x - 1 + sage: R = PolynomialRing(GF(2), x) + sage: f = R(x^9 + x^7 + x^6 + x^5 + x^4 + x^2 + x) + sage: h = R(x^10 + x^7 + x^6 + x^5 + x^4 + x^3 + x^2 + 1) + sage: pow(f, 2, h) + x^9 + x^8 + x^7 + x^5 + x^3 + TESTS:: sage: x^(1/2) @@ -1722,13 +1728,14 @@ cdef class Polynomial(CommutativeAlgebraElement): :: sage: k = GF(5) + sage: D. = k[] sage: l. = k.extension(x^2 + 2) sage: R. = l[] sage: f = t^4 + (2*x - 1)*t^3 + (2*x + 1)*t^2 + 3 sage: h = t^4 - x*t^3 + (3*x + 1)*t^2 + 2*t + 2*x - 1 sage: pow(f, 2, h) 3*t^3 + (2*x + 3)*t^2 + (2*x + 2)*t + 2*x + 2 - sage: pow(f, 10**7, h) # fast + sage: pow(f, 10**7, h) 4*x*t^3 + 2*x*t^2 + 4*x*t + 4 """ if not PY_TYPE_CHECK_EXACT(right, Integer) or \ From 878bd99af7fb041f9a61887693e062cf0b1e20e9 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Sat, 1 Feb 2014 23:42:05 -0800 Subject: [PATCH 066/163] Marked new doctests as "not tested". --- src/sage/rings/polynomial/polynomial_element.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index e908d23478a..840de629281 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -1733,9 +1733,9 @@ cdef class Polynomial(CommutativeAlgebraElement): sage: R. = l[] sage: f = t^4 + (2*x - 1)*t^3 + (2*x + 1)*t^2 + 3 sage: h = t^4 - x*t^3 + (3*x + 1)*t^2 + 2*t + 2*x - 1 - sage: pow(f, 2, h) + sage: pow(f, 2, h) # not tested - see #15777 3*t^3 + (2*x + 3)*t^2 + (2*x + 2)*t + 2*x + 2 - sage: pow(f, 10**7, h) + sage: pow(f, 10**7, h) # not tested - see #15777 4*x*t^3 + 2*x*t^2 + 4*x*t + 4 """ if not PY_TYPE_CHECK_EXACT(right, Integer) or \ From 3a881677e4a83e4d4de51b95778fabadb5f4e7eb Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Sun, 2 Feb 2014 08:11:46 -0800 Subject: [PATCH 067/163] Added doctests to matrix_space.py. --- src/sage/matrix/matrix_space.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index 0e8d24490b5..7a3e9782cd0 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -227,7 +227,7 @@ def __init__(self, base_ring, We test that in the real or complex double dense case, conversion from the base ring is done by a call morphism. - Note that by trac ticket #9138, other algebras usually + Note that by :trac:`9138`, other algebras usually get a conversion map by multiplication with the one element. :: @@ -242,6 +242,21 @@ def __init__(self, base_ring, From: Complex Double Field To: Full MatrixSpace of 2 by 2 dense matrices over Complex Double Field + We check that :trac:`10095` is fixed:: + + sage: M = Matrix(QQ, [[1 for dummy in range(125)]]) + sage: V = M.right_kernel() + sage: V + Vector space of degree 125 and dimension 124 over Rational Field + Basis matrix: + 124 x 125 dense matrix over Rational Field + sage: MatrixSpace(ZZ,20,20)(1) \ MatrixSpace(ZZ,20,1).random_element() + 20 x 1 dense matrix over Rational Field + sage: MatrixSpace(ZZ,200,200)(1) \ MatrixSpace(ZZ,200,1).random_element() + 200 x 1 dense matrix over Rational Field + sage: A = MatrixSpace(RDF,1000,1000).random_element() + sage: B = MatrixSpace(RDF,1000,1000).random_element() + sage: C = A * B """ if ncols == None: ncols = nrows from sage.categories.all import Modules, Algebras From 71f53cffc4943f5a4849bb4d051f0d6d31e2fa57 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Mon, 3 Feb 2014 12:48:24 -0800 Subject: [PATCH 068/163] Finished implementing homsets for finite algebras. --- .../finite_algebras/finite_algebra.py | 9 +- .../finite_algebras/finite_algebra_element.py | 13 +- .../finite_algebra_morphism.py | 149 +++++++++++++----- 3 files changed, 123 insertions(+), 48 deletions(-) diff --git a/src/sage/algebras/finite_algebras/finite_algebra.py b/src/sage/algebras/finite_algebras/finite_algebra.py index 90cc6ac1272..bda1be17736 100644 --- a/src/sage/algebras/finite_algebras/finite_algebra.py +++ b/src/sage/algebras/finite_algebras/finite_algebra.py @@ -149,7 +149,7 @@ def _element_constructor_(self, x): TypeError: algebra is not unitary sage: B = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) - sage: B(17) # indirect doctest + sage: B(17) 17*e0 + 17*e2 """ return self.element_class(self, x) @@ -161,6 +161,13 @@ def _element_constructor_(self, x): def _Hom_(self, B, category): """ Construct a homset of ``self`` and ``B``. + + EXAMPLES:: + + sage: A = FiniteAlgebra(QQ, [Matrix([1])]) + sage: B = FiniteAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A._Hom_(B, A.category()) + Set of Homomorphisms from Finite algebra of degree 1 over Rational Field to Finite algebra of degree 2 over Rational Field """ if isinstance(B, FiniteAlgebra): category = FiniteDimensionalAlgebrasWithBasis(self.base_ring()).or_subcategory(category) diff --git a/src/sage/algebras/finite_algebras/finite_algebra_element.py b/src/sage/algebras/finite_algebras/finite_algebra_element.py index 9c5daa50c81..47806356e33 100644 --- a/src/sage/algebras/finite_algebras/finite_algebra_element.py +++ b/src/sage/algebras/finite_algebras/finite_algebra_element.py @@ -97,14 +97,13 @@ def __init__(self, A, elt=None, check=True): self._vector = elt.base_extend(k) self._matrix = Matrix(k, sum([elt[i] * A.table()[i] for i in xrange(n)])) elif is_Matrix(elt): - if A.is_unitary(): - self._vector = A._one * elt - if not check or sum([self._vector[i]*A.table()[i] for i in xrange(n)]) == elt: - self._matrix = elt - else: - raise ValueError("matrix does not define an element of the algebra") - else: + if not A.is_unitary(): raise TypeError("algebra is not unitary") + self._vector = A._one * elt + if not check or sum([self._vector[i]*A.table()[i] for i in xrange(n)]) == elt: + self._matrix = elt + else: + raise ValueError("matrix does not define an element of the algebra") else: raise TypeError("elt should be a vector, a matrix, " + "or an element of the base field") diff --git a/src/sage/algebras/finite_algebras/finite_algebra_morphism.py b/src/sage/algebras/finite_algebras/finite_algebra_morphism.py index 70ced77cabe..117ab44d5a9 100644 --- a/src/sage/algebras/finite_algebras/finite_algebra_morphism.py +++ b/src/sage/algebras/finite_algebras/finite_algebra_morphism.py @@ -12,6 +12,7 @@ # http://www.gnu.org/licenses/ #***************************************************************************** +from sage.misc.cachefunc import cached_method from sage.categories.homset import Hom from sage.rings.morphism import RingHomomorphism_im_gens from sage.rings.homset import RingHomset_generic @@ -24,7 +25,7 @@ class FiniteAlgebraMorphism(RingHomomorphism_im_gens): INPUT: - - ``A``, ``B`` -- finite algebras + - ``parent`` -- the parent homset - ``f`` -- matrix of the underlying `k`-linear map @@ -33,8 +34,8 @@ class FiniteAlgebraMorphism(RingHomomorphism_im_gens): unitary and ``f`` respects unit elements - ``check`` -- boolean (default: ``True``); check whether the given - k-linear map really defines a (not necessarily unitary) - k-algebra homomorphism + `k`-linear map really defines a (not necessarily unitary) + `k`-algebra homomorphism The algebras ``A`` and ``B`` must be defined over the same base field. @@ -44,7 +45,7 @@ class FiniteAlgebraMorphism(RingHomomorphism_im_gens): sage: A = FiniteAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: B = FiniteAlgebra(QQ, [Matrix([1])]) sage: H = Hom(A, B) - sage: f = FiniteAlgebraMorphism(H, Matrix([[1], [0]])) + sage: f = H(Matrix([[1], [0]])) sage: f.domain() is A True sage: f.codomain() is B @@ -56,37 +57,44 @@ class FiniteAlgebraMorphism(RingHomomorphism_im_gens): .. TODO:: An example illustrating unitary flag. """ - def __init__(self, parent, im_gens, check=True, unitary=True, f=None): + def __init__(self, parent, f, check=True, unitary=True): """ - TEST:: + TESTS:: sage: from sage.algebras.finite_algebras.finite_algebra_morphism import FiniteAlgebraMorphism sage: A = FiniteAlgebra(QQ, [Matrix([1])]) sage: B = FiniteAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: H = Hom(A, B) sage: phi = FiniteAlgebraMorphism(H, Matrix([[1, 0]])) - sage: TestSuite(phi).run(skip="_test_category") # Currently ring morphisms are not using the category framework + sage: TestSuite(phi).run(skip="_test_category") """ A = parent.domain() B = parent.codomain() - if not (unitary and check) and (not A.is_unitary() - or not B.is_unitary() - or self(A.one()) != B.one()): + + RingHomomorphism_im_gens.__init__(self, parent=parent, im_gens=f.rows(), check=check) + self._matrix = f + + if unitary and check and (not A.is_unitary() + or not B.is_unitary() + or self(A.one()) != B.one()): raise ValueError("homomorphism does not respect unit elements") - if f is None: - if is_Matrix(im_gens): - f = im_gens - im_gens = f.rows() - else: - f = matrix(im_gens) + def _repr_(self): + """ + TESTS:: - RingHomomorphism_im_gens.__init__(self, parent=parent, im_gens=im_gens, check=check) - self._matrix = f + sage: A = FiniteAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: I = A.maximal_ideal() + sage: q = A.quotient_map(I) + sage: q._repr_() + 'Morphism from Finite algebra of degree 2 over Rational Field to Finite algebra of degree 1 over Rational Field given by matrix\n[1]\n[0]' + """ + return "Morphism from {} to {} given by matrix\n{}".format( + self.domain(), self.codomain(), self._matrix) def __call__(self, x): """ - TEST:: + TESTS:: sage: A = FiniteAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: I = A.maximal_ideal() @@ -98,31 +106,55 @@ def __call__(self, x): B = self.codomain() return B.element_class(B, x.vector() * self._matrix) - def _repr_(self): + def __eq__(self, other): """ - TEST:: + Check equality. - sage: A = FiniteAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) - sage: I = A.maximal_ideal() - sage: q = A.quotient_map(I) - sage: q._repr_() - 'Morphism from Finite algebra of degree 2 over Rational Field to Finite algebra of degree 1 over Rational Field given by matrix\n[1]\n[0]' + TESTS:: + + sage: A = FiniteAlgebra(QQ, [Matrix([1])]) + sage: B = FiniteAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: H = Hom(A, B) + sage: phi = H(Matrix([[1, 0]])) + sage: psi = H(Matrix([[1, 0]])) + sage: phi == psi + True + sage: phi == H.zero() + False """ - return "Morphism from {} to {} given by matrix\n{}".format( - self.domain(), self.codomain(), self._matrix) + return (isinstance(other, FiniteAlgebraMorphism) + and self.parent() == other.parent() + and self._matrix == other._matrix) + + def __ne__(self, other): + """ + Check not equals. + + TESTS:: + + sage: A = FiniteAlgebra(QQ, [Matrix([1])]) + sage: B = FiniteAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: H = Hom(A, B) + sage: phi = H(Matrix([[1, 0]])) + sage: psi = H(Matrix([[1, 0]])) + sage: phi != psi + False + sage: phi != H.zero() + True + """ + return not self.__eq__(other) def matrix(self): """ Return the matrix of ``self``. - EXAMPLE:: + EXAMPLES:: - sage: from sage.algebras.finite_algebras.finite_algebra_morphism import FiniteAlgebraMorphism sage: A = FiniteAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: B = FiniteAlgebra(QQ, [Matrix([1])]) sage: M = Matrix([[1], [0]]) sage: H = Hom(A, B) - sage: f = FiniteAlgebraMorphism(H, M) + sage: f = H(M) sage: f.matrix() == M True """ @@ -156,17 +188,54 @@ class FiniteAlgebraHomset(RingHomset_generic): """ Set of morphisms between two finite algebras. """ - def __call__(self, im_gens, check=True, unitary=True): + @cached_method + def zero(self): + """ + Construct the zero morphism of ``self``. + + EXAMPLES:: + + sage: A = FiniteAlgebra(QQ, [Matrix([1])]) + sage: B = FiniteAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: H = Hom(A, B) + sage: H.zero() + Morphism from Finite algebra of degree 1 over Rational Field to + Finite algebra of degree 2 over Rational Field given by matrix + [0 0] + """ + from sage.matrix.constructor import matrix + return FiniteAlgebraMorphism(self, matrix.zero(self.domain().ngens(), + self.codomain().ngens()), + False, False) + + def __call__(self, f, check=True, unitary=True): """ Construct a homomorphism. + + .. TODO:: + + Implement taking generator images and converting them to a matrix. + + EXAMPLES:: + + sage: A = FiniteAlgebra(QQ, [Matrix([1])]) + sage: B = FiniteAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: H = Hom(A, B) + sage: H(Matrix([[1, 0]])) + Morphism from Finite algebra of degree 1 over Rational Field to + Finite algebra of degree 2 over Rational Field given by matrix + [1 0] """ - if is_Matrix(im_gens): - return FiniteAlgebraMorphism(self, im_gens.rows(), check=check, unitary=unitary, f=im_gens) - if isinstance(im_gens, FiniteAlgebraMorphism): - if im_gens.parent() == self: - return FiniteAlgebraMorphism(self, im_gens.im_gens(), check=check, unitary=unitary, f=im_gens._matrix) + if isinstance(f, FiniteAlgebraMorphism): + if f.parent() is self: + return f + if f.parent() == self: + return FiniteAlgebraMorphism(self, f._matrix, check, unitary) + elif is_Matrix(f): + return FiniteAlgebraMorphism(self, f, check, unitary) try: - return FiniteAlgebraMorphism(self, im_gens.rows(), check=check, unitary=unitary, f=im_gens) - except (NotImplementedError, ValueError): - return RingHomset_generic.__call__(self, im_gens, check) + from sage.matrix.constructor import Matrix + return FiniteAlgebraMorphism(self, Matrix(f), check, unitary) + except Exception: + return RingHomset_generic.__call__(self, f, check) From 42e2f4ef1a2a86864c0e5f08e7c247763842a553 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Mon, 3 Feb 2014 17:41:32 -0800 Subject: [PATCH 069/163] Changed finite algebras to finite dimensional algebras. --- src/doc/en/reference/algebras/index.rst | 8 +- src/sage/algebras/all.py | 2 +- src/sage/algebras/finite_algebras/all.py | 1 - .../__init__.py | 0 .../finite_dimensional_algebras/all.py | 1 + .../finite_dimensional_algebra.py} | 212 +++++++++--------- .../finite_dimensional_algebra_element.py} | 86 +++---- .../finite_dimensional_algebra_ideal.py} | 42 ++-- .../finite_dimensional_algebra_morphism.py} | 74 +++--- 9 files changed, 213 insertions(+), 213 deletions(-) delete mode 100644 src/sage/algebras/finite_algebras/all.py rename src/sage/algebras/{finite_algebras => finite_dimensional_algebras}/__init__.py (100%) create mode 100644 src/sage/algebras/finite_dimensional_algebras/all.py rename src/sage/algebras/{finite_algebras/finite_algebra.py => finite_dimensional_algebras/finite_dimensional_algebra.py} (61%) rename src/sage/algebras/{finite_algebras/finite_algebra_element.py => finite_dimensional_algebras/finite_dimensional_algebra_element.py} (74%) rename src/sage/algebras/{finite_algebras/finite_algebra_ideal.py => finite_dimensional_algebras/finite_dimensional_algebra_ideal.py} (74%) rename src/sage/algebras/{finite_algebras/finite_algebra_morphism.py => finite_dimensional_algebras/finite_dimensional_algebra_morphism.py} (62%) diff --git a/src/doc/en/reference/algebras/index.rst b/src/doc/en/reference/algebras/index.rst index 297f1c38127..f13340962dc 100644 --- a/src/doc/en/reference/algebras/index.rst +++ b/src/doc/en/reference/algebras/index.rst @@ -4,10 +4,10 @@ Algebras .. toctree:: :maxdepth: 2 - sage/algebras/finite_algebras/finite_algebra - sage/algebras/finite_algebras/finite_algebra_element - sage/algebras/finite_algebras/finite_algebra_ideal - sage/algebras/finite_algebras/finite_algebra_morphism + sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra + sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element + sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_ideal + sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_morphism sage/algebras/free_algebra sage/algebras/free_algebra_element diff --git a/src/sage/algebras/all.py b/src/sage/algebras/all.py index bf67be53c86..53a8e27cc20 100644 --- a/src/sage/algebras/all.py +++ b/src/sage/algebras/all.py @@ -32,7 +32,7 @@ from steenrod.all import * -from finite_algebras.all import FiniteAlgebra +from finite_dimensional_algebras.all import FiniteDimensionalAlgebra from group_algebra_new import GroupAlgebra diff --git a/src/sage/algebras/finite_algebras/all.py b/src/sage/algebras/finite_algebras/all.py deleted file mode 100644 index 93fb73ea455..00000000000 --- a/src/sage/algebras/finite_algebras/all.py +++ /dev/null @@ -1 +0,0 @@ -from finite_algebra import FiniteAlgebra diff --git a/src/sage/algebras/finite_algebras/__init__.py b/src/sage/algebras/finite_dimensional_algebras/__init__.py similarity index 100% rename from src/sage/algebras/finite_algebras/__init__.py rename to src/sage/algebras/finite_dimensional_algebras/__init__.py diff --git a/src/sage/algebras/finite_dimensional_algebras/all.py b/src/sage/algebras/finite_dimensional_algebras/all.py new file mode 100644 index 00000000000..3400b37a58c --- /dev/null +++ b/src/sage/algebras/finite_dimensional_algebras/all.py @@ -0,0 +1 @@ +from finite_dimensional_algebra import FiniteDimensionalAlgebra diff --git a/src/sage/algebras/finite_algebras/finite_algebra.py b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py similarity index 61% rename from src/sage/algebras/finite_algebras/finite_algebra.py rename to src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py index bda1be17736..cdfdadaf95d 100644 --- a/src/sage/algebras/finite_algebras/finite_algebra.py +++ b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py @@ -1,5 +1,5 @@ """ -Finite algebras +Finite Dimensional Algebras """ #***************************************************************************** @@ -13,8 +13,8 @@ # http://www.gnu.org/licenses/ #***************************************************************************** -from finite_algebra_element import FiniteAlgebraElement -from finite_algebra_ideal import FiniteAlgebraIdeal +from finite_dimensional_algebra_element import FiniteDimensionalAlgebraElement +from finite_dimensional_algebra_ideal import FiniteDimensionalAlgebraIdeal from sage.categories.all import FiniteDimensionalAlgebrasWithBasis from sage.matrix.constructor import Matrix @@ -25,9 +25,9 @@ from sage.misc.cachefunc import cached_method -class FiniteAlgebra(Algebra): +class FiniteDimensionalAlgebra(Algebra): """ - Create a finite `k`-algebra from a multiplication table. + Create a finite dimensional `k`-algebra from a multiplication table. INPUT: @@ -35,64 +35,64 @@ class FiniteAlgebra(Algebra): - ``table`` -- a list of matrices - - ``names`` -- string (default: ``'e'``) - names for the basis + - ``names`` -- (default: ``'e'``) string; names for the basis elements - - ``assume_associative`` -- boolean (default: ``False``). If + - ``assume_associative`` -- (default: ``False``) boolean; if ``True``, then methods requiring associativity assume this - without checking. + without checking - - ``category`` -- Category - the category to which this algebra - belongs (default: ``FiniteDimensionalAlgebrasWithBasis``(`k`)). + - ``category`` -- (default: ``FiniteDimensionalAlgebrasWithBasis(k)``) + the category to which this algebra belongs The list ``table`` must have the following form: there exists a finite dimensional `k`-algebra of degree `n` with basis - `(e_1,...,e_n)` such that the `i`-th element of ``table`` is the + `(e_1, \ldots, e_n)` such that the `i`-th element of ``table`` is the matrix of right multiplication by `e_i` with respect to the basis - `(e_1,...,e_n)`. + `(e_1, \ldots, e_n)`. EXAMPLES:: - sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: A - Finite algebra of degree 2 over Finite Field of size 3 + Finite dimensional algebra of degree 2 over Finite Field of size 3 - sage: B = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) sage: B - Finite algebra of degree 3 over Rational Field + Finite dimensional algebra of degree 3 over Rational Field """ def __init__(self, k, table, names='e', assume_associative=False, category=None): """ TESTS:: - sage: A = FiniteAlgebra(QQ, []) + sage: A = FiniteDimensionalAlgebra(QQ, []) sage: A - Finite algebra of degree 0 over Rational Field + Finite dimensional algebra of degree 0 over Rational Field sage: type(A) - + sage: TestSuite(A).run() - sage: B = FiniteAlgebra(GF(7), [Matrix([1])]) + sage: B = FiniteDimensionalAlgebra(GF(7), [Matrix([1])]) sage: B - Finite algebra of degree 1 over Finite Field of size 7 + Finite dimensional algebra of degree 1 over Finite Field of size 7 sage: TestSuite(B).run() - sage: C = FiniteAlgebra(CC, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: C = FiniteDimensionalAlgebra(CC, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: C - Finite algebra of degree 2 over Complex Field with 53 bits of precision + Finite dimensional algebra of degree 2 over Complex Field with 53 bits of precision sage: TestSuite(C).run() - sage: FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]])]) + sage: FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]])]) Traceback (most recent call last): ... ValueError: input is not a multiplication table - sage: D. = FiniteAlgebra(RR, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [-1, 0]])]) + sage: D. = FiniteDimensionalAlgebra(RR, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [-1, 0]])]) sage: D.gens() (a, b) - sage: E = FiniteAlgebra(QQ, [Matrix([0])]) + sage: E = FiniteDimensionalAlgebra(QQ, [Matrix([0])]) sage: E.gens() (e,) """ @@ -112,16 +112,16 @@ def _repr_(self): TEST:: - sage: FiniteAlgebra(RR, [Matrix([1])])._repr_() - 'Finite algebra of degree 1 over Real Field with 53 bits of precision' + sage: FiniteDimensionalAlgebra(RR, [Matrix([1])])._repr_() + 'Finite dimensional algebra of degree 1 over Real Field with 53 bits of precision' """ - return "Finite algebra of degree {} over {}".format(self.degree(), self.base_ring()) + return "Finite dimensional algebra of degree {} over {}".format(self.degree(), self.base_ring()) def _coerce_map_from_(self, S): """ TESTS:: - sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: A.has_coerce_map_from(ZZ) True sage: A.has_coerce_map_from(GF(3)) @@ -133,22 +133,22 @@ def _coerce_map_from_(self, S): """ return S == self or (self.base_ring().has_coerce_map_from(S) and self.is_unitary()) - Element = FiniteAlgebraElement + Element = FiniteDimensionalAlgebraElement def _element_constructor_(self, x): """ TESTS:: - sage: A = FiniteAlgebra(QQ, [Matrix([0])]) + sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([0])]) sage: a = A(0) sage: a.parent() - Finite algebra of degree 1 over Rational Field + Finite dimensional algebra of degree 1 over Rational Field sage: A(1) Traceback (most recent call last): ... TypeError: algebra is not unitary - sage: B = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) sage: B(17) 17*e0 + 17*e2 """ @@ -164,16 +164,16 @@ def _Hom_(self, B, category): EXAMPLES:: - sage: A = FiniteAlgebra(QQ, [Matrix([1])]) - sage: B = FiniteAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([1])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: A._Hom_(B, A.category()) - Set of Homomorphisms from Finite algebra of degree 1 over Rational Field to Finite algebra of degree 2 over Rational Field + Set of Homomorphisms from Finite dimensional algebra of degree 1 over Rational Field to Finite dimensional algebra of degree 2 over Rational Field """ - if isinstance(B, FiniteAlgebra): + if isinstance(B, FiniteDimensionalAlgebra): category = FiniteDimensionalAlgebrasWithBasis(self.base_ring()).or_subcategory(category) - from sage.algebras.finite_algebras.finite_algebra_morphism import FiniteAlgebraHomset - return FiniteAlgebraHomset(self, B, category=category) - return super(FiniteAlgebra, self)._Hom_(B, category) + from sage.algebras.finite_dimensional_algebras.finite_dimensional_algebra_morphism import FiniteDimensionalAlgebraHomset + return FiniteDimensionalAlgebraHomset(self, B, category=category) + return super(FiniteDimensionalAlgebra, self)._Hom_(B, category) def ngens(self): """ @@ -182,7 +182,7 @@ def ngens(self): EXAMPLES:: - sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: A.ngens() 2 """ @@ -197,7 +197,7 @@ def gen(self, i): EXAMPLES:: - sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: A.gen(0) e0 """ @@ -209,7 +209,7 @@ def basis(self): EXAMPLES:: - sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: A.basis() [e0, e1] """ @@ -221,11 +221,11 @@ def _ideal_class_(self, n=0): EXAMPLES:: - sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: A._ideal_class_() - + """ - return FiniteAlgebraIdeal + return FiniteDimensionalAlgebraIdeal def table(self): """ @@ -234,7 +234,7 @@ def table(self): EXAMPLES:: - sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: A.table() [ [1 0] [0 1] @@ -251,7 +251,7 @@ def left_table(self): EXAMPLES:: - sage: B = FiniteAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1],[-1,0]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1],[-1,0]])]) sage: B.left_table() [ [1 0] [ 0 1] @@ -268,8 +268,8 @@ def __cmp__(self, other): EXAMPLES:: - sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) - sage: B = FiniteAlgebra(GF(5), [Matrix([0])]) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: B = FiniteDimensionalAlgebra(GF(5), [Matrix([0])]) sage: cmp(A, A) 0 sage: cmp(B, B) @@ -277,7 +277,7 @@ def __cmp__(self, other): sage: cmp(A, B) 1 """ - if not isinstance(other, FiniteAlgebra): + if not isinstance(other, FiniteDimensionalAlgebra): return cmp(type(self), type(other)) if self.base_ring() == other.base_ring(): return cmp(self.table(), other.table()) @@ -290,13 +290,13 @@ def base_extend(self, F): EXAMPLES:: - sage: C = FiniteAlgebra(GF(2), [Matrix([1])]) + sage: C = FiniteDimensionalAlgebra(GF(2), [Matrix([1])]) sage: k. = GF(4) sage: C.base_extend(k) - Finite algebra of degree 1 over Finite Field in y of size 2^2 + Finite dimensional algebra of degree 1 over Finite Field in y of size 2^2 """ # Base extension of the multiplication table is done by __init__. - return FiniteAlgebra(F, self.table()) + return FiniteDimensionalAlgebra(F, self.table()) @cached_method def cardinality(self): @@ -305,15 +305,15 @@ def cardinality(self): EXAMPLES:: - sage: A = FiniteAlgebra(GF(7), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [2, 3]])]) + sage: A = FiniteDimensionalAlgebra(GF(7), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [2, 3]])]) sage: A.cardinality() 49 - sage: B = FiniteAlgebra(RR, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [2, 3]])]) + sage: B = FiniteDimensionalAlgebra(RR, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [2, 3]])]) sage: B.cardinality() +Infinity - sage: C = FiniteAlgebra(RR, []) + sage: C = FiniteDimensionalAlgebra(RR, []) sage: C.cardinality() 1 """ @@ -328,11 +328,11 @@ def ideal(self, gens=None, given_by_matrix=False): INPUT: - - ``A`` -- a :class:`FiniteAlgebra` + - ``A`` -- a :class:`FiniteDimensionalAlgebra` - ``gens`` -- (default: None) - either an element of ``A`` or a list of elements of ``A``, given as vectors, matrices, or - FiniteAlgebraElements. If ``given_by_matrix`` is ``True``, then + FiniteDimensionalAlgebraElements. If ``given_by_matrix`` is ``True``, then ``gens`` should instead be a matrix whose rows form a basis of an ideal of ``A``. @@ -341,9 +341,9 @@ def ideal(self, gens=None, given_by_matrix=False): EXAMPLES:: - sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: A.ideal(A([1,1])) - Ideal (e0 + e1) of Finite algebra of degree 2 over Finite Field of size 3 + Ideal (e0 + e1) of Finite dimensional algebra of degree 2 over Finite Field of size 3 """ return self._ideal_class_()(self, gens=gens, given_by_matrix=given_by_matrix) @@ -355,11 +355,11 @@ def is_associative(self): EXAMPLES:: - sage: A = FiniteAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1],[-1,0]])]) + sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1],[-1,0]])]) sage: A.is_associative() True - sage: B = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,1]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,1], [0,0,0], [1,0,0]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,1]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,1], [0,0,0], [1,0,0]])]) sage: B.is_associative() False @@ -383,11 +383,11 @@ def is_commutative(self): EXAMPLES:: - sage: B = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) sage: B.is_commutative() True - sage: C = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,0,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,1,0], [0,0,1]])]) + sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,0,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,1,0], [0,0,1]])]) sage: C.is_commutative() False """ @@ -405,15 +405,15 @@ def is_finite(self): EXAMPLES:: - sage: A = FiniteAlgebra(GF(7), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [2, 3]])]) + sage: A = FiniteDimensionalAlgebra(GF(7), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [2, 3]])]) sage: A.is_finite() True - sage: B = FiniteAlgebra(RR, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [2, 3]])]) + sage: B = FiniteDimensionalAlgebra(RR, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [2, 3]])]) sage: B.is_finite() False - sage: C = FiniteAlgebra(RR, []) + sage: C = FiniteDimensionalAlgebra(RR, []) sage: C.is_finite() True """ @@ -427,25 +427,25 @@ def is_unitary(self): EXAMPLES:: - sage: A = FiniteAlgebra(QQ, []) + sage: A = FiniteDimensionalAlgebra(QQ, []) sage: A.is_unitary() True - sage: B = FiniteAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1], [-1,0]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1], [-1,0]])]) sage: B.is_unitary() True - sage: C = FiniteAlgebra(QQ, [Matrix([[0,0], [0,0]]), Matrix([[0,0], [0,0]])]) + sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[0,0], [0,0]]), Matrix([[0,0], [0,0]])]) sage: C.is_unitary() False - sage: D = FiniteAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[1,0], [0,1]])]) + sage: D = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[1,0], [0,1]])]) sage: D.is_unitary() False .. NOTE:: - If a finite algebra over a field admits a left identity, + If a finite dimensional algebra over a field admits a left identity, then this is the unique left identity, and it is also a right identity. """ @@ -469,11 +469,11 @@ def is_zero(self): EXAMPLES:: - sage: A = FiniteAlgebra(QQ, []) + sage: A = FiniteDimensionalAlgebra(QQ, []) sage: A.is_zero() True - sage: B = FiniteAlgebra(GF(7), [Matrix([0])]) + sage: B = FiniteDimensionalAlgebra(GF(7), [Matrix([0])]) sage: B.is_zero() False """ @@ -486,15 +486,15 @@ def one(self): EXAMPLES:: - sage: A = FiniteAlgebra(QQ, []) + sage: A = FiniteDimensionalAlgebra(QQ, []) sage: A.one() 0 - sage: B = FiniteAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1], [-1,0]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1], [-1,0]])]) sage: B.one() e0 - sage: C = FiniteAlgebra(QQ, [Matrix([[0,0], [0,0]]), Matrix([[0,0], [0,0]])]) + sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[0,0], [0,0]]), Matrix([[0,0], [0,0]])]) sage: C.one() Traceback (most recent call last): ... @@ -514,11 +514,11 @@ def random_element(self, *args, **kwargs): EXAMPLES:: - sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: A.random_element() # random e0 + 2*e1 - sage: B = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) sage: B.random_element(num_bound=1000) # random 215/981*e0 + 709/953*e1 + 931/264*e2 """ @@ -528,22 +528,22 @@ def _is_valid_homomorphism_(self, other, im_gens): """ TESTS:: - sage: A = FiniteAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) - sage: B = FiniteAlgebra(QQ, [Matrix([1])]) + sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([1])]) sage: Hom(A, B)(Matrix([[1], [0]])) - Morphism from Finite algebra of degree 2 over Rational Field to Finite algebra of degree 1 over Rational Field given by matrix + Morphism from Finite dimensional algebra of degree 2 over Rational Field to Finite dimensional algebra of degree 1 over Rational Field given by matrix [1] [0] sage: Hom(B, A)(Matrix([[1, 0]])) - Morphism from Finite algebra of degree 1 over Rational Field to Finite algebra of degree 2 over Rational Field given by matrix + Morphism from Finite dimensional algebra of degree 1 over Rational Field to Finite dimensional algebra of degree 2 over Rational Field given by matrix [1 0] sage: H = Hom(A, A) sage: H(Matrix.identity(QQ, 2)) - Morphism from Finite algebra of degree 2 over Rational Field to Finite algebra of degree 2 over Rational Field given by matrix + Morphism from Finite dimensional algebra of degree 2 over Rational Field to Finite dimensional algebra of degree 2 over Rational Field given by matrix [1 0] [0 1] sage: H(Matrix([[1, 0], [0, 0]])) - Morphism from Finite algebra of degree 2 over Rational Field to Finite algebra of degree 2 over Rational Field given by matrix + Morphism from Finite dimensional algebra of degree 2 over Rational Field to Finite dimensional algebra of degree 2 over Rational Field given by matrix [1 0] [0 0] sage: H(Matrix([[1, 0], [1, 1]])) @@ -572,24 +572,24 @@ def quotient_map(self, ideal): INPUT: - - ``ideal`` -- a ``FiniteAlgebraIdeal`` + - ``ideal`` -- a ``FiniteDimensionalAlgebraIdeal`` OUTPUT: - - :class:`~sage.algebras.finite_algebras.finite_algebra_morphism.FiniteAlgebraMorphism`; + - :class:`~sage.algebras.finite_dimensional_algebras.finite_dimensional_algebra_morphism.FiniteDimensionalAlgebraMorphism`; the quotient homomorphism EXAMPLES:: - sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: q0 = A.quotient_map(A.zero_ideal()) sage: q0 - Morphism from Finite algebra of degree 2 over Finite Field of size 3 to Finite algebra of degree 2 over Finite Field of size 3 given by matrix + Morphism from Finite dimensional algebra of degree 2 over Finite Field of size 3 to Finite dimensional algebra of degree 2 over Finite Field of size 3 given by matrix [1 0] [0 1] sage: q1 = A.quotient_map(A.ideal(A.gen(1))) sage: q1 - Morphism from Finite algebra of degree 2 over Finite Field of size 3 to Finite algebra of degree 1 over Finite Field of size 3 given by matrix + Morphism from Finite dimensional algebra of degree 2 over Finite Field of size 3 to Finite dimensional algebra of degree 1 over Finite Field of size 3 given by matrix [1] [0] """ @@ -602,7 +602,7 @@ def quotient_map(self, ideal): v[p] = 1 v = self.element_class(self, v) table.append(f.solve_right(v.matrix() * f)) - B = FiniteAlgebra(k, table) + B = FiniteDimensionalAlgebra(k, table) return self.hom(f, codomain=B, check=False) def maximal_ideal(self): @@ -616,17 +616,17 @@ def maximal_ideal(self): OUTPUT: - - :class:`~sage.algebras.finite_algebras.finite_algebra_ideal.FiniteAlgebraIdeal`; + - :class:`~sage.algebras.finite_dimensional_algebras.finite_dimensional_algebra_ideal.FiniteDimensionalAlgebraIdeal`; the unique maximal ideal of ``self``. If ``self`` is not a local algebra, a ``ValueError`` is raised. EXAMPLES:: - sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: A.maximal_ideal() - Ideal (0, e1) of Finite algebra of degree 2 over Finite Field of size 3 + Ideal (0, e1) of Finite dimensional algebra of degree 2 over Finite Field of size 3 - sage: B = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) sage: B.maximal_ideal() Traceback (most recent call last): ... @@ -644,7 +644,7 @@ def maximal_ideal(self): raise ValueError("algebra is not local") if f[0][1] > 1: gens.append(f[0][0](x)) - return FiniteAlgebraIdeal(self, gens) + return FiniteDimensionalAlgebraIdeal(self, gens) def primary_decomposition(self): """ @@ -661,16 +661,16 @@ def primary_decomposition(self): EXAMPLES:: - sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: A.primary_decomposition() - [Morphism from Finite algebra of degree 2 over Finite Field of size 3 to Finite algebra of degree 2 over Finite Field of size 3 given by matrix [1 0] + [Morphism from Finite dimensional algebra of degree 2 over Finite Field of size 3 to Finite dimensional algebra of degree 2 over Finite Field of size 3 given by matrix [1 0] [0 1]] - sage: B = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) sage: B.primary_decomposition() - [Morphism from Finite algebra of degree 3 over Rational Field to Finite algebra of degree 1 over Rational Field given by matrix [0] + [Morphism from Finite dimensional algebra of degree 3 over Rational Field to Finite dimensional algebra of degree 1 over Rational Field given by matrix [0] [0] - [1], Morphism from Finite algebra of degree 3 over Rational Field to Finite algebra of degree 2 over Rational Field given by matrix [1 0] + [1], Morphism from Finite dimensional algebra of degree 3 over Rational Field to Finite dimensional algebra of degree 2 over Rational Field given by matrix [1 0] [0 1] [0 0]] """ @@ -716,11 +716,11 @@ def maximal_ideals(self): EXAMPLES:: - sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: A.maximal_ideals() - [Ideal (e1) of Finite algebra of degree 2 over Finite Field of size 3] + [Ideal (e1) of Finite dimensional algebra of degree 2 over Finite Field of size 3] - sage: B = FiniteAlgebra(QQ, []) + sage: B = FiniteDimensionalAlgebra(QQ, []) sage: B.maximal_ideals() [] """ diff --git a/src/sage/algebras/finite_algebras/finite_algebra_element.py b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.py similarity index 74% rename from src/sage/algebras/finite_algebras/finite_algebra_element.py rename to src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.py index 47806356e33..a3bf5ccd0f8 100644 --- a/src/sage/algebras/finite_algebras/finite_algebra_element.py +++ b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.py @@ -23,13 +23,13 @@ from sage.structure.element import AlgebraElement, is_Vector, parent -class FiniteAlgebraElement(AlgebraElement): +class FiniteDimensionalAlgebraElement(AlgebraElement): """ - Create an element of a :class:`FiniteAlgebra` using a multiplication table. + Create an element of a :class:`FiniteDimensionalAlgebra` using a multiplication table. INPUT: - - ``A`` -- a :class:`FiniteAlgebra` which will be the parent + - ``A`` -- a :class:`FiniteDimensionalAlgebra` which will be the parent - ``elt`` -- vector, matrix or element of the base field (default: ``None``) @@ -44,7 +44,7 @@ class FiniteAlgebraElement(AlgebraElement): EXAMPLES:: - sage: A = FiniteAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) sage: A(17) 2*e0 sage: A([1,1]) @@ -54,13 +54,13 @@ def __init__(self, A, elt=None, check=True): """ TESTS:: - sage: A = FiniteAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) sage: A(QQ(4)) Traceback (most recent call last): ... TypeError: elt should be a vector, a matrix, or an element of the base field - sage: B = FiniteAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1], [-1,0]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1], [-1,0]])]) sage: elt = B(Matrix([[1,1], [-1,1]])); elt e0 + e1 sage: TestSuite(elt).run() @@ -114,7 +114,7 @@ def vector(self): EXAMPLE:: - sage: B = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) sage: B(5).vector() (5, 0, 5) """ @@ -126,7 +126,7 @@ def matrix(self): EXAMPLE:: - sage: B = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) sage: B(5).matrix() [5 0 0] [0 5 0] @@ -140,7 +140,7 @@ def left_matrix(self): EXAMPLES:: - sage: C = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,0,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,1,0], [0,0,1]])]) + sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,0,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,1,0], [0,0,1]])]) sage: C([1,2,0]).left_matrix() [1 0 0] [0 1 0] @@ -159,7 +159,7 @@ def _repr_(self): EXAMPLE:: - sage: A = FiniteAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) sage: A(1) e0 """ @@ -195,7 +195,7 @@ def _latex_(self): EXAMPLE:: - sage: A = FiniteAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) sage: latex(A(1)) # indirect doctest \left(\begin{array}{rr} 1 & 0 \\ @@ -209,7 +209,7 @@ def __eq__(self, other): """ EXAMPLES:: - sage: A = FiniteAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) sage: A(2) == 2 True sage: A(2) == 3 @@ -225,7 +225,7 @@ def __ne__(self, other): """ EXAMPLE:: - sage: B = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) sage: B(1) != 0 True """ @@ -234,27 +234,27 @@ def __ne__(self, other): def __gt__(self, other): """ Raise a ``TypeError`` as there is no (natural) ordering defined on a - finite algebra:: + finite dimensional algebra:: - sage: A = FiniteAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) sage: A(1) > 0 Traceback (most recent call last): ... - TypeError: there is no ordering defined on a finite algebra + TypeError: there is no ordering defined on a finite dimensional algebra sage: A(1) < 0 Traceback (most recent call last): ... - TypeError: there is no ordering defined on a finite algebra + TypeError: there is no ordering defined on a finite dimensional algebra sage: A(1) >= 0 Traceback (most recent call last): ... - TypeError: there is no ordering defined on a finite algebra + TypeError: there is no ordering defined on a finite dimensional algebra sage: A(1) <= 0 Traceback (most recent call last): ... - TypeError: there is no ordering defined on a finite algebra + TypeError: there is no ordering defined on a finite dimensional algebra """ - raise TypeError("there is no ordering defined on a finite algebra") + raise TypeError("there is no ordering defined on a finite dimensional algebra") __lt__ = __ge__ = __le__ = __gt__ @@ -262,37 +262,37 @@ def _add_(self, other): """ EXAMPLE:: - sage: A = FiniteAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) sage: A.basis()[0] + A.basis()[1] e0 + e1 """ - return FiniteAlgebraElement(self.parent(), self._vector + other._vector) + return FiniteDimensionalAlgebraElement(self.parent(), self._vector + other._vector) def _sub_(self, other): """ EXAMPLE:: - sage: A = FiniteAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) sage: A.basis()[0] - A.basis()[1] e0 + 2*e1 """ - return FiniteAlgebraElement(self.parent(), self._vector - other._vector) + return FiniteDimensionalAlgebraElement(self.parent(), self._vector - other._vector) def _mul_(self, other): """ EXAMPLE:: - sage: C = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,0,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,1,0], [0,0,1]])]) + sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,0,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,1,0], [0,0,1]])]) sage: C.basis()[1] * C.basis()[2] e1 """ - return FiniteAlgebraElement(self.parent(), self._vector * other._matrix) + return FiniteDimensionalAlgebraElement(self.parent(), self._vector * other._matrix) def _lmul_(self, other): """ TESTS:: - sage: C = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,0,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,1,0], [0,0,1]])]) + sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,0,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,1,0], [0,0,1]])]) sage: c = C.random_element() sage: c * 2 == c + c True @@ -300,13 +300,13 @@ def _lmul_(self, other): if not self.parent().base_ring().has_coerce_map_from(other.parent()): raise TypeError("unsupported operand parent(s) for '*': '{}' and '{}'" .format(self.parent(), other.parent())) - return FiniteAlgebraElement(self.parent(), self._vector * other) + return FiniteDimensionalAlgebraElement(self.parent(), self._vector * other) def _rmul_(self, other): """ TESTS:: - sage: C = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,0,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,1,0], [0,0,1]])]) + sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,0,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,1,0], [0,0,1]])]) sage: c = C.random_element() sage: 2 * c == c + c True @@ -314,7 +314,7 @@ def _rmul_(self, other): if not self.parent().base_ring().has_coerce_map_from(other.parent()): raise TypeError("unsupported operand parent(s) for '*': '{}' and '{}'" .format(self.parent(), other.parent())) - return FiniteAlgebraElement(self.parent(), other * self._vector) # Note the different order + return FiniteDimensionalAlgebraElement(self.parent(), other * self._vector) # Note the different order def __pow__(self, n): """ @@ -322,7 +322,7 @@ def __pow__(self, n): EXAMPLE:: - sage: B = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) sage: b = B(vector(QQ, [2,3,4])) sage: b^6 64*e0 + 576*e1 + 4096*e2 @@ -331,13 +331,13 @@ def __pow__(self, n): if not (A._assume_associative or A.is_associative()): raise TypeError("algebra is not associative") if n > 0: - return FiniteAlgebraElement(A, self.vector() * self._matrix.__pow__(n - 1)) + return FiniteDimensionalAlgebraElement(A, self.vector() * self._matrix.__pow__(n - 1)) if not A.is_unitary(): raise TypeError("algebra is not unitary") if n == 0: return A.one() a = self.inverse() - return FiniteAlgebraElement(A, a.vector() * a.matrix().__pow__(-n - 1)) + return FiniteDimensionalAlgebraElement(A, a.vector() * a.matrix().__pow__(-n - 1)) def is_invertible(self): """ @@ -346,13 +346,13 @@ def is_invertible(self): .. NOTE:: - If an element of a unitary finite algebra over a field + If an element of a unitary finite dimensional algebra over a field admits a left inverse, then this is the unique left inverse, and it is also a right inverse. EXAMPLE:: - sage: C = FiniteAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1], [-1,0]])]) + sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1], [-1,0]])]) sage: C([1,2]).is_invertible() True sage: C(0).is_invertible() @@ -372,13 +372,13 @@ def inverse(self): .. NOTE:: - If an element of a unitary finite algebra over a field + If an element of a unitary finite dimensional algebra over a field admits a left inverse, then this is the unique left inverse, and it is also a right inverse. EXAMPLE:: - sage: C = FiniteAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1], [-1,0]])]) + sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1], [-1,0]])]) sage: C([1,2]).inverse() 1/5*e0 - 2/5*e1 """ @@ -389,7 +389,7 @@ def inverse(self): try: a = self.matrix().inverse() - return FiniteAlgebraElement(A, a, check=True) + return FiniteDimensionalAlgebraElement(A, a, check=True) except (ZeroDivisionError, ValueError): raise ZeroDivisionError("element is not invertible") @@ -399,7 +399,7 @@ def is_zerodivisor(self): EXAMPLES:: - sage: C = FiniteAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) + sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) sage: C([1,0]).is_zerodivisor() False sage: C([0,1]).is_zerodivisor() @@ -413,13 +413,13 @@ def is_nilpotent(self): EXAMPLES:: - sage: C = FiniteAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) + sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) sage: C([1,0]).is_nilpotent() False sage: C([0,1]).is_nilpotent() True - sage: A = FiniteAlgebra(QQ, [Matrix([0])]) + sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([0])]) sage: A([1]).is_nilpotent() True """ @@ -434,7 +434,7 @@ def minimal_polynomial(self): EXAMPLES:: - sage: B = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) sage: B(0).minimal_polynomial() x sage: b = B.random_element() @@ -463,7 +463,7 @@ def characteristic_polynomial(self): EXAMPLES:: - sage: B = FiniteAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) sage: B(0).characteristic_polynomial() x^3 sage: b = B.random_element() diff --git a/src/sage/algebras/finite_algebras/finite_algebra_ideal.py b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_ideal.py similarity index 74% rename from src/sage/algebras/finite_algebras/finite_algebra_ideal.py rename to src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_ideal.py index f368a8765f3..44ad798d6b6 100644 --- a/src/sage/algebras/finite_algebras/finite_algebra_ideal.py +++ b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_ideal.py @@ -12,7 +12,7 @@ # http://www.gnu.org/licenses/ #***************************************************************************** -from finite_algebra_element import FiniteAlgebraElement +from finite_dimensional_algebra_element import FiniteDimensionalAlgebraElement from sage.matrix.constructor import Matrix from sage.matrix.matrix import is_Matrix @@ -23,28 +23,28 @@ from sage.misc.cachefunc import cached_method -class FiniteAlgebraIdeal(Ideal_generic): +class FiniteDimensionalAlgebraIdeal(Ideal_generic): """ - An ideal of a :class:`FiniteAlgebra`. + An ideal of a :class:`FiniteDimensionalAlgebra`. INPUT: - - ``A`` -- a finite algebra + - ``A`` -- a finite dimensional algebra - ``gens`` -- the generators of this ideal - ``given_by_matrix`` -- (default: ``False``) whether the basis matrix is given by ``gens`` EXAMPLES:: - sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: A.ideal(A([0,1])) - Ideal (e1) of Finite algebra of degree 2 over Finite Field of size 3 + Ideal (e1) of Finite dimensional algebra of degree 2 over Finite Field of size 3 """ def __init__(self, A, gens=None, given_by_matrix=False): """ EXAMPLES:: - sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: I = A.ideal(A([0,1])) sage: TestSuite(I).run(skip="_test_category") # Currently ideals are not using the category framework """ @@ -56,12 +56,12 @@ def __init__(self, A, gens=None, given_by_matrix=False): elif gens is None: self._basis_matrix = Matrix(k, 0, n) elif isinstance(gens, (list, tuple)): - B = [FiniteAlgebraIdeal(A, x).basis_matrix() for x in gens] + B = [FiniteDimensionalAlgebraIdeal(A, x).basis_matrix() for x in gens] B = reduce(lambda x, y: x.stack(y), B, Matrix(k, 0, n)) self._basis_matrix = B.echelon_form().image().basis_matrix() elif is_Matrix(gens): - gens = FiniteAlgebraElement(A, gens) - elif isinstance(gens, FiniteAlgebraElement): + gens = FiniteDimensionalAlgebraElement(A, gens) + elif isinstance(gens, FiniteDimensionalAlgebraElement): gens = gens.vector() B = Matrix([gens * b for b in A.table()]) self._basis_matrix = B.echelon_form().image().basis_matrix() @@ -71,7 +71,7 @@ def __eq__(self, other): """ EXAMPLES:: - sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: I = A.ideal(A([1,1])) sage: J = A.ideal(A([0,1])) sage: I == J @@ -81,7 +81,7 @@ def __eq__(self, other): sage: I == I + J True - sage: A2 = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A2 = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: A is A2 False sage: A == A2 @@ -92,7 +92,7 @@ def __eq__(self, other): """ if self is other: return True - if not isinstance(other, FiniteAlgebraIdeal): + if not isinstance(other, FiniteDimensionalAlgebraIdeal): return False if self.ring() != other.ring(): return False @@ -102,7 +102,7 @@ def __ne__(self, other): """ EXAMPLES:: - sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: I = A.ideal(A([1,1])) sage: J = A.ideal(A([0,1])) sage: I != J @@ -118,7 +118,7 @@ def __contains__(self, elt): """ EXAMPLES:: - sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: J = A.ideal(A([0,1])) sage: A([0,1]) in J True @@ -133,7 +133,7 @@ def __le__(self, other): """ EXAMPLES:: - sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: I = A.ideal(A([1,1])) sage: J = A.ideal(A([0,1])) sage: I <= J @@ -153,7 +153,7 @@ def __lt__(self, other): """ EXAMPLES:: - sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: I = A.ideal(A([1,1])) sage: J = A.ideal(A([0,1])) sage: I < J @@ -169,7 +169,7 @@ def __ge__(self, other): """ EXAMPLES:: - sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: I = A.ideal(A([1,1])) sage: J = A.ideal(A([0,1])) sage: I >= J @@ -185,7 +185,7 @@ def __gt__(self, other): """ EXAMPLES:: - sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: I = A.ideal(A([1,1])) sage: J = A.ideal(A([0,1])) sage: I > J @@ -203,7 +203,7 @@ def basis_matrix(self): EXAMPLES:: - sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: I = A.ideal(A([1,1])) sage: I.basis_matrix() [1 0] @@ -218,7 +218,7 @@ def vector_space(self): EXAMPLES:: - sage: A = FiniteAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: I = A.ideal(A([1,1])) sage: I.vector_space() Vector space of degree 2 and dimension 2 over Finite Field of size 3 diff --git a/src/sage/algebras/finite_algebras/finite_algebra_morphism.py b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_morphism.py similarity index 62% rename from src/sage/algebras/finite_algebras/finite_algebra_morphism.py rename to src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_morphism.py index 117ab44d5a9..1bde54a10d4 100644 --- a/src/sage/algebras/finite_algebras/finite_algebra_morphism.py +++ b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_morphism.py @@ -19,9 +19,9 @@ from sage.matrix.constructor import matrix from sage.matrix.matrix import is_Matrix -class FiniteAlgebraMorphism(RingHomomorphism_im_gens): +class FiniteDimensionalAlgebraMorphism(RingHomomorphism_im_gens): """ - Create a morphism between two :class:`finite algebras `. + Create a morphism between two :class:`finite dimensional algebras `. INPUT: @@ -41,9 +41,9 @@ class FiniteAlgebraMorphism(RingHomomorphism_im_gens): EXAMPLES:: - sage: from sage.algebras.finite_algebras.finite_algebra_morphism import FiniteAlgebraMorphism - sage: A = FiniteAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) - sage: B = FiniteAlgebra(QQ, [Matrix([1])]) + sage: from sage.algebras.finite_dimensional_algebras.finite_dimensional_algebra_morphism import FiniteDimensionalAlgebraMorphism + sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([1])]) sage: H = Hom(A, B) sage: f = H(Matrix([[1], [0]])) sage: f.domain() is A @@ -61,11 +61,11 @@ def __init__(self, parent, f, check=True, unitary=True): """ TESTS:: - sage: from sage.algebras.finite_algebras.finite_algebra_morphism import FiniteAlgebraMorphism - sage: A = FiniteAlgebra(QQ, [Matrix([1])]) - sage: B = FiniteAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: from sage.algebras.finite_dimensional_algebras.finite_dimensional_algebra_morphism import FiniteDimensionalAlgebraMorphism + sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([1])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: H = Hom(A, B) - sage: phi = FiniteAlgebraMorphism(H, Matrix([[1, 0]])) + sage: phi = FiniteDimensionalAlgebraMorphism(H, Matrix([[1, 0]])) sage: TestSuite(phi).run(skip="_test_category") """ A = parent.domain() @@ -83,11 +83,11 @@ def _repr_(self): """ TESTS:: - sage: A = FiniteAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: I = A.maximal_ideal() sage: q = A.quotient_map(I) sage: q._repr_() - 'Morphism from Finite algebra of degree 2 over Rational Field to Finite algebra of degree 1 over Rational Field given by matrix\n[1]\n[0]' + 'Morphism from Finite dimensional algebra of degree 2 over Rational Field to Finite dimensional algebra of degree 1 over Rational Field given by matrix\n[1]\n[0]' """ return "Morphism from {} to {} given by matrix\n{}".format( self.domain(), self.codomain(), self._matrix) @@ -96,7 +96,7 @@ def __call__(self, x): """ TESTS:: - sage: A = FiniteAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: I = A.maximal_ideal() sage: q = A.quotient_map(I) sage: q(0) == 0 and q(1) == 1 @@ -112,8 +112,8 @@ def __eq__(self, other): TESTS:: - sage: A = FiniteAlgebra(QQ, [Matrix([1])]) - sage: B = FiniteAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([1])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: H = Hom(A, B) sage: phi = H(Matrix([[1, 0]])) sage: psi = H(Matrix([[1, 0]])) @@ -122,7 +122,7 @@ def __eq__(self, other): sage: phi == H.zero() False """ - return (isinstance(other, FiniteAlgebraMorphism) + return (isinstance(other, FiniteDimensionalAlgebraMorphism) and self.parent() == other.parent() and self._matrix == other._matrix) @@ -132,8 +132,8 @@ def __ne__(self, other): TESTS:: - sage: A = FiniteAlgebra(QQ, [Matrix([1])]) - sage: B = FiniteAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([1])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: H = Hom(A, B) sage: phi = H(Matrix([[1, 0]])) sage: psi = H(Matrix([[1, 0]])) @@ -150,8 +150,8 @@ def matrix(self): EXAMPLES:: - sage: A = FiniteAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) - sage: B = FiniteAlgebra(QQ, [Matrix([1])]) + sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([1])]) sage: M = Matrix([[1], [0]]) sage: H = Hom(A, B) sage: f = H(M) @@ -166,15 +166,15 @@ def inverse_image(self, I): INPUT: - - ``I`` -- ``FiniteAlgebraIdeal``, an ideal of ``self.codomain()`` + - ``I`` -- ``FiniteDimensionalAlgebraIdeal``, an ideal of ``self.codomain()`` OUTPUT: - -- ``FiniteAlgebraIdeal``, the inverse image of `I` under ``self``. + -- ``FiniteDimensionalAlgebraIdeal``, the inverse image of `I` under ``self``. EXAMPLE:: - sage: A = FiniteAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: I = A.maximal_ideal() sage: q = A.quotient_map(I) sage: B = q.codomain() @@ -184,9 +184,9 @@ def inverse_image(self, I): coker_I = I.basis_matrix().transpose().kernel().basis_matrix().transpose() return self.domain().ideal((self._matrix * coker_I).kernel().basis_matrix(), given_by_matrix=True) -class FiniteAlgebraHomset(RingHomset_generic): +class FiniteDimensionalAlgebraHomset(RingHomset_generic): """ - Set of morphisms between two finite algebras. + Set of morphisms between two finite dimensional algebras. """ @cached_method def zero(self): @@ -195,16 +195,16 @@ def zero(self): EXAMPLES:: - sage: A = FiniteAlgebra(QQ, [Matrix([1])]) - sage: B = FiniteAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([1])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: H = Hom(A, B) sage: H.zero() - Morphism from Finite algebra of degree 1 over Rational Field to - Finite algebra of degree 2 over Rational Field given by matrix + Morphism from Finite dimensional algebra of degree 1 over Rational Field to + Finite dimensional algebra of degree 2 over Rational Field given by matrix [0 0] """ from sage.matrix.constructor import matrix - return FiniteAlgebraMorphism(self, matrix.zero(self.domain().ngens(), + return FiniteDimensionalAlgebraMorphism(self, matrix.zero(self.domain().ngens(), self.codomain().ngens()), False, False) @@ -218,24 +218,24 @@ def __call__(self, f, check=True, unitary=True): EXAMPLES:: - sage: A = FiniteAlgebra(QQ, [Matrix([1])]) - sage: B = FiniteAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([1])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: H = Hom(A, B) sage: H(Matrix([[1, 0]])) - Morphism from Finite algebra of degree 1 over Rational Field to - Finite algebra of degree 2 over Rational Field given by matrix + Morphism from Finite dimensional algebra of degree 1 over Rational Field to + Finite dimensional algebra of degree 2 over Rational Field given by matrix [1 0] """ - if isinstance(f, FiniteAlgebraMorphism): + if isinstance(f, FiniteDimensionalAlgebraMorphism): if f.parent() is self: return f if f.parent() == self: - return FiniteAlgebraMorphism(self, f._matrix, check, unitary) + return FiniteDimensionalAlgebraMorphism(self, f._matrix, check, unitary) elif is_Matrix(f): - return FiniteAlgebraMorphism(self, f, check, unitary) + return FiniteDimensionalAlgebraMorphism(self, f, check, unitary) try: from sage.matrix.constructor import Matrix - return FiniteAlgebraMorphism(self, Matrix(f), check, unitary) + return FiniteDimensionalAlgebraMorphism(self, Matrix(f), check, unitary) except Exception: return RingHomset_generic.__call__(self, f, check) From 7663187b1d343ebf07c9e94fdd211e80c367d01b Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Wed, 5 Feb 2014 01:58:06 -0800 Subject: [PATCH 070/163] Let GCC 4.7.3 build on Rapsberry Pi (hard floats only). --- build/pkgs/gcc/SPKG.txt | 28 ---------------------------- build/pkgs/gcc/spkg-install | 5 +++++ 2 files changed, 5 insertions(+), 28 deletions(-) diff --git a/build/pkgs/gcc/SPKG.txt b/build/pkgs/gcc/SPKG.txt index d0445ae2650..a9014ce4568 100644 --- a/build/pkgs/gcc/SPKG.txt +++ b/build/pkgs/gcc/SPKG.txt @@ -27,31 +27,3 @@ http://gcc.gnu.org/ * Lots of stuff can be removed, run ./spkg-src to do this automatically (after downloading the sources). - -== Changelog == - -=== gcc-4.7.3.p1 (R. Andrew Ohana, 26 November 2013) === - * Trac #15433: work around for incompatiblity between g++ and - an OS X 10.9 header - -=== gcc-4.7.3.p0 (Jeroen Demeyer, 11 April 2013) === - * Trac #14441: upgrade to version 4.7.3. - -=== gcc-4.7.2.p1 (Jeroen Demeyer, 4 April 2013) === - * Trac #14378: Use $SAGE_SPKG_INST variable. - * Disable bootstrap-debug on all systems. - * Remove libitm which is broken on OS X 10.4 PPC. - -=== gcc-4.7.2.p0 (Jeroen Demeyer, 8 January 2013) === - * Trac #13913: add spkg-src script to remove lots of unneeded things - from the sources and run it. - * Rename $CONFIGURE_FLAGS to $GCC_CONFIGURE to be consistent with - other packages. - * Disable Native Language Support and remove the corresponding source - files. - -=== gcc-4.7.2 (Jeroen Demeyer, 30 September 2012) === - * #13150: Upgrade to version 4.7.2 of GCC (as optional package). - -=== gcc-4.6.3 (Jeroen Demeyer, 7 March 2012) === - * #12369: Initial release. diff --git a/build/pkgs/gcc/spkg-install b/build/pkgs/gcc/spkg-install index d5ee892b155..10a7586429f 100755 --- a/build/pkgs/gcc/spkg-install +++ b/build/pkgs/gcc/spkg-install @@ -57,6 +57,11 @@ if { uname -sr | grep 'Darwin 13\.' ;} &>/dev/null; then sed 's+defined(__GNUC_STDC_INLINE__)+& \&\& !defined(__cplusplus)+' /usr/include/sys/cdefs.h > "$SAGE_LOCAL/include/sys/cdefs.h" fi +# Let GCC build on Raspberry Pi using hard floats. +if [ `uname -m` = "armv6l" ]; then + GCC_CONFIGURE="--with-arch=armv6 --with-fpu=vfp --with-float=hard $GCC_CONFIGURE" +fi + if [ "$SAGE_CHECK" = yes ]; then # Enable internal checks in GCC. These checks do not affect the # binaries produced by GCC, but they do increase the compile time From 6a2796cc250490c995e6b8e7b56c0df71fbcc51d Mon Sep 17 00:00:00 2001 From: Nathann Cohen Date: Wed, 5 Feb 2014 14:21:48 +0100 Subject: [PATCH 071/163] trac #15787: removing libptcblas and libptf77blas from the list of mandatory ATLAS files --- src/doc/en/installation/source.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/doc/en/installation/source.rst b/src/doc/en/installation/source.rst index 70c2ed5c143..ccd8e5c7e48 100644 --- a/src/doc/en/installation/source.rst +++ b/src/doc/en/installation/source.rst @@ -1034,10 +1034,10 @@ Environment variables dealing with specific Sage packages: own version of ATLAS, set this variable to be the directory containing your ATLAS installation. It should contain the files :file:`libatlas`, :file:`liblapack`, - :file:`libcblas`, :file:`libptcblas`, :file:`libf77blas`, and - :file:`libptf77blas`, with extensions ``.a``, ``.so``, or ``.dylib``. - For backward compatibility, the libraries may also be in the subdirectory - :file:`SAGE_ATLAS_LIB/lib/`. + :file:`libcblas`, :file:`libf77blas` (and optionally :file:`libptcblas` and + :file:`libptf77blas` for multi-threaded computations), with extensions ``.a``, + ``.so``, or ``.dylib``. For backward compatibility, the libraries may also be + in the subdirectory :file:`SAGE_ATLAS_LIB/lib/`. - :envvar:`SAGE_MATPLOTLIB_GUI` - if set to anything non-empty except ``no``, then Sage will attempt to build the graphical backend when it builds the From cf1bb527e67f43b87a5661b969e6d1dcf4f295da Mon Sep 17 00:00:00 2001 From: "R. Andrew Ohana" Date: Tue, 28 Jan 2014 01:28:38 -0800 Subject: [PATCH 072/163] Cython: upgrade to 0.20.1 --- build/pkgs/cython/SPKG.txt | 50 ----------------------- build/pkgs/cython/checksums.ini | 8 ++-- build/pkgs/cython/package-version.txt | 2 +- build/pkgs/cython/patches/build_dir.patch | 31 -------------- build/pkgs/cython/patches/gdbout.patch | 20 --------- src/sage/modular/modsym/p1list.pyx | 6 ++- src/sage/symbolic/pynac.pyx | 3 +- 7 files changed, 11 insertions(+), 109 deletions(-) delete mode 100644 build/pkgs/cython/patches/build_dir.patch delete mode 100644 build/pkgs/cython/patches/gdbout.patch diff --git a/build/pkgs/cython/SPKG.txt b/build/pkgs/cython/SPKG.txt index e2e27fc239b..1bb082d461e 100644 --- a/build/pkgs/cython/SPKG.txt +++ b/build/pkgs/cython/SPKG.txt @@ -28,53 +28,3 @@ Apache License, Version 2.0 == Dependencies == * Python - -== Changelog == - -=== cython-0.19.1.p0 (R. Andrew Ohana, 11 May 2013, #14570) === - * Add build_dir.patch - -=== cython-0.19.1 (R. Andrew Ohana, 11 May 2013, #14569) === - * Upgrade Cython 0.19.1 - * Remove deps.patch and restrict.patch - -=== cython-0.19.p1 (Robert Bradshaw, 7 May 2013, #14544) === - * Add deps.patch. - -=== cython-0.19.p0 (Jeroen Demeyer, 19 April 2013, #14452) === - * Upgrade Cython to 0.19 - * Add restrict.patch. - -=== cython-0.17.4 (Robert Bradshaw, 4 January 2013, #13896) === - * Upgrade Cython 0.17.4 - -=== cython-0.17.3 (Volker Braun, 14 December 2012, #13832) === - * Upgrade Cython 0.17.3 - -=== cython-0.17.2 (Volker Braun, 21 November 2012, #13740) === - * Upgrade Cython 0.17.2 - -=== cython-0.17pre (Robert Bradshaw, 25 June 2012, #13029) === - * Upgrade Cython to 0.17 prerelease. - -=== cython-0.15.1 (Robert Bradshaw, 3 October 2011, #11761) === - * Upgrade Cython to 0.15.1 - -=== cython-0.14.1.p3 (Robert Bradshaw, 1 March 2011, #10493) === - * Upgrade Cython to 0.14.1 - * Disable (broken) temp arg assignments. - -=== cython-0.13.p1 (Robert Bradshaw, 1 October 2010) === - * Removed __getattr__ hack (upstreamed). - -=== cython-0.13.p0 (Robert Bradshaw, 16 September 2010) === - * New upstream release. - * Add a patch to speed up __getattr__(). - * Minor clean-up in spkg-install. - * SPKG.txt reformatted to 80 columns; Changelog section added. - -=== cython-0.12.1 === - -See Mercurial repository for a few changes previously made; most of the rest is -"lost". - diff --git a/build/pkgs/cython/checksums.ini b/build/pkgs/cython/checksums.ini index 1f5d7e9615f..2dfc5f980bc 100644 --- a/build/pkgs/cython/checksums.ini +++ b/build/pkgs/cython/checksums.ini @@ -1,4 +1,4 @@ -tarball=cython-VERSION.tar.bz2 -sha1=9728545db586559ff736a18183c57e419ad18b4a -md5=7838eac2e779d60fe4eefab920f54f31 -cksum=650483743 +tarball=Cython-VERSION.tar.gz +sha1=e159219be7449d514d5964a91a474cecd3a927a9 +md5=e330ff28980ef87359c49e68af9aec40 +cksum=1438694019 diff --git a/build/pkgs/cython/package-version.txt b/build/pkgs/cython/package-version.txt index b4cac08b71e..851c7b6943e 100644 --- a/build/pkgs/cython/package-version.txt +++ b/build/pkgs/cython/package-version.txt @@ -1 +1 @@ -0.19.1.p0 +0.20.1rc1 diff --git a/build/pkgs/cython/patches/build_dir.patch b/build/pkgs/cython/patches/build_dir.patch deleted file mode 100644 index f2e8aa7bb4a..00000000000 --- a/build/pkgs/cython/patches/build_dir.patch +++ /dev/null @@ -1,31 +0,0 @@ -From d5743eb30e21233d8adeedab5a73dc9444e367ff Mon Sep 17 00:00:00 2001 -From: "R. Andrew Ohana" -Date: Sat, 11 May 2013 23:15:39 -0700 -Subject: [PATCH] fully fix build_dir copying - ---- - Cython/Build/Dependencies.py | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/Cython/Build/Dependencies.py b/Cython/Build/Dependencies.py -index a2676e1..5e73782 100644 ---- a/Cython/Build/Dependencies.py -+++ b/Cython/Build/Dependencies.py -@@ -671,10 +671,10 @@ def cythonize(module_list, exclude=[], nthreads=0, aliases=None, quiet=False, fo - if build_dir: - root = os.path.realpath(os.path.abspath(find_root_package_dir(m.sources[0]))) - def copy_to_build_dir(filepath, root=root): -- filepath = os.path.abspath(filepath) -- if os.path.realpath(filepath).startswith(root): -- mod_dir = os.path.join( -- build_dir, os.path.dirname(_relpath(filepath))) -+ filepath = os.path.realpath(os.path.abspath(filepath)) -+ if filepath.startswith(root): -+ mod_dir = os.path.join(build_dir, -+ os.path.dirname(_relpath(filepath, root))) - if not os.path.isdir(mod_dir): - os.makedirs(mod_dir) - shutil.copy(filepath, mod_dir) --- -1.8.2.1 - diff --git a/build/pkgs/cython/patches/gdbout.patch b/build/pkgs/cython/patches/gdbout.patch deleted file mode 100644 index bf188e988c4..00000000000 --- a/build/pkgs/cython/patches/gdbout.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- src.orig/Cython/Compiler/CmdLine.py 2013-05-11 07:46:55.000000000 +0200 -+++ src/Cython/Compiler/CmdLine.py 2013-06-04 19:09:59.000000000 +0200 -@@ -28,6 +28,7 @@ Options: - -w, --working Sets the working directory for Cython (the directory modules - are searched from) - --gdb Output debug information for cygdb -+ --gdb-outdir Specify gdb debug information output directory. Implies --gdb. - - -D, --no-docstrings Strip docstrings from the compiled module. - -a, --annotate Produce a colorized HTML version of the source. -@@ -138,6 +125,9 @@ def parse_command_line(args): - elif option == "--gdb": - options.gdb_debug = True - options.output_dir = os.curdir -+ elif option == "--gdb-outdir": -+ options.gdb_debug = True -+ options.output_dir = pop_arg() - elif option == '-2': - options.language_level = 2 - elif option == '-3': diff --git a/src/sage/modular/modsym/p1list.pyx b/src/sage/modular/modsym/p1list.pyx index fd6939babcc..e392a3ecd0f 100644 --- a/src/sage/modular/modsym/p1list.pyx +++ b/src/sage/modular/modsym/p1list.pyx @@ -1270,7 +1270,8 @@ def lift_to_sl2z_llong(llong c, llong d, int N): sage: from sage.modular.modsym.p1list import lift_to_sl2z_llong sage: lift_to_sl2z_llong(2,6,11) - [1L, 8L, 2L, 17L] + [1L, 8L, 2L, 17L] # 32-bit + [1, 8, 2, 17] # 64-bit sage: m=Matrix(Integers(),2,2,lift_to_sl2z_llong(2,6,11)) sage: m [ 1 8] @@ -1333,7 +1334,8 @@ def lift_to_sl2z(c, d, N): sage: lift_to_sl2z(2,3,6) [1, 1, 2, 3] sage: lift_to_sl2z(2,3,6000000) - [1L, 1L, 2L, 3L] + [1L, 1L, 2L, 3L] # 32-bit + [1, 1, 2, 3] # 64-bit You will get a ValueError exception if the input is invalid. Note that here gcd(15,6,24)=3:: diff --git a/src/sage/symbolic/pynac.pyx b/src/sage/symbolic/pynac.pyx index 1549bb170f5..df4cfd8f276 100644 --- a/src/sage/symbolic/pynac.pyx +++ b/src/sage/symbolic/pynac.pyx @@ -120,7 +120,8 @@ def paramset_from_Expression(Expression e): sage: from sage.symbolic.pynac import paramset_from_Expression sage: f = function('f') sage: paramset_from_Expression(f(x).diff(x)) - [0L] + [0L] # 32-bit + [0] # 64-bit """ return paramset_to_PyTuple(ex_to_fderivative(e._gobj).get_parameter_set()) From b17f7c80784b19b7fe7f58ea01dc9c911d545825 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Sat, 8 Feb 2014 14:10:54 +0100 Subject: [PATCH 073/163] Fix various declarations --- src/sage/libs/gap/gap_includes.pxd | 13 +++++++------ src/sage/libs/polybori/decl.pxd | 24 ++++++++++++------------ src/sage/libs/ppl.pyx | 8 ++++---- 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/sage/libs/gap/gap_includes.pxd b/src/sage/libs/gap/gap_includes.pxd index 80451505912..4cdd08967f0 100644 --- a/src/sage/libs/gap/gap_includes.pxd +++ b/src/sage/libs/gap/gap_includes.pxd @@ -12,6 +12,11 @@ include "sage/ext/stdsage.pxi" include "sage/ext/interrupt.pxi" # ctrl-c interrupt block support +cdef extern from "gap/system.h": + ctypedef char libGAP_Char + ctypedef int libGAP_Int + ctypedef unsigned char libGAP_UChar + cdef extern from "gap/libgap.h": void libgap_initialize(int argc, char** argv) ctypedef void(*libgap_gasman_callback_ptr)() @@ -28,10 +33,6 @@ cdef extern from "gap/libgap.h": void libgap_enter() void libgap_exit() -cdef extern from "gap/system.h": - ctypedef char libGAP_Char - ctypedef unsigned char libGAP_UChar - cdef extern from "gap/code.h": ctypedef unsigned int libGAP_Stat ctypedef libGAP_Stat* libGAP_PtrBody @@ -58,8 +59,8 @@ cdef extern from "gap/objects.h": ctypedef void* libGAP_Obj libGAP_Obj libGAP_SHALLOW_COPY_OBJ(libGAP_Obj obj) bint libGAP_IS_INTOBJ(libGAP_Obj obj) - libGAP_Obj libGAP_INTOBJ_INT(int) - int libGAP_INT_INTOBJ(libGAP_Obj) + libGAP_Obj libGAP_INTOBJ_INT(libGAP_Int) + libGAP_Int libGAP_INT_INTOBJ(libGAP_Obj) libGAP_UInt libGAP_TNUM_OBJ(libGAP_Obj obj) char* libGAP_TNAM_OBJ(libGAP_Obj obj) cdef int libGAP_FIRST_REAL_TNUM diff --git a/src/sage/libs/polybori/decl.pxd b/src/sage/libs/polybori/decl.pxd index 8abba09434a..168f02fa96d 100644 --- a/src/sage/libs/polybori/decl.pxd +++ b/src/sage/libs/polybori/decl.pxd @@ -29,7 +29,7 @@ cdef extern from "pb_wrap.h": bint (* isConstant)() bint (* isTerminated)() bint (* is_equal "operator==")(PBNavigator right) - int (* hash)() + size_t (* hash)() # non-allocating versions PBNavigator* PBNavigator_construct \ @@ -44,7 +44,7 @@ cdef extern from "pb_wrap.h": ctypedef struct PBBlockIter "COrderingBase::block_iterator": int (* value "operator*")() PBBlockIter (* next "operator++")() - int (* hash)() + size_t (* hash)() bint PBBlockIter_equals "operator=="(PBBlockIter lhs, PBBlockIter rhs) @@ -65,13 +65,13 @@ cdef extern from "pb_wrap.h": bint (* is_equal "operator==")(PBVar right) ctypedef struct PBRing "BoolePolyRing": - long (*id) () - int (* nVariables )() + size_t (*id) () + size_t (* nVariables )() PBVar (* variable )(int n) PBOrdering (*ordering )() void (*appendBlock "ordering().appendBlock")(int nextBlockStartIndex) void (*changeOrdering )(int) - int (*hash )() + size_t (*hash )() void (*setVariableName ) (int idx, char *varname) char* (*getVariableName )(int idx) PBRing (*clone )() @@ -88,7 +88,7 @@ cdef extern from "pb_wrap.h": int (* value "operator*")() int (* next "operator++")() bint (* equal "equal")(PBMonomIter rhs) - int (* hash)() + size_t (* hash)() void PBMonomIter_destruct "Destruct" \ (PBMonomIter *mem) @@ -105,8 +105,8 @@ cdef extern from "pb_wrap.h": ctypedef struct PBMonom "DefaultRinged": bint (* reducibleBy)(PBMonom rhs) int (* deg)() - int (* hash)() - int (* stableHash)() + size_t (* hash)() + size_t (* stableHash)() int (* firstIndex)() comparecodes (* compare)(PBMonom rhs) PBSet (* set)() @@ -146,8 +146,8 @@ cdef extern from "pb_wrap.h": int (* nNodes)() int (* nSupport)() int (* size)() - int (* hash)() - int (* stableHash)() + size_t (* hash)() + size_t (* stableHash)() PBNavigator (* navigation)() PBSet (* cartesianProduct)(PBSet rhs) PBSet (* diff)(PBSet rhs) @@ -195,8 +195,8 @@ cdef extern from "pb_wrap.h": int (* eliminationLength)() int (* nUsedVariables)() int (* nNodes)() - int (* hash)() - int (* stableHash)() + size_t (* hash)() + size_t (* stableHash)() bint (* isZero)() bint (* isOne)() bint (* isConstant)() diff --git a/src/sage/libs/ppl.pyx b/src/sage/libs/ppl.pyx index 8f1d7d683fb..86fba181dce 100644 --- a/src/sage/libs/ppl.pyx +++ b/src/sage/libs/ppl.pyx @@ -187,11 +187,11 @@ restore_pre_PPL_rounding() #################################################### # Cython does not support ctypedef within cppclass; Hack around this restriction: cdef extern from "ppl.hh" namespace "Parma_Polyhedra_Library::Generator": - ctypedef enum PPL_GeneratorType: + ctypedef enum PPL_GeneratorType "Parma_Polyhedra_Library::Generator::Type": LINE, RAY, POINT, CLOSURE_POINT cdef extern from "ppl.hh" namespace "Parma_Polyhedra_Library::Constraint": - ctypedef enum PPL_ConstraintType: + ctypedef enum PPL_ConstraintType "Parma_Polyhedra_Library::Constraint::Type": EQUALITY, NONSTRICT_INEQUALITY, STRICT_INEQUALITY cdef extern from "ppl.hh" namespace "Parma_Polyhedra_Library::MIP_Problem": @@ -328,7 +328,7 @@ cdef extern from "ppl.hh" namespace "Parma_Polyhedra_Library": cdef enum PPL_Optimization_Mode: MINIMIZATION, MAXIMIZATION - cdef enum PPL_MIP_Problem_Status: + cdef enum MIP_Problem_Status: UNFEASIBLE_MIP_PROBLEM, UNBOUNDED_MIP_PROBLEM, OPTIMIZED_MIP_PROBLEM cdef cppclass PPL_Polyhedron: @@ -426,7 +426,7 @@ cdef extern from "ppl.hh" namespace "Parma_Polyhedra_Library": void set_optimization_mode(PPL_Optimization_Mode mode) PPL_Optimization_Mode optimization_mode() bint is_satisfiable() - PPL_MIP_Problem_Status solve() + MIP_Problem_Status solve() void evaluate_objective_function(PPL_Generator evaluating_point, PPL_Coefficient &num, PPL_Coefficient &den) except +ValueError PPL_Generator& feasible_point() PPL_Generator optimizing_point() except +ValueError From d0b48c62a7d6c1445017d53ee7d35df7a05d3037 Mon Sep 17 00:00:00 2001 From: Erik Quaeghebeur Date: Sun, 9 Feb 2014 14:00:24 +0100 Subject: [PATCH 074/163] third try for trac issue #15686 --- src/sage/numerical/backends/generic_backend.pyx | 7 +++---- src/sage/numerical/mip.pyx | 16 +++++++--------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/sage/numerical/backends/generic_backend.pyx b/src/sage/numerical/backends/generic_backend.pyx index 01d3b190d60..3db5190c2c3 100644 --- a/src/sage/numerical/backends/generic_backend.pyx +++ b/src/sage/numerical/backends/generic_backend.pyx @@ -980,15 +980,14 @@ cpdef GenericBackend get_solver(constraint_generation = False, solver = None): ``"CPLEX"``, ``"Gurobi"``, ``"PPL"``, or ``None``. If ``solver=None`` (default), the default solver is used (see ``default_mip_solver`` method. - - ``constraint_generation`` + - ``constraint_generation`` -- Only used when ``solver=None``. - When set to ``True``, after solving the ``MixedIntegerLinearProgram``, it is possible to add a constraint, and then solve it again. The effect is that solvers that do not support this feature will not be - used when ``solver=None``, + used. - - When set to ``False`` (default), also solvers that do not support this - feature may be used when ``solver=None``. + - Defaults to ``False``. .. SEEALSO:: diff --git a/src/sage/numerical/mip.pyx b/src/sage/numerical/mip.pyx index 7a53d7e0e8b..b1fd0832635 100644 --- a/src/sage/numerical/mip.pyx +++ b/src/sage/numerical/mip.pyx @@ -216,15 +216,14 @@ cdef class MixedIntegerLinearProgram(SageObject): - When set to ``False``, the ``MixedIntegerLinearProgram`` is defined as a minimization. - - ``constraint_generation`` + - ``constraint_generation`` -- Only used when ``solver=None``. - When set to ``True``, after solving the ``MixedIntegerLinearProgram``, it is possible to add a constraint, and then solve it again. The effect is that solvers that do not support this feature will not be - used when ``solver=None``, + used. - - When set to ``False`` (default), also solvers that do not support this - feature may be used when ``solver=None``. + - Defaults to ``False``. .. SEEALSO:: @@ -280,15 +279,14 @@ cdef class MixedIntegerLinearProgram(SageObject): - When set to ``False``, the ``MixedIntegerLinearProgram`` is defined as a minimization. - - ``constraint_generation`` + - ``constraint_generation`` -- Only used when ``solver=None``. - - When set to ``True``, after solving the + - When set to ``True``, after solving the ``MixedIntegerLinearProgram``, it is possible to add a constraint, and then solve it again. The effect is that solvers that do not - support this feature will not be used when ``solver=None``, + support this feature will not be used. - - When set to ``False`` (default), also solvers that do not support - this feature may be used when ``solver=None``. + - Defaults to ``False``. - ``check_redundant`` -- whether to check that constraints added to the program are redundant with constraints already in the program. From 9f3a73e90f9b034b16f42953c60cd573891315c6 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Mon, 10 Feb 2014 06:57:15 -0800 Subject: [PATCH 075/163] Add support for ARMv7 boards using hard floats to gcc package. --- build/pkgs/gcc/spkg-install | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/build/pkgs/gcc/spkg-install b/build/pkgs/gcc/spkg-install index 10a7586429f..e1648c9aff2 100755 --- a/build/pkgs/gcc/spkg-install +++ b/build/pkgs/gcc/spkg-install @@ -62,6 +62,11 @@ if [ `uname -m` = "armv6l" ]; then GCC_CONFIGURE="--with-arch=armv6 --with-fpu=vfp --with-float=hard $GCC_CONFIGURE" fi +# Let GCC build on more recent ARM boards using hard floats. +if [ `uname -m` = "armv7l" ]; then + GCC_CONFIGURE="--with-arch=armv7-a --with-fpu=vfpv3-d16 --with-float=hard $GCC_CONFIGURE" +fi + if [ "$SAGE_CHECK" = yes ]; then # Enable internal checks in GCC. These checks do not affect the # binaries produced by GCC, but they do increase the compile time From 6dd9dd6c0c36a474642abc3952b46f98a5ceaad5 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Mon, 10 Feb 2014 10:47:33 -0800 Subject: [PATCH 076/163] Changed inverses, doc, and arith return type. Doc now uses finite-dimensonal and all blocks are "EXAMPLES::". --- .../finite_dimensional_algebra.py | 52 +++++------ .../finite_dimensional_algebra_element.py | 92 +++++++++++-------- .../finite_dimensional_algebra_ideal.py | 4 +- .../finite_dimensional_algebra_morphism.py | 14 +-- 4 files changed, 90 insertions(+), 72 deletions(-) diff --git a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py index cdfdadaf95d..4c306eebdaf 100644 --- a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py +++ b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py @@ -1,5 +1,5 @@ """ -Finite Dimensional Algebras +Finite-Dimensional Algebras """ #***************************************************************************** @@ -27,7 +27,7 @@ class FiniteDimensionalAlgebra(Algebra): """ - Create a finite dimensional `k`-algebra from a multiplication table. + Create a finite-dimensional `k`-algebra from a multiplication table. INPUT: @@ -46,7 +46,7 @@ class FiniteDimensionalAlgebra(Algebra): the category to which this algebra belongs The list ``table`` must have the following form: there exists a - finite dimensional `k`-algebra of degree `n` with basis + finite-dimensional `k`-algebra of degree `n` with basis `(e_1, \ldots, e_n)` such that the `i`-th element of ``table`` is the matrix of right multiplication by `e_i` with respect to the basis `(e_1, \ldots, e_n)`. @@ -55,11 +55,11 @@ class FiniteDimensionalAlgebra(Algebra): sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: A - Finite dimensional algebra of degree 2 over Finite Field of size 3 + Finite-dimensional algebra of degree 2 over Finite Field of size 3 sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) sage: B - Finite dimensional algebra of degree 3 over Rational Field + Finite-dimensional algebra of degree 3 over Rational Field """ def __init__(self, k, table, names='e', assume_associative=False, category=None): @@ -68,19 +68,19 @@ def __init__(self, k, table, names='e', assume_associative=False, category=None) sage: A = FiniteDimensionalAlgebra(QQ, []) sage: A - Finite dimensional algebra of degree 0 over Rational Field + Finite-dimensional algebra of degree 0 over Rational Field sage: type(A) sage: TestSuite(A).run() sage: B = FiniteDimensionalAlgebra(GF(7), [Matrix([1])]) sage: B - Finite dimensional algebra of degree 1 over Finite Field of size 7 + Finite-dimensional algebra of degree 1 over Finite Field of size 7 sage: TestSuite(B).run() sage: C = FiniteDimensionalAlgebra(CC, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: C - Finite dimensional algebra of degree 2 over Complex Field with 53 bits of precision + Finite-dimensional algebra of degree 2 over Complex Field with 53 bits of precision sage: TestSuite(C).run() sage: FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]])]) @@ -113,9 +113,9 @@ def _repr_(self): TEST:: sage: FiniteDimensionalAlgebra(RR, [Matrix([1])])._repr_() - 'Finite dimensional algebra of degree 1 over Real Field with 53 bits of precision' + 'Finite-dimensional algebra of degree 1 over Real Field with 53 bits of precision' """ - return "Finite dimensional algebra of degree {} over {}".format(self.degree(), self.base_ring()) + return "Finite-dimensional algebra of degree {} over {}".format(self.degree(), self.base_ring()) def _coerce_map_from_(self, S): """ @@ -142,7 +142,7 @@ def _element_constructor_(self, x): sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([0])]) sage: a = A(0) sage: a.parent() - Finite dimensional algebra of degree 1 over Rational Field + Finite-dimensional algebra of degree 1 over Rational Field sage: A(1) Traceback (most recent call last): ... @@ -167,7 +167,7 @@ def _Hom_(self, B, category): sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([1])]) sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: A._Hom_(B, A.category()) - Set of Homomorphisms from Finite dimensional algebra of degree 1 over Rational Field to Finite dimensional algebra of degree 2 over Rational Field + Set of Homomorphisms from Finite-dimensional algebra of degree 1 over Rational Field to Finite-dimensional algebra of degree 2 over Rational Field """ if isinstance(B, FiniteDimensionalAlgebra): category = FiniteDimensionalAlgebrasWithBasis(self.base_ring()).or_subcategory(category) @@ -293,7 +293,7 @@ def base_extend(self, F): sage: C = FiniteDimensionalAlgebra(GF(2), [Matrix([1])]) sage: k. = GF(4) sage: C.base_extend(k) - Finite dimensional algebra of degree 1 over Finite Field in y of size 2^2 + Finite-dimensional algebra of degree 1 over Finite Field in y of size 2^2 """ # Base extension of the multiplication table is done by __init__. return FiniteDimensionalAlgebra(F, self.table()) @@ -343,7 +343,7 @@ def ideal(self, gens=None, given_by_matrix=False): sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: A.ideal(A([1,1])) - Ideal (e0 + e1) of Finite dimensional algebra of degree 2 over Finite Field of size 3 + Ideal (e0 + e1) of Finite-dimensional algebra of degree 2 over Finite Field of size 3 """ return self._ideal_class_()(self, gens=gens, given_by_matrix=given_by_matrix) @@ -445,7 +445,7 @@ def is_unitary(self): .. NOTE:: - If a finite dimensional algebra over a field admits a left identity, + If a finite-dimensional algebra over a field admits a left identity, then this is the unique left identity, and it is also a right identity. """ @@ -531,19 +531,19 @@ def _is_valid_homomorphism_(self, other, im_gens): sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([1])]) sage: Hom(A, B)(Matrix([[1], [0]])) - Morphism from Finite dimensional algebra of degree 2 over Rational Field to Finite dimensional algebra of degree 1 over Rational Field given by matrix + Morphism from Finite-dimensional algebra of degree 2 over Rational Field to Finite-dimensional algebra of degree 1 over Rational Field given by matrix [1] [0] sage: Hom(B, A)(Matrix([[1, 0]])) - Morphism from Finite dimensional algebra of degree 1 over Rational Field to Finite dimensional algebra of degree 2 over Rational Field given by matrix + Morphism from Finite-dimensional algebra of degree 1 over Rational Field to Finite-dimensional algebra of degree 2 over Rational Field given by matrix [1 0] sage: H = Hom(A, A) sage: H(Matrix.identity(QQ, 2)) - Morphism from Finite dimensional algebra of degree 2 over Rational Field to Finite dimensional algebra of degree 2 over Rational Field given by matrix + Morphism from Finite-dimensional algebra of degree 2 over Rational Field to Finite-dimensional algebra of degree 2 over Rational Field given by matrix [1 0] [0 1] sage: H(Matrix([[1, 0], [0, 0]])) - Morphism from Finite dimensional algebra of degree 2 over Rational Field to Finite dimensional algebra of degree 2 over Rational Field given by matrix + Morphism from Finite-dimensional algebra of degree 2 over Rational Field to Finite-dimensional algebra of degree 2 over Rational Field given by matrix [1 0] [0 0] sage: H(Matrix([[1, 0], [1, 1]])) @@ -584,12 +584,12 @@ def quotient_map(self, ideal): sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: q0 = A.quotient_map(A.zero_ideal()) sage: q0 - Morphism from Finite dimensional algebra of degree 2 over Finite Field of size 3 to Finite dimensional algebra of degree 2 over Finite Field of size 3 given by matrix + Morphism from Finite-dimensional algebra of degree 2 over Finite Field of size 3 to Finite-dimensional algebra of degree 2 over Finite Field of size 3 given by matrix [1 0] [0 1] sage: q1 = A.quotient_map(A.ideal(A.gen(1))) sage: q1 - Morphism from Finite dimensional algebra of degree 2 over Finite Field of size 3 to Finite dimensional algebra of degree 1 over Finite Field of size 3 given by matrix + Morphism from Finite-dimensional algebra of degree 2 over Finite Field of size 3 to Finite-dimensional algebra of degree 1 over Finite Field of size 3 given by matrix [1] [0] """ @@ -624,7 +624,7 @@ def maximal_ideal(self): sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: A.maximal_ideal() - Ideal (0, e1) of Finite dimensional algebra of degree 2 over Finite Field of size 3 + Ideal (0, e1) of Finite-dimensional algebra of degree 2 over Finite Field of size 3 sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) sage: B.maximal_ideal() @@ -663,14 +663,14 @@ def primary_decomposition(self): sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: A.primary_decomposition() - [Morphism from Finite dimensional algebra of degree 2 over Finite Field of size 3 to Finite dimensional algebra of degree 2 over Finite Field of size 3 given by matrix [1 0] + [Morphism from Finite-dimensional algebra of degree 2 over Finite Field of size 3 to Finite-dimensional algebra of degree 2 over Finite Field of size 3 given by matrix [1 0] [0 1]] sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) sage: B.primary_decomposition() - [Morphism from Finite dimensional algebra of degree 3 over Rational Field to Finite dimensional algebra of degree 1 over Rational Field given by matrix [0] + [Morphism from Finite-dimensional algebra of degree 3 over Rational Field to Finite-dimensional algebra of degree 1 over Rational Field given by matrix [0] [0] - [1], Morphism from Finite dimensional algebra of degree 3 over Rational Field to Finite dimensional algebra of degree 2 over Rational Field given by matrix [1 0] + [1], Morphism from Finite-dimensional algebra of degree 3 over Rational Field to Finite-dimensional algebra of degree 2 over Rational Field given by matrix [1 0] [0 1] [0 0]] """ @@ -718,7 +718,7 @@ def maximal_ideals(self): sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: A.maximal_ideals() - [Ideal (e1) of Finite dimensional algebra of degree 2 over Finite Field of size 3] + [Ideal (e1) of Finite-dimensional algebra of degree 2 over Finite Field of size 3] sage: B = FiniteDimensionalAlgebra(QQ, []) sage: B.maximal_ideals() diff --git a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.py b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.py index a3bf5ccd0f8..898ceabe337 100644 --- a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.py +++ b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.py @@ -15,7 +15,7 @@ import re -from sage.misc.cachefunc import cached_method +from sage.misc.lazy_attribute import lazy_attribute from sage.matrix.constructor import Matrix from sage.matrix.matrix import is_Matrix from sage.modules.free_module_element import vector @@ -24,7 +24,7 @@ class FiniteDimensionalAlgebraElement(AlgebraElement): - """ + r""" Create an element of a :class:`FiniteDimensionalAlgebra` using a multiplication table. INPUT: @@ -112,7 +112,7 @@ def vector(self): """ Return ``self`` as a vector. - EXAMPLE:: + EXAMPLES:: sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) sage: B(5).vector() @@ -124,7 +124,7 @@ def matrix(self): """ Return the matrix for multiplication by ``self`` from the right. - EXAMPLE:: + EXAMPLES:: sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) sage: B(5).matrix() @@ -157,7 +157,7 @@ def _repr_(self): """ Return the string representation of ``self``. - EXAMPLE:: + EXAMPLES:: sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) sage: A(1) @@ -193,7 +193,7 @@ def _latex_(self): r""" Return the LaTeX representation of ``self``. - EXAMPLE:: + EXAMPLES:: sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) sage: latex(A(1)) # indirect doctest @@ -223,7 +223,7 @@ def __eq__(self, other): def __ne__(self, other): """ - EXAMPLE:: + EXAMPLES:: sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) sage: B(1) != 0 @@ -234,59 +234,59 @@ def __ne__(self, other): def __gt__(self, other): """ Raise a ``TypeError`` as there is no (natural) ordering defined on a - finite dimensional algebra:: + finite-dimensional algebra:: sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) sage: A(1) > 0 Traceback (most recent call last): ... - TypeError: there is no ordering defined on a finite dimensional algebra + TypeError: there is no ordering defined on a finite-dimensional algebra sage: A(1) < 0 Traceback (most recent call last): ... - TypeError: there is no ordering defined on a finite dimensional algebra + TypeError: there is no ordering defined on a finite-dimensional algebra sage: A(1) >= 0 Traceback (most recent call last): ... - TypeError: there is no ordering defined on a finite dimensional algebra + TypeError: there is no ordering defined on a finite-dimensional algebra sage: A(1) <= 0 Traceback (most recent call last): ... - TypeError: there is no ordering defined on a finite dimensional algebra + TypeError: there is no ordering defined on a finite-dimensional algebra """ - raise TypeError("there is no ordering defined on a finite dimensional algebra") + raise TypeError("there is no ordering defined on a finite-dimensional algebra") __lt__ = __ge__ = __le__ = __gt__ def _add_(self, other): """ - EXAMPLE:: + EXAMPLES:: sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) sage: A.basis()[0] + A.basis()[1] e0 + e1 """ - return FiniteDimensionalAlgebraElement(self.parent(), self._vector + other._vector) + return self.__class__(self.parent(), self._vector + other._vector) def _sub_(self, other): """ - EXAMPLE:: + EXAMPLES:: sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) sage: A.basis()[0] - A.basis()[1] e0 + 2*e1 """ - return FiniteDimensionalAlgebraElement(self.parent(), self._vector - other._vector) + return self.__class__(self.parent(), self._vector - other._vector) def _mul_(self, other): """ - EXAMPLE:: + EXAMPLES:: sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,0,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,1,0], [0,0,1]])]) sage: C.basis()[1] * C.basis()[2] e1 """ - return FiniteDimensionalAlgebraElement(self.parent(), self._vector * other._matrix) + return self.__class__(self.parent(), self._vector * other._matrix) def _lmul_(self, other): """ @@ -300,7 +300,7 @@ def _lmul_(self, other): if not self.parent().base_ring().has_coerce_map_from(other.parent()): raise TypeError("unsupported operand parent(s) for '*': '{}' and '{}'" .format(self.parent(), other.parent())) - return FiniteDimensionalAlgebraElement(self.parent(), self._vector * other) + return self.__class__(self.parent(), self._vector * other) def _rmul_(self, other): """ @@ -320,7 +320,7 @@ def __pow__(self, n): """ Return ``self`` raised to the power ``n``. - EXAMPLE:: + EXAMPLES:: sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) sage: b = B(vector(QQ, [2,3,4])) @@ -331,13 +331,13 @@ def __pow__(self, n): if not (A._assume_associative or A.is_associative()): raise TypeError("algebra is not associative") if n > 0: - return FiniteDimensionalAlgebraElement(A, self.vector() * self._matrix.__pow__(n - 1)) + return self.__class__(A, self.vector() * self._matrix.__pow__(n - 1)) if not A.is_unitary(): raise TypeError("algebra is not unitary") if n == 0: return A.one() a = self.inverse() - return FiniteDimensionalAlgebraElement(A, a.vector() * a.matrix().__pow__(-n - 1)) + return self.__class__(A, a.vector() * a.matrix().__pow__(-n - 1)) def is_invertible(self): """ @@ -346,11 +346,11 @@ def is_invertible(self): .. NOTE:: - If an element of a unitary finite dimensional algebra over a field + If an element of a unitary finite-dimensional algebra over a field admits a left inverse, then this is the unique left inverse, and it is also a right inverse. - EXAMPLE:: + EXAMPLES:: sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1], [-1,0]])]) sage: C([1,2]).is_invertible() @@ -358,13 +358,34 @@ def is_invertible(self): sage: C(0).is_invertible() False """ + return self._inverse is not None + + @lazy_attribute + def _inverse(self): + """ + The two-sided inverse of ``self``, if it exists; otherwise this + is ``None``. + + EXAMPLES:: + + sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1], [-1,0]])]) + sage: C([1,2])._inverse + 1/5*e0 - 2/5*e1 + sage: C(0)._inverse is None + True + """ + A = self.parent() + if not A.is_unitary(): + return None + try: - self.inverse() - except ZeroDivisionError: - return False - return True + a = self.matrix().inverse() + y = FiniteDimensionalAlgebraElement(A, a, check=True) + y._inverse = self + return y + except (ZeroDivisionError, ValueError): + return None - @cached_method def inverse(self): """ Return the two-sided multiplicative inverse of ``self``, if it @@ -372,26 +393,23 @@ def inverse(self): .. NOTE:: - If an element of a unitary finite dimensional algebra over a field + If an element of a unitary finite-dimensional algebra over a field admits a left inverse, then this is the unique left inverse, and it is also a right inverse. - EXAMPLE:: + EXAMPLES:: sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1], [-1,0]])]) sage: C([1,2]).inverse() 1/5*e0 - 2/5*e1 """ - A = self.parent() if not A.is_unitary(): raise TypeError("algebra is not unitary") - try: - a = self.matrix().inverse() - return FiniteDimensionalAlgebraElement(A, a, check=True) - except (ZeroDivisionError, ValueError): + if self._inverse is None: raise ZeroDivisionError("element is not invertible") + return self._inverse def is_zerodivisor(self): """ diff --git a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_ideal.py b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_ideal.py index 44ad798d6b6..7a5b91bd26b 100644 --- a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_ideal.py +++ b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_ideal.py @@ -29,7 +29,7 @@ class FiniteDimensionalAlgebraIdeal(Ideal_generic): INPUT: - - ``A`` -- a finite dimensional algebra + - ``A`` -- a finite-dimensional algebra - ``gens`` -- the generators of this ideal - ``given_by_matrix`` -- (default: ``False``) whether the basis matrix is given by ``gens`` @@ -38,7 +38,7 @@ class FiniteDimensionalAlgebraIdeal(Ideal_generic): sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: A.ideal(A([0,1])) - Ideal (e1) of Finite dimensional algebra of degree 2 over Finite Field of size 3 + Ideal (e1) of Finite-dimensional algebra of degree 2 over Finite Field of size 3 """ def __init__(self, A, gens=None, given_by_matrix=False): """ diff --git a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_morphism.py b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_morphism.py index 1bde54a10d4..3e9c5fd4ef3 100644 --- a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_morphism.py +++ b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_morphism.py @@ -21,7 +21,7 @@ class FiniteDimensionalAlgebraMorphism(RingHomomorphism_im_gens): """ - Create a morphism between two :class:`finite dimensional algebras `. + Create a morphism between two :class:`finite-dimensional algebras `. INPUT: @@ -87,7 +87,7 @@ def _repr_(self): sage: I = A.maximal_ideal() sage: q = A.quotient_map(I) sage: q._repr_() - 'Morphism from Finite dimensional algebra of degree 2 over Rational Field to Finite dimensional algebra of degree 1 over Rational Field given by matrix\n[1]\n[0]' + 'Morphism from Finite-dimensional algebra of degree 2 over Rational Field to Finite-dimensional algebra of degree 1 over Rational Field given by matrix\n[1]\n[0]' """ return "Morphism from {} to {} given by matrix\n{}".format( self.domain(), self.codomain(), self._matrix) @@ -186,7 +186,7 @@ def inverse_image(self, I): class FiniteDimensionalAlgebraHomset(RingHomset_generic): """ - Set of morphisms between two finite dimensional algebras. + Set of morphisms between two finite-dimensional algebras. """ @cached_method def zero(self): @@ -199,8 +199,8 @@ def zero(self): sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: H = Hom(A, B) sage: H.zero() - Morphism from Finite dimensional algebra of degree 1 over Rational Field to - Finite dimensional algebra of degree 2 over Rational Field given by matrix + Morphism from Finite-dimensional algebra of degree 1 over Rational Field to + Finite-dimensional algebra of degree 2 over Rational Field given by matrix [0 0] """ from sage.matrix.constructor import matrix @@ -222,8 +222,8 @@ def __call__(self, f, check=True, unitary=True): sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: H = Hom(A, B) sage: H(Matrix([[1, 0]])) - Morphism from Finite dimensional algebra of degree 1 over Rational Field to - Finite dimensional algebra of degree 2 over Rational Field given by matrix + Morphism from Finite-dimensional algebra of degree 1 over Rational Field to + Finite-dimensional algebra of degree 2 over Rational Field given by matrix [1 0] """ if isinstance(f, FiniteDimensionalAlgebraMorphism): From d35d7b06cc5389763aeca95d7e1044deea001eff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 10 Feb 2014 21:54:17 +0100 Subject: [PATCH 077/163] trac #15345 first step: coercion of Laurent polynomials into fractions --- src/sage/rings/fraction_field.py | 7 +++++ .../rings/polynomial/laurent_polynomial.pyx | 26 +++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/sage/rings/fraction_field.py b/src/sage/rings/fraction_field.py index d5ead35647c..dbcd828f730 100644 --- a/src/sage/rings/fraction_field.py +++ b/src/sage/rings/fraction_field.py @@ -269,6 +269,7 @@ def _coerce_map_from_(self, S): from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ from sage.rings.number_field.number_field_base import NumberField + from sage.rings.polynomial.laurent_polynomial_ring import LaurentPolynomialRing_generic # The case ``S`` being `\QQ` requires special handling since `\QQ` is # not implemented as a ``FractionField_generic``. @@ -283,6 +284,12 @@ def _coerce_map_from_(self, S): self._number_field_to_frac_of_ring_of_integers, \ parent_as_first_arg=False) + # special treatment for LaurentPolynomialRings + if isinstance(S, LaurentPolynomialRing_generic): + return CallableConvertMap(S, self, \ + lambda x: self._element_class(self, *x.to_fraction()), + parent_as_first_arg=False) + if isinstance(S, FractionField_generic) and \ self._R.has_coerce_map_from(S.ring()): return CallableConvertMap(S, self, \ diff --git a/src/sage/rings/polynomial/laurent_polynomial.pyx b/src/sage/rings/polynomial/laurent_polynomial.pyx index 0d943c38064..3f123fd9b07 100644 --- a/src/sage/rings/polynomial/laurent_polynomial.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial.pyx @@ -492,6 +492,32 @@ cdef class LaurentPolynomial_mpair(CommutativeAlgebraElement): self._compute_polydict() return self._prod.dict() + def to_fraction(self): + """ + Return one representation of self as a pair (numerator, denominator) + + Here both the numerator and the denominator are polynomials. + + This is used for coercion into the fraction field. + + EXAMPLES:: + + sage: L. = LaurentPolynomialRing(QQ) + sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7 + sage: f.to_fraction() + (4*x^7*y^7*z + 3*x^3*y^8*z^2 + 2*x^4*y^7 + x^6*z^2, y^7*z^2) + """ + ring = self.parent().polynomial_ring() + numer = self._poly + denom = ring.one() + var = ring.gens() + for i, j in enumerate(self._mon): + if j > 0: + poly *= var[i]**j + else: + denom *= var[i]**(-j) + return (numer, denom) + cpdef ModuleElement _add_(self, ModuleElement _right): """ Returns the Laurent polynomial self + right. From d1ea9d8bfbba01fbeef4f4ae50a19127bfeea2a2 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Mon, 10 Feb 2014 15:36:51 -0800 Subject: [PATCH 078/163] Added special case of q_int(0). --- src/sage/combinat/q_analogues.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/sage/combinat/q_analogues.py b/src/sage/combinat/q_analogues.py index 6f3e052eca4..0abb1eff44d 100644 --- a/src/sage/combinat/q_analogues.py +++ b/src/sage/combinat/q_analogues.py @@ -56,12 +56,22 @@ def q_int(n, q=None): Traceback (most recent call last): ... ValueError: 3/2 must be an integer + + TESTS: + + We check that :trac:`15805` is fixed:: + + sage: from sage.combinat.q_analogues import q_int + sage: q_int(0).parent() + Univariate Polynomial Ring in q over Integer Ring """ if not n in ZZ: raise ValueError('%s must be an integer' % n) if q is None: q = ZZ['q'].gens()[0] + if n == 0: # Special case + return q.parent().zero() if n >= 0: return sum(q**i for i in range(n)) return -q**n*sum(q**i for i in range(-n)) From bb7be967b6a741c20e2511bca10a3b3e98fd2aee Mon Sep 17 00:00:00 2001 From: "R. Andrew Ohana" Date: Mon, 10 Feb 2014 20:51:06 -0800 Subject: [PATCH 079/163] mpmath: upgrade to version 0.18 --- build/pkgs/mpmath/SPKG.txt | 21 --------------------- build/pkgs/mpmath/checksums.ini | 8 ++++---- build/pkgs/mpmath/package-version.txt | 2 +- build/pkgs/mpmath/spkg-install | 8 ++------ 4 files changed, 7 insertions(+), 32 deletions(-) diff --git a/build/pkgs/mpmath/SPKG.txt b/build/pkgs/mpmath/SPKG.txt index b258e8037a5..9217b20bee9 100644 --- a/build/pkgs/mpmath/SPKG.txt +++ b/build/pkgs/mpmath/SPKG.txt @@ -18,24 +18,3 @@ Mpmath is a pure-Python library for multiprecision floating-point arithmetic. It == Dependencies == * Python - -== Changelog == - -=== mpmath-0.17 (Fredrik Johansson, Feb 1, 2011) === - * Updated to mpmath-0.17. - -=== mpmath-0.16 (Fredrik Johansson, Oct 30, 2010) === - * Updated to mpmath-0.16. - -=== mpmath-0.15 (Fredrik Johansson, Jun 6th, 2010) === - * Updated to mpmath-0.15. - -=== mpmath-0.14 (Harald Schilly, Feb 20th, 2010) === - * #8159: updated to mpmath-0.14. - -=== mpmath-0.13 (Fredrik Johansson, August 14th, 2009) === - * Updated to mpmath-0.13. - -=== mpmath-0.12 (Mike Hansen, June 19th, 2009) === - * Initial spkg. - diff --git a/build/pkgs/mpmath/checksums.ini b/build/pkgs/mpmath/checksums.ini index c433457b423..db86a30f6e4 100644 --- a/build/pkgs/mpmath/checksums.ini +++ b/build/pkgs/mpmath/checksums.ini @@ -1,4 +1,4 @@ -tarball=mpmath-VERSION.tar.bz2 -sha1=46254d3a2acf56c1512b7806db5357061e4939e7 -md5=2159cd9eded153a5a4e4bd2b7318b63b -cksum=2551903054 +tarball=mpmath-VERSION.tar.gz +sha1=b103be6ab76aa2747f5b5d46b9a097b97a191dee +md5=e2e7a7932969f52f25b7e19d8f0438bd +cksum=1143910860 diff --git a/build/pkgs/mpmath/package-version.txt b/build/pkgs/mpmath/package-version.txt index 50653ad0a6e..a4d2aceeb8d 100644 --- a/build/pkgs/mpmath/package-version.txt +++ b/build/pkgs/mpmath/package-version.txt @@ -1 +1 @@ -0.17 +0.18 diff --git a/build/pkgs/mpmath/spkg-install b/build/pkgs/mpmath/spkg-install index f4eefa6f657..1ce15960504 100755 --- a/build/pkgs/mpmath/spkg-install +++ b/build/pkgs/mpmath/spkg-install @@ -9,12 +9,8 @@ fi # We need to delete the old path, so that there are no leftovers from the # previous installation, otherwise mpmath could get broken (for example by # importing some local files instead of the standard library ones...) -if [ "$SAGE_ROOT" = "" ]; then - echo "Please set the SAGE_ROOT variable" - exit 1 -fi -echo "Deleting $SAGE_ROOT/local/lib/python/site-packages/mpmath*" -rm -rf $SAGE_ROOT/local/lib/python/site-packages/mpmath* +echo "Deleting $SAGE_LOCAL/lib/python/site-packages/mpmath*" +rm -rf "$SAGE_LOCAL"/lib/python/site-packages/mpmath* cd src/ From 80450c0b9ab464dc06c38568f91f70be744f13df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 11 Feb 2014 10:07:25 +0100 Subject: [PATCH 080/163] trac #15805 : small enhancement --- src/sage/combinat/q_analogues.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/combinat/q_analogues.py b/src/sage/combinat/q_analogues.py index 0abb1eff44d..c449dde71c0 100644 --- a/src/sage/combinat/q_analogues.py +++ b/src/sage/combinat/q_analogues.py @@ -69,8 +69,8 @@ def q_int(n, q=None): raise ValueError('%s must be an integer' % n) if q is None: - q = ZZ['q'].gens()[0] - if n == 0: # Special case + q = ZZ['q'].gen() + if n == 0: # Special case return q.parent().zero() if n >= 0: return sum(q**i for i in range(n)) From 3c151ec215be2f31df26c0089d967de585ea457b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 11 Feb 2014 10:34:46 +0100 Subject: [PATCH 081/163] trac #15345 corrected code --- src/sage/rings/polynomial/laurent_polynomial.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/polynomial/laurent_polynomial.pyx b/src/sage/rings/polynomial/laurent_polynomial.pyx index 3f123fd9b07..31b721e673b 100644 --- a/src/sage/rings/polynomial/laurent_polynomial.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial.pyx @@ -513,9 +513,9 @@ cdef class LaurentPolynomial_mpair(CommutativeAlgebraElement): var = ring.gens() for i, j in enumerate(self._mon): if j > 0: - poly *= var[i]**j + numer *= var[i] ** j else: - denom *= var[i]**(-j) + denom *= var[i] ** (-j) return (numer, denom) cpdef ModuleElement _add_(self, ModuleElement _right): From 9d9e0499f9075e78d87841c102718ec7ef609e9c Mon Sep 17 00:00:00 2001 From: Rudi Pendavingh Date: Tue, 11 Feb 2014 11:01:48 +0100 Subject: [PATCH 082/163] Updated the docstring of LinearMatroid.extensions() and .coextensions(). It is now explicitly stated that only (co)rank-preserving (co)extensions are generated, and not the extension by a coloop, nor the coextension by a loop. --- src/sage/matroids/linear_matroid.pyx | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/sage/matroids/linear_matroid.pyx b/src/sage/matroids/linear_matroid.pyx index a50ed41c70f..47f2aede816 100644 --- a/src/sage/matroids/linear_matroid.pyx +++ b/src/sage/matroids/linear_matroid.pyx @@ -2402,7 +2402,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): cpdef linear_extensions(self, element=None, F=None, simple=False, fundamentals=None): r""" - Create a list of linear matroids represented by single-element + Create a list of linear matroids represented by rank-preserving single-element extensions of this linear matroid representation. INPUT: @@ -2416,8 +2416,9 @@ cdef class LinearMatroid(BasisExchangeMatroid): OUTPUT: - A list of linear matroids represented by single-element extensions of - this linear matroid representation. + A list of linear matroids represented by rank-preserving single-element extensions of + this linear matroid representation. In particular, the extension by a coloop is not + generated. If one or more of the above inputs is given, the list is restricted to matroids @@ -2470,7 +2471,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): cpdef linear_coextensions(self, element=None, F=None, cosimple=False, fundamentals=None): r""" - Create a list of linear matroids represented by single-element + Create a list of linear matroids represented by corank-preserving single-element coextensions of this linear matroid representation. INPUT: @@ -2484,8 +2485,9 @@ cdef class LinearMatroid(BasisExchangeMatroid): OUTPUT: - A list of linear matroids represented by single-element coextensions - of this linear matroid representation. + A list of linear matroids represented by corank-preserving single-element + coextensions of this linear matroid representation. In particular, the coextension + by a loop is not generated. If one or more of the above inputs is given, the list is restricted to coextensions From 62bf2e942c670fae6cc705126cced936e8cd268e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 11 Feb 2014 14:01:51 +0100 Subject: [PATCH 083/163] trac #15345 better coercion --- .../rings/polynomial/laurent_polynomial_ring.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/sage/rings/polynomial/laurent_polynomial_ring.py b/src/sage/rings/polynomial/laurent_polynomial_ring.py index 395deb7e6d8..34ab45fa3ea 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ring.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ring.py @@ -562,17 +562,17 @@ def _coerce_map_from_(self, R): From: Multivariate Polynomial Ring in x, y over Rational Field To: Multivariate Laurent Polynomial Ring in x, y over Rational Field """ - - if R is self._R: + if R is self._R or (isinstance(R, LaurentPolynomialRing_generic) + and self._R.has_coerce_map_from(R._R)): from sage.structure.coerce_maps import CallableConvertMap return CallableConvertMap(R, self, self._element_constructor_, parent_as_first_arg=False) - else: - f = self._R.coerce_map_from(R) - if f is not None: - from sage.categories.homset import Hom - from sage.categories.morphism import CallMorphism - return CallMorphism(Hom(self._R, self)) * f + + f = self._R.coerce_map_from(R) + if f is not None: + from sage.categories.homset import Hom + from sage.categories.morphism import CallMorphism + return CallMorphism(Hom(self._R, self)) * f def __cmp__(left, right): """ From 6d4916c33c0dc3c96f34740ce511b750333fa781 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 11 Feb 2014 16:53:53 +0100 Subject: [PATCH 084/163] trac #15345 documentation added --- src/sage/rings/fraction_field.py | 9 ++++++++- src/sage/rings/polynomial/laurent_polynomial_ring.py | 8 ++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/sage/rings/fraction_field.py b/src/sage/rings/fraction_field.py index dbcd828f730..96912f3c630 100644 --- a/src/sage/rings/fraction_field.py +++ b/src/sage/rings/fraction_field.py @@ -265,11 +265,18 @@ def _coerce_map_from_(self, S): sage: F2(R22(F2('a'))) a + Coercion from Laurent polynomials now works (:trac:`15345`):: + + sage: R = LaurentPolynomialRing(ZZ, 'x') + sage: T = PolynomialRing(ZZ, 'x') + sage: R.gen() + FractionField(T).gen() + 2*x """ from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ from sage.rings.number_field.number_field_base import NumberField - from sage.rings.polynomial.laurent_polynomial_ring import LaurentPolynomialRing_generic + from sage.rings.polynomial.laurent_polynomial_ring import \ + LaurentPolynomialRing_generic # The case ``S`` being `\QQ` requires special handling since `\QQ` is # not implemented as a ``FractionField_generic``. diff --git a/src/sage/rings/polynomial/laurent_polynomial_ring.py b/src/sage/rings/polynomial/laurent_polynomial_ring.py index 34ab45fa3ea..f768d5551cc 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ring.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ring.py @@ -561,6 +561,14 @@ def _coerce_map_from_(self, R): Call morphism: From: Multivariate Polynomial Ring in x, y over Rational Field To: Multivariate Laurent Polynomial Ring in x, y over Rational Field + + Let us check that coercion between Laurent Polynomials over + different base rings works (:trac:`15345`):: + + sage: R = LaurentPolynomialRing(ZZ, 'x') + sage: T = LaurentPolynomialRing(QQ, 'x') + sage: R.gen() + 3*T.gen() + 4*x """ if R is self._R or (isinstance(R, LaurentPolynomialRing_generic) and self._R.has_coerce_map_from(R._R)): From 13cbb1c7e39941c24c7690fcdd73ef8ceb465d25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 13 Jan 2014 15:54:55 +0100 Subject: [PATCH 085/163] trac #15668 implement fixed simplicial complex --- src/sage/homology/simplicial_complex.py | 28 +++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/sage/homology/simplicial_complex.py b/src/sage/homology/simplicial_complex.py index dde9afa9407..a2879038a44 100644 --- a/src/sage/homology/simplicial_complex.py +++ b/src/sage/homology/simplicial_complex.py @@ -3237,6 +3237,34 @@ def automorphism_group(self): return permgroup + def fixed_complex(self, G): + r""" + Return the fixed simplicial complex `Fix(G)` for a subgroup `G` + + INPUT: + + - `G` -- a subgroup of the automorphism group of the simplicial complex + + OUTPUT: + + - a simplicial complex + + EXAMPLES:: + + sage: RP2 = simplicial_complexes.ProjectivePlane() + sage: CP2 = simplicial_complexes.ComplexProjectivePlane() + sage: G = CP2.automorphism_group() + sage: H = G.subgroup([G([(2,3),(5,6),(8,9)])]) + sage: CP2.fixed_complex(H).is_isomorphic(RP2) + True + """ + invariant_f = [u for u in self.face_iterator() + if all(sorted([sigma(j) for j in u]) == sorted(list(u)) + for sigma in G.gens())] + new_verts = [min(o) for o in G.orbits()] + return SimplicialComplex([[s for s in f if s in new_verts] + for f in invariant_f]) + def _Hom_(self, other, category=None): """ Return the set of simplicial maps between simplicial complexes From d8fe179634642a312afd3761459943bf02352dbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 13 Jan 2014 16:26:45 +0100 Subject: [PATCH 086/163] trac #15668 more general input is allowed --- src/sage/homology/simplicial_complex.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/sage/homology/simplicial_complex.py b/src/sage/homology/simplicial_complex.py index a2879038a44..d4685c90030 100644 --- a/src/sage/homology/simplicial_complex.py +++ b/src/sage/homology/simplicial_complex.py @@ -3244,6 +3244,7 @@ def fixed_complex(self, G): INPUT: - `G` -- a subgroup of the automorphism group of the simplicial complex + or a list of elements of the automorphism group OUTPUT: @@ -3257,7 +3258,19 @@ def fixed_complex(self, G): sage: H = G.subgroup([G([(2,3),(5,6),(8,9)])]) sage: CP2.fixed_complex(H).is_isomorphic(RP2) True + + One can also input a list of automorphisms:: + + sage: CP2.fixed_complex([G([(2,3),(5,6),(8,9)])]).is_isomorphic(RP2) + True """ + from sage.categories.groups import Groups + if G in Groups(): + gens = G.gens() + else: + gens = G + G = self.automorphism_group().subgroup(gens) + invariant_f = [u for u in self.face_iterator() if all(sorted([sigma(j) for j in u]) == sorted(list(u)) for sigma in G.gens())] From 1860ed38997cc3a7dc43cea05a9f9f0a4eabbf22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 15 Jan 2014 21:20:05 +0100 Subject: [PATCH 087/163] trac #15668 added a basic example + correct raise syntax for python3 --- src/sage/homology/simplicial_complex.py | 28 ++++++++++++++----------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/sage/homology/simplicial_complex.py b/src/sage/homology/simplicial_complex.py index d4685c90030..8ca5806fd67 100644 --- a/src/sage/homology/simplicial_complex.py +++ b/src/sage/homology/simplicial_complex.py @@ -486,7 +486,7 @@ def face(self, n): if n >= 0 and n <= self.dimension(): return Simplex(self.__tuple[:n] + self.__tuple[n+1:]) else: - raise IndexError, "%s does not have an nth face for n=%s." % (self, n) + raise IndexError("%s does not have an nth face for n=%s." % (self, n)) def faces(self): """ @@ -1587,7 +1587,7 @@ def suspension(self, n=1, is_mutable=True): (0, 1, 2, 3, 4, 5, 6, 7) """ if n<0: - raise ValueError, "n must be non-negative." + raise ValueError("n must be non-negative.") if n==0: return self if n==1: @@ -1941,7 +1941,6 @@ def _homology_(self, dim=None, **kwds): sage: T._homology_(subcomplex=U) {0: 0, 1: 0, 2: Z} """ - from sage.modules.all import VectorSpace from sage.homology.homology_group import HomologyGroup base_ring = kwds.get('base_ring', ZZ) @@ -2232,7 +2231,7 @@ def connected_sum(self, other, is_mutable=True): """ if not (self.is_pure() and other.is_pure() and self.dimension() == other.dimension()): - raise ValueError, "Complexes are not pure of the same dimension." + raise ValueError("Complexes are not pure of the same dimension.") # first find a top-dimensional simplex to remove from each surface keep_left = self._facets[0] keep_right = other._facets[0] @@ -2384,7 +2383,7 @@ def generated_subcomplex(self,sub_vertex_set, is_mutable=True): """ if not self.vertices().set().issuperset(sub_vertex_set): - raise ValueError, "input must be a subset of the vertex set." + raise ValueError("input must be a subset of the vertex set.") faces = [] for i in range(self.dimension()+1): for j in self.faces()[i]: @@ -3239,7 +3238,7 @@ def automorphism_group(self): def fixed_complex(self, G): r""" - Return the fixed simplicial complex `Fix(G)` for a subgroup `G` + Return the fixed simplicial complex `Fix(G)` for a subgroup `G`. INPUT: @@ -3250,7 +3249,15 @@ def fixed_complex(self, G): - a simplicial complex - EXAMPLES:: + A basic example:: + + sage: S4 = simplicial_complexes.Sphere(4) + sage: S3 = simplicial_complexes.Sphere(3) + sage: fix = S4.fixed_complex([S4.automorphism_group()([(0,1)])]) + sage: fix.is_isomorphic(S3) + True + + A more sophisticated example:: sage: RP2 = simplicial_complexes.ProjectivePlane() sage: CP2 = simplicial_complexes.ComplexProjectivePlane() @@ -3259,10 +3266,7 @@ def fixed_complex(self, G): sage: CP2.fixed_complex(H).is_isomorphic(RP2) True - One can also input a list of automorphisms:: - - sage: CP2.fixed_complex([G([(2,3),(5,6),(8,9)])]).is_isomorphic(RP2) - True + REFERENCES: """ from sage.categories.groups import Groups if G in Groups(): @@ -3273,7 +3277,7 @@ def fixed_complex(self, G): invariant_f = [u for u in self.face_iterator() if all(sorted([sigma(j) for j in u]) == sorted(list(u)) - for sigma in G.gens())] + for sigma in gens)] new_verts = [min(o) for o in G.orbits()] return SimplicialComplex([[s for s in f if s in new_verts] for f in invariant_f]) From 222dd04284ddc2a70a90a060c9d65b17d1bfa3d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 11 Feb 2014 19:08:05 +0100 Subject: [PATCH 088/163] trac #15668 correct algo ? --- src/sage/homology/simplicial_complex.py | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/sage/homology/simplicial_complex.py b/src/sage/homology/simplicial_complex.py index 8ca5806fd67..efd5d471f23 100644 --- a/src/sage/homology/simplicial_complex.py +++ b/src/sage/homology/simplicial_complex.py @@ -3242,12 +3242,18 @@ def fixed_complex(self, G): INPUT: - - `G` -- a subgroup of the automorphism group of the simplicial complex - or a list of elements of the automorphism group + - `G` -- a subgroup of the automorphism group of the + simplicial complex or a list of elements of the + automorphism group OUTPUT: - - a simplicial complex + - a simplicial complex `Fix(G)` + + Vertices in `Fix(G)` are the orbits of `G` (acting on vertices + of ``self``) that form a simplex in ``self``. More generally, + simplices in `Fix(G)` correspond to simplices in ``self`` that + are union of such orbits. A basic example:: @@ -3257,6 +3263,13 @@ def fixed_complex(self, G): sage: fix.is_isomorphic(S3) True + Another simple example:: + + sage: T = SimplicialComplex([[1,2,3],[2,3,4]]) + sage: G = CP2.automorphism_group() + sage: T.fixed_complex([G([(1,4)])]) + Simplicial complex with vertex set ? and facets ? + A more sophisticated example:: sage: RP2 = simplicial_complexes.ProjectivePlane() @@ -3265,8 +3278,6 @@ def fixed_complex(self, G): sage: H = G.subgroup([G([(2,3),(5,6),(8,9)])]) sage: CP2.fixed_complex(H).is_isomorphic(RP2) True - - REFERENCES: """ from sage.categories.groups import Groups if G in Groups(): @@ -3275,10 +3286,10 @@ def fixed_complex(self, G): gens = G G = self.automorphism_group().subgroup(gens) - invariant_f = [u for u in self.face_iterator() + invariant_f = [list(u) for u in self.face_iterator() if all(sorted([sigma(j) for j in u]) == sorted(list(u)) for sigma in gens)] - new_verts = [min(o) for o in G.orbits()] + new_verts = [min(o) for o in G.orbits() if o in invariant_f] return SimplicialComplex([[s for s in f if s in new_verts] for f in invariant_f]) From 4af4e2c15e023bf58aadf563d55f0ac39d48daea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 11 Feb 2014 19:23:55 +0100 Subject: [PATCH 089/163] trac #15668 more doc --- src/sage/homology/simplicial_complex.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/sage/homology/simplicial_complex.py b/src/sage/homology/simplicial_complex.py index efd5d471f23..61197a94c25 100644 --- a/src/sage/homology/simplicial_complex.py +++ b/src/sage/homology/simplicial_complex.py @@ -3260,15 +3260,17 @@ def fixed_complex(self, G): sage: S4 = simplicial_complexes.Sphere(4) sage: S3 = simplicial_complexes.Sphere(3) sage: fix = S4.fixed_complex([S4.automorphism_group()([(0,1)])]) + sage: fix + Simplicial complex with vertex set (0, 2, 3, 4, 5) and 5 facets sage: fix.is_isomorphic(S3) True Another simple example:: sage: T = SimplicialComplex([[1,2,3],[2,3,4]]) - sage: G = CP2.automorphism_group() + sage: G = T.automorphism_group() sage: T.fixed_complex([G([(1,4)])]) - Simplicial complex with vertex set ? and facets ? + Simplicial complex with vertex set (2, 3) and facets {(2, 3)} A more sophisticated example:: From 24b6fe94424561dce5e9f97e656c82c486aa6c78 Mon Sep 17 00:00:00 2001 From: Peter Bruin Date: Tue, 11 Feb 2014 18:58:48 +0000 Subject: [PATCH 090/163] Update Denis Simon's GP scripts to versions of 06/04/2011 (ell.gp) resp. 13/01/2014 (ellQ.gp, ellcommon.gp, qfsolve.gp, resultant3.gp) --- src/ext/pari/simon/ell.gp | 1809 ++++++------ src/ext/pari/simon/ellQ.gp | 2553 ++++++++++------- src/ext/pari/simon/ellcommon.gp | 126 + src/ext/pari/simon/qfsolve.gp | 1447 ++++++---- src/ext/pari/simon/resultant3.gp | 466 +-- src/sage/quadratic_forms/qfsolve.py | 31 +- .../elliptic_curves/ell_number_field.py | 61 +- .../elliptic_curves/ell_rational_field.py | 14 +- src/sage/schemes/elliptic_curves/gp_simon.py | 4 +- .../schemes/hyperelliptic_curves/mestre.py | 2 +- src/sage/schemes/plane_conics/con_field.py | 4 +- .../plane_conics/con_rational_field.py | 14 +- 12 files changed, 3737 insertions(+), 2794 deletions(-) create mode 100644 src/ext/pari/simon/ellcommon.gp diff --git a/src/ext/pari/simon/ell.gp b/src/ext/pari/simon/ell.gp index d121ae14279..503daf21636 100644 --- a/src/ext/pari/simon/ell.gp +++ b/src/ext/pari/simon/ell.gp @@ -1,5 +1,5 @@ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -\\ Copyright (C) 2007 Denis Simon +\\ Copyright (C) 2011 Denis Simon \\ \\ Distributed under the terms of the GNU General Public License (GPL) \\ @@ -13,173 +13,170 @@ \\ http://www.gnu.org/licenses/ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -\\ -\\ Auteur: -\\ Denis SIMON -> simon@math.unicaen.fr -\\ adresse du fichier: -\\ www.math.unicaen.fr/~simon/ell.gp -\\ -\\ ********************************************* -\\ * VERSION 25/03/2009 * -\\ ********************************************* -\\ -\\ Programme de calcul du rang des courbes elliptiques -\\ dans les corps de nombres. -\\ langage: GP -\\ pour l'utiliser, lancer gp, puis taper -\\ \r ell.gp -\\ -\\ -\\ Explications succintes : -\\ definition du corps : -\\ bnf=bnfinit(y^2+1); -\\ (il est indispensable que la variable soit y). -\\ on peut ensuite poser : -\\ X = Mod(y,bnf.pol); -\\ -\\ La fonction bnfellrank() accepte toutes les courbes sous la forme -\\ [a1,a2,a3,a4,a6] -\\ Les coefficients peuvent etre entiers ou non. -\\ L'algorithme utilise est celui de la 2-descente. -\\ La 2-torsion peut etre quelconque. -\\ Il suffit de taper : -\\ -\\ gp > ell = [a1,a2,a3,a4,a6]; -\\ gp > bnfellrank(bnf,ell) -\\ -\\ Retourne un vecteur [r,s,vec] -\\ ou r est le rang probable (c'est toujours une minoration du rang), -\\ s est le 2-rang du groupe de Selmer, -\\ vec est une liste de points dans E(K)/2E(K). -\\ -\\ Courbes avec #E[2](K) >= 2: -\\ ell doit etre sous la forme -\\ y^2 = x^3 + A*^2 + B*x -\\ avec A et B entiers algebriques -\\ gp > ell = [0,A,0,B,0] -\\ gp > bnfell2descent_viaisog(ell) -\\ = algorithme de la 2-descente par isogenies -\\ Attention A et B doivent etre entiers -\\ -\\ Courbes avec #E[2](K) = 4: y^2 = (x-e1)*(x-e2)*(x-e3) -\\ -> bnfell2descent_complete(bnf,e1,e2,e3); -\\ = algorithme de la 2-descente complete -\\ Attention: les ei doivent etre entiers algebriques. -\\ -\\ -\\ On peut avoir plus ou moins de details de calculs avec -\\ DEBUGLEVEL_ell = 0; -\\ DEBUGLEVEL_ell = 1; 2; 3;... -\\ +/* + Auteur : + Denis SIMON -> simon@math.unicaen.fr + adresse du fichier : + www.math.unicaen.fr/~simon/ell.gp + + ********************************************* + * VERSION 06/04/2011 * + ********************************************* + + \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + \\ Comment utiliser ce programme ? \\ + \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + + Programme de calcul du rang des courbes elliptiques + dans les corps de nombres. + langage: GP + pour l'utiliser, lancer gp, puis taper + \r ell.gp + + \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + \\ Description des principales fonctions \\ + \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + + Explications succintes : + definition du corps : + bnf=bnfinit(y^2+1); + (il est indispensable que la variable soit y). + on peut ensuite poser : + X = Mod(y,bnf.pol); + + La fonction bnfellrank() accepte toutes les courbes sous la forme + [a1,a2,a3,a4,a6] + Les coefficients peuvent etre entiers ou non. + L'algorithme utilise est celui de la 2-descente. + La 2-torsion peut etre quelconque. + Il suffit de taper : + + gp > ell = [a1,a2,a3,a4,a6]; + gp > bnfellrank(bnf,ell) + + Retourne un vecteur [r,s,vec] + ou r est le rang probable (c'est toujours une minoration du rang), + s est le 2-rang du groupe de Selmer, + vec est une liste de points dans E(K)/2E(K). + + Courbes avec #E[2](K) >= 2: + ell doit etre sous la forme + y^2 = x^3 + A*^2 + B*x + avec A et B entiers algebriques + gp > ell = [0,A,0,B,0] + gp > bnfell2descent_viaisog(ell) + = algorithme de la 2-descente par isogenies + Attention A et B doivent etre entiers + + Courbes avec #E[2](K) = 4: y^2 = (x-e1)*(x-e2)*(x-e3) + -> bnfell2descent_complete(bnf,e1,e2,e3); + = algorithme de la 2-descente complete + Attention: les ei doivent etre entiers algebriques. + + + \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + \\ Affichage des calculs \\ + \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + + On peut avoir plus ou moins de details de calculs avec + DEBUGLEVEL_ell = 0; + DEBUGLEVEL_ell = 1; 2; 3;... + +*/ { \\ -\\ Variables globales usuelles +\\ Usual global variables \\ - DEBUGLEVEL_ell = 1; \\ pour avoir plus ou moins de details - LIM1 = 2; \\ limite des points triviaux sur les quartiques - LIM3 = 4; \\ limite des points sur les quartiques ELS - LIMTRIV = 2; \\ limite des points triviaux sur la courbe elliptique +global(DEBUGLEVEL_ell, LIM1, LIM3, LIMTRIV):small; + + DEBUGLEVEL_ell = 0; \\ From 0 to 5 : choose a higher value to have + \\ more details printed. + LIM1 = 2; \\ Limit for the search of trivial points on quartics + LIM3 = 4; \\ Limit for the search of points on ELS quartics + LIMTRIV = 2; \\ Limit for the search of trivial points on the elliptic curve \\ -\\ Variables globales techniques +\\ Technical global variables \\ - BIGINT = 32000; \\ l'infini - MAXPROB = 20; - LIMBIGPRIME = 30; \\ pour distinguer un petit nombre premier d'un grand - \\ utilise un test probabiliste pour les grands - \\ si LIMBIGPRIME = 0, n'utilise aucun test probabiliste - NBIDEAUX = 10; +global(MAXPROB, LIMBIGPRIME):small; + MAXPROB = 20; + LIMBIGPRIME = 30; \\ for primes larger than this limit: use a probabilistic test + \\ LIMBIGPRIME = 0 means: only deterministic tests } -\\ -\\ Programmes -\\ +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +\\ SCRIPT \\ +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -\\ -\\ Fonctions communes ell.gp et ellQ.gp -\\ +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +\\ MANIPULATION OF GLOBAL VARIABLES \\ +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -{ -ellinverturst(urst) = -local(u = urst[1], r = urst[2], s = urst[3], t = urst[4]); - [1/u,-r/u^2,-s/u,(r*s-t)/u^3]; -} -{ -ellchangecurveinverse(ell,v) = ellchangecurve(ell,ellinverturst(v)); -} -{ -ellchangepointinverse(pt,v) = ellchangepoint(pt,ellinverturst(v)); -} -{ -ellcomposeurst(urst1,urst2) = -local(u1 = urst1[1], r1 = urst1[2], s1 = urst1[3], t1 = urst1[4], - u2 = urst2[1], r2 = urst2[2], s2 = urst2[3], t2 = urst2[4]); - [u1*u2,u1^2*r2+r1,u1*s2+s1,u1^3*t2+s1*u1^2*r2+t1]; -} -if( DEBUGLEVEL_ell >= 4, print("mysubst")); -{ -mysubst(polsu,subsx) = - if( type(lift(polsu)) == "t_POL", - return(simplify(subst(lift(polsu),variable(lift(polsu)),subsx)) ) - , return(simplify(lift(polsu)))); -} -if( DEBUGLEVEL_ell >= 4, print("nfsign")); -{ -nfsign(nf,a,i) = -\\ return the sign of the algebraic number a in the i-th real embedding. -local(nf_roots,ay,def); +{default_ell( + DEBUGLEVEL_ell_val:small = 0, + LIM1_val:small = 2, + LIM3_val:small = 4, + LIMTRIV_val:small = 2, + MAXPROB_val:small = 20, + LIMBIGPRIME_val:small = 30 + ) = - if( a == 0, return(0)); + DEBUGLEVEL_ell = DEBUGLEVEL_ell_val; + print(" DEBUGLEVEL_ell = ",DEBUGLEVEL_ell); - a = lift(a); - if( type(a) != "t_POL", - return(sign(a))); + LIM1 = LIM1_val; + print(" LIM1 = ",LIM1); - nf_roots = nf.roots; - def = default(realprecision); + LIM3 = LIM3_val; + print(" LIM3 = ",LIM3); - ay = 0; - while( ay == 0 || precision(ay) < 10, + LIMTRIV = LIMTRIV_val; + print(" LIMTRIV = ",LIMTRIV); - ay = subst(a,variable(a),nf_roots[i]); + MAXPROB = MAXPROB_val; + print(" MAXPROB = ",MAXPROB); - if( ay == 0 || precision(ay) < 10, -if( DEBUGLEVEL_ell >= 3, - print(" **** Warning: doubling the real precision in nfsign **** ", - 2*default(realprecision))); - default(realprecision,2*default(realprecision)); - nf_roots = real(polroots(nf.pol)) - ) - ); - default(realprecision,def); + LIMBIGPRIME = LIMBIGPRIME_val; + print(" LIMBIGPRIME = ",LIMBIGPRIME); +} - return(sign(ay)); +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +\\ COMMON FUNCTIONS TO ell.gp AND ellQ.gp \\ +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + +{ellcomposeurst(urst1,urst2) = +local(u1 = urst1[1], r1 = urst1[2], s1 = urst1[3], t1 = urst1[4], + u2 = urst2[1], r2 = urst2[2], s2 = urst2[3], t2 = urst2[4]); + [u1*u2,u1^2*r2+r1,u1*s2+s1,u1^3*t2+s1*u1^2*r2+t1]; } -if( DEBUGLEVEL_ell >= 4, print("degre")); -{ -degre(idegre) = +{ellinverturst(urst) = +local(u = urst[1], r = urst[2], s = urst[3], t = urst[4]); + [1/u,-r/u^2,-s/u,(r*s-t)/u^3]; +} +{mysubst(polsu,subsx) = + if( type(lift(polsu)) == "t_POL", + return(simplify(subst(lift(polsu),variable(lift(polsu)),subsx))) + , return(simplify(lift(polsu)))); +} +{degre(idegre) = local(ideg = idegre, jdeg = 0); while( ideg >>= 1, jdeg++); return(jdeg); } -if( DEBUGLEVEL_ell >= 4, print("nfissquare")); -{ -nfissquare(nf, a) = #nfsqrt(nf,a) > 0; +{nfissquare(nf, a) = #nfsqrt(nf,a) > 0; } -if( DEBUGLEVEL_ell >= 4, print("nfsqrt")); -{ -nfsqrt( nf, a) = -\\ si a est un carre, renvoie [sqrt(a)], sinon []. -local(alift,ta,res,pfact); +{nfsqrt( nf, a) = +\\ if a is a square in the number field nf returns [sqrt(a)], otherwise []. +local(alift,ta,py,pfact); -if( DEBUGLEVEL_ell >= 5, print("entree dans nfsqrt ",a)); - if( a==0 || a==1, -if( DEBUGLEVEL_ell >= 5, print("fin de nfsqrt")); +if( DEBUGLEVEL_ell >= 5, print(" starting nfsqrt ",a)); + if( a==0 || a==1, +if( DEBUGLEVEL_ell >= 5, print(" end of nfsqrt ",a)); return([a])); alift = lift(a); @@ -187,119 +184,122 @@ if( DEBUGLEVEL_ell >= 5, print("fin de nfsqrt")); if( !poldegree(alift), alift = polcoeff(alift,0)); if( type(alift) != "t_POL", - if( issquare(alift), -if( DEBUGLEVEL_ell >= 5, print("fin de nfsqrt")); + if( issquare(alift), +if( DEBUGLEVEL_ell >= 5, print(" end of nfsqrt ",sqrtrat(alift))); return([sqrtrat(alift)]))); if( poldegree(nf.pol) <= 1, -if( DEBUGLEVEL_ell >= 5, print("fin de nfsqrt")); +if( DEBUGLEVEL_ell >= 5, print(" end of nfsqrt ",[])); return([])); if( ta == "t_POL", a = Mod(a,nf.pol)); -\\ tous les plgements reels doivent etre >0 +\\ the norm should be a square + + if( !issquare(norm(a)), +if( DEBUGLEVEL_ell >= 5, print(" end of nfsqrt ",[])); + return([])); + +\\ the real embeddings must all be >0 for( i = 1, nf.r1, - if( nfsign(nf,a,i) < 0, -if( DEBUGLEVEL_ell >= 5, print("fin de nfsqrt")); + if( nfrealsign(nf,a,i) < 0, +if( DEBUGLEVEL_ell >= 5, print(" end of nfsqrt ",[])); return([]))); -\\ factorisation sur K du polynome X^2-a : +\\ factorization over nf of the polynomial X^2-a - if( variable(nf.pol) == x, - py = subst(nf.pol,x,y); - pfact = lift(factornf(x^2-mysubst(alift,Mod(y,py)),py)[1,1]) + if( variable(nf.pol) == 'x, + py = subst(nf.pol,'x,'y); + pfact = lift(factornf('x^2-mysubst(alift,Mod('y,py)),py)[1,1]) , - pfact = lift(factornf(x^2-a,nf.pol)[1,1])); + pfact = lift(factornf('x^2-a,nf.pol)[1,1])); if( poldegree(pfact) == 2, -if( DEBUGLEVEL_ell >= 5, print("fin de nfsqrt")); +if( DEBUGLEVEL_ell >= 5, print(" end of nfsqrt ",[])); return([])); -if( DEBUGLEVEL_ell >= 5, print("fin de nfsqrt")); - return([subst(polcoeff(pfact,0),y,Mod(variable(nf.pol),nf.pol))]); +if( DEBUGLEVEL_ell >= 5, print(" end of nfsqrt ",pfact)); + return([subst(polcoeff(pfact,0),'y,Mod(variable(nf.pol),nf.pol))]); } -if( DEBUGLEVEL_ell >= 4, print("sqrtrat")); -{ -sqrtrat(a) = +{nfrealsign(nf,a,i) = +\\ return the sign of the algebraic number a in the i-th real embedding. +local(nf_roots,ay,prec0); + + if( a == 0, return(0)); + + a = lift(a); + if( type(a) != "t_POL", + return(sign(a))); + + nf_roots = nf.roots; + prec0 = default(realprecision); + + ay = 0; + while( ay == 0 || precision(ay) < 10, + + ay = subst(a,variable(a),nf_roots[i]); + + if( ay == 0 || precision(ay) < 10, +if( DEBUGLEVEL_ell >= 3, + print(" **** Warning: doubling the real precision in nfrealsign **** ", + 2*default(realprecision))); + default(realprecision,2*default(realprecision)); + nf_roots = real(polroots(nf.pol)) + ) + ); + default(realprecision,prec0); + + return(sign(ay)); +} +{sqrtrat(a) = sqrtint(numerator(a))/sqrtint(denominator(a)); } +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +\\ FUNCTIONS SPECIFIC TO ell.gp \\ +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -\\ -\\ Fonctions propres a ell.gp -\\ - -if( DEBUGLEVEL_ell >= 4, print("nfpolratroots")); -{ -nfpolratroots(nf,pol) = +{nfpolratroots(nf,pol) = local(f,ans); f = nffactor(nf,lift(pol))[,1]; ans = []; - for( j = 1, #f, + for( j = 1, #f, if( poldegree(f[j]) == 1, ans = concat(ans,[-polcoeff(f[j],0)/polcoeff(f[j],1)]))); return(ans); } -if( DEBUGLEVEL_ell >= 4, print("nfmodid2")); -{ -nfmodid2(nf,a,ideal) = -if( DEBUGLEVEL_ell >= 5, print("entree dans nfmodid2")); -\\ ideal doit etre sous la forme primedec - if( #nf.zk == 1, -if( DEBUGLEVEL_ell >= 5, print("fin de nfmodid2")); - return(a*Mod(1,ideal.p))); - a = mynfeltmod(nf,a,nfbasistoalg(nf,ideal[2])); - if( gcd(denominator(content(lift(a))),ideal.p) == 1, -if( DEBUGLEVEL_ell >= 5, print("fin de nfmodid2")); - return(a*Mod(1,ideal.p))); -if( DEBUGLEVEL_ell >= 5, print("fin de nfmodid2")); - return(a); -} -if( DEBUGLEVEL_ell >= 4, print("nfhilb2")); -{ -nfhilb2(nf,a,b,p) = -local(res); +{mynfhilbert2(nf,a,b,p) = +\\ p is a prime output by idealprimedec() above 2 +local(v,res); + +if( DEBUGLEVEL_ell >= 5, print(" starting mynfhilbert2")); + v = idealval(nf,a,p)\2; + if( v, a *= nfbasistoalg(nf,p[2])^(-2*v)); -if( DEBUGLEVEL_ell >= 5, print("entree dans nfhilb2")); - if( nfqpsoluble(nf,a*x^2+b,initp(nf,p)), res = 1, res = -1); -if( DEBUGLEVEL_ell >= 5, print("fin de nfhilb2")); + v = idealval(nf,b,p)\2; + if( v, b *= nfbasistoalg(nf,p[2])^(-2*v)); + + if( nfqp_soluble(nf,a*'x^2+b,initp(nf,p)), res = 1, res = -1); +if( DEBUGLEVEL_ell >= 5, print(" end of mynfhilbert2",res)); return(res); } -if( DEBUGLEVEL_ell >= 4, print("mynfhilbertp")); -{ -mynfhilbertp(nf,a,b,p) = +{mynfhilbertp(nf,a,b,p) = \\ calcule le symbole de Hilbert quadratique local (a,b)_p \\ * en l'ideal premier p du corps nf, \\ * a et b sont des elements non nuls de nf, sous la forme -\\ * de polymods ou de polynomes, et p renvoye par primedec. -local(alpha,beta,sig,aux,aux2,rep); +\\ * de polmods ou de polynomes, et p renvoye par idealprimedec(). -if( DEBUGLEVEL_ell >= 5, print("entree dans mynfhilbertp ",p)); - if( a == 0 || b == 0, print("0 argument in mynfhilbertp")); +if( DEBUGLEVEL_ell >= 5, print(" starting mynfhilbertp at ",p)); + if( a == 0 || b == 0, error("mynfhilbertp: argument = 0")); if( p.p == 2, -if( DEBUGLEVEL_ell >= 5, print("fin de mynfhilbertp")); - return(nfhilb2(nf,a,b,p))); +if( DEBUGLEVEL_ell >= 5, print(" end of mynfhilbertp")); + return(mynfhilbert2(nf,a,b,p))); if( type(a) != "t_POLMOD", a = Mod(a,nf.pol)); if( type(b) != "t_POLMOD", b = Mod(b,nf.pol)); - - alpha = idealval(nf,a,p); beta = idealval(nf,b,p); -if( DEBUGLEVEL_ell >= 5, print("[alpha,beta] = ",[alpha,beta])); - if( (alpha%2 == 0) && (beta%2 == 0), -if( DEBUGLEVEL_ell >= 5, print("fin de mynfhilbertp")); - return(1)); - aux2 = idealnorm(nf,p)\2; - if( alpha%2 && beta%2 && aux2%2, sig = 1, sig = -1); - if( beta, aux = nfmodid2(nf,a^beta/b^alpha,p), aux = nfmodid2(nf,b^alpha,p)); - aux = aux^aux2 + sig; - aux = lift(lift(aux)); - if( aux == 0, rep = 1, rep = (idealval(nf,aux,p) >= 1) ); -if( DEBUGLEVEL_ell >= 5, print("fin de mynfhilbertp")); - if( rep, return(1), return(-1)); +return(nfhilbert(nf,a,b,p)); } -if( DEBUGLEVEL_ell >= 4, print("ideallistfactor")); -{ -ideallistfactor(nf,listfact) = -local(Slist,S1,test,i,j,k); +{ideallistfactor(nf,listfact) = +local(Slist,S1,test,k); -if( DEBUGLEVEL_ell >= 5, print("entree dans ideallistfactor")); +if( DEBUGLEVEL_ell >= 5, print(" starting ideallistfactor")); Slist = []; test = 1; for( i = 1, #listfact, if( listfact[i] == 0, next); @@ -309,28 +309,26 @@ if( DEBUGLEVEL_ell >= 5, print("entree dans ideallistfactor")); if( Slist[k] == S1[j], test = 0; break)); if( test, Slist = concat(Slist,[S1[j]]), test = 1); )); -if( DEBUGLEVEL_ell >= 5, print("fin de ideallistfactor")); +if( DEBUGLEVEL_ell >= 5, print(" end of ideallistfactor")); return(Slist); } -if( DEBUGLEVEL_ell >= 4, print("mynfhilbert")); -{ -mynfhilbert(nf,a,b) = +{mynfhilbert(nf,a,b) = \\ calcule le symbole de Hilbert quadratique global (a,b): \\ =1 si l'equation X^2-aY^2-bZ^2=0 a une solution non triviale, \\ =-1 sinon, \\ a et b doivent etre non nuls. local(al,bl,S); -if( DEBUGLEVEL_ell >= 4, print("entree dans mynfhilbert ",[a,b])); +if( DEBUGLEVEL_ell >= 4, print(" starting mynfhilbert ",[a,b])); if( a == 0 || b == 0, error("mynfhilbert : argument = 0")); al = lift(a); bl = lift(b); -\\ solutions locales aux places reelles +\\ solutions locales aux places reelles for( i = 1, nf.r1, - if( nfsign(nf,al,i) < 0 && nfsign(nf,bl,i) < 0, -if( DEBUGLEVEL_ell >= 3, print("mynfhilbert non soluble a l'infini")); -if( DEBUGLEVEL_ell >= 4, print("fin de mynfhilbert")); + if( nfrealsign(nf,al,i) < 0 && nfrealsign(nf,bl,i) < 0, +if( DEBUGLEVEL_ell >= 3, print(" mynfhilbert: no solution at infinity")); +if( DEBUGLEVEL_ell >= 4, print(" end of mynfhilbert")); return(-1)) ); @@ -341,39 +339,35 @@ if( DEBUGLEVEL_ell >= 4, print("fin de mynfhilbert")); S = ideallistfactor(nf,[2,a,b]); forstep ( i = #S, 2, -1, -\\ d'apres la formule du produit on peut eviter un premier +\\ d'apres la formule du produit on peut eviter un premier if( mynfhilbertp(nf,a,b, S[i]) == -1, -if( DEBUGLEVEL_ell >= 3, print("mynfhilbert non soluble en : ",S[i])); -if( DEBUGLEVEL_ell >= 4, print("fin de mynfhilbert")); +if( DEBUGLEVEL_ell >= 3, print(" mynfhilbert: no solution at: ",S[i])); +if( DEBUGLEVEL_ell >= 4, print(" end of mynfhilbert")); return(-1))); -if( DEBUGLEVEL_ell >= 4, print("fin de mynfhilbert")); +if( DEBUGLEVEL_ell >= 4, print(" end of mynfhilbert")); return(1); } -if( DEBUGLEVEL_ell >= 4, print("initp")); -{ -initp( nf, p) = -\\ pp[1] est l'ideal sous forme reduite +{initp( nf, p) = +\\ pp[1] est l'ideal sous forme reduite \\ pp[2] est un entier de Zk avec une valuation 1 en p \\ pp[3] est la valuation de 2 en p -\\ pp[4] sert a detecter les carres dans Qp +\\ pp[4] sert a detecter les carres dans Qp \\ si p|2 il faut la structure de Zk/p^(1+2v) d'apres Hensel -\\ sinon il suffit de calculer x^(N(p)-1)/2 -\\ pp[5] est un systeme de representants de Zk/p +\\ sinon il suffit de calculer x^(N(p)-1)/2 +\\ pp[5] est un systeme de representants de Zk/p \\ c'est donc un ensemble de cardinal p^f . local(idval,pp); -if( DEBUGLEVEL_ell >= 5, print("entree dans initp")); +if( DEBUGLEVEL_ell >= 5, print(" starting initp for p = ",p)); idval = idealval(nf,2,p); pp=[ p, nfbasistoalg(nf,p[2]), idval, 0, repres(nf,p) ]; if( idval, pp[4] = idealstar(nf,idealpow(nf,p,1+2*idval)), pp[4] = p.p^p.f\2 ); -if( DEBUGLEVEL_ell >= 5, print("fin de initp")); +if( DEBUGLEVEL_ell >= 5, print(" end of initp")); return(pp); } -if( DEBUGLEVEL_ell >= 4, print("deno")); -{ -deno(num) = +{deno(num) = \\ calcule un denominateur du polynome num if( num == 0, return(1)); @@ -381,24 +375,25 @@ deno(num) = return(denominator(content(num)))); return(denominator(num)); } -if( DEBUGLEVEL_ell >= 4, print("nfratpoint")); -{ -nfratpoint(nf,pol,lim,singlepoint=1) = +{nfratpoint(nf,pol,lim,singlepoint=1) = \\ Si singlepoint == 1, cherche un seul point, sinon plusieurs. -local(compt1,compt2,deg,n,AA,point,listpoints,denoz,vectx,xx,evpol,sq); +local(compt1,compt2,deg,n,AA,point,listpoints,vectx,evpol,sq,xpol); + +if( DEBUGLEVEL_ell >= 4, + print(" starting nfratpoint with pol = ",pol); + print(" lim = ",lim)); -if( DEBUGLEVEL_ell >= 4, print("entree dans nfratpoint avec pol = ",pol); print("lim = ",lim)); compt1 = 0; compt2 = 0; deg = poldegree(pol); n = poldegree(nf.pol); AA = lim<<1; if( !singlepoint, listpoints = []); -\\ cas triviaux +\\ cas triviaux sq = nfsqrt(nf,polcoeff(pol,0)); if( sq!= [], point = [ 0, sq[1], 1]; if( singlepoint, -if( DEBUGLEVEL_ell >= 4, print("fin de nfratpoint")); +if( DEBUGLEVEL_ell >= 4, print(" end of nfratpoint")); return(point)); listpoints = concat(listpoints,[point]) ); @@ -406,19 +401,21 @@ if( DEBUGLEVEL_ell >= 4, print("fin de nfratpoint")); if( sq != [], point = [ 1, sq[1], 0]; if( singlepoint, -if( DEBUGLEVEL_ell >= 4, print("fin de nfratpoint")); +if( DEBUGLEVEL_ell >= 4, print(" end of nfratpoint")); return(point)); listpoints = concat(listpoints,[point]) ); - + \\ boucle generale point = []; vectx = vector(n,i,[-lim,lim]); for( denoz = 1, lim, + if( poldegree(pol)%2 == 0 && + !issquare(Mod(norm(pollead(pol)),denoz)), next); forvec( xx = vectx, if( denoz == 1 || gcd(content(xx),denoz) == 1, xpol = nfbasistoalg(nf,xx~); - evpol = subst(pol,x,xpol/denoz); + evpol = subst(pol,'x,xpol/denoz); sq = nfsqrt(nf,evpol); if( sq != [], point = [xpol/denoz, sq[1], 1]; @@ -427,21 +424,19 @@ if( DEBUGLEVEL_ell >= 4, print("fin de nfratpoint")); )); if( singlepoint, listpoints = point); -if( DEBUGLEVEL_ell >= 4, print("sortie de nfratpoint")); -if( DEBUGLEVEL_ell >= 3, print("points trouves par nfratpoint = ",listpoints)); - return(listpoints); +if( DEBUGLEVEL_ell >= 3, print(" points found by nfratpoint = ",listpoints)); +if( DEBUGLEVEL_ell >= 4, print(" end of nfratpoint")); + return(Vec(listpoints)); } -if( DEBUGLEVEL_ell >= 4, print("repres")); -{ -repres(nf,p) = +{repres(nf,p) = \\ calcule un systeme de representants Zk/p -local(fond,mat,i,j,k,f,rep,pp,ppi,pp2,jppi,gjf); +local(fond,mat,f,rep,pp,ppi,pp2,jppi,gjf); -if( DEBUGLEVEL_ell >= 5, print("entree dans repres")); +if( DEBUGLEVEL_ell >= 5, print(" starting repres")); fond = []; mat = idealhnf(nf,p); for( i = 1, #mat, - if( mat[i,i] != 1, fond = concat(fond,nf.zk[i]))); + if( mat[i,i] != 1, fond = concat(fond,nf.nf[7][i]))); f = #fond; pp = p.p; rep = vector(pp^f,i,0); @@ -454,148 +449,60 @@ if( DEBUGLEVEL_ell >= 5, print("entree dans repres")); jppi = j*ppi; for( k = 0, ppi-1, rep[jppi+k+1] = rep[k+1]+gjf )); ppi *= pp); -if( DEBUGLEVEL_ell >= 5, print("fin de repres")); +if( DEBUGLEVEL_ell >= 5, print(" end of repres")); return(Mod(rep,nf.pol)); } -if( DEBUGLEVEL_ell >= 4, print("val")); -{ -val(nf,num,p) = - if( num == 0, BIGINT, idealval(nf,lift(num),p)); +{val(nf,num,p) = + if( num == 0, 32000, idealval(nf,lift(num),p)); } -if( DEBUGLEVEL_ell >= 4, print("nfissquarep")); -{ -nfissquarep(nf,a,p,q) = -\\ suppose que a est un carre modulo p^q -\\ et renvoie sqrt(a) mod p^q (ou plutot p^(q/2)) -local(pherm,f,aaa,n,pp,qq,e,z,xx,yy,r,aux,b,m,vp,inv2x,zinit,zlog,expo); - -if( DEBUGLEVEL_ell >= 5, print("entree dans nfissquarep ",a,p,q)); - if( a == 0 || a == 1, -if( DEBUGLEVEL_ell >= 4, print("fin de nfissquarep")); - return(a)); - pherm = idealhnf(nf,p); -if( DEBUGLEVEL_ell >= 5, print("pherm = ",pherm)); - f = idealval(nf,a,p); - if( f >= q, - if( f > q, aaa = nfbasistoalg(nf,p[2])^((q+1)>>1), aaa = 0); -if( DEBUGLEVEL_ell >= 4, print("fin de nfissquarep")); - return(aaa)); - if( f, aaa = a*nfbasistoalg(nf,p[5]/p.p)^f, aaa = a); - if( pherm[1,1] != 2, -\\ cas ou p ne divise pas 2 -\\ algorithme de Shanks - n = nfrandintmodid(nf,pherm); - while( nfpsquareodd(nf,n,p), n = nfrandintmodid(nf,pherm)); - pp = Mod(1,p.p); - n *= pp; - qq = idealnorm(nf,pherm)\2; - e = 1; while( !(qq%2), e++; qq \= 2); - z = mynfeltreduce(nf,lift(lift(n^qq)),pherm); - yy = z;r = e; - xx = mynfeltreduce(nf,lift(lift((aaa*pp)^(qq\2))),pherm); - aux = mynfeltreduce(nf,aaa*xx,pherm); - b = mynfeltreduce(nf,aux*xx,pherm); - xx = aux; - aux = b;m = 0; - while( !val(nf,aux-1,p), m++; aux = mynfeltreduce(nf,aux^2,pherm)); - while( m, - if( m == r, error("nfissquarep : m = r")); - yy *= pp; - aux = mynfeltreduce(nf,lift(lift(yy^(1<<(r-m-1)))),pherm); - yy = mynfeltreduce(nf,aux^2,pherm); - r = m; - xx = mynfeltreduce(nf,xx*aux,pherm); - b = mynfeltreduce(nf,b*yy,pherm); - aux = b;m = 0; - while( !val(nf,aux-1,p), m++; aux = mynfeltreduce(nf,aux^2,pherm)); - ); -\\ lift de Hensel -\\ - if( q > 1, - vp = idealval(nf,xx^2-aaa,p); - if( vp < q-f, - yy = 2*xx; - inv2x = nfbasistoalg(nf,idealaddtoone(nf,yy,p)[1])/yy; - while( vp < q, vp++; xx -= (xx^2-aaa)*inv2x); - ); - if( f, xx *= nfbasistoalg(nf,p[2])^(f>>1)); - ); - xx = mynfeltreduce(nf,xx,idealpow(nf,p,q)) - , -\\ cas ou p divise 2 */ - if( q-f > 1, id = idealpow(nf,p,q-f), id = pherm); - zinit = idealstar(nf,id,2); - zlog = ideallog(nf,aaa,zinit); - xx = 1; - for( i = 1, #zlog, - expo = zlog[i]; - if( expo, - if( !expo%2, - expo = expo>>1 - , aux = zinit[2][i]; - expo = expo*((aux+1)>>1)%aux - ); - xx *= nfbasistoalg(nf,zinit[2][3][i])^expo - ) - ); - if( f, - xx *= nfbasistoalg(nf,p[2])^(f>>1); - id = idealpow(nf,p,q)); - xx = mynfeltreduce(nf,xx,id); - ); -if( DEBUGLEVEL_ell >= 4, print("fin de nfissquarep ",xx)); - return(xx); -} -if( DEBUGLEVEL_ell >= 4, print("nfpsquareodd")); -{ -nfpsquareodd( nf, a, p) = -\\ renvoie 1 si a est un carre dans ZK_p 0 sinon -\\ seulement pour p premier avec 2 +{nfissquaremodpodd( nf, a, p) = +\\ Return 1 if a is a p-adic square, 0 otherwise. +\\ Only for a prime ideal p coprime to 2. +\\ a = t_POLMOD local(v,ap,norme,den); -if( DEBUGLEVEL_ell >= 5, print("entree dans nfpsquareodd")); +if( DEBUGLEVEL_ell >= 5, print(" starting nfissquaremodpodd")); if( a == 0, -if( DEBUGLEVEL_ell >= 5, print("fin de nfpsquareodd")); +if( DEBUGLEVEL_ell >= 5, print(" end of nfissquaremodpodd")); return(1)); v = idealval(nf,lift(a),p); if( v%2, -if( DEBUGLEVEL_ell >= 5, print("fin de nfpsquareodd")); +if( DEBUGLEVEL_ell >= 5, print(" end of nfissquaremodpodd")); return(0)); ap = a/nfbasistoalg(nf,p[2])^v; - norme = idealnorm(nf,p)\2; + norme = (p.p^p.f-1)/2; den = denominator(content(lift(ap)))%p.p; - if(sign(den), ap*=Mod(1,p.p)); + if( sign(den), ap *= Mod(1,p.p)); ap = ap^norme-1; if( ap == 0, -if( DEBUGLEVEL_ell >= 5, print("fin de nfpsquareodd")); +if( DEBUGLEVEL_ell >= 5, print(" end of nfissquaremodpodd")); return(1)); ap = lift(lift(ap)); if( idealval(nf,ap,p) > 0, -if( DEBUGLEVEL_ell >= 5, print("fin de nfpsquareodd")); +if( DEBUGLEVEL_ell >= 5, print(" end of nfissquaremodpodd")); return(1)); -if( DEBUGLEVEL_ell >= 5, print("fin de nfpsquareodd")); +if( DEBUGLEVEL_ell >= 5, print(" end of nfissquaremodpodd")); return(0); } -if( DEBUGLEVEL_ell >= 4, print("nfpsquare")); -{ -nfpsquare( nf, a, p, zinit) = -\\ a est un entier de K -\\ renvoie 1 si a est un carre dans ZKp 0 sinon -local(valap,zlog,i); +{nfissquaremodp( nf, a, p, zinit) = +\\ a is an algebraic integer of nf +\\ returns 1 if a is a square modulo the prime ideal p, 0 otherwise +\\ a = t_POLMOD +local(valap,zlog); -if( DEBUGLEVEL_ell >= 5, print("entree dans nfpsquare ",[a,p,zinit])); +if( DEBUGLEVEL_ell >= 5, print(" starting nfissquaremodp ",[a,p,zinit])); if( a == 0, -if( DEBUGLEVEL_ell >= 5, print("fin de nfpsquare")); +if( DEBUGLEVEL_ell >= 5, print(" end of nfissquaremodp")); return(1)); if( p.p != 2, -if( DEBUGLEVEL_ell >= 5, print("fin de nfpsquare")); - return(nfpsquareodd(nf,a,p))); +if( DEBUGLEVEL_ell >= 5, print(" end of nfissquaremodp")); + return(nfissquaremodpodd(nf,a,p))); valap = idealval(nf,a,p); if( valap%2, -if( DEBUGLEVEL_ell >= 5, print("fin de nfpsquare")); +if( DEBUGLEVEL_ell >= 5, print(" end of nfissquaremodp")); return(0)); if( valap, zlog = ideallog(nf,a*(nfbasistoalg(nf,p[5])/p.p)^valap,zinit) @@ -603,72 +510,163 @@ if( DEBUGLEVEL_ell >= 5, print("fin de nfpsquare")); zlog = ideallog(nf,a,zinit)); for( i = 1, #zinit[2][2], if( !(zinit[2][2][i]%2) && (zlog[i]%2), -if( DEBUGLEVEL_ell >= 5, print("fin de nfpsquare")); +if( DEBUGLEVEL_ell >= 5, print(" end of nfissquaremodp")); return(0))); -if( DEBUGLEVEL_ell >= 5, print("fin de nfpsquare")); +if( DEBUGLEVEL_ell >= 5, print(" end of nfissquaremodp")); return(1); } -if( DEBUGLEVEL_ell >= 4, print("nfpsquareq")); -{ -nfpsquareq( nf, a, p, q) = +{nfissquaremodpq( nf, a, p, q) = \\ cette fonction renvoie 1 si a est un carre \\ ?inversible? modulo P^q et 0 sinon. \\ P divise 2, et ?(a,p)=1?. -local(vala,zinit,zlog,i); +local(vala,zinit,zlog); -if( DEBUGLEVEL_ell >= 5, print("entree dans nfpsquareq ",[a,p,q])); +if( DEBUGLEVEL_ell >= 5, print(" starting nfissquaremodpq ",[a,p,q])); if( a == 0, -if( DEBUGLEVEL_ell >= 5, print("fin de nfpsquareq")); +if( DEBUGLEVEL_ell >= 5, print(" end of nfissquaremodpq")); return(1)); vala = idealval(nf,a,p); if( vala >= q, -if( DEBUGLEVEL_ell >= 5, print("fin de nfpsquareq")); +if( DEBUGLEVEL_ell >= 5, print(" end of nfissquaremodpq")); return(1)); if( vala%2, -if( DEBUGLEVEL_ell >= 5, print("fin de nfpsquareq")); +if( DEBUGLEVEL_ell >= 5, print(" end of nfissquaremodpq")); return(0)); zinit = idealstar(nf,idealpow(nf,p,q-vala),2); zlog = ideallog(nf,a*nfbasistoalg(nf,p[5]/2)^vala,zinit); for( i = 1, #zinit[2][2], if( !(zinit[2][2][i]%2) && (zlog[i]%2), -if( DEBUGLEVEL_ell >= 5, print("fin de nfpsquareq")); +if( DEBUGLEVEL_ell >= 5, print(" end of nfissquaremodpq")); return(0))); -if( DEBUGLEVEL_ell >= 5, print("fin de nfpsquareq")); +if( DEBUGLEVEL_ell >= 5, print(" end of nfissquaremodpq")); return(1); } -if( DEBUGLEVEL_ell >= 4, print("nflemma6")); -{ -nflemma6( nf, pol, p, nu, xx) = +{nfsqrtmodpq(nf,a,p,q) = +\\ suppose que a est un carre modulo p^q +\\ et renvoie x tel que x^2 = a mod p^q. +local(p_hnf,f,aaa,qq,e,xx,yy,r,aux,b,m,vp,inv2x,zinit,zlog,expo,p_ini,non_sq,id); + +if( DEBUGLEVEL_ell >= 5, print(" starting nfsqrtmodpq ",a,p,q)); + if( a == 0 || a == 1, +if( DEBUGLEVEL_ell >= 5, print(" end of nfsqrtmodpq")); + return(a)); + f = idealval(nf,a,p); + if( f >= q, +if( DEBUGLEVEL_ell >= 5, print(" end of nfsqrtmodpq")); + return(0)); +if( f%2, error("nfsqrtmodpq: a is not a square, odd valuation")); + a = nfalgtobasis(nf,a); + if( f, aaa = nfeltpow(nf,nfeltdiv(nf,a,p[5]/p.p),f), aaa = a); + p_hnf = idealhnf(nf,p); + p_ini = nfmodprinit(nf,p); +if( DEBUGLEVEL_ell >= 5, print(" p_hnf = ",p_hnf)); +if( DEBUGLEVEL_ell >= 5, print(" p_ini = ",p_ini)); + + if( p.p != 2, +\\ first case : p is odd + +\\ Shanks sqrt algorithm +if( DEBUGLEVEL_ell >= 5, print(" Shanks sqrt algorithm")); + non_sq = nfrandintmodid(nf,p_hnf); + while( nfissquaremodpodd(nf,non_sq,p), non_sq = nfrandintmodid(nf,p_hnf)); + non_sq = nfalgtobasis(nf,non_sq); + qq = ( p.p^p.f -1) \ 2; + e = 1; while( !(qq%2), e++; qq \= 2); + non_sq = nfeltpowmodpr(nf,non_sq,qq,p_ini); + yy = non_sq; r = e; + xx = nfeltpowmodpr(nf,aaa,qq\2,p_ini); + aux = nfeltmulmodpr(nf,aaa,xx,p_ini); + b = nfeltmulmodpr(nf,aux,xx,p_ini); + xx = aux; + aux = b; m = 0; + while( !val(nf,nfbasistoalg(nf,aux)-1,p), + m++; + aux = nfeltpowmodpr(nf,aux,2,p_ini) + ); + while( m, + if( m == r, error("nfsqrtmodpq: m = r")); + aux = nfeltpowmodpr(nf,yy,1<<(r-m-1),p_ini); + yy = nfeltpowmodpr(nf,aux,2,p_ini); + r = m; + xx = nfeltmulmodpr(nf,xx,aux,p_ini); + b = nfeltmulmodpr(nf,b,yy,p_ini); + aux = b;m = 0; + while( !val(nf,nfbasistoalg(nf,aux)-1,p), + m++; + aux = nfeltpowmodpr(nf,aux,2,p_ini) + ) + ); + +\\ lift de Hensel +\\ + + xx = nfbasistoalg(nf,xx); + aaa= nfbasistoalg(nf,aaa); + if( q > 1, +if( DEBUGLEVEL_ell >= 5, print(" Hensel lifting")); + vp = idealval(nf,xx^2-aaa,p); + if( vp < q-f, + yy = 2*xx; + inv2x = nfbasistoalg(nf,idealaddtoone(nf,yy,p)[1])/yy; + while( vp < q, vp++; xx -= (xx^2-aaa)*inv2x); + ); + if( f, xx *= nfbasistoalg(nf,p[2])^(f\2)); + ); + xx = mynfeltreduce(nf,xx,idealpow(nf,p,q)) + , +\\ cas ou p divise 2 */ + if( q-f > 1, id = idealpow(nf,p,q-f), id = p_hnf); + zinit = idealstar(nf,id,2); + zlog = ideallog(nf,aaa,zinit); + xx = 1; + for( i = 1, #zlog, + expo = zlog[i]; + if( expo, + if( !expo%2, + expo = expo>>1 + , aux = zinit[2][i]; + expo = expo*((aux+1)>>1)%aux + ); + xx *= nfbasistoalg(nf,zinit[2][3][i])^expo + ) + ); + if( f, + xx *= nfbasistoalg(nf,p[2])^(f>>1); + id = idealpow(nf,p,q)); + xx = mynfeltreduce(nf,xx,id); + ); +if( DEBUGLEVEL_ell >= 5, print(" end of nfsqrtmodpq ",xx)); + return(xx); +} +{nflemma6( nf, pol, p, nu, xx) = local(gx,gpx,lambda,mu); -if( DEBUGLEVEL_ell >= 5, print("entree dans nflemma6")); - gx = subst( pol, x, xx); - if( nfpsquareodd(nf,gx,p), -if( DEBUGLEVEL_ell >= 5, print("fin de nflemma6")); +if( DEBUGLEVEL_ell >= 5, print(" starting nflemma6")); + gx = subst( pol, 'x, xx); + if( nfissquaremodpodd(nf,gx,p), +if( DEBUGLEVEL_ell >= 5, print(" end of nflemma6")); return(1)); - gpx = subst( pol', x, xx); + gpx = subst( pol', 'x, xx); lambda = val(nf,gx,p);mu = val(nf,gpx,p); if( lambda>2*mu, -if( DEBUGLEVEL_ell >= 5, print("fin de nflemma6")); +if( DEBUGLEVEL_ell >= 5, print(" end of nflemma6")); return(1)); if( (lambda >= 2*nu) && (mu >= nu), -if( DEBUGLEVEL_ell >= 5, print("fin de nflemma6")); +if( DEBUGLEVEL_ell >= 5, print(" end of nflemma6")); return(0)); -if( DEBUGLEVEL_ell >= 5, print("fin de nflemma6")); +if( DEBUGLEVEL_ell >= 5, print(" end of nflemma6")); return(-1); } -if( DEBUGLEVEL_ell >= 4, print("nflemma7")); -{ -nflemma7( nf, pol, p, nu, xx, zinit) = +{nflemma7( nf, pol, p, nu, xx, zinit) = local(gx,gpx,v,lambda,mu,q); if( DEBUGLEVEL_ell >= 5, print("entree dans nflemma7 ",[xx,nu])); - gx = subst( pol, x, xx); - if( nfpsquare(nf,gx,p,zinit), + gx = subst( pol, 'x, xx); + if( nfissquaremodp(nf,gx,p,zinit), if( DEBUGLEVEL_ell >= 5, print("fin de nflemma7")); return(1)); - gpx = subst( pol', x, xx); + gpx = subst( pol', 'x, xx); v = p[3]; lambda = val(nf,gx,p);mu = val(nf,gpx,p); if( lambda>2*mu, @@ -682,7 +680,7 @@ if( DEBUGLEVEL_ell >= 5, print("fin de nflemma7")); if( q > 2*v, if( DEBUGLEVEL_ell >= 5, print("fin de nflemma7")); return(-1)); - if( nfpsquareq(nf,gx*nfbasistoalg(nf,p[5]/2)^lambda,p,q), + if( nfissquaremodpq(nf,gx*nfbasistoalg(nf,p[5]/2)^lambda,p,q), if( DEBUGLEVEL_ell >= 5, print("fin de nflemma7")); return(1)) , @@ -696,55 +694,47 @@ if( DEBUGLEVEL_ell >= 5, print("fin de nflemma7")); if( q > 2*v, if( DEBUGLEVEL_ell >= 5, print("fin de nflemma7")); return(-1)); - if( nfpsquareq(nf,gx*nfbasistoalg(nf,p[5]/2)^lambda,p,q), + if( nfissquaremodpq(nf,gx*nfbasistoalg(nf,p[5]/2)^lambda,p,q), if( DEBUGLEVEL_ell >= 5, print("fin de nflemma7")); return(0)) ); if( DEBUGLEVEL_ell >= 5, print("fin de nflemma7")); return(-1); } -if( DEBUGLEVEL_ell >= 4, print("nfzpsoluble")); -{ -nfzpsoluble( nf, pol, p, nu, pnu, x0) = +{nfzp_soluble( nf, pol, p, nu, pnu, x0) = local(result,pnup,lrep); -if( DEBUGLEVEL_ell >= 5, print("entree dans nfzpsoluble ",[lift(x0),nu])); +if( DEBUGLEVEL_ell >= 5, print("entree dans nfzp_soluble ",[lift(x0),nu])); if( p[3] == 0, result = nflemma6(nf,pol,p[1],nu,x0), result = nflemma7(nf,pol,p[1],nu,x0,p[4])); if( result == +1, -if( DEBUGLEVEL_ell >= 5, print("fin de nfzpsoluble")); +if( DEBUGLEVEL_ell >= 5, print("fin de nfzp_soluble")); return(1)); if( result == -1, -if( DEBUGLEVEL_ell >= 5, print("fin de nfzpsoluble")); +if( DEBUGLEVEL_ell >= 5, print("fin de nfzp_soluble")); return(0)); pnup = pnu*p[2]; lrep = #p[5]; nu++; for( i = 1, lrep, - if( nfzpsoluble(nf,pol,p,nu,pnup,x0+pnu*p[5][i]), -if( DEBUGLEVEL_ell >= 5, print("fin de nfzpsoluble")); + if( nfzp_soluble(nf,pol,p,nu,pnup,x0+pnu*p[5][i]), +if( DEBUGLEVEL_ell >= 5, print("fin de nfzp_soluble")); return(1))); -if( DEBUGLEVEL_ell >= 5, print("fin de nfzpsoluble")); +if( DEBUGLEVEL_ell >= 5, print("fin de nfzp_soluble")); return(0); } -if( DEBUGLEVEL_ell >= 4, print("mynfeltmod")); -{ -mynfeltmod(nf,a,b) = +{mynfeltmod(nf,a,b) = local(qred); qred = round(nfalgtobasis(nf,a/b)); qred = a-b*nfbasistoalg(nf,qred); return(qred); } -if( DEBUGLEVEL_ell >= 4, print("mynfeltreduce")); -{ -mynfeltreduce(nf,a,id) = +{mynfeltreduce(nf,a,id) = nfbasistoalg(nf,nfeltreduce(nf,nfalgtobasis(nf,a),id)); } -if( DEBUGLEVEL_ell >= 4, print("nfrandintmodid")); -{ -nfrandintmodid( nf, id) = +{nfrandintmodid( nf, id) = local(res); if( DEBUGLEVEL_ell >= 5, print("entree dans nfrandintmodid")); @@ -755,33 +745,27 @@ if( DEBUGLEVEL_ell >= 5, print("entree dans nfrandintmodid")); if( DEBUGLEVEL_ell >= 5, print("fin de nfrandintmodid")); return(res); } -if( DEBUGLEVEL_ell >= 4, print("nfrandint")); -{ -nfrandint( nf, borne) = -local(l,res,i); +{nfrandint( nf, borne) = +local(d,res); -if( DEBUGLEVEL_ell >= 5, print("entree dans nfrandint")); - l = #nf.zk; - res = vectorv(l,i,0); - for( i = 1, l, - if( borne, res[i] = random(borne<<1)-borne, res[i] = random() )); +if( DEBUGLEVEL_ell >= 5, print(" starting nfrandint")); + d = poldegree(nf.pol); + res = vectorv(d,i,if( borne, random(borne<<1)-borne, random())); res = nfbasistoalg(nf,res); -if( DEBUGLEVEL_ell >= 5, print("fin de nfrandint")); +if( DEBUGLEVEL_ell >= 5, print(" end of nfrandint")); return(res); } -if( DEBUGLEVEL_ell >= 4, print("nfqpsolublebig")); -{ -nfqpsolublebig( nf, pol, p,ap=0,b=1) = -local(deg,i,xx,z,Px,j,cont,pi,pol2,Roots); +{nfqp_solublebig( nf, pol, p,ap=0,b=1) = +local(deg,xx,z,Px,cont,pi,pol2,Roots); -if( DEBUGLEVEL_ell >= 4, print("entree dans nfqpsolublebig avec ",p.p)); +if( DEBUGLEVEL_ell >= 4, print(" starting nfqp_solublebig avec ",p.p)); deg = poldegree(pol); - if( nfpsquareodd(nf,polcoeff(pol,0),p), -if( DEBUGLEVEL_ell >= 4, print("fin de nfqpsolublebig")); + if( nfissquaremodpodd(nf,polcoeff(pol,0),p), +if( DEBUGLEVEL_ell >= 4, print(" end of nfqp_solublebig")); return(1)); - if( nfpsquareodd(nf,pollead(pol),p), -if( DEBUGLEVEL_ell >= 4, print("fin de nfqpsolublebig")); + if( nfissquaremodpodd(nf,pollead(pol),p), +if( DEBUGLEVEL_ell >= 4, print(" end of nfqp_solublebig")); return(1)); \\ on tient compte du contenu de pol @@ -801,9 +785,9 @@ if( DEBUGLEVEL_ell >= 4, print("fin de nfqpsolublebig")); xx = -ap*z+b*xx; Px=polcoeff(pol,deg); forstep (j=deg-1,0,-1,Px=Px*xx+polcoeff(pol,j)); - Px *= z^(deg); - if( nfpsquareodd(nf,Px,p), -if( DEBUGLEVEL_ell >= 4, print("fin de nfqpsolublebig")); + Px *= z^deg; + if( nfissquaremodpodd(nf,Px,p), +if( DEBUGLEVEL_ell >= 4, print(" end of nfqp_solublebig")); return(1)); ) ); @@ -812,15 +796,14 @@ if( DEBUGLEVEL_ell >= 4, print("fin de nfqpsolublebig")); Roots = nfpolrootsmod(nf,pol2,p); pi = nfbasistoalg(nf,p[2]); for( i = 1, #Roots, - if( nfqpsolublebig(nf,subst(pol,x,pi*x+Roots[i]),p), + if( nfqp_solublebig(nf,subst(pol,'x,pi*'x+Roots[i]),p), +if( DEBUGLEVEL_ell >= 4, print("fin de nfqp_solublebig")); return(1))); -if( DEBUGLEVEL_ell >= 4, print("fin de nfqpsolublebig")); +if( DEBUGLEVEL_ell >= 4, print(" end of nfqp_solublebig")); return(0); } -if( DEBUGLEVEL_ell >= 4, print("nfpolrootsmod")); -{ -nfpolrootsmod(nf,pol,p) = +{nfpolrootsmod(nf,pol,p) = \\ calcule les racines modulo l'ideal p du polynome pol. \\ p est un ideal premier de nf, sous la forme idealprimedec local(factlist,sol); @@ -832,37 +815,38 @@ local(factlist,sol); sol = concat(sol, [-polcoeff(factlist[i],0)/polcoeff(factlist[i],1)]))); return(sol); } -if( DEBUGLEVEL_ell >= 4, print("nfqpsoluble")); -{ -nfqpsoluble( nf, pol, p) = - -if( DEBUGLEVEL_ell >= 4, print("entree dans nfqpsoluble ",p)); -if( DEBUGLEVEL_ell >= 5, print("pol = ",pol)); - if( nfpsquare(nf,pollead(pol),p[1],p[4]), -if( DEBUGLEVEL_ell >= 5, print("fin de nfqpsoluble")); +{nfqp_soluble( nf, pol, p) = +\\ p is a prime output by initp() +\\ return 1 if pol(x) = y^2 has a p-adic rational solution +\\ (possibly oo) +\\ coeff of nfqfsoluble must be integers. + +if( DEBUGLEVEL_ell >= 5, print(" starting nfqp_soluble ",p)); +if( DEBUGLEVEL_ell >= 5, print(" pol = ",pol)); + if( nfissquaremodp(nf,pollead(pol),p[1],p[4]), +if( DEBUGLEVEL_ell >= 5, print(" end of nfqp_soluble")); return(1)); - if( nfpsquare(nf,polcoeff(pol,0),p[1],p[4]), -if( DEBUGLEVEL_ell >= 5, print("fin de nfqpsoluble")); + if( nfissquaremodp(nf,polcoeff(pol,0),p[1],p[4]), +if( DEBUGLEVEL_ell >= 5, print(" end of nfqp_soluble")); return(1)); - if( nfzpsoluble(nf,pol,p,0,1,0), -if( DEBUGLEVEL_ell >= 5, print("fin de nfqpsoluble")); + if( nfzp_soluble(nf,pol,p,0,1,0), +if( DEBUGLEVEL_ell >= 5, print(" end of nfqp_soluble")); return(1)); - if( nfzpsoluble(nf,polrecip(pol),p,1, p[2],0), -if( DEBUGLEVEL_ell >= 5, print("fin de nfqpsoluble")); + if( nfzp_soluble(nf,polrecip(pol),p,1, p[2],0), +if( DEBUGLEVEL_ell >= 5, print(" end of nfqp_soluble")); return(1)); -if( DEBUGLEVEL_ell >= 5, print("fin de nfqpsoluble")); +if( DEBUGLEVEL_ell >= 5, print(" end of nfqp_soluble")); return(0); } -if( DEBUGLEVEL_ell >= 4, print("nflocallysoluble")); -{ -nflocallysoluble( nf, pol, r=0,a=1,b=1) = +{nflocallysoluble( nf, pol, r=0,a=1,b=1) = +\\ Test whether Y^2 = pol is Everywhere Locally Soluble local(pol0,plist,add,ff,p,Delta,vecpol,vecpolr,Sturmr); -if( DEBUGLEVEL_ell >= 4, print("entree dans nflocallysoluble ",[pol,r,a,b])); +if( DEBUGLEVEL_ell >= 4, print(" starting nflocallysoluble ",[pol,r,a,b])); pol0 = pol; -\\ -\\ places finies de plist */ -\\ + +\\ places finies + pol *= deno(content(lift(pol)))^2; for( ii = 1, 3, if( ii == 1, plist = idealprimedec(nf,2)); @@ -872,45 +856,45 @@ if( DEBUGLEVEL_ell >= 4, print("entree dans nflocallysoluble ",[pol,r,a,b])); add = idealadd(nf,a,b); ff = factor(idealnorm(nf,add))[,1]; addprimes(ff); -if( DEBUGLEVEL_ell >= 4, print("liste de premiers = ",ff)); +if( DEBUGLEVEL_ell >= 4, print(" list of primes = ",ff)); plist = idealfactor(nf,add)[,1]); for( i = 1, #plist, - p = plist[i]; -if( DEBUGLEVEL_ell >= 3, print("p = ",p)); - if( p.p < LIMBIGPRIME, - if( !nfqpsoluble(nf,pol,initp(nf,p)), -if( DEBUGLEVEL_ell >= 2, print(" non ELS en ",p)); -if( DEBUGLEVEL_ell >= 4, print("fin de nflocallysoluble")); + p = plist[i]; +if( DEBUGLEVEL_ell >= 3, print(" p = ",p)); + if( p.p < LIMBIGPRIME || !LIMBIGPRIME, + if( !nfqp_soluble(nf,pol,initp(nf,p)), +if( DEBUGLEVEL_ell >= 2, print(" not ELS at ",p)); +if( DEBUGLEVEL_ell >= 4, print(" end of nflocallysoluble")); return(0)), - if( !nfqpsolublebig(nf,pol,p,r/a,b), -if( DEBUGLEVEL_ell >= 2, print(" non ELS en ",p.p," ( = grand premier )")); -if( DEBUGLEVEL_ell >= 4, print("fin de nflocallysoluble")); + if( !nfqp_solublebig(nf,pol,p,r/a,b), +if( DEBUGLEVEL_ell >= 2, print(" not ELS at ",p.p," ( = big prime )")); +if( DEBUGLEVEL_ell >= 4, print(" end of nflocallysoluble")); return(0)))); -); -\\ places reelles + ); + +\\ places reelles + if( nf.r1, Delta = poldisc(pol); vecpol = Vec(pol); for( i = 1, nf.r1, - if( nfsign(nf,pollead(pol),i) > 0, next); - if( nfsign(nf,polcoeff(pol,0),i) > 0, next); - if( nfsign(nf,Delta,i) < 0, next); + if( nfrealsign(nf,pollead(pol),i) > 0, next); + if( nfrealsign(nf,polcoeff(pol,0),i) > 0, next); + if( nfrealsign(nf,Delta,i) < 0, next); vecpolr = vector(#vecpol,j,mysubst(vecpol[j],nf.roots[i])); Sturmr = polsturm(Pol(vecpolr)); - if( Sturmr == 0, -if( DEBUGLEVEL_ell >= 2, print(" non ELS a l'infini")); -if( DEBUGLEVEL_ell >= 4, print("fin de nflocallysoluble")); + if( Sturmr == 0, +if( DEBUGLEVEL_ell >= 2, print(" not ELS at infinity")); +if( DEBUGLEVEL_ell >= 4, print(" end of nflocallysoluble")); return(0)); )); -if( DEBUGLEVEL_ell >= 2, print(" quartique ELS ")); -if( DEBUGLEVEL_ell >= 4, print("fin de nflocallysoluble")); +if( DEBUGLEVEL_ell >= 2, print(" quartic ELS ")); +if( DEBUGLEVEL_ell >= 4, print(" end of nflocallysoluble")); return(1); } -if( DEBUGLEVEL_ell >= 4, print("nfellcount")); -{ -nfellcount( nf, c, d, KS2gen, pointstriv) = -local(found,listgen,listpointscount,m1,m2,lastloc,mask,i,d1,iaux,j,triv,pol,point,deuxpoints); +{nfellcount( nf, c, d, KS2gen, pointstriv) = +local(found,listgen,listpointscount,m1,m2,lastloc,mask,i,d1,iaux,j,triv,pol,point,deuxpoints,aux,v); -if( DEBUGLEVEL_ell >= 4, print("entree dans nfellcount ",[c,d])); +if( DEBUGLEVEL_ell >= 4, print(" starting nfellcount ",[c,d])); found = 0; listgen = KS2gen; listpointscount = []; @@ -921,26 +905,27 @@ if( DEBUGLEVEL_ell >= 4, print("entree dans nfellcount ",[c,d])); i = 1; while( i < mask, d1 = 1; iaux = i; j = 1; - while( iaux, + while( iaux, if( iaux%2, d1 *= listgen[j]); iaux >>= 1; j++); -if( DEBUGLEVEL_ell >= 2, print("d1 = ",d1)); +if( DEBUGLEVEL_ell >= 2, print(" d1 = ",d1)); triv = 0; for( j = 1, #pointstriv, if( pointstriv[j][3]*pointstriv[j][1] && nfissquare(nf,d1*pointstriv[j][1]*pointstriv[j][3]), listpointscount = concat(listpointscount,[pointstriv[j]]); -if( DEBUGLEVEL_ell >= 2, print("point trivial")); +if( DEBUGLEVEL_ell >= 2, print(" comes from a trivial point")); triv = 1; m1++; if( degre(i) > lastloc, m2++); - found = 1; lastloc = -1; break)); + found = 1; lastloc = -1; break + )); if( !triv, pol = Pol([d1,0,c,0,d/d1]); -if( DEBUGLEVEL_ell >= 3, print("quartique = y^2 = ",pol)); +if( DEBUGLEVEL_ell >= 3, print(" quartic: y^2 = ",pol)); point = nfratpoint(nf,pol,LIM1,1); if( point != [], -if( DEBUGLEVEL_ell >= 2, print("point sur la quartique")); -if( DEBUGLEVEL_ell >= 3, print(point)); +if( DEBUGLEVEL_ell >= 2, print(" point on the quartic")); +if( DEBUGLEVEL_ell >= 3, print(" ",point)); m1++; if( point[3] != 0, aux = d1*point[1]/point[3]^2; @@ -955,8 +940,8 @@ if( DEBUGLEVEL_ell >= 3, print(point)); if( degre(i) > lastloc, m2++; lastloc = degre(i)); point = nfratpoint(nf,pol,LIM3,1); if( point != [], -if( DEBUGLEVEL_ell >= 2, print("point sur la quartique")); -if( DEBUGLEVEL_ell >= 3, print(point)); +if( DEBUGLEVEL_ell >= 2, print(" point on the quartic")); +if( DEBUGLEVEL_ell >= 3, print(" ",point)); m1++; aux = d1*point[1]/point[3]^2; deuxpoints = [ aux*point[1], aux*point[2]/point[3] ]; @@ -964,7 +949,7 @@ if( DEBUGLEVEL_ell >= 3, print(point)); if( degre(i) > lastloc, m2++); found = 1; lastloc = -1 , -if( DEBUGLEVEL_ell >= 2, print("pas de point trouve sur la quartique")); +if( DEBUGLEVEL_ell >= 2, print(" no point found on the quartic")); )))); if( found, found = 0; @@ -977,14 +962,12 @@ if( DEBUGLEVEL_ell >= 2, print("pas de point trouve sur la quartique")); ); for( i = 1, #listpointscount, if( #listpointscount[i] > 1, - if( subst(x^3+c*x^2+d*x,x,listpointscount[i][1])-listpointscount[i][2]^2 != 0, - error("nfellcount : MAUVAIS POINT = ",listpointscount[i])))); -if( DEBUGLEVEL_ell >= 4, print("fin de nfellcount")); + if( subst('x^3+c*'x^2+d*'x,'x,listpointscount[i][1])-listpointscount[i][2]^2 != 0, + error("nfellcount: WRONG POINT = ",listpointscount[i])))); +if( DEBUGLEVEL_ell >= 4, print(" end of nfellcount")); return([listpointscount,[m1,m2]]); } -if( DEBUGLEVEL_ell >= 4, print("bnfell2descent_viaisog")); -{ -bnfell2descent_viaisog( bnf, ell) = +{bnfell2descent_viaisog( bnf, ell) = \\ Calcul du rang des courbes elliptiques avec 2-torsion \\ dans le corps de nombres bnf \\ par la methode des 2-isogenies. @@ -995,20 +978,20 @@ bnfell2descent_viaisog( bnf, ell) = \\ ell doit etre sous la forme \\ y^2=x^3+ax^2+bx -> ell = [0,a,0,b,0] \\ avec a et b entiers. -local(i,P,Pfact,tors,pointstriv,apinit,bpinit,plist,KS2prod,oddclass,KS2gen,listpoints,pointgen,n1,n2,certain,np1,np2,listpoints2,aux1,aux2,certainp,rang,strange); +local(P,Pfact,tors,pointstriv,apinit,bpinit,plist,KS2prod,oddclass,KS2gen,listpoints,pointgen,n1,n2,certain,np1,np2,listpoints2,aux1,aux2,certainp,rang,strange); -if( DEBUGLEVEL_ell >= 2, print("Algorithme de la 2-descente par isogenies")); -if( DEBUGLEVEL_ell >= 3, print("entree dans bnfell2descent_viaisog")); - if( variable(bnf.pol) != y, - error(" bnfell2descent_viaisog : la variable du corps de nombres doit etre y ")); +if( DEBUGLEVEL_ell >= 2, print(" Algorithm of 2-descent via isogenies")); +if( DEBUGLEVEL_ell >= 3, print(" starting bnfell2descent_viaisog")); + if( variable(bnf.pol) != 'y, + error("bnfell2descent_viaisog: the variable of the number field must be y")); ell = ellinit(Mod(lift(ell),bnf.pol),1); if( ell.disc == 0, - error(" bnfell2descent_viaisog : courbe singuliere !!")); + error("bnfell2descent_viaisog: singular curve !!")); if( ell.a1 != 0 || ell.a3 != 0 || ell.a6 != 0, - error(" bnfell2descent_viaisog : la courbe n'est pas sous la forme [0,a,0,b,0]")); + error("bnfell2descent_viaisog: curve not of the form [0,a,0,b,0]")); if( denominator(nfalgtobasis(bnf,ell.a2)) > 1 || denominator(nfalgtobasis(bnf,ell.a4)) > 1, - error(" bnfell2descent_viaisog : coefficients non entiers")); + error("bnfell2descent_viaisog: non integral coefficients")); P = Pol([1,ell.a2,ell.a4])*Mod(1,bnf.pol); Pfact = factornf(P,bnf.pol)[,1]; @@ -1023,11 +1006,11 @@ if( DEBUGLEVEL_ell >= 3, print("entree dans bnfell2descent_viaisog")); \\ et de quelques renseignements associes plist = idealfactor(bnf,6*ell.disc)[,1]; -if( DEBUGLEVEL_ell >= 3, print(" Recherche de points triviaux sur la courbe")); - P *= x; -if( DEBUGLEVEL_ell >= 3, print("Y^2 = ",P)); +if( DEBUGLEVEL_ell >= 3, print(" Search for trivial points on the curve")); + P *= 'x; +if( DEBUGLEVEL_ell >= 3, print(" Y^2 = ",P)); pointstriv = concat( pointstriv, nfratpoint(bnf.nf,P,LIMTRIV,0)); -if( DEBUGLEVEL_ell >= 1, print("points triviaux sur E(K) = "); +if( DEBUGLEVEL_ell >= 1, print(" trivial points on E(K) = "); print(lift(pointstriv)); print()); KS2prod = ell.a4; @@ -1039,17 +1022,18 @@ if( DEBUGLEVEL_ell >= 1, print("points triviaux sur E(K) = "); KS2prod = idealmul(bnf,KS2prod,(KS2gen[5][3][1]))); ); KS2gen = KS2gen[1]; -\\ A CHANGER : KS2gen = matbasistoalg(bnf,KS2gen); for( i = 1, #KS2gen, KS2gen[i] = nfbasistoalg(bnf, KS2gen[i])); KS2gen = concat(Mod(lift(bnf.tufu),bnf.pol),KS2gen); if( DEBUGLEVEL_ell >= 2, - print("#K(b,2)gen = ",#KS2gen); - print("K(b,2)gen = ",KS2gen)); + print(" #K(b,2)gen = ",#KS2gen); + print(" K(b,2)gen = ",KS2gen)); listpoints = nfellcount(bnf.nf,ell.a2,ell.a4,KS2gen,pointstriv); pointgen = listpoints[1]; -if( DEBUGLEVEL_ell >= 1, print("points sur E(K) = ",lift(pointgen)); print()); +if( DEBUGLEVEL_ell >= 1, + print(" points on E(K) = ",lift(pointgen)); + print()); n1 = listpoints[2][1]; n2 = listpoints[2][2]; certain = (n1 == n2); @@ -1072,13 +1056,12 @@ if( DEBUGLEVEL_ell >= 1, if( !oddclass, KS2prod = idealmul(bnf,KS2prod,(KS2gen[5][3][1])))); KS2gen = KS2gen[1]; -\\ A CHANGER KS2gen = matbasistoalg(bnf,KS2gen); for( i = 1, #KS2gen, KS2gen[i] = nfbasistoalg(bnf, KS2gen[i])); KS2gen = concat(Mod(lift(bnf.tufu),bnf.pol),KS2gen); if( DEBUGLEVEL_ell >= 2, - print("#K(a^2-4b,2)gen = ",#KS2gen); - print("K(a^2-4b,2)gen = ",KS2gen)); + print(" #K(a^2-4b,2)gen = ",#KS2gen); + print(" K(a^2-4b,2)gen = ",KS2gen)); P = Pol([1,apinit,bpinit])*Mod(1,bnf.pol); Pfact= factornf(P,bnf.pol)[,1]; @@ -1086,15 +1069,15 @@ if( DEBUGLEVEL_ell >= 2, pointstriv=[[0,0,1],[-polcoeff(Pfact[1],0),0,1],[-polcoeff(Pfact[2],0),0,1]] , pointstriv = [[0,0,1]]); -if( DEBUGLEVEL_ell >= 3, print(" Recherche de points triviaux sur la courbe")); - P *= x; -if( DEBUGLEVEL_ell >= 3, print("Y^2 = ",P)); +if( DEBUGLEVEL_ell >= 3, print(" Search for trivial points on the curve")); + P *= 'x; +if( DEBUGLEVEL_ell >= 3, print(" Y^2 = ",P)); pointstriv = concat( pointstriv, nfratpoint(bnf.nf,P,LIMTRIV,0)); -if( DEBUGLEVEL_ell >= 1, print("points triviaux sur E'(K) = "); +if( DEBUGLEVEL_ell >= 1, print(" trivial points on E'(K) = "); print(lift(pointstriv)); print()); listpoints = nfellcount(bnf.nf,apinit,bpinit,KS2gen,pointstriv); -if( DEBUGLEVEL_ell >= 1, print("points sur E'(K) = ",lift(listpoints[1]))); +if( DEBUGLEVEL_ell >= 1, print(" points on E'(K) = ",lift(listpoints[1]))); np1 = listpoints[2][1]; np2 = listpoints[2][2]; listpoints2 = vector(#listpoints[1],i,0); for( i = 1, #listpoints[1], @@ -1105,7 +1088,7 @@ if( DEBUGLEVEL_ell >= 1, print("points sur E'(K) = ",lift(listpoints[1]))); listpoints2[i][1] = aux2^2/aux1/4; listpoints2[i][2] = aux2*(bpinit-aux1)/aux1/8 , listpoints2[i] = listpoints[1][i])); -if( DEBUGLEVEL_ell >= 1, print("points sur E(K) = ",lift(listpoints2)); print()); +if( DEBUGLEVEL_ell >= 1, print(" points on E(K) = ",lift(listpoints2)); print()); pointgen = concat(pointgen,listpoints2); certainp = (np1 == np2); @@ -1130,16 +1113,16 @@ if( DEBUGLEVEL_ell >= 1, if( DEBUGLEVEL_ell >= 1, if( certain && certainp, print("#E(K)/2E(K) = ",(1<<(rang+tors))); - print("rang = ",rang); print() + print("rank = ",rang); print() , print("#E(K)/2E(K) >= ",(1<<(rang+tors))); print(); - print(rang," <= rang <= ",n2+np2-2); print() + print(rang," <= rank <= ",n2+np2-2); print() )); strange = (n2+np2-n1-np1)%2; if( strange, if( DEBUGLEVEL_ell >= 1, - print(" !!! III doit etre un carre !!!"); print("donc")); + print(" !!! III should be a square !!!"); print("hence")); if( certain, np1++; certainp = (np1 == np2); @@ -1181,79 +1164,76 @@ if( DEBUGLEVEL_ell >= 1, if( DEBUGLEVEL_ell >= 1, if( certain && certainp, print("#E(K)/2E(K) = ",(1<<(rang+tors))); print(); - print("rang = ",rang); print() + print("rank = ",rang); print() , print("#E(K)/2E(K) >= ",(1<<(rang+tors))); print(); - print(rang," <= rang <= ",n2+np2-2); print()) + print(rang," <= rank <= ",n2+np2-2); print()) )); -\\ fin de strange +\\ end of strange -if( DEBUGLEVEL_ell >= 1, print("points = ",pointgen)); -if( DEBUGLEVEL_ell >= 3, print("fin de bnfell2descent_viaisog")); +if( DEBUGLEVEL_ell >= 1, print(" points = ",pointgen)); +if( DEBUGLEVEL_ell >= 3, print(" end of bnfell2descent_viaisog")); return([rang,n2+np2-2+tors,pointgen]); } -if( DEBUGLEVEL_ell >= 4, print("nfchinremain")); -{ -nfchinremain( nf, b, fact) = +{nfchinese( nf, b, fact) = \\ Chinese Remainder Theorem -local(l,fact2,i); +local(l,fact2); -if( DEBUGLEVEL_ell >= 4, print("entree dans nfchinremain")); +if( DEBUGLEVEL_ell >= 4, print(" starting nfchinese")); l = #fact[,1]; fact2 = vector(l,i,idealdiv(nf,b,idealpow(nf,fact[i,1],fact[i,2]))); -\\ for( i = 1, l, -\\ fact2[i] = idealdiv(nf,b,idealpow(nf,fact[i,1],fact[i,2]))); fact2 = idealaddtoone(nf,fact2); -\\ A CHANGER : fact2 = matbasistoalg(nf,fact2); for( i = 1, l, fact2[i] = nfbasistoalg(nf,fact2[i])); -if( DEBUGLEVEL_ell >= 4, print("fin de nfchinremain")); +if( DEBUGLEVEL_ell >= 4, print(" end of nfchinese")); return(fact2); } -if( DEBUGLEVEL_ell >= 4, print("bnfqfsolve2")); -{ -bnfqfsolve2(bnf, aleg, bleg, auto=[y]) = +{bnfqfsolve2(bnf, aleg, bleg, aut=['y]) = \\ Solves Legendre Equation x^2-aleg*Y^2=bleg*Z^2 \\ Using quadratic norm equations -\\ auto contient les automorphismes de bnf sous forme de polynomes -\\ en y, avec auto[1]=y . -local(aux,solvepolrel,auxsolve,solvepolabs,exprxy,rrrnf,bbbnf,SL0,i,SL1,SL,sunL,fondsunL,normfondsunL,SK,sunK,fondsunK,vecbleg,matnorm,matnormmod,expsolution,solution,reste,carre,verif); - -if( DEBUGLEVEL_ell >= 3, print("entree dans bnfqfsolve2")); - solvepolrel = x^2-aleg; -if( DEBUGLEVEL_ell >= 4, print("aleg = ",aleg)); -if( DEBUGLEVEL_ell >= 4, print("bleg = ",bleg)); - - if( #auto > 1, -if( DEBUGLEVEL_ell >= 4, print("factorisation du discriminant avec les automorhpismes de bnf")); - for( i = 2, #auto, - aux = abs(polresultant(lift(aleg)-subst(lift(aleg),y,auto[i]),bnf.pol)); +\\ aut contains the Galois automorphisms of bnf ( as polynomials in y) +\\ with aut[1] = y. +local(aux,solvepolrel,auxsolve,solvepolabs,exprxy,rrrnf,bbbnf,SL0,SL1,SL,sunL,fondsunL,normfondsunL,SK,sunK,fondsunK,vecbleg,matnorm,matnormmod,expsolution,solution,reste,carre,verif,x0,x1); + +if( DEBUGLEVEL_ell >= 3, print(" starting bnfqfsolve2")); + solvepolrel = 'x^2-aleg; +if( DEBUGLEVEL_ell >= 4, print(" aleg = ",aleg)); +if( DEBUGLEVEL_ell >= 4, print(" bleg = ",bleg)); + + if( nfissquare(bnf,aleg), +if( DEBUGLEVEL_ell >= 4, print(" aleg is a square !!")); + aleg = nfsqrt(bnf,aleg)[1]; + return([aleg,1,0]~) + ); + + if( #aut > 1, +if( DEBUGLEVEL_ell >= 4, print(" factorization of the discriminant using the automorphisms of bnf")); + for( i = 2, #aut, + aux = abs(polresultant(lift(aleg)-subst(lift(aleg),'y,aut[i]),bnf.pol)); if( aux, addprimes(factor(aux)[,1])))); auxsolve = rnfequation(bnf,solvepolrel,1); solvepolabs = auxsolve[1]; exprxy = auxsolve[2]; if( auxsolve[3], -if( DEBUGLEVEL_ell >=5, print(" CECI EST LE NOUVEAU CAS auxsolve[3] != 0"))); -if( DEBUGLEVEL_ell >= 4, print(" bbbnfinit ",solvepolabs)); +if( DEBUGLEVEL_ell >= 5, print(" case with auxsolve[3] != 0"))); +if( DEBUGLEVEL_ell >= 4, print(" bbbnfinit ",solvepolabs)); rrrnf = rnfinit(bnf,solvepolrel); bbbnf = bnfinit(solvepolabs,1); -if( DEBUGLEVEL_ell >= 4, print(" done")); +if( DEBUGLEVEL_ell >= 4, print(" done")); SL0 = 1; -if( DEBUGLEVEL_ell >= 4, print("bbbnf.clgp = ",bbbnf.clgp)); +if( DEBUGLEVEL_ell >= 4, print(" bbbnf.clgp = ",bbbnf.clgp)); for( i = 1, #bbbnf.clgp[2], if( bbbnf.clgp[2][i]%2 == 0, SL0 = idealmul(bbbnf,SL0,bbbnf.clgp[3][i][1,1]))); SL1 = idealmul(bbbnf,SL0,rnfeltup(rrrnf,bleg)); SL = idealfactor(bbbnf,SL1)[,1]~; sunL = bnfsunit(bbbnf,SL); -\\ A CHANGER : fondsunL = concat(bbbnf.futu,matbasistoalg(bbbnf,sunL[1])); fondsunL = concat(bbbnf.futu,vector(#sunL[1],i,nfbasistoalg(bbbnf,sunL[1][i]))); normfondsunL = norm(rnfeltabstorel( rrrnf,fondsunL)); SK = idealfactor(bnf,idealnorm(bbbnf,SL1))[,1]~; sunK = bnfsunit(bnf,SK); -\\ A CHANGER : fondsunK = concat(bnf.futu,matbasistoalg(bnf,sunK[1])); fondsunK = concat(bnf.futu,vector(#sunK[1],i,nfbasistoalg(bnf,sunK[1][i]))); vecbleg = bnfissunit(bnf,sunK,bleg); matnorm = matrix(#fondsunK,#normfondsunL,i,j,0); @@ -1261,38 +1241,37 @@ if( DEBUGLEVEL_ell >= 4, print("bbbnf.clgp = ",bbbnf.clgp)); matnorm[,i] = lift(bnfissunit( bnf,sunK,normfondsunL[i] ))); matnormmod = matnorm*Mod(1,2); expsolution = lift(matinverseimage( matnormmod, vecbleg*Mod(1,2))); -if( expsolution == []~, error(" bnfqfsolve2 : IL N'Y A PAS DE SOLUTION ")); + if( !length(expsolution), error("bnfqfsolve2 : NO SOLUTION !! ")); solution = prod( i = 1, #expsolution, fondsunL[i]^expsolution[i]); solution = rnfeltabstorel(rrrnf,solution); reste = (lift(vecbleg) - matnorm*expsolution)/2; carre = prod( i = 1, #vecbleg, fondsunK[i]^reste[i]); solution *= carre; - x1=polcoeff(lift(solution),1,x);x0=polcoeff(lift(solution),0,x); + x1 = polcoeff(lift(solution),1,'x); + x0 = polcoeff(lift(solution),0,'x); verif = x0^2 - aleg*x1^2-bleg; -if( verif, error(" bnfqfsolve2 : MAUVAIS POINT")); -if( DEBUGLEVEL_ell >= 3, print("fin de bnfqfsolve2")); - return([x0,x1,1]); +if( verif, error("bnfqfsolve2: WRONG POINT")); +if( DEBUGLEVEL_ell >= 3, print(" end of bnfqfsolve2")); + return([x0,x1,1]~); } -if( DEBUGLEVEL_ell >= 4, print("bnfqfsolve")); -{ -bnfqfsolve(bnf, aleg, bleg, flag3, auto=[y]) = +{bnfqfsolve(bnf, aleg, bleg, flag3, aut=['y]) = \\ cette fonction resout l'equation X^2-aleg*Y^2=bleg*Z^2 \\ dans le corps de nombres nf. \\ la solution est [X,Y,Z], \\ [0,0,0] sinon. -local(nf,aa,bb,na,nb,maxna,maxnb,mat,resl,t,sq,pol,vecrat,alpha,xx,yy,borne,test,sun,fact,suni,k,f,l,aux,alpha2,maxnbiter,idbb,rem,nbiter,mask,oldnb,newnb,bor,testici,de,xxp,yyp,rap,verif); +local(nf,aa,bb,na,nb,maxnb,mat,resl,t,sq,pol,vecrat,alpha,xx,yy,borne,test,sun,fact,suni,f,l,aux,alpha2,maxnbiter,idbb,rem,nbiter,mask,oldnb,newnb,bor,testici,de,xxp,yyp,rap,verif); -if( DEBUGLEVEL_ell >=5, print("entree dans bnfqfsolve")); -if( DEBUGLEVEL_ell >= 3, print("(a,b) = (",aleg,",",bleg,")")); +if( DEBUGLEVEL_ell >= 5, print(" starting bnfqfsolve")); +if( DEBUGLEVEL_ell >= 3, print(" (a,b) = (",aleg,",",bleg,")")); nf = bnf.nf; aleg = Mod(lift(aleg),nf.pol); aa = aleg; bleg = Mod(lift(bleg),nf.pol); bb = bleg; - if( aa == 0, -if( DEBUGLEVEL_ell >= 5, print("fin de bnfqfsolve")); + if( aa == 0, +if( DEBUGLEVEL_ell >= 5, print(" end of bnfqfsolve")); return([0,1,0]~)); if( bb == 0, -if( DEBUGLEVEL_ell >= 5, print("fin de bnfqfsolve")); +if( DEBUGLEVEL_ell >= 5, print(" end of bnfqfsolve")); return([0,0,1]~)); na = abs(norm(aa)); nb = abs(norm(bb)); @@ -1302,10 +1281,10 @@ if( DEBUGLEVEL_ell >= 5, print("fin de bnfqfsolve")); test = 0; nbiter = 0; while( 1, - if( flag3 && bnf.clgp[1]>1, resl = bnfqfsolve2(bnf,aa,bb,auto)~; break); -if( DEBUGLEVEL_ell >= 4, print("(na,nb,a,b) = ",lift([na,nb,aa,bb,norm(aa),norm(bb)]))); -if( DEBUGLEVEL_ell >= 5, print("***",nb,"*** ")); - if( nb >= maxnb, + if( flag3 && bnf.clgp[1]>1, resl = bnfqfsolve2(bnf,aa,bb,aut); break); +if( DEBUGLEVEL_ell >= 4, print(" (na,nb,a,b) = ",lift([na,nb,aa,bb,norm(aa),norm(bb)]))); +if( DEBUGLEVEL_ell >= 5, print(" ***",nb,"*** ")); + if( nb >= maxnb, mat = Mod(matid(3),nf.pol); aa = aleg; bb = bleg; na = abs(norm(aleg)); nb = abs(norm(bleg))); if( aa == 1, resl = [1,1,0]~; break); @@ -1327,19 +1306,19 @@ if( DEBUGLEVEL_ell >= 5, print("***",nb,"*** ")); t = na; na = nb; nb = t; t = mat[,3]; mat[,3] = mat[,2]; mat[,2] = t); if( nb == 1, -if( DEBUGLEVEL_ell >= 4, print("(a,b) = ",lift([aa,bb]))); -if( DEBUGLEVEL_ell >= 4, print("(na,nb) = ",lift([na,nb]))); +if( DEBUGLEVEL_ell >= 4, print(" (a,b) = ",lift([aa,bb]))); +if( DEBUGLEVEL_ell >= 4, print(" (na,nb) = ",lift([na,nb]))); if( aleg == aa && bleg == bb, mat = Mod(matid(3),nf.pol)); - if( flag3, resl = bnfqfsolve2(bnf,aa,bb,auto)~; break); - pol = aa*x^2+bb; + if( flag3, resl = bnfqfsolve2(bnf,aa,bb,aut); break); + pol = aa*'x^2+bb; vecrat = nfratpoint(nf,pol,borne++,1); if( vecrat != 0, resl=[vecrat[2],vecrat[1],vecrat[3]]~; break); alpha = 0; -if( DEBUGLEVEL_ell >= 4, print("borne = ",borne)); +if( DEBUGLEVEL_ell >= 4, print(" bound = ",borne)); while( alpha==0, xx = nfrandint(nf,borne); yy = nfrandint(nf,borne); - borne++; + borne++; alpha = xx^2-aa*yy^2 ); bb *= alpha; nb *= abs(norm(alpha)); t = xx*mat[,1]+yy*mat[,2]; @@ -1354,21 +1333,21 @@ if( DEBUGLEVEL_ell >= 4, print("on factorise bb = ",bb)); if( DEBUGLEVEL_ell >= 4, print("fact = ",fact)); suni = concat(bnf.futu,vector(#sun[1],i,nfbasistoalg(bnf,sun[1][i]))); for( i = 1, #suni, - if( (f = fact[i]>>1), + if( (f = fact[i]>>1), test =0; for( k = 1, 3, mat[k,3] /= suni[i]^f); nb /= abs(norm(suni[i]))^(2*f); bb /= suni[i]^(2*f))); -if( DEBUGLEVEL_ell >= 4, print("on factorise bb = ",bb)); +if( DEBUGLEVEL_ell >= 4, print(" factorization of bb = ",bb)); fact = idealfactor(nf,bb); -if( DEBUGLEVEL_ell >= 4, print("fact = ",fact)); +if( DEBUGLEVEL_ell >= 4, print(" fact = ",fact)); l = #fact[,1]; if( test, aux = 1; for( i = 1, l, if( (f = fact[i,2]>>1) && - !(fact[i,1][1]%2) && !nfpsquareodd(nf,aa,fact[i,1]), + !(fact[i,1][1]%2) && !nfissquaremodpodd(nf,aa,fact[i,1]), aux=idealmul(nf,aux,idealpow(nf,fact[i,1],f)))); if( aux != 1, test = 0; @@ -1378,28 +1357,31 @@ if( DEBUGLEVEL_ell >= 4, print("fact = ",fact)); mat[,3] *= alpha)); if( test, maxnbiter = 1<= 4, print("sq = ",sq); print("fact = ",fact); print("l = ",l)); - if( l > 1, +if( DEBUGLEVEL_ell >= 4, + print(" sq = ",sq); + print(" fact = ",fact); + print(" l = ",l)); + if( l > 1, idbb = idealhnf(nf,bb); - rem = nfchinremain(nf,idbb,fact)); + rem = nfchinese(nf,idbb,fact)); test = 1; nbiter = 1; while( test && nbiter <= maxnbiter, if( l > 1, mask = nbiter; xx = 0; for( i = 1, l, if( mask%2, xx += rem[i]*sq[i], xx -= rem[i]*sq[i] ); mask >>= 1) - , + , test = 0; xx = sq[1]); xx = mynfeltmod(nf,xx,bb); alpha = xx^2-aa; if( alpha == 0, resl=[xx,1,0]~; break(2)); t = alpha/bb; -if( DEBUGLEVEL_ell >= 4, print("[alpha,bb] = ",[alpha,bb])); +if( DEBUGLEVEL_ell >= 4, print(" [alpha,bb] = ",[alpha,bb])); oldnb = nb; newnb = abs(norm(t)); -if( DEBUGLEVEL_ell >= 4, print("[oldnb,newnb,oldnb/newnb] = ",[oldnb,newnb,oldnb/newnb+0.])); +if( DEBUGLEVEL_ell >= 4, print(" [oldnb,newnb,oldnb/newnb] = ",[oldnb,newnb,oldnb/newnb+0.])); while( nb > newnb, mat[,3] *= t; bb = t; nb = newnb; @@ -1414,8 +1396,8 @@ if( DEBUGLEVEL_ell >= 4, print("[oldnb,newnb,oldnb/newnb] = ",[oldnb,newnb,oldnb if( nb == oldnb, nbiter++, test = 0); ); if( nb == oldnb, - if( flag3, resl = bnfqfsolve2(bnf,aa,bb,auto)~; break); - pol = aa*x^2+bb; + if( flag3, resl = bnfqfsolve2(bnf,aa,bb,aut); break); + pol = aa*'x^2+bb; vecrat =nfratpoint(nf,pol,borne++<<1,1); if( vecrat != 0, resl = [vecrat[2],vecrat[1],vecrat[3]]~; break); @@ -1425,18 +1407,18 @@ if( DEBUGLEVEL_ell >= 4, print("[oldnb,newnb,oldnb/newnb] = ",[oldnb,newnb,oldnb xxp = mynfeltmod(bnf,de*xx,bb); yyp = mynfeltmod(bnf,de*yy,bb); rap = (norm(xxp^2-aa*yyp^2)/nb^2+0.); if( abs(rap) < 1, -if( DEBUGLEVEL_ell >= 4, print("********** \n \n MIRACLE ",rap," \n \n ***")); +if( DEBUGLEVEL_ell >= 4, print(" ********** \n \n MIRACLE ",rap," \n \n ***")); t = (xxp^2-aa*yyp^2)/bb; mat[,3] *= t; bb = t; nb = abs(norm(bb)); -if( DEBUGLEVEL_ell >= 4, print("newnb = ",nb)); +if( DEBUGLEVEL_ell >= 4, print(" newnb = ",nb)); t = xxp*mat[,1]+yyp*mat[,2]; mat[,2] = aa*yyp*mat[,1] + xxp*mat[,2]; mat[,1] = t; xx = xxp; yy = -yyp; testici = 0; )); - if( testici, + if( testici, alpha = 0; while( alpha == 0, xx = nfrandint(nf,4*borne); yy = nfrandint(nf,4*borne); @@ -1448,31 +1430,29 @@ if( DEBUGLEVEL_ell >= 4, print("newnb = ",nb)); mat[,1] = t; mat[,3] *= alpha;))))); resl = lift(mat*resl); -if( DEBUGLEVEL_ell >= 5, print("resl1 = ",resl)); -if( DEBUGLEVEL_ell >= 5, print("content = ",content(resl))); +if( DEBUGLEVEL_ell >= 5, print(" resl1 = ",resl)); +if( DEBUGLEVEL_ell >= 5, print(" content = ",content(resl))); resl /= content(resl); resl = Mod(lift(resl),nf.pol); -if( DEBUGLEVEL_ell >=5, print("resl3 = ",resl)); +if( DEBUGLEVEL_ell >=5, print(" resl3 = ",resl)); fact = idealadd(nf,idealadd(nf,resl[1],resl[2]),resl[3]); fact = bnfisprincipal(bnf,fact,3); resl *=1/nfbasistoalg(nf,fact[2]); -if( DEBUGLEVEL_ell >= 5, print("resl4 = ",resl)); -if( DEBUGLEVEL_ell >= 3, print("resl = ",resl)); +if( DEBUGLEVEL_ell >= 5, print(" resl4 = ",resl)); +if( DEBUGLEVEL_ell >= 3, print(" resl = ",resl)); verif = (resl[1]^2-aleg*resl[2]^2-bleg*resl[3]^2 == 0); - if( !verif && DEBUGLEVEL_ell >= 0, error(" bnfqfsolve : MAUVAIS POINT")); -if( DEBUGLEVEL_ell >= 3, print("fin de bnfqfsolve")); + if( !verif, error("bnfqfsolve: WRONG POINT")); +if( DEBUGLEVEL_ell >= 3, print(" end of bnfqfsolve")); return(resl); } -if( DEBUGLEVEL_ell >= 4, print("bnfredquartique2")); -{ -bnfredquartique2( bnf, pol, r,a,b) = +{bnfredquartique( bnf, pol, r,a,b) = \\ reduction d'une quartique issue de la 2-descente -\\ en connaissant les valeurs de r, a et b. -local(gcc,princ,den,ap,rp,pol2); +\\ en connaissant les valeurs de r, a et b. +local(gcc,princ,rp,pol2); -if( DEBUGLEVEL_ell >= 4, print("entree dans bnfredquartique2")); -if( DEBUGLEVEL_ell >= 4, print([r,a,b])); -if( DEBUGLEVEL_ell >= 3, print(" reduction de la quartique ",pol)); +if( DEBUGLEVEL_ell >= 4, print(" starting bnfredquartique")); +if( DEBUGLEVEL_ell >= 4, print(" ",[r,a,b])); +if( DEBUGLEVEL_ell >= 3, print(" reduction of the quartic ",pol)); if( a == 0, rp = 0 @@ -1485,210 +1465,214 @@ if( DEBUGLEVEL_ell >= 3, print(" reduction de la quartique ",pol)); princ = bnfisprincipal(bnf,gcc,3); if( princ[1] == 0, gcc = nfbasistoalg(bnf,princ[2]) , -if( DEBUGLEVEL_ell >= 3, print(" quartique non reduite")); -if( DEBUGLEVEL_ell >= 4, print("fin de bnfredquartique2")); +if( DEBUGLEVEL_ell >= 3, print(" quartic not reduced")); +if( DEBUGLEVEL_ell >= 4, print(" end of bnfredquartique")); return([pol,0,1])); rp = nfbasistoalg(bnf,idealaddtoone(bnf.nf,a/gcc,b/gcc)[1])/(a/gcc); rp = mynfeltmod(bnf,r*rp,b)/gcc; b /= gcc; ) ); - pol2 = subst(pol/b,x,rp+b*x)/b^3; -if( DEBUGLEVEL_ell >= 3, print(" quartique reduite = ",pol2)); -if( DEBUGLEVEL_ell >= 4, print("fin de bnfredquartique2")); + pol2 = subst(pol/b,'x,rp+b*'x)/b^3; +if( DEBUGLEVEL_ell >= 3, print(" quartic reduced: ",pol2)); +if( DEBUGLEVEL_ell >= 4, print(" end of bnfredquartique")); return([pol2,rp,b]); } -if( DEBUGLEVEL_ell >= 4, print("bnfell2descent_gen")); -{ -bnfell2descent_gen( bnf, ell, ext, help=[], bigflag=1, flag3=1, auto=[y]) = +{bnfell2descent_gen( bnf, ell, ext, help=[], bigflag=1, flag3=1, aut=['y]) = \\ bnf a un polynome en y. \\ si ell= y^2=P(x), alors ext est \\ ext[1] est une equation relative du corps (=P(x)), -\\ ext[2] est le resultat rnfequation(bnf,P,2); -\\ ext[3] est le buchinitfu (sur Q) de l'extension. +\\ ext[2] est le resultat rnfequation(bnf,P,1); +\\ ext[3] est le bnfinit (sur Q) de l'extension. \\ dans la suite ext est note L = K(theta). \\ help est une liste de points deja connus sur ell. \\ si bigflag !=0 alors on applique bnfredquartique. \\ si flag3 ==1 alors on utilise bnfqfsolve2 (equation aux normes) pour resoudre Legendre -\\ auto est une liste d'automorphismes connus de bnf +\\ aut est une liste d'automorphismes connus de bnf \\ (ca peut aider a factoriser certains discriminiants). \\ ell est de la forme y^2=x^3+A*x^2+B*x+C \\ ie ell=[0,A,0,B,C], avec A,B et C entiers. \\ -local(nf,unnf,ellnf,A,B,C,S,plist,Lrnf,SLprod,oddclass,SLlist,LS2gen,polrel,alpha,ttheta,KS2gen,LS2genunit,normLS2,normcoord,LS2coordtilda,LS2tilda,i,aux,j,listgen,listpoints,listpointstriv,listpointsmwr,list,m1,m2,loc,lastloc,maskwhile,iwhile,zc,iaux,liftzc,ispointtriv,point,c,b,a,sol,found,alphac,r,denc,dena,cp,alphacp,beta,mattr,vec,z1,ff,cont,d,e,polorig,pol,redq,transl,multip,UVW,pointxx,point2,v,rang); +local(nf,unnf,ellnf,A,B,C,S,plist,Lrnf,SLprod,LS2,LS2gen,polrel,alpha,ttheta,KS2gen,normLS2,normcoord,LS2coordtilda,LS2tilda,aux,listgen,listpointstriv,listpoints,m1,m2,loc,lastloc,maskwhile,iwhile,zc,iaux,liftzc,ispointtriv,point,c,b,a,found,alphac,r,denc,dena,cp,alphacp,beta,mattr,vec,z1,cont,d,e,polorig,pol,redq,transl,multip,UVW,pointxx,point2,rang,listELS,listnotELS); -if( DEBUGLEVEL_ell >= 4, print("entree dans bnfell2descent_gen")); - -\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -\\ construction de L(S,2) \\ -\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +if( DEBUGLEVEL_ell >= 4, print(" starting bnfell2descent_gen")); nf = bnf.nf; unnf = Mod(1,nf.pol); ellnf = ell*unnf; if( #ellnf <= 5, ellnf = ellinit(ellnf,1)); - A = ellnf.a2; if( DEBUGLEVEL_ell >= 2, print("A = ",A)); - B = ellnf.a4; if( DEBUGLEVEL_ell >= 2, print("B = ",B)); - C = ellnf.a6; if( DEBUGLEVEL_ell >= 2, print("C = ",C)); + + A = ellnf.a2; if( DEBUGLEVEL_ell >= 2, print(" A = ",A)); + B = ellnf.a4; if( DEBUGLEVEL_ell >= 2, print(" B = ",B)); + C = ellnf.a6; if( DEBUGLEVEL_ell >= 2, print(" C = ",C)); + +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +\\ Construction of L(S,2) \\ +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + +if( DEBUGLEVEL_ell >= 2, print(); print(" Computing L(S,2)")); + + polrel = ext[1]; + alpha = Mod(Mod('y,nf.pol),polrel); \\ alpha est l'element primitif de K + ttheta = Mod('x,polrel); \\ ttheta est la racine de P(x) S = 6*lift(ellnf.disc); plist = idealfactor(nf,S)[,1]; Lrnf = ext[3]; - SLprod = subst(lift(ext[1]'),y,lift(ext[2][2])); -if( DEBUGLEVEL_ell >= 3, print(ext[2])); - oddclass = 0; - while( !oddclass, -\\ Constructoin de S: - SLlist = idealfactor(Lrnf,SLprod)[,1]~; + SLprod = subst(lift(polrel'),'y,lift(ext[2][2])); +if( DEBUGLEVEL_ell >= 3, print(" ",ext[2])); + + while( 1, \\ Construction des S-unites - LS2gen = bnfsunit(Lrnf,SLlist); -if( DEBUGLEVEL_ell >= 4, print("LS2gen = ",LS2gen)); -\\ on ajoute la partie paire du groupe de classes. - oddclass = LS2gen[5][1]%2; - if( !oddclass, -if( DEBUGLEVEL_ell >= 3, print("2-class group ",LS2gen[5][3][1][1,1])); - S *= LS2gen[5][3][1][1,1]; - SLprod = idealmul(Lrnf,SLprod,(LS2gen[5][3][1]))); + LS2gen = bnfsunit(Lrnf, idealfactor(Lrnf,SLprod)[,1]~); +if( DEBUGLEVEL_ell >= 4, print(" LS2gen = ",LS2gen)); +\\ si le groupe de classes est impair, on a fini. + if( LS2gen[5][1]%2, break); +if( DEBUGLEVEL_ell >= 3, print(" 2-class group ",LS2gen[5][3][1][1,1])); + S *= LS2gen[5][3][1][1,1]; + SLprod = idealmul(Lrnf,SLprod,(LS2gen[5][3][1])); ); - polrel = ext[1]; - alpha = Mod(Mod(y,nf.pol),polrel); \\ alpha est l'element primitif de K - ttheta = Mod(x,polrel); \\ ttheta est la racine de P(x) - KS2gen = bnfsunit(bnf,idealfactor(nf,S)[,1]~); + +if( DEBUGLEVEL_ell >= 3, print(" #KS2gen = ",#KS2gen[1])); +if( DEBUGLEVEL_ell >= 3, print(" KS2gen = ",KS2gen[1])); -if( DEBUGLEVEL_ell >= 3, print("#KS2gen = ",#KS2gen[1])); -if( DEBUGLEVEL_ell >= 3, print("KS2gen = ",KS2gen[1])); + LS2gen = LS2gen[1]; + LS2 = vector(#LS2gen,i,lift(nfbasistoalg(Lrnf,LS2gen[i]))); + LS2 = concat(lift(Lrnf.futu),LS2); - LS2genunit = lift(Lrnf.futu); -\\ A CHANGER : LS2genunit = concat(LS2genunit,lift(matbasistoalg(Lrnf,LS2gen[1]))); - LS2genunit = concat(LS2genunit,vector(#LS2gen[1],i,lift(nfbasistoalg(Lrnf,LS2gen[1][i])))); + LS2 = subst(LS2,'x,ttheta); + LS2 = LS2*Mod(1,polrel); +if( DEBUGLEVEL_ell >= 3, print(" #LS2 = ",#LS2)); +if( DEBUGLEVEL_ell >= 3, print(" LS2 = ",LS2)); +if( DEBUGLEVEL_ell >= 2, print(" L(S,2) = ",LS2)); - LS2genunit = subst(LS2genunit,x,ttheta); - LS2genunit = LS2genunit*Mod(1,polrel); -if( DEBUGLEVEL_ell >= 3, print("#LS2genunit = ",#LS2genunit)); -if( DEBUGLEVEL_ell >= 3, print("LS2genunit = ",LS2genunit)); +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +\\ Construction of the Selmer group \\ +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + +if( DEBUGLEVEL_ell >= 2, print(); print(" Computing the Selmer group")); \\ dans LS2gen, on ne garde que ceux dont la norme est un carre. - normLS2gen = norm(LS2genunit); -if( DEBUGLEVEL_ell >= 4, print("normLS2gen = ",normLS2gen)); + normLS2 = norm(LS2); +if( DEBUGLEVEL_ell >= 4, print(" normLS2 = ",normLS2)); \\ matrice de l'application norme - normcoord = matrix(#KS2gen[1]+#bnf[8][5]+1,#normLS2gen,i,j,0); - for( i = 1, #normLS2gen, - normcoord[,i] = bnfissunit(bnf,KS2gen,normLS2gen[i])); -if( DEBUGLEVEL_ell >= 4, print("normcoord = ",normcoord)); + normcoord = matrix(#KS2gen[1]+#bnf[8][5]+1,#normLS2,i,j,0); + for( i = 1, #normLS2, + normcoord[,i] = bnfissunit(bnf,KS2gen,normLS2[i])); +if( DEBUGLEVEL_ell >= 4, print(" normcoord = ",normcoord)); \\ construction du noyau de la norme LS2coordtilda = lift(matker(normcoord*Mod(1,2))); -if( DEBUGLEVEL_ell >= 4, print("LS2coordtilda = ",LS2coordtilda)); +if( DEBUGLEVEL_ell >= 4, print(" LS2coordtilda = ",LS2coordtilda)); LS2tilda = vector(#LS2coordtilda[1,],i,0); for( i = 1, #LS2coordtilda[1,], aux = 1; for( j = 1, #LS2coordtilda[,i], if( sign(LS2coordtilda[j,i]), - aux *= LS2genunit[j])); + aux *= LS2[j])); LS2tilda[i] = aux; ); -if( DEBUGLEVEL_ell >= 3, print("LS2tilda = ",LS2tilda)); -if( DEBUGLEVEL_ell >= 3, print("norm(LS2tilda) = ",norm(LS2tilda))); +if( DEBUGLEVEL_ell >= 3, print(" LS2tilda = ",LS2tilda)); +if( DEBUGLEVEL_ell >= 3, print(" norm(LS2tilda) = ",norm(LS2tilda))); \\ Fin de la construction de L(S,2) listgen = LS2tilda; -if( DEBUGLEVEL_ell >= 2, print("LS2gen = ",listgen)); -if( DEBUGLEVEL_ell >= 2, print("#LS2gen = ",#listgen)); - listpoints = []; +if( DEBUGLEVEL_ell >= 2, print(" #LS2gen = ",#listgen)); +if( DEBUGLEVEL_ell >= 2, print(" LS2gen = ",listgen)); -if( DEBUGLEVEL_ell >= 3, print("(A,B,C) = ",[A,B,C])); +if( DEBUGLEVEL_ell >= 3, print(" (A,B,C) = ",[A,B,C])); \\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\ Recherche de points triviaux \\ \\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -if( DEBUGLEVEL_ell >= 2, print(" Recherche de points triviaux sur la courbe ")); - listpointstriv = nfratpoint(nf,x^3+A*x^2+B*x+C,LIMTRIV,0); +if( DEBUGLEVEL_ell >= 2, print(" Search for trivial points on the curve")); + listpointstriv = nfratpoint(nf,'x^3+A*'x^2+B*'x+C,LIMTRIV,0); listpointstriv = concat(help,listpointstriv); -if( DEBUGLEVEL_ell >= 1, print("points triviaux sur la courbe = ",listpointstriv)); +if( DEBUGLEVEL_ell >= 1, print(" Trivial points on the curve = ",listpointstriv)); \\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\ parcours de L(S,2) \\ \\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ - listpointsmwr = []; - list = [ 6, ellnf.disc, 0]; + listpoints = []; m1 = 0; m2 = 0; lastloc = -1; maskwhile = 1<<#listgen; listELS = [0]; listnotELS = []; iwhile = 1; + while( iwhile < maskwhile, -if( DEBUGLEVEL_ell >= 4, print("iwhile = ",iwhile); print("listgen = ",listgen)); +if( DEBUGLEVEL_ell >= 4, + print(" iwhile = ",iwhile); + print(" listgen = ",listgen) +); \\ utilise la structure de groupe pour detecter une eventuelle solubilite locale. -if( DEBUGLEVEL_ell >= 4, print("listELS = ",listELS); - print("listnotELS = ",listnotELS)); - sol = 1; loc = 0; + loc = 0; for( i = 1, #listELS, for( j = 1, #listnotELS, if( bitxor(listELS[i],listnotELS[j]) == iwhile, -if( DEBUGLEVEL_ell >= 3, print(" Non ELS d'apres la structure de groupe")); +if( DEBUGLEVEL_ell >= 3, print(" Not ELS from group structure")); listnotELS = concat(listnotELS,[iwhile]); - sol = 0; break(2)))); - if( !sol, iwhile++; next); + iwhile++; + next(3) + ))); for( i = 1, #listELS, for( j = i+1, #listELS, if( bitxor(listELS[i],listELS[j]) == iwhile, -if( DEBUGLEVEL_ell >= 3, print(" ELS d'aptres la structure de ")); +if( DEBUGLEVEL_ell >= 3, print(" ELS from group structure")); listELS = concat(listELS,[iwhile]); - loc = 2; - break(2)))); + loc = 1; + break(2) + ))); - iaux = vector(#listgen,i,bittest(iwhile,i-1))~; + iaux = vectorv(#listgen,i,bittest(iwhile,i-1)); iaux = (LS2coordtilda*iaux)%2; + zc = unnf*prod( i = 1, #LS2, LS2[i]^iaux[i]); - zc = unnf*prod( i = 1, #LS2genunit,LS2genunit[i]^iaux[i]); - -if( DEBUGLEVEL_ell >= 2, print("zc = ",zc)); +if( DEBUGLEVEL_ell >= 2, print(" zc = ",zc)); liftzc = lift(zc); \\ Est-ce un point trivial ? + found = 0; ispointtriv = 0; for( i = 1, #listpointstriv, point = listpointstriv[i]; if( #point == 2 || point[3] != 0, - if( nfissquare(Lrnf.nf,subst((lift(point[1])-x)*lift(liftzc),y,lift(ext[2][2]))), -if( DEBUGLEVEL_ell >= 2, print(" vient du point trivial ",point)); - listpointsmwr = concat(listpointsmwr,[point]); - m1++; - listELS = concat(listELS,[iwhile]); - if( degre(iwhile) > lastloc, m2++); - sol = found = ispointtriv = 1; break - ))); + if( nfissquare(Lrnf.nf,subst((lift(point[1])-'x)*lift(liftzc),'y,lift(ext[2][2]))), +if( DEBUGLEVEL_ell >= 2, print(" comes from the trivial point ",point)); + listpoints = concat(listpoints,[point]); + found = 1; ispointtriv = 1; break + ))); -\\ Ce n'est pas un point trivial - if( !ispointtriv, - c = polcoeff(liftzc,2); - b = -polcoeff(liftzc,1); - a = polcoeff(liftzc,0); - sol = 0; found = 0; \\ \\\\\\\\\\\\\ \\ On cherche a ecrire zc sous la forme a-b*theta \\ \\\\\\\\\\\\\ - if( c == 0, sol = 1, + + if( !found, \\ si ce n'est pas un point trivial + a = polcoeff(liftzc,0); + b =-polcoeff(liftzc,1); + c = polcoeff(liftzc,2); + + if( c != 0, alphac = (A*b+B*c-a)*c+b^2; -if( DEBUGLEVEL_ell >= 3, print("alphac = ",alphac)); +if( DEBUGLEVEL_ell >= 3, print(" alphac = ",alphac)); r = nfsqrt(nf,norm(zc))[1]; if( alphac == 0, \\ cas particulier -if( DEBUGLEVEL_ell >= 3, print(" on continue avec 1/zc")); - sol = 1; zc = norm(zc)*(1/zc); -if( DEBUGLEVEL_ell >= 2, print(" zc = ",zc)) +if( DEBUGLEVEL_ell >= 3, print(" continuing with 1/zc")); + zc = norm(zc)*(1/zc); +if( DEBUGLEVEL_ell >= 2, print(" zc = ",zc)) , \\ Il faut resoudre une forme quadratique \\ Existence (locale = globale) d'une solution : @@ -1696,151 +1680,149 @@ if( DEBUGLEVEL_ell >= 2, print(" zc = ",zc)) if( denc != 1, cp = c*denc^2, cp = c); dena = deno(lift(alphac)); if( dena != 1, alphacp = alphac*dena^2, alphacp = alphac); -if( DEBUGLEVEL_ell >= 2, print1(" symbole de Hilbert (",alphacp,",",cp,") = ")); - sol = loc || (mynfhilbert(nf, alphacp,cp)+1); -if( DEBUGLEVEL_ell >= 2, print(sol-1)); - if( sol, - beta = A*(A*b*c+B*c^2+b^2)-C*c^2+a*b; - mattr = matid(3); - mattr[1,1] = c ;mattr[2,2] = alphac ; - mattr[3,3] = r ;mattr[2,3] = -beta; - mattr[1,2] = -(b +A*c) ;mattr[1,3] = a-B*c+A*(A*c+b); -if( DEBUGLEVEL_ell >= 2, print1(" sol de Legendre = ")); - vec = bnfqfsolve(bnf,alphacp,cp,flag3,auto); +if( DEBUGLEVEL_ell >= 2, print(" Hilbert symbol (",alphacp,",",cp,") = ")); + if( !loc && mynfhilbert(nf, alphacp,cp) < 0, +if( DEBUGLEVEL_ell >= 3, print(" no local solution")); + listnotELS = concat(listnotELS,[iwhile]); + iwhile++; + next + ); +\\ Ici on a l'existence locale + beta = A*(A*b*c+B*c^2+b^2)-C*c^2+a*b; + mattr = matid(3); + mattr[1,1] = c ;mattr[2,2] = alphac ; + mattr[3,3] = r ;mattr[2,3] = -beta; + mattr[1,2] = -(b +A*c) ;mattr[1,3] = a-B*c+A*(A*c+b); +if( DEBUGLEVEL_ell >= 2, print1(" sol of quadratic equation = ")); + vec = bnfqfsolve(bnf,alphacp,cp,flag3,aut); if( DEBUGLEVEL_ell >= 2, print(lift(vec))); - aux = vec[2]*dena; - vec[2] = vec[1];vec[1] = aux; - vec[3] = vec[3]*denc; - vec = (mattr^(-1))*vec; - vec /= content(lift(vec)); - z1 = (vec[3]*ttheta+vec[2])*ttheta+vec[1]; -if( DEBUGLEVEL_ell >= 3, print(" z1 = ",z1)); - zc *= z1^2; -if( DEBUGLEVEL_ell >= 2, print(" zc*z1^2 = ",zc)); - ) - ) + aux = vec[2]*dena; + vec[2] = vec[1];vec[1] = aux; + vec[3] = vec[3]*denc; + vec = (mattr^(-1))*vec; + vec /= content(lift(vec)); + z1 = (vec[3]*ttheta+vec[2])*ttheta+vec[1]; +if( DEBUGLEVEL_ell >= 3, print(" z1 = ",z1)); + zc *= z1^2; +if( DEBUGLEVEL_ell >= 2, print(" zc*z1^2 = ",zc)); + ) ) ); - if( !sol, - listnotELS = concat(listnotELS,[iwhile]); - iwhile++; - next - ); - \\ \\\\\\\\\\ \\ Maintenant zc est de la forme a-b*theta \\ \\\\\\\\\\ - if( !ispointtriv, + + if( !found, + +if( DEBUGLEVEL_ell >= 3, print(" zc = ",zc)); liftzc = lift(zc); -if( DEBUGLEVEL_ell >= 3, print(" zc = ",liftzc)); -if( DEBUGLEVEL_ell >= 4, print(" N(zc) = ",norm(zc))); - if( poldegree(liftzc) >= 2, error(" bnfell2descent_gen : c <> 0")); - b = -polcoeff(liftzc,1); a = polcoeff(liftzc,0); -if( DEBUGLEVEL_ell >= 4, print(" on factorise (a,b) = ",idealadd(nf,a,b))); - ff = idealfactor(nf,idealadd(nf,a,b)); -if( DEBUGLEVEL_ell >= 4, print(" ff = ",ff)); - cont = 1; - for( i = 1, #ff[,1], - cont = idealmul(nf,cont,idealpow(nf,ff[i,1],ff[i,2]\2))); - cont = idealinv(nf,cont); - cont = nfbasistoalg(nf,bnfisprincipal(bnf,cont,3)[2])^2; - a *= cont; b *= cont; zc *= cont; -if( DEBUGLEVEL_ell >= 4, print(" [a,b] = ",[a,b])); + b =-polcoeff(liftzc,1); + c = polcoeff(liftzc,2); +if( c, error("bnfell2descent_gen : c <> 0")); + +\\ remove denominators and try to simplify zc + cont = idealadd(nf,a,b); + if( cont != 1, + cont = idealfactor(nf,cont); + cont[,2] \= 2; + aux = 1; + for( i = 1, #cont[,1], +\\ ***************************************************************** +\\ aux = idealmul(nf,aux,idealpow(nf,cont[i,1],cont[i,2])) + aux = idealmul(nf,aux,idealpow(nf,idealhnf(nf,cont[i,1]),cont[i,2])) +\\ ***************************************************************** + ); + cont = nfbasistoalg(nf,bnfisprincipal(bnf,aux)[2])^2; + a /= cont; + b /= cont; + zc/= cont; + liftzc = lift(zc); +if( DEBUGLEVEL_ell >= 3, print(" new zc = ",zc)); + ); + if( nfissquare(nf,b), -if( DEBUGLEVEL_ell >= 3, print(" b est un carre")); +if( DEBUGLEVEL_ell >= 3, print(" b is a square")); point = [a/b,nfsqrt(nf,(a/b)^3+A*(a/b)^2+B*(a/b)+C)[1]]; -if( DEBUGLEVEL_ell >= 2, print("point trouve = ",point)); - listpointsmwr = concat(listpointsmwr,[point]); - m1++; - if( degre(iwhile) > lastloc, m2++); - found = ispointtriv = 1 +if( DEBUGLEVEL_ell >= 2, print(" point found = ",point)); + listpoints = concat(listpoints,[point]); + found = 1; ispointtriv = 1 ) ); \\ \\\\\\\\\\\ -\\ Construction de la quartique +\\ Construction de la quartique \\ \\\\\\\\\\\ - if( !ispointtriv, + + if( !found, \\ si ce n'est pas un point trivial r = nfsqrt(nf,norm(zc))[1]; -if( DEBUGLEVEL_ell >= 4, print(" r = ",r)); +if( DEBUGLEVEL_ell >= 4, print(" r = ",r)); c = -2*(A*b+3*a); -if( DEBUGLEVEL_ell >= 4, print(" c = ",c)); +if( DEBUGLEVEL_ell >= 4, print(" c = ",c)); d = 8*r; -if( DEBUGLEVEL_ell >= 4, print(" d = ",d)); +if( DEBUGLEVEL_ell >= 4, print(" d = ",d)); e = (A^2*b^2 - 2*A*a*b-4*B*b^2-3*a^2); -if( DEBUGLEVEL_ell >= 4, print(" e = ",e)); - polorig = b*(x^4+c*x^2+d*x+e)*unnf; -if( DEBUGLEVEL_ell >= 2, print(" quartique : (",lift(b),")*Y^2 = ",lift(polorig/b))); - list[3] = b; +if( DEBUGLEVEL_ell >= 4, print(" e = ",e)); + polorig = b*('x^4+c*'x^2+d*'x+e)*unnf; +if( DEBUGLEVEL_ell >= 2, print(" quartic: (",lift(b),")*Y^2 = ",lift(polorig/b))); pol = polorig; if( bigflag, - redq = bnfredquartique2(bnf,pol,r,a,b); -if( DEBUGLEVEL_ell >= 2, print(" reduite: Y^2 = ",lift(redq[1]))); + redq = bnfredquartique(bnf,pol,r,a,b); +if( DEBUGLEVEL_ell >= 2, print(" reduced: Y^2 = ",lift(redq[1]))); pol = redq[1]; transl = redq[2]; multip = redq[3] ); + +\\ Search for a point on the quartic point = nfratpoint(nf,pol,LIM1,1); - if( point != [], -if( DEBUGLEVEL_ell >= 2, print("point = ",point)); - m1++; + found = point != []; +\\ If no point is found, check if it is ELS + if( !found && !loc, if( bigflag, - point[1] = point[1]*multip+transl; - point[2] = nfsqrt(nf,subst(polorig,x,point[1]/point[3]))[1]); - mattr = matid(3); - mattr[1,1] = -2*b^2; mattr[1,2] = (A*b+a)*b; - mattr[1,3] = a^2+(2*B-A^2)*b^2; mattr[2,2] = -b; - mattr[2,3] = a+A*b; mattr[3,3] =r; - UVW = [point[1]^2,point[3]^2,point[1]*point[3]]~; - vec = (mattr^(-1))*UVW; - z1 = (vec[3]*ttheta+vec[2])*ttheta+vec[1]; - zc *= z1^2; - zc /= -polcoeff(lift(zc),1); -if( DEBUGLEVEL_ell >= 3, print("zc*z1^2 = ",zc)); - pointxx = polcoeff(lift(zc),0); - point2 = [ pointxx, nfsqrt(nf,subst(x^3+A*x^2+B*x+C,x,pointxx))[1]]; -if( DEBUGLEVEL_ell >= 1, print(" point trouve = ",point2)); - listpointsmwr = concat(listpointsmwr,[point2]); - if( degre(iwhile) > lastloc, m2++); - found = 1; lastloc = -1 - , - if( loc - || (!bigflag && nflocallysoluble(nf,pol,r,a,b)) - || (bigflag && nflocallysoluble(nf,pol,0,1,1)), - - if( !loc, listlistELS=concat(listELS,[iwhile])); - if( degre(iwhile) > lastloc, m2++; lastloc = degre(iwhile)); - point = nfratpoint(nf,pol,LIM3,1); - if( point != [], - m1++; - if( bigflag, - point[1] = point[1]*multip+transl; - point[2] = nfsqrt(nf,subst(polorig,x,point[1]/point[3]))[1]; - ); - mattr = matid(3); - mattr[1,1] = -2*b^2; mattr[1,2] = (A*b+a)*b; - mattr[1,3] = a^2+(2*B-A^2)*b^2; mattr[2,2] = -b; - mattr[2,3] = a+A*b; mattr[3,3] =r; - UVW = [point[1]^2,point[3]^2,point[1]*point[3]]~; - vec = (mattr^(-1))*UVW; - z1 = (vec[3]*ttheta+vec[2])*ttheta+vec[1]; - zc *= z1^2; - zc /= -polcoeff(lift(zc),1); -if( DEBUGLEVEL_ell >= 3, print(" zc*z1^2 = ",zc)); - pointxx = polcoeff(lift(zc),0); - point2 = [ pointxx, nfsqrt(nf,subst(x^3+A*x^2+B*x+C,x,pointxx))[1]]; -if( DEBUGLEVEL_ell >= 1, print(" point trouve = ",point2)); - listpointsmwr = concat(listpointsmwr,[point2]); - found = 1; lastloc = -1; - ) - , listnotELS = concat(listnotELS,[iwhile]) - ) + loc = nflocallysoluble(nf,pol,r,a,b) + , loc = nflocallysoluble(nf,pol,0,1,1) + )); + if( !loc, + listnotELS = concat(listnotELS,[iwhile]); + iwhile++; + next ) ); + +\\ If no point is found, search harder + if( !found, +if( DEBUGLEVEL_ell >= 2, print("quartic is ELS")); + point = nfratpoint(nf,pol,LIM3,1); + found = point != [] + ); + + if( found && !ispointtriv, + if( bigflag, + point[1] = point[1]*multip+transl; + point[2] = nfsqrt(nf,subst(polorig,'x,point[1]/point[3]))[1]); + mattr = matid(3); + mattr[1,1] = -2*b^2; mattr[1,2] = (A*b+a)*b; + mattr[1,3] = a^2+(2*B-A^2)*b^2; mattr[2,2] = -b; + mattr[2,3] = a+A*b; mattr[3,3] =r; + UVW = [point[1]^2,point[3]^2,point[1]*point[3]]~; + vec = (mattr^(-1))*UVW; + z1 = (vec[3]*ttheta+vec[2])*ttheta+vec[1]; + zc *= z1^2; + zc /= -polcoeff(lift(zc),1); +if( DEBUGLEVEL_ell >= 3, print(" zc*z1^2 = ",zc)); + pointxx = polcoeff(lift(zc),0); + point2 = [ pointxx, nfsqrt(nf,subst('x^3+A*'x^2+B*'x+C,'x,pointxx))[1]]; +if( DEBUGLEVEL_ell >= 1, print(" point found = ",point2)); + listpoints = concat(listpoints,[point2]); + ); + + listELS = concat(listELS,[iwhile]); + if( degre(iwhile) > lastloc, m2++; lastloc = degre(iwhile)); + if( found, + m1++; found = 0; lastloc = -1; - v = degre(iwhile); - iwhile = 1<>= 1; LS2coordtilda = vecextract(LS2coordtilda,1<<#listgen-iwhile-1); listgen = vecextract(listgen,1<<#listgen-iwhile-1); @@ -1853,56 +1835,55 @@ if( DEBUGLEVEL_ell >= 1, print(" point trouve = ",point2)); ); if( DEBUGLEVEL_ell >= 2, - print("m1 = ",m1); - print("m2 = ",m2)); + print(" m1 = ",m1); + print(" m2 = ",m2)); if( DEBUGLEVEL_ell >= 1, print("#S(E/K)[2] = ",1<= 1, print("#E(K)/2E(K) = ",1<= ",1<= ",m1)); + print("rank(E/K) >= ",m1)); rang = m1; if( (m2-m1)%2, if( DEBUGLEVEL_ell >= 1, - print(" III devrait etre un carre, donc "); + print(" III should be a square, hence "); if( m2-m1 > 1, print("#E(K)/2E(K) >= ",1<<(m1+1)); print("#III(E/K)[2] <= ",1<<(m2-m1-1)); - print("rang(E/K) >= ",m1+1) + print("rank(E/K) >= ",m1+1) , print("#E(K)/2E(K) = ",1<<(m1+1)); print("#III(E/K)[2] = 1"); - print("rang(E/K) = ",m1+1))); + print("rank(E/K) = ",m1+1))); rang = m1+1) ); -if( DEBUGLEVEL_ell >= 1, print("listpointsmwr = ",listpointsmwr)); - for( i = 1, #listpointsmwr, - if( #listpointsmwr[i] == 3, - listpointsmwr[i] = vecextract(listpointsmwr[i],3)); - if( !ellisoncurve(ellnf,listpointsmwr[i]), - error("bnfell2descent : MAUVAIS POINT "))); -if( DEBUGLEVEL_ell >= 4, print("fin de bnfell2descent_gen")); - return([rang,m2,listpointsmwr]); + +if( DEBUGLEVEL_ell >= 1, print(" listpoints = ",listpoints)); + for( i = 1, #listpoints, + if( #listpoints[i] == 3, + listpoints[i] = vecextract(listpoints[i],3)); + if( !ellisoncurve(ellnf,listpoints[i]), + error("bnfell2descent: WRONG POINT "))); +if( DEBUGLEVEL_ell >= 4, print(" end of bnfell2descent_gen")); + return([rang,m2,listpoints]); } -if( DEBUGLEVEL_ell >= 4, print("bnfellrank")); -{ -bnfellrank(bnf,ell,help=[],bigflag=1,flag3=1) = +{bnfellrank(bnf,ell,help=[],bigflag=1,flag3=1) = \\ Algorithme de la 2-descente sur la courbe elliptique ell. \\ help est une liste de points connus sur ell. \\ attention bnf a un polynome en y. \\ si bigflag !=0, on reduit les quartiques \\ si flag3 != 0, on utilise bnfqfsolve2 -local(urst,urst1,den,factden,eqtheta,rnfeq,bbnf,ext,rang); +local(urst,urst1,den,factden,eqtheta,rnfeq,bbnf,ext,rang,f); -if( DEBUGLEVEL_ell >= 3, print("entree dans bnfellrank")); +if( DEBUGLEVEL_ell >= 3, print(" starting bnfellrank")); if( #ell <= 5, ell = ellinit(ell,1)); \\ removes the coefficients a1 and a3 @@ -1930,27 +1911,27 @@ if( DEBUGLEVEL_ell >= 3, print("entree dans bnfellrank")); \\ choix de l'algorithme suivant la 2-torsion ell *= Mod(1,bnf.pol); eqtheta = Pol([1,ell.a2,ell.a4,ell.a6]); -if( DEBUGLEVEL_ell >= 1, print("courbe elliptique : Y^2 = ",eqtheta)); +if( DEBUGLEVEL_ell >= 1, print(" elliptic curve: Y^2 = ",eqtheta)); f = nfpolratroots(bnf,eqtheta); if( #f == 0, \\ cas 1: 2-torsion triviale rnfeq = rnfequation(bnf,eqtheta,1); - urst1 = [1,-rnfeq[3]*Mod(y,bnf.pol),0,0]; - if( rnfeq[3] != 0, + urst1 = [1,-rnfeq[3]*Mod('y,bnf.pol),0,0]; + if( rnfeq[3] != 0, ell = ellchangecurve(ell,urst1); urst = ellcomposeurst(urst,urst1); - eqtheta = subst(eqtheta,x,x-rnfeq[3]*Mod(y,bnf.pol)); + eqtheta = subst(eqtheta,'x,'x-rnfeq[3]*Mod('y,bnf.pol)); rnfeq = rnfequation(bnf,eqtheta,1); -if( DEBUGLEVEL_ell >= 2, print("translation : on travaille avec Y^2 = ",eqtheta)); +if( DEBUGLEVEL_ell >= 2, print(" translation: working with Y^2 = ",eqtheta)); ); -if( DEBUGLEVEL_ell >= 3, print1("bbnfinit ")); +if( DEBUGLEVEL_ell >= 3, print1(" bbnfinit ")); bbnf = bnfinit(rnfeq[1],1); -if( DEBUGLEVEL_ell >= 3, print("done")); +if( DEBUGLEVEL_ell >= 3, print(" done")); ext = [eqtheta, rnfeq, bbnf]; rang = bnfell2descent_gen(bnf,ell,ext,help,bigflag,flag3) , if( #f == 1, \\ cas 2: 2-torsion = Z/2Z - if( f[1] != 0, + if( f[1] != 0, urst1 = [1,f[1],0,0]; ell = ellchangecurve(ell,urst1); urst = ellcomposeurst(urst,urst1) @@ -1959,28 +1940,26 @@ if( DEBUGLEVEL_ell >= 3, print("done")); , \\ cas 3: 2-torsion = Z/2Z*Z/2Z rang = bnfell2descent_complete(bnf,f[1],f[2],f[3],flag3) )); - - rang[3] = ellchangepointinverse(rang[3],urst); -if( DEBUGLEVEL_ell >= 3, print("fin de bnfellrank")); + + rang[3] = ellchangepoint(rang[3],ellinverturst(urst)); +if( DEBUGLEVEL_ell >= 3, print(" end of bnfellrank")); return(rang); } -if( DEBUGLEVEL_ell >= 4, print("bnfell2descent_complete")); -{ -bnfell2descent_complete(bnf,e1,e2,e3,flag3=1,auto=[y]) = +{bnfell2descent_complete(bnf,e1,e2,e3,flag3=1,aut=['y]) = \\ calcul du rang d'une courbe elliptique \\ par la methode de 2-descente complete. \\ Y^2 = (x-e1)*(x-e2)*(x-e3); \\ en suivant la methode decrite par J.Silverman \\ si flag3 ==1 alors on utilise bnfqfsolve2 (equation aux normes) -\\ pour resoudre Legendre -\\ on pourra alors utiliser auto=nfgaloisconj(bnf.pol) +\\ pour resoudre Legendre +\\ on pourra alors utiliser aut=nfgaloisconj(bnf.pol) \\ e1, e2 et e3 sont des entiers algebriques de bnf. -local(KS2prod,oddclass,KS2gen,i,vect,selmer,rang,X,Y,b1,b2,vec,z1,z2,d31,quart0,quart,cont,fa,point,solx,soly,listepoints); +local(KS2prod,oddclass,KS2gen,vect,selmer,rang,b1,b2,vec,z1,z2,d31,quart0,quart,cont,fa,point,solx,soly,listepoints,strange); -if( DEBUGLEVEL_ell >= 2, print("Algorithme de la 2-descente complete")); +if( DEBUGLEVEL_ell >= 2, print(" Algorithm of complete 2-descent")); \\ calcul de K(S,2) @@ -1993,13 +1972,13 @@ if( DEBUGLEVEL_ell >= 2, print("Algorithme de la 2-descente complete")); KS2prod = idealmul(bnf,KS2prod,(KS2gen[5][3][1]))); ); KS2gen = KS2gen[1]; -\\ A CHANGER : KS2gen = matbasistoalg(bnf,KS2gen); for( i = 1, #KS2gen, KS2gen[i] = nfbasistoalg(bnf, KS2gen[i])); KS2gen = concat(Mod(lift(bnf.tufu),bnf.pol),KS2gen); if( DEBUGLEVEL_ell >= 2, - print("#K(S,2)gen = ",#KS2gen); - print("K(S,2)gen = ",KS2gen)); + print(" #K(S,2)gen = ",#KS2gen); + print(" K(S,2)gen = ",KS2gen) +); \\ parcours de K(S,2)*K(S,2) @@ -2013,24 +1992,24 @@ if( DEBUGLEVEL_ell >= 2, forvec( Y = vect, b2 = prod( i = 1, #KS2gen, KS2gen[i]^Y[i]); -if( DEBUGLEVEL_ell >= 3, print("[b1,b2] = ",lift([b1,b2]))); +if( DEBUGLEVEL_ell >= 3, print(" [b1,b2] = ",lift([b1,b2]))); \\ points triviaux provenant de la 2-torsion - if( b1==1 && b2==1, -if( DEBUGLEVEL_ell >= 2, print(" point trivial [0]")); + if( b1==1 && b2==1, +if( DEBUGLEVEL_ell >= 2, print(" trivial point [0]")); selmer++; rang++; next); if( nfissquare(bnf.nf,(e2-e1)*b1) && nfissquare(bnf.nf,(e2-e3)*(e2-e1)*b2), -if( DEBUGLEVEL_ell >= 2, print(" point trivial [e2,0]")); +if( DEBUGLEVEL_ell >= 2, print(" trivial point [e2,0]")); selmer++; rang++; next); if( nfissquare(bnf.nf,(e1-e2)*b2) && nfissquare(bnf.nf,(e1-e3)*(e1-e2)*b1), -if( DEBUGLEVEL_ell >= 2, print(" point trivial [e1,0]")); +if( DEBUGLEVEL_ell >= 2, print(" trivial point [e1,0]")); selmer++; rang++; next); if( nfissquare(bnf.nf,(e3-e1)*b1) && nfissquare(bnf.nf,(e3-e2)*b2), -if( DEBUGLEVEL_ell >= 2, print(" point trivial [e3,0]")); +if( DEBUGLEVEL_ell >= 2, print(" trivial point [e3,0]")); selmer++; rang++; next); \\ premier critere local : sur les formes quadratiques @@ -2039,58 +2018,58 @@ if( DEBUGLEVEL_ell >= 2, print(" point trivial [e3,0]")); || mynfhilbert(bnf.nf,b2,b1*(e3-e1)) < 0 || mynfhilbert(bnf.nf,b1,b2*(e3-e2)) < 0 , -if( DEBUGLEVEL_ell >= 3, print("non ELS")); +if( DEBUGLEVEL_ell >= 3, print(" not ELS")); next); -if( DEBUGLEVEL_ell >= 2, print("[b1,b2] = ",lift([b1,b2]))); -if( DEBUGLEVEL_ell >= 2, print("qf loc soluble")); +if( DEBUGLEVEL_ell >= 2, print(" [b1,b2] = ",lift([b1,b2]))); +if( DEBUGLEVEL_ell >= 2, print(" quadratic forms locally soluble")); \\ solution de la premiere forme quadratique if( b1 != b2, vec = bnfqfsolve(bnf,b1*b2,b1*(e2-e1),flag3); -if( DEBUGLEVEL_ell >= 3, print("sol part = ",vec)); - if( vec[3] == 0, error("bnfell2descent_complete : BUG !!! : vec[3]=0 ")); +if( DEBUGLEVEL_ell >= 3, print(" sol part = ",vec)); + if( vec[3] == 0, error("bnfell2descent_complete: BUG !!! : vec[3]=0 ")); z1 = vec[1]/vec[3]/b1; z2 = vec[2]/vec[3] , z1 = (1+(e2-e1)/b1)/2; z2 = z1-1 ); d31 = e3-e1; - quart0 = b2^2*(z1^2*b1 - d31)*x^4 - 4*z1*b2^2*z2*b1*x^3 - + 2*b1*b2*(z1^2*b1 + 2*b2*z2^2 + d31)*x^2 - 4*z1*b2*z2*b1^2*x + quart0 = b2^2*(z1^2*b1 - d31)*'x^4 - 4*z1*b2^2*z2*b1*'x^3 + + 2*b1*b2*(z1^2*b1 + 2*b2*z2^2 + d31)*'x^2 - 4*z1*b2*z2*b1^2*'x + b1^2*(z1^2*b1 - d31); quart = quart0*b1*b2; -if( DEBUGLEVEL_ell >= 4, print("quart = ",quart)); +if( DEBUGLEVEL_ell >= 4, print(" quart = ",quart)); quart *= denominator(simplify(content(quart)))^2; cont = simplify(content(lift(quart))); fa = factor(cont); for( i = 1, #fa[,1], quart /= fa[i,1]^(2*(fa[i,2]\2))); -if( DEBUGLEVEL_ell >= 3, print("quart red = ",quart)); +if( DEBUGLEVEL_ell >= 3, print(" quartic reduced = ",quart)); \\ la quartique est-elle localement soluble ? - + if( !nflocallysoluble(bnf.nf,quart), -if( DEBUGLEVEL_ell >= 2, print(" quartique non ELS ")); +if( DEBUGLEVEL_ell >= 2, print(" quartic not ELS")); next); selmer++; \\ recherche de points sur la quartique. point = nfratpoint(bnf.nf,quart,LIM3,1); - if( point != [], -if( DEBUGLEVEL_ell >= 2, print("point trouve sur la quartique !!")); -if( DEBUGLEVEL_ell >= 3, print(point)); - if( point[3], + if( point != [], +if( DEBUGLEVEL_ell >= 2, print(" point found on the quartic !!")); +if( DEBUGLEVEL_ell >= 3, print(" ",point)); + if( point[3], point /= point[3]; z1 = (2*b2*point[1]*z2-z1*(b1+b2*point[1]^2))/(b1-b2*point[1]^2); solx = b1*z1^2+e1; soly = nfsqrt(bnf.nf,(solx-e1)*(solx-e2)*(solx-e3))[1]; listepoints = concat(listepoints,[[solx,soly]]); -if( DEBUGLEVEL_ell >= 1, print("point sur la courbe elliptique =",[solx,soly])) +if( DEBUGLEVEL_ell >= 1, print(" point on the elliptic curve =",[solx,soly])) ); rang++ , -if( DEBUGLEVEL_ell >= 2, print("aucun point trouve sur la quartique")) +if( DEBUGLEVEL_ell >= 2, print(" no point found on the quartic")) ) ) ); @@ -2111,10 +2090,22 @@ if( DEBUGLEVEL_ell >= 1, selmer = valuation(selmer,2); if( DEBUGLEVEL_ell >= 1, if( strange, - print(selmer-2," >= rang >= ",rang) -, print("rang = ",rang)); + print(selmer-2," >= rank >= ",rang) +, print("rank = ",rang)); if( rang, print("points = ",listepoints)); ); return([rang,selmer,listepoints]); } + +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +\\ HELP MESSAGES \\ +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + +{ + addhelp(bnfellrank, + "bnfellrank(K,E,help=[]): E is a 5-component vector defining an elliptic curve defined over the number field K (output by bnfinit()). Returns a vector [r,s,v], where r is a lower bound for the rank of E(K), s is the rank of its 2-Selmer group and v is a list of independant points in E(K)/2E(K). If help is a vector of nontrivial points on E(K), the result might be faster. See also ?default_ell"); +\\ others + addhelp(default_ell, + "default_ell(DEBUGLEVEL_ell, LIM1, LIM3, LIMTRIV, MAXPROB, LIMBIGPRIME): output/set the value of the global variables used for ellrank() and other related functions. DEBUGLEVEL_ell: 0-5 : choose the quantity of information printed during the computation (default=0: print nothing); LIM1 (resp LIM3): search limit for easy (resp hard) points on quartics; LIMTRIV: search limit for trivial points on elliptic curves; MAXPROB, LIMBIGPRIME: technical."); +} diff --git a/src/ext/pari/simon/ellQ.gp b/src/ext/pari/simon/ellQ.gp index 3c147ef9898..c114534ff13 100644 --- a/src/ext/pari/simon/ellQ.gp +++ b/src/ext/pari/simon/ellQ.gp @@ -1,5 +1,5 @@ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -\\ Copyright (C) 2008 Denis Simon +\\ Copyright (C) 2014 Denis Simon \\ \\ Distributed under the terms of the GNU General Public License (GPL) \\ @@ -13,496 +13,657 @@ \\ http://www.gnu.org/licenses/ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -\\ -\\ Auteur: -\\ Denis SIMON -> simon@math.unicaen.fr -\\ adresse du fichier: -\\ www.math.unicaen.fr/~simon/ellQ.gp -\\ -\\ ********************************************* -\\ * VERSION 29/04/2008 * -\\ ********************************************* -\\ -\\ Programme de calcul du rang des courbes elliptiques sur Q. -\\ langage: GP -\\ pour l'utiliser, lancer gp, puis taper -\\ \r ellQ.gp -\\ -\\ Ce programme utilise le module de resolution des formes quadratiques -\\ situe a l'adresse -\\ www.math.unicaen.fr/~simon/qfsolve.gp -\\ Il faut donc aussi taper: -\\ \r qfsolve.gp -\\ -\\ Explications succintes : -\\ La fonction ellrank() accepte toutes les courbes sous la forme -\\ [a1,a2,a3,a4,a6] -\\ Les coefficients peuvent etre entiers ou non. -\\ L'algorithme utilise est celui de la 2-descente. -\\ La 2-torsion peut etre quelconque. -\\ Il suffit de taper : -\\ -\\ gp > ell = [a1,a2,a3,a4,a6]; -\\ gp > ellrank(ell) -\\ -\\ Retourne un vecteur [r,s,vec] -\\ ou r est le rang probable (c'est toujours une minoration du rang), -\\ s est le 2-rang du groupe de Selmer, -\\ vec est une liste de points independants dans E(Q)/2E(Q). -\\ -\\ Courbes de la forme: k*y^2 = x^3+A*x^2+B*x+C -\\ sans 2-torsion, A,B,C entiers. -\\ gp > bnf = bnfinit(x^3+A*x^2+B*x+C); -\\ gp > ell = ellinit([0,A,0,B,C],1); -\\ gp > rank = ell2descent_gen(ell,bnf,k); -\\ -\\ Courbes avec #E[2](Q) >= 2: -\\ ell doit etre sous la forme -\\ y^2 = x^3 + A*^2 + B*x -\\ avec A et B entiers. -\\ gp > ell = [0,A,0,B,0] -\\ gp > ell2descent_viaisog(ell) -\\ = algorithme de la 2-descente par isogenies -\\ Attention A et B doivent etre entiers -\\ -\\ Courbes avec #E[2](Q) = 4: y^2 = (x-e1)*(x-e2)*(x-e3) -\\ gp > ell2descent_complete(e1,e2,e3) -\\ = algorithme de la 2-descente complete -\\ Attention: les ei doivent etre entiers. -\\ -\\ -\\ On peut avoir plus ou moins de details de calculs avec -\\ DEBUGLEVEL_ell = 0; -\\ DEBUGLEVEL_ell = 1; 2; 3;... -\\ -\\ -\\ +/* + Auteur : + Denis SIMON -> simon@math.unicaen.fr + adresse du fichier : + www.math.unicaen.fr/~simon/ellQ.gp + + ********************************************* + * VERSION 13/01/2014 * + ********************************************* + + + \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + \\ English \\ + \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + + This package provides functions to compute the rank of elliptic + curves over Q using 2-descent. + This package requires the other package qfsolve.gp downloadable at + www.math.unicaen.fr/~simon/qfsolve.gp + It also requires the package ellcommon.gp downloadable at + www.math.unicaen.fr/~simon/ellcommon.gp + + They can be run under GP by the commands + gp > \r qfsolve.gp + gp > \r ellcommon.gp + gp > \r ellQ.gp + + The main function is ellrank(), which takes as an argument + any elliptic curve in the form [a1,a2,a3,a4,a6] + the result is a vector [r,s,v], where + r is a lower bound for the rank, + s is the rank of the 2-Selmer group + v is a set of independant points in E(Q)/2E(Q). + + Example: + + gp > ell = [1,2,3,4,5]; + gp > ellrank(ell) + %1 = [1, 1, [[1,2]] + In this example, the rank is exactly 1, and [1,2] has infinite order. + + more details on the computations may be obtained by setting + DEBUGLEVEL_ell = 1 (the higher value, the more details) + + Other functions: + + ell2descent_complete, ell2descent_gen, ell2descent_viaisog, + ellhalf, ellredgen, ellsort, elltors2, elltorseven, + locallysoluble, ratpoint, redquartic, + bnfpSelmer, reducemodsquares + + Quick information is obtained by typing + gp > ?NameOfTheFunction + + \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + \\ Comment utiliser ce programme ? \\ + \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + + Ce module contient des fonctions pour calculer le rang des courbes + elliptiques sur Q, en utilisant la 2-descente. + langage : GP + + Ce module utilise les modules complementaires suivants : + qfsolve.gp + ellcommon.gp + qui sont disponibles a l'adresse + www.math.unicaen.fr/~simon/qfsolve.gp + www.math.unicaen.fr/~simon/ellcommon.gp + + Pour l'utiliser, lancer gp, puis taper + \r qfsolve.gp + \r ellcommon.gp + \r ellQ.gp + + \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + \\ Description des principales fonctions \\ + \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + + Explications succintes : + La fonction ellrank() accepte toutes les courbes sous la forme + [a1,a2,a3,a4,a6] + Les coefficients peuvent etre entiers ou non. + L'algorithme utilise est celui de la 2-descente. + La 2-torsion peut etre quelconque. + Il suffit de taper : + + gp > ell = [a1,a2,a3,a4,a6]; + gp > ellrank(ell) + + Retourne un vecteur [r,s,v] ou + r est le rang probable (c'est toujours une minoration du rang), + s est le 2-rang du groupe de Selmer, + v est une liste de points independants dans E(Q)/2E(Q). + + Exemple : + + gp > ell = [1,2,3,4,5]; + gp > ellrank(ell) + %1 = [1, 1, [[1,2]] + Ici, le rang est exactement 1, et le point [1,2] est d'ordre infini. + + Courbes de la forme : k*y^2 = x^3+A*x^2+B*x+C + sans 2-torsion, A,B,C entiers. + gp > bnf = bnfinit(x^3+A*x^2+B*x+C); + gp > ell = ellinit([0,A,0,B,C],1); + gp > rank = ell2descent_gen(ell,bnf,k); + + Courbes avec #E[2](Q) >= 2 : + ell doit etre sous la forme + y^2 = x^3 + A*x^2 + B*x + avec A et B entiers. + gp > ell = [0,A,0,B,0] + gp > ell2descent_viaisog(ell) + = algorithme de la 2-descente par isogenies + Attention A et B doivent etre entiers + + Courbes avec #E[2](Q) = 4 : y^2 = (x-e1)*(x-e2)*(x-e3) + gp > ell2descent_complete(e1,e2,e3) + = algorithme de la 2-descente complete + Attention : les ei doivent etre entiers. + + \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + \\ Autres fonctions utiles \\ + \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + + elltors2(E) : determine le groupe E[2](Q) + elltorseven(E) : determine le groupe E[2^*](Q) + ellhalf(E,P) : liste les points Q tels que 2Q = P + ellredgen(E,v) : reduction des points de v sur E + + locallysoluble(pol): teste si y^2=pol(x) est ELS + ratpoint(pol,lim): cherche un point sur y^2=pol(x) + redquartic(pol): reduction de la quartique pol + + + Aide en ligne : + ?NomDeLaFonction + + + \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + \\ Affichage des calculs \\ + \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + + On peut avoir plus ou moins de details de calculs avec + DEBUGLEVEL_ell = 0; + DEBUGLEVEL_ell = 1; 2; 3;... + +*/ { \\ -\\ Variables globales usuelles +\\ Usual global variables \\ - DEBUGLEVEL_ell = 1; \\ pour avoir plus ou moins de details - LIM1 = 5; \\ limite des points triviaux sur les quartiques - LIM3 = 50; \\ limite des points sur les quartiques ELS - LIMTRIV = 50; \\ limite des points triviaux sur la courbe elliptique +global(DEBUGLEVEL_ell, LIM1, LIM3, LIMTRIV, ELLREDGENFLAG, COMPLETE):small; + + DEBUGLEVEL_ell = 0; \\ From 0 to 5: choose a higher value to have + \\ more details printed. + LIM1 = 5; \\ Limit for the search of trivial points on quartics + LIM3 = 50; \\ Limit for the search of points on ELS quartics + LIMTRIV = 3; \\ Limit for the search of trivial points on the elliptic curve + ELLREDGENFLAG = 1; \\ to reduce the generators at the end + COMPLETE = 0; \\ Use Complete 2-descent when full 2-torsion, + \\ otherwise 2-descent via isogenies. \\ -\\ Variables globales techniques +\\ Technical global variables \\ +global(MAXPROB, LIMBIGPRIME):small; + MAXPROB = 20; - LIMBIGPRIME = 30; \\ pour distinguer un petit nombre premier d'un grand - \\ utilise un test probabiliste pour les grands - \\ si LIMBIGPRIME = 0, n'utilise aucun test probabiliste - ELLREDGENFLAG = 1;\\ pour reduire les genereteurs a la fin de l'algorithme + LIMBIGPRIME = 30; \\ for primes larger than this limit: use a probabilistic test + \\ LIMBIGPRIME = 0 means: only deterministic tests } -\\ -\\ Programmes -\\ +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +\\ SCRIPT \\ +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -\\ -\\ Fonctions communes ell.gp et ellQ.gp -\\ -{ -ellinverturst(urst) = -local(u = urst[1], r = urst[2], s = urst[3], t = urst[4]); - [1/u,-r/u^2,-s/u,(r*s-t)/u^3]; -} -{ -ellchangecurveinverse(ell,v) = ellchangecurve(ell,ellinverturst(v)); -} -{ -ellchangepointinverse(pt,v) = ellchangepoint(pt,ellinverturst(v)); -} -{ -ellcomposeurst(urst1,urst2) = -local(u1 = urst1[1], r1 = urst1[2], s1 = urst1[3], t1 = urst1[4], - u2 = urst2[1], r2 = urst2[2], s2 = urst2[3], t2 = urst2[4]); - [u1*u2,u1^2*r2+r1,u1*s2+s1,u1^3*t2+s1*u1^2*r2+t1]; -} -{ -ellinverturst(urst) = -local(u = urst[1], r = urst[2], s = urst[3], t = urst[4]); - [1/u,-r/u^2,-s/u,(r*s-t)/u^3]; -} -{ -ellchangecurveinverse(ell,v) = ellchangecurve(ell,ellinverturst(v)); -} -{ -ellchangepointinverse(pt,v) = ellchangepoint(pt,ellinverturst(v)); -} -{ -ellcomposeurst(urst1,urst2) = -local(u1 = urst1[1], r1 = urst1[2], s1 = urst1[3], t1 = urst1[4], - u2 = urst2[1], r2 = urst2[2], s2 = urst2[3], t2 = urst2[4]); - [u1*u2,u1^2*r2+r1,u1*s2+s1,u1^3*t2+s1*u1^2*r2+t1]; -} -{ -polratroots(pol) = -local(f,ans); - f = factor(pol)[,1]; - ans = []; - for( j = 1, #f, - if( poldegree(f[j]) == 1, - ans = concat(ans,[-polcoeff(f[j],0)/polcoeff(f[j],1)]))); - return(ans); -} -if( DEBUGLEVEL_ell >= 4, print("mysubst")); -{ -mysubst(polsu,subsx) = - if( type(lift(polsu)) == "t_POL", - return(simplify(subst(lift(polsu),variable(lift(polsu)),subsx))) - , return(simplify(lift(polsu)))); -} -if( DEBUGLEVEL_ell >= 4, print("degre")); -{ -degre(idegre) = -local(ideg,jdeg); +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +\\ MANIPULATION OF GLOBAL VARIABLES \\ +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ - ideg = idegre; jdeg = 0; - while( ideg >>= 1, jdeg++); - return(jdeg); -} -if( DEBUGLEVEL_ell >= 4, print("nfissquare")); -{ -nfissquare(nf, a) = #nfsqrt(nf,a) > 0; -} -if( DEBUGLEVEL_ell >= 4, print("nfsqrt")); -{ -nfsqrt( nf, a) = -\\ si a est un carre, renvoie [sqrt(a)], sinon []. -local(alift,ta,res,pfact,r1,py); - -if( DEBUGLEVEL_ell >= 5, print("entree dans nfsqrt ",a)); - if( a==0 || a==1, -if( DEBUGLEVEL_ell >= 5, print("fin de nfsqrt")); - return([a])); - - alift = lift(a); - ta = type(a); - if( !poldegree(alift), alift = polcoeff(alift,0)); - - if( type(alift) != "t_POL", - if( issquare(alift), -if( DEBUGLEVEL_ell >= 5, print("fin de nfsqrt")); - return([sqrtrat(alift)]))); - - if( poldegree(nf.pol) <= 1, -if( DEBUGLEVEL_ell >= 5, print("fin de nfsqrt")); - return([])); - if( ta == "t_POL", a = Mod(a,nf.pol)); - -\\ tous les plgements reels doivent etre >0 -\\ - r1 = nf.sign[1]; - for( i = 1, r1, - py = mysubst(alift,nf.roots[i]); - if( sign(py) < 0, -if( DEBUGLEVEL_ell >= 5, print("fin de nfsqrt")); - return([]))); -\\ factorisation sur K du polynome X^2-a : - if( variable(nf.pol) == x, - py = subst(nf.pol,x,y); - pfact = lift(factornf(x^2-mysubst(alift,Mod(y,py)),py)[1,1]) - , - pfact = lift(factornf(x^2-a,nf.pol)[1,1])); - if( poldegree(pfact) == 2, -if( DEBUGLEVEL_ell >= 5, print("fin de nfsqrt")); - return([])); -if( DEBUGLEVEL_ell >= 5, print("fin de nfsqrt")); - return([subst(polcoeff(pfact,0),y,Mod(variable(nf.pol),nf.pol))]); -} -if( DEBUGLEVEL_ell >= 4, print("sqrtrat")); -{ -sqrtrat(a) = - sqrtint(numerator(a))/sqrtint(denominator(a)); -} -\\ -\\ Fonctions propres a ellQ.gp -\\ +{default_ellQ( + DEBUGLEVEL_ell_val:small = 0, + LIM1_val:small = 5, + LIM3_val:small = 50, + LIMTRIV_val:small = 3, + ELLREDGENFLAG_val:small = 1, + COMPLETE_val:small = 0, + MAXPROB_val:small = 20, + LIMBIGPRIME_val:small = 30 + ) = -if( DEBUGLEVEL_ell >= 4, print("ellhalf")); -{ -ellhalf(ell,P)= -\\ renvoie tous les points Q sur ell tels que 2Q = P. -local(pol2,ratroots,half,x2,y2,P2); + DEBUGLEVEL_ell = DEBUGLEVEL_ell_val; + print(" DEBUGLEVEL_ell = ",DEBUGLEVEL_ell); - if(#ell < 13, ell=ellinit(ell,1)); + LIM1 = LIM1_val; + print(" LIM1 = ",LIM1); - pol2 = Pol([4,ell.b2,2*ell.b4,ell.b6]); \\ polynome de 2-division + LIM3 = LIM3_val; + print(" LIM3 = ",LIM3); - if( P == [0], - ratroots = polratroots(pol2); - half = vector(#ratroots,i,[ratroots[i],ellordinate(ell,ratroots[i])[1]]); - half = concat( [[0]], half); - return(half) - ); + LIMTRIV = LIMTRIV_val; + print(" LIMTRIV = ",LIMTRIV); - x2=Pol([1,0,-ell.b4,-2*ell.b6,-ell.b8]); \\ x(2P) = x2/pol2 + ELLREDGENFLAG = ELLREDGENFLAG_val; + print(" ELLREDGENFLAG = ",ELLREDGENFLAG); - half = []; - ratroots = polratroots(x2-P[1]*pol2); - if( #ratroots == 0, return(half)); - for( i = 1, #ratroots, - y2 = ellordinate(ell,ratroots[i]); - for( j = 1, #y2, - P2 = [ratroots[i],y2[j]]; - if( ellpow(ell,P2,2) == P, half = concat(half,[P2])) - ) - ); - return(half); -} -if( DEBUGLEVEL_ell >= 4, print("elltors2")); -{ -elltors2(ell)= -\\ Calcule le sous-groupe de 2-torsion de la courbe elliptique ell. -local(pol2,ratroots,tors2); + COMPLETE = COMPLETE_val; + print(" COMPLETE = ",COMPLETE); -if( DEBUGLEVEL_ell >= 4, print("calcul de la 2-torsion")); - if(#ell < 13, ell=ellinit(ell,1)); - tors2 = ellhalf(ell,[0]); - if( #tors2 == 1, - tors2 = [1, [], []], - if( #tors2 == 2, - tors2 = [2, [2], [tors2[2]]] - , tors2 = [4, [2,2], [tors2[2],tors2[3]]] - )); -if( DEBUGLEVEL_ell >= 4, print("E[2] = ",tors2)); - return(tors2); + MAXPROB = MAXPROB_val; + print(" MAXPROB = ",MAXPROB); + + LIMBIGPRIME = LIMBIGPRIME_val; + print(" LIMBIGPRIME = ",LIMBIGPRIME); } -if( DEBUGLEVEL_ell >= 4, print("elltorseven")); -{ -elltorseven(ell)= -\\ Calcule le 2-Sylow sous-groupe de torsion de la courbe elliptique ell. -local(torseven,P2); -if( DEBUGLEVEL_ell >= 4, print("calcul de la 2^n-torsion")); - if(#ell < 13, ell=ellinit(ell,1)); - torseven = elltors2(ell); +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +\\ FUNCTIONS FOR POLYNOMIALS \\ +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ - while( torseven[1] != 1, - P2 = ellhalf(ell,torseven[3][1]); - if( #P2 > 0, - torseven[1] *= 2; - torseven[2][1] *= 2; - torseven[3][1] = P2[1]; - next - ); - if( #torseven[3] == 1, break()); - - P2 = ellhalf(ell,torseven[3][2]); - if( #P2 > 0, - torseven[1] *= 2; - torseven[2][2] *= 2; - torseven[3][2] = P2[1]; - next - ); - P2 = ellhalf(ell,elladd(ell,torseven[3][1],torseven[3][2])); - if( #P2 > 0, - torseven[1] *= 2; - torseven[2][1] *= 2; - torseven[3][1] = P2[1]; - next - ); - break() - ); +{ratpoint( pol, lim:small = 1, singlepoint = 1, infinity = 1) = +\\ Search for points on y^2=pol(x). +\\ The coeff of pol must be integers. +\\ If singlepoint >= 1, stop after a first point is found. -if( DEBUGLEVEL_ell >= 4, print("E[2^n] = ",torseven)); - return(torseven); -} -if( DEBUGLEVEL_ell >= 4, print("polratroots")); -{ -polratroots(pol) = -local(f,ans); - f = factor(pol)[,1]; - ans=[]; - for( j = 1, #f, - if( poldegree(f[j]) == 1, - ans = concat(ans,[-polcoeff(f[j],0)/polcoeff(f[j],1)]))); - return(ans); -} -if( DEBUGLEVEL_ell >= 4, print("ratpoint")); -{ -ratpoint(pol,lim=1,singlepoint=1,tryhard=0) = -\\ Recherche de points sur y^2=pol(x). -\\ Les coeff de pol sont entiers. -\\ Si singlepoint >= 1, cherche un seul point, sinon plusieurs. -\\ Si tryhard == 1, on essaye une autre strategie quand pol est imprimitif. +my(listpoints,point1,odd,deg4,pol16,tab16,pol9,tab9,pol5,tab5,pol0,vecz,vecx,lead,zz,xx,evpol,iz,factpol,deg,vz,epsmax); -local(listpoints,point1,odd,deg4,pol16,tab16,pol9,tab9,pol5,tab5,pol0,vecz,vecx,lead,zz,xx,x16,x9,x5,evpol,ix,iz,K,factK,e,cont,ind,p,sol,factpol,r,M,U); +if( DEBUGLEVEL_ell >= 4, + print(" Starting ratpoint with pol = ",pol); + print(" lim = ",lim);); -if( DEBUGLEVEL_ell >= 4, print("entree dans ratpoint avec pol = ",pol); print("lim = ",lim);); if( !singlepoint, listpoints = []); point1 = []; -\\ cas triviaux - if( issquare(pollead(pol)), +\\ +\\ trivial solutions +\\ + +\\ the leading coeff is a square + if( infinity && issquare(pollead(pol)), point1 = [ 1, sqrtrat(pollead(pol)), 0]; -if( DEBUGLEVEL_ell >= 3, print("solution triviale: a est un carre")); +if( DEBUGLEVEL_ell >= 3, print(" trivial solution: lead(pol) is a square")); if( singlepoint, -if( DEBUGLEVEL_ell >= 4, print("fin de ratpoint")); +if( DEBUGLEVEL_ell >= 4, print(" end of ratpoint")); return(point1)); listpoints = concat(listpoints,[point1])); + +\\ the constant coeff is a square if( issquare(polcoeff(pol,0)), point1 = [ 0, sqrtrat(polcoeff(pol,0)) ]; -if( DEBUGLEVEL_ell >= 3, print("solution triviale: e est un carre")); +if( DEBUGLEVEL_ell >= 3, print(" trivial solution: pol(0) is a square")); if( singlepoint, -if( DEBUGLEVEL_ell >= 4, print("fin de ratpoint")); +if( DEBUGLEVEL_ell >= 4, print(" end of ratpoint")); return(point1)); listpoints = concat(listpoints,[point1])); - odd = poldegree(pol)%2; - deg4 = poldegree(pol) == 4; -\\ initialisation du crible modulo 16, 9 et 5 +\\ roots of pol ? + factpol = nfroots(,pol); + if( #factpol, +if( DEBUGLEVEL_ell >= 3, print(" trivial solution: roots of pol",factpol)); + if( singlepoint, +if( DEBUGLEVEL_ell >= 4, print(" end of ratpoint")); + return([factpol[1],0])); + listpoints = concat(listpoints,vector(#factpol,i,[factpol[i],0])) + ); + +\\ +\\ Sieve +\\ + +\\ initialisation of the sieve modulo 16, 9 and 5 +\\ used only with even degree when lim is large + + deg = poldegree(pol); + odd = deg%2; + deg4 = ( !odd && lim > 20); if( deg4, + pol16 = (Vec(pol)*Mod(1,16))~; tab16 = matrix(16,16); - for(xx = 0, 16-1, + for(xx = 0, 16-1, for(zz = 0, 16-1, - tab16[xx+1,zz+1] = !issquare([xx^4,xx^3*zz,xx^2*zz^2,xx*zz^3,zz^4]*pol16))); + tab16[xx+1,zz+1] = !issquare(vector(deg+1,i,xx^(deg+1-i)*zz^(i-1))*pol16))); pol9 = (Vec(pol)~)*Mod(1,9); tab9 = matrix(9,9); - for(xx = 0, 9-1, + for(xx = 0, 9-1, for(zz = 0, 9-1, - tab9[xx+1,zz+1] = !issquare([xx^4,xx^3*zz,xx^2*zz^2,xx*zz^3,zz^4]*pol9))); + tab9[xx+1,zz+1] = !issquare(vector(deg+1,i,xx^(deg+1-i)*zz^(i-1))*pol9))); pol5 = (Vec(pol)~)*Mod(1,5); tab5 = matrix(5,5); - for(xx = 0, 5-1, + for(xx = 0, 5-1, for(zz = 0, 5-1, - tab5[xx+1,zz+1] = !issquare([xx^4,xx^3*zz,xx^2*zz^2,xx*zz^3,zz^4]*pol5))) + tab5[xx+1,zz+1] = !issquare(vector(deg+1,i,xx^(deg+1-i)*zz^(i-1))*pol5))); ); - lead = pollead(pol); - pol0 = polcoeff(pol,0); - - if( odd, +\\ if the degree is odd, search only for square denominators + if( odd, vecz = vector(lim,i,i^2); , -\\ si le degre de pol est pair, il faut que le coeff dominant soit -\\ un carre mod zz. +\\ if the degree is even, the leading coeff must be +\\ a square modulo zz. + lead = pollead(pol); vecz = vector(lim); zz = 0; for( i = 1, lim, zz++; while( !issquare(Mod(lead,zz)),zz++); vecz[i] = zz )); -\\ le coeff constant doit etre un carre mod xx. + +\\ the constant coeff must be a square modulo xx. + pol0 = polcoeff(pol,0); vecx = vector(lim); xx = 0; for( i = 1, lim, xx++; while( !issquare(Mod(pol0,xx)),xx++); vecx[i] = xx); -if( DEBUGLEVEL_ell >= 4, print("xmax = ",vecx[lim])); -if( DEBUGLEVEL_ell >= 4, print("zmax = ",vecz[lim])); +if( DEBUGLEVEL_ell >= 4, print(" xmax = ",vecx[lim])); +if( DEBUGLEVEL_ell >= 4, print(" zmax = ",vecz[lim])); + +if( DEBUGLEVEL_ell >= 5, print(" vecx = ",vecx)); +if( DEBUGLEVEL_ell >= 5, print(" vecz = ",vecz)); + + if( deg4, + vz = vector(lim,i,Pol( + vector(deg+1,j,polcoeff(pol,deg+1-j)*vecz[i]^(j-1)))); + ); -if( DEBUGLEVEL_ell >= 5, print("vecx = ",vecx)); -if( DEBUGLEVEL_ell >= 5, print("vecz = ",vecz)); +\\ if deg is even and pol has no odd terms, +\\ it is enough to consider xx > 0 + if( !odd && subst(pol,x,-x)==pol, epsmax = 1, epsmax = 2); -\\ boucle sur x = xx/zz +\\ loop over x = xx/zz +\\ the loop on [xx,zz] is done diagonally +\\ to start with the smallest values of both xx and zz. for( somme = 2, 2*lim, for( ix = max(1,somme-lim), min(lim,somme-1), xx = vecx[ix]; iz = somme-ix; zz = vecz[iz]; - if( gcd(zz,xx) > 1, next); - if( odd && !issquare(lead*Mod(xx,zz)), next); - for( eps = 1, 2, if( eps == 2, zz = -zz); - if( deg4 && - (tab16[xx%16+1,zz%16+1] || tab9[xx%9+1,zz%9+1] || tab5[xx%5+1,zz%5+1]) - , next); - evpol = subst(pol,variable(pol),xx/zz); - if( issquare(evpol), - point1 = [xx/zz,sqrtrat(evpol)]; - if( singlepoint, break(3)); - listpoints = concat(listpoints,[point1]) - )))); - - if( point1 != [], -if( DEBUGLEVEL_ell >= 3, print("point trouve par ratpoint = ",point1)); -if( DEBUGLEVEL_ell >= 4, print("sortie de ratpoint ")); + if( gcd(zz,xx) != 1, next); + for( eps = 1, epsmax, +\\ when eps = 1, xx > 0; when eps = 2, xx < 0. + if( deg4, + if( tab16[xx%16+1,zz%16+1], xx=-xx;next); + if( tab9[xx%9+1,zz%9+1], xx=-xx;next); + if( tab5[xx%5+1,zz%5+1], xx=-xx;next); + evpol = subst(vz[iz],'x,xx) + , + evpol = subst(pol,variable(pol),xx/zz) + ); + if( issquare(evpol), + point1 = [xx/zz,sqrtrat(subst(pol,variable(pol),xx/zz))]; +if( DEBUGLEVEL_ell >= 4, print(" point found by ratpoint = ",point1)); + if( singlepoint, break(3)); + listpoints = concat(listpoints,[point1]) + ); + xx = -xx + ))); + + if( point1 != [], +if( DEBUGLEVEL_ell >= 3, print(" point found by ratpoint = ",point1)); +if( DEBUGLEVEL_ell >= 4, print(" end of ratpoint ")); if( singlepoint, return(point1), return(listpoints)) ); -\\ -\\ Essaye une autre strategie quand pol a un content non trivial -\\ +return([]); +} +{redquartic(pol) = +\\ reduction of the quartic polynomial. +\\ (also works with other degrees) +my(localprec,prec0,d,disc2,test,r,normderiv,disc2v,q,M); - if( !odd && tryhard, -if( DEBUGLEVEL_ell >= 4, print(" Autre strategie dans ratpoint **********")); - K = content(pol); +if( DEBUGLEVEL_ell >= 4, print(" starting redquartic")); +if( DEBUGLEVEL_ell >= 3, print(" reduction of the quartic ",pol)); + +\\ choice of the real precision used in the computation + localprec = prec0 = default(realprecision); + d = poldegree(pol); + disc2 = poldisc(pol)^2; + test = 0; + while( test == 0, +if( DEBUGLEVEL_ell >= 4, print(" precision = ",localprec)); + r = polroots(pol); + normderiv = vector( d, i, norm(subst(pol',variable(pol),r[i]))); + disc2v = prod( i = 1, d, normderiv[i]) * pollead(pol)^(2*d-4); + test = abs(disc2v-disc2) < 10^(-localprec\2); + if( !test, default(realprecision, localprec *= 2)) + ); + +\\ former choice of the quadratic form +\\ q = Vec(sum( i = 1, d, norm(x-r[i]))); +\\ Now, uses the quadratic form normalized as in Cremona-Stoll + q = Vec(sum( i = 1, d, norm('x-r[i]) / normderiv[i]^(1/(d-2)))); + M = qfbreduce([q[1],q[2]/2;q[2]/2,q[3]]); + pol = subst(pol,variable(pol),Pol(M[1,])/Pol(M[2,]))*Pol(M[2,])^poldegree(pol); + + if( localprec != prec0, default(realprecision,prec0)); + +if( DEBUGLEVEL_ell >= 3, print(" reduced quartic = ",pol)); +if( DEBUGLEVEL_ell >= 4, print(" end of redquartic")); + + return([pol,M]); +} +{listratpoint( pol, redflag = 0) = +my(list,i,K,ff,C,p,M,U,newpol,factpol,ll,listf,rr); + +if( DEBUGLEVEL_ell >= 5, print(" Starting listratpoint with ",pol)); + list = [[pol,matid(2),1,1]]; + i = 1; + while( i <= #list, + + pol = list[i][1]; + + K = abs(content(pol)); if( K != 1, - pol /= K; - factK = factor(K); - e = factK[,2]\2; - cont = factorback(factK[,1],e); - K /= cont^2; - if(K != 1, - e = factK[,2]%2; - ind = #e; while( !e[ind], ind--); - p = factK[ind,1]; - if( valuation( pollead(pol), p) == 1 || - ( valuation( pollead(pol), p) >= 2 && valuation( polcoeff(pol,poldegree(pol)-1), p) == 0), -if( DEBUGLEVEL_ell >= 4, print(" utilise une racine de pol mod p = ",p)); - sol = ratpoint(K/p^2*subst(polrecip(pol),variable(pol),p*variable(pol)),lim,singlepoint,1); - if( #sol > 0, - point1 = [ 1/(sol[1]*p), - sol[2]*cont*p/(p*sol[1])^(poldegree(pol)/2) ]; -if( DEBUGLEVEL_ell >= 4, print("sortie de ratpoint ",point1)); - return(point1) - ) - ); - factpol = factormod(pol,p)[,1]; - for( i = 1, #factpol, - if( poldegree(factpol[i]) !=1, next); -if( DEBUGLEVEL_ell >= 4, print(" utilise une racine de pol mod p = ",p)); - r = -centerlift(polcoeff(factpol[i],0)); - if( valuation(subst(pol,variable(pol),r),p) > 2, next); - M = [p,r;0,1]; - U = redquartique(subst(K*pol,variable(pol),p*variable(pol)+r)); - if( content(U[1]) != p, next); - sol = ratpoint(K/p^2*U[1],lim,singlepoint,1); - if( #sol > 0, - M = (M*U[2])*[sol[1], #sol == 2]~; - point1 = [ M[1]/M[2], sol[2]*cont*p/M[2]^(poldegree(pol)/2) ]; -if( DEBUGLEVEL_ell >= 4, print("sortie de ratpoint ",point1)); - return(point1) - ) - ) + pol = (list[i][1] /= K); + list[i][3] *= K + ); + + K = list[i][3]; + if( K == 1, i++; next); + + ff = factor(K); + if( vecmax(ff[,2]) > 1, + ff[,2] \= 2; + C = factorback(ff); + list[i][4] *= C; + K = ( list[i][3] /= C^2); + if( K == 1, i++; next); + ff = factor(K); + ); + + p = ff[1,1]; + M = list[i][2]; + C = list[i][4]; + + if( pollead(pol)%p == 0, + U = M*[1,0;0,p]; + if( content(U) == 1, + newpol = subst(pol,'x,'x/p)*p^(poldegree(pol)-1); + list = concat(list, [[newpol,U,K/p,C*p]]) ) + ); + + factpol = centerlift(polrootsmod(pol,p)); + for( j = 1, #factpol, + U = M*[p,factpol[j];0,1]; + if( content(U) == 1, + newpol = subst(pol,'x,p*'x+factpol[j])/p; + list = concat(list, [[newpol,U,K/p,C*p]]) + )); + + i++; + ); + + ll = sum( i = 1, #list, list[i][3] == 1); + listf = vector(ll); + i = 1; + for( j = 1, #list, + if( list[j][3] == 1, + listf[i] = list[j]; i++)); + + if( redflag, + for( i = 1, #listf, + rr = redquartic(listf[i][1]); + listf[i][1] = rr[1]; + listf[i][2] = listf[i][2]*rr[2] ) ); - return([]); +if( DEBUGLEVEL_ell >= 5, print(" Output of listratpoint = ",listf)); + +return(listf); } -if( DEBUGLEVEL_ell >= 5, print("psquare")); -{ -psquare( a, p) = -local(ap,v); +{ratpoint2( pol, lim:small = 1, singlepoint = 1, redflag = 0) = +my(listpoints,list,rr,y2,aux); -if( DEBUGLEVEL_ell >= 5, print("entree dans psquare ",[a,p])); -\\ a est un entier -\\ renvoie 1 si a est un carre dans Zp 0 sinon + listpoints = []; + list = listratpoint(pol,redflag); + for( i = 1, #list, + rr = ratpoint(list[i][1],lim,singlepoint); + if( singlepoint && #rr, rr=[rr]); + for( j = 1, #rr, + y2 = rr[j][2]*list[i][4]; + if( #rr[j] == 2, + aux = [rr[j][1],1]~ + , aux = [rr[j][1],rr[j][3]]~ + ); + aux = list[i][2] * aux; + if( aux[2] == 0, + rr[j] = [aux[1],y2,0] + , rr[j] = [aux[1]/aux[2],y2/aux[2]^(poldegree(pol)\2)] + ); + ); + if( singlepoint && #rr, return(rr[1])); + listpoints = concat(listpoints,rr); + ); + listpoints = vecsort(listpoints,,2); +return(listpoints); +} +{polrealrootsisolate(pol) = +\\ pol is a squarefree polynomial in Z[x]. +\\ Returns a list of vectors [a,b] with a and b rationals +\\ such that the intervals ]a,b] are disjoints and contain +\\ all the real roots of pol, and excatly one in each interval. +my(st,a,res,ind,b,c,stab,stac); + +if( DEBUGLEVEL_ell >= 5, print(" starting polrealrootsisolate with pol = ",pol)); + st = polsturm(pol); + if( !st, return([])); + a = 1; + while( polsturm(pol,-a,a) < st, a <<= 1); + res = [[-a,a,st]]; + ind = 1; + while( #res < st, + while( res[ind][3] == 1, ind++); + a = res[ind][1]; b = res[ind][2]; stab = res[ind][3]; + c = (a+b)/2; + stac = polsturm(pol,a,c); + if( stac == 0, res[ind][1] = c; next); + if( stac == stab, res[ind][2] = c; next); + res[ind] = [a,c,stac]; + res = concat(res,[[c,b,stab-stac]]); + ); + res = vector(st,i,[res[i][1],res[i][2]]); + res = vecsort(res,1); +if( DEBUGLEVEL_ell >= 5, print(" end of polrealrootsisolate with res = ",res)); + return(res); +} +{polrealrootsimprove(pol,v) = +\\ pol is a polynomial and v is a vector v=[a,b] +\\ such that pol contains exactly one root in the interval ]a,b]. +\\ Returns another interval with the same property, but with half length. +\\ (dichotomy) +my(c,v2,vc); + + c = (v[1]+v[2])/2; + v2 = subst(pol,variable(pol),v[2]); + if( v2 == 0, return([c,v[2]])); + vc = subst(pol,variable(pol),c); + if( sign(v2)*sign(vc) >= 0, v[2] = c, v[1] = c); + return(v); +} +{polrootsmodpn(pol,p) = +\\ Compute a list v. Each element of v is of the form +\\ [a,b], with maximal b <= valuation(poldisc(pol),p) +\\ and a is a root of pol modulo p^b. +my(vd,rac,i,pol2,r,newrac); + +if( DEBUGLEVEL_ell >= 5, print(" starting polrootsmodpn ",p,":",pol)); + + vd = valuation(poldisc(pol),p); + rac = [[0,0]]; + i = 1; + while (i <= #rac, +\\ if( rac[i][2] > vd, i++; next); + if( rac[i][2] >= vd, i++; next); + pol2 = subst(pol,'x,rac[i][1]+'x*p^rac[i][2]); + pol2 /= content(pol2); + r = lift(polrootsmod(pol2,p)); + if( #r == 0, i++; next); + newrac = vector(#r,j,[rac[i][1] + p^rac[i][2]*r[j],rac[i][2]+1]); + rac = concat(rac, vector(#r-1,j,newrac[j+1])); + rac[i] = newrac[1]; + ); +if( DEBUGLEVEL_ell >= 5, print(" end of polrootsmodpn ",rac)); + return(rac); +} + +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +\\ FUNCTIONS FOR LOCAL COMPUTATIONS \\ +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + +{ppinit( nf, p) = +\\ a little more structure than idealprimedec() +my(pdec,pp); + + pdec = idealprimedec(nf,p); + pp = vector(#pdec,i, + [ pdec[i] + , nfbasistoalg(nf,pdec[i][2]) + , if( p == 2, idealstar(nf,idealpow(nf,pdec[i],1+2*pdec[i].e)),0) + , nfmodprinit(nf,pdec[i]) + ]); + return(pp); +} +{nfpsquareodd( nf, a, pr) = +\\ pr is a prime ideal of nf as output by nfmodprinit +\\ a is an element of nf. +\\ Returns 1 if a is a square in the p-adics, 0 otherwise +\\ works only for p odd. +my(p,v,ap,den,norme); + +if( DEBUGLEVEL_ell >= 5, print(" starting nfpsquareodd(",a,",",pr)); if( a == 0, -if( DEBUGLEVEL_ell >= 5, print("fin de psquare 1")); +if( DEBUGLEVEL_ell >= 5, print(" end of nfpsquareodd")); return(1)); -\\ + + p = pr[3]; + v = idealval(nf,lift(a),p); + if( v%2, +if( DEBUGLEVEL_ell >= 5, print(" end of nfpsquareodd")); + return(0)); + ap = nfalgtobasis(nf,a/nfbasistoalg(nf,p[2])^v); + den = valuation(denominator(content(ap)),p.p); + if( den, + den += den%2; + ap = p.p^den*nfeltmul(nf,ap,nfeltpow(nf,p[2],-den*p.e)) + ); + + norme = (p.p^p.f-1)/2; + ap = nfeltpowmodpr(nf,ap,norme,pr); + ap[1] -= 1; + if( ap == 0, +if( DEBUGLEVEL_ell >= 5, print(" end of nfpsquareodd")); + return(1)); + if( idealval(nf,ap,p) > 0, +if( DEBUGLEVEL_ell >= 5, print(" end of nfpsquareodd")); + return(1)); +if( DEBUGLEVEL_ell >= 5, print(" end of nfpsquareodd")); + return(0); +} +{psquare( a, p) = +\\ a is an integer. +\\ p is a prime integer. +\\ Returns 1 if a is a square in the p-adics, 0 otherwise. +my(v,ap); + +if( DEBUGLEVEL_ell >= 5, print(" starting psquare ",[a,p])); + + if( a == 0, +if( DEBUGLEVEL_ell >= 5, print(" end of psquare 1")); + return(1)); + v = valuation(a,p); if( v%2, -if( DEBUGLEVEL_ell >= 5, print("fin de psquare 0")); +if( DEBUGLEVEL_ell >= 5, print(" end of psquare 0")); return(0)); - if( p == 2, + if( p == 2, ap = (a>>v)%8-1, ap = kronecker(a/p^v,p)-1 ); -if( DEBUGLEVEL_ell >= 5, print("fin de psquare ", !ap)); +if( DEBUGLEVEL_ell >= 5, print(" end of psquare ", !ap)); return(!ap); } -if( DEBUGLEVEL_ell >= 4, print("lemma6")); -{ -lemma6(pol, p, nu, xx) = -local(gx,gpx,lambda,mu); +{lemma6(pol, p, nu, xx) = +\\ technical lemma for local solubility of quartics +\\ Only for p <> 2. +my(gx,gpx,lambda,mu); -\\ pour les p <> 2 gx = subst( pol, variable(pol), xx); if( psquare(gx,p), return(1)); gpx = subst( pol', variable(pol), xx); @@ -513,12 +674,11 @@ local(gx,gpx,lambda,mu); if( (lambda >= 2*nu) && (mu >= nu), return(0)); return(-1); } -if( DEBUGLEVEL_ell >= 4, print("lemma7")); -{ -lemma7( pol, nu, xx) = -local(gx,gpx,lambda,mu,q); +{lemma7( pol, nu, xx) = +\\ technical lemma for local solubility of quartics +\\ at p = 2. +my(gx,gpx,lambda,mu,q); -\\ pour p = 2 gx = subst( pol, variable(pol), xx); if( psquare(gx,2), return(1)); gpx = subst( pol', variable(pol), xx); @@ -535,27 +695,25 @@ local(gx,gpx,lambda,mu,q); if( q == -2 && (gx>>lambda)%4 == 1, return(0)); return(-1); } -if( DEBUGLEVEL_ell >= 4, print("zpsoluble")); -{ -zpsoluble(pol, p, nu, pnu, x0, pnup) = -local(result,pol2,fact,x1); +{zp_soluble(pol, p, nu, pnu, x0, pnup) = +my(result,pol2,fact,x1); -if( DEBUGLEVEL_ell >= 5, print("entree dans zpsoluble ",[pol,p,x0,nu])); +if( DEBUGLEVEL_ell >= 5, print(" starting zp_soluble ",[pol,p,x0,nu])); if( p == 2, result = lemma7(pol,nu,x0), result = lemma6(pol,p,nu,x0)); if( result == +1, -if( DEBUGLEVEL_ell >= 5, print("fin de zpsoluble 1 lemma")); +if( DEBUGLEVEL_ell >= 5, print(" end of zp_soluble 1 lemma")); return(1)); if( result == -1, -if( DEBUGLEVEL_ell >= 5, print("fin de zpsoluble 0 lemma")); +if( DEBUGLEVEL_ell >= 5, print(" end of zp_soluble 0 lemma")); return(0)); pnup = pnu*p; nu++; - if( p< LIMBIGPRIME || !LIMBIGPRIME, + if( p < LIMBIGPRIME || !LIMBIGPRIME, for( i = 0, p-1, - if( zpsoluble(pol,p,nu,pnup,x0+pnu*i), -if( DEBUGLEVEL_ell >= 5, print("fin de zpsoluble")); + if( zp_soluble(pol,p,nu,pnup,x0+pnu*i), +if( DEBUGLEVEL_ell >= 5, print(" end of zp_soluble")); return(1))) , pol2 = subst(pol,variable(pol),x0+pnu*variable(pol)); @@ -565,594 +723,865 @@ if( DEBUGLEVEL_ell >= 5, print("fin de zpsoluble")); fact = factormod(pol2,p)[,1]; for( i = 1, #fact, x1 = -centerlift(polcoeff(fact[i],0)); - if( zpsoluble(pol,p,nu,pnup,x0+pnu*x1), -if( DEBUGLEVEL_ell >= 5, print("fin de zpsoluble")); + if( zp_soluble(pol,p,nu,pnup,x0+pnu*x1), +if( DEBUGLEVEL_ell >= 5, print(" end of zp_soluble")); return(1))); for( i = 1, MAXPROB, x1 = random(p); - if( zpsoluble(pol,p,nu,pnup,x0+pnu*x1), -if( DEBUGLEVEL_ell >= 5, print("fin de zpsoluble")); + if( zp_soluble(pol,p,nu,pnup,x0+pnu*x1), +if( DEBUGLEVEL_ell >= 5, print(" end of zp_soluble")); return(1))) ); if( DEBUGLEVEL_ell >= 2, - if( p >= LIMBIGPRIME, - print("******* test probabiliste en p = ",p,"*******"))); -if( DEBUGLEVEL_ell >= 5, print("fin de zpsoluble")); + if( p >= LIMBIGPRIME, + print(" ******* probabilistic test at p = ",p,"*******"))); +if( DEBUGLEVEL_ell >= 5, print(" end of zp_soluble")); return(0); } -if( DEBUGLEVEL_ell >= 4, print("qpsoluble")); -{ -qpsoluble(pol, p) = -if( DEBUGLEVEL_ell >= 5, print("entree dans qpsoluble ",p); print("pol = ",pol)); +{qp_soluble(pol, p) = +if( DEBUGLEVEL_ell >= 5, + print(" starting qp_soluble ",p); + print(" pol = ",pol)); if( psquare(pollead(pol),p), -if( DEBUGLEVEL_ell >= 5, print("fin de qpsoluble 1")); +if( DEBUGLEVEL_ell >= 5, print(" end of qp_soluble 1")); return(1)); if( psquare(polcoeff(pol,0),p), -if( DEBUGLEVEL_ell >= 5, print("fin de qpsoluble 1")); +if( DEBUGLEVEL_ell >= 5, print(" end of qp_soluble 1")); return(1)); - if( zpsoluble(pol,p,0,1,0), -if( DEBUGLEVEL_ell >= 5, print("fin de qpsoluble 1")); + if( zp_soluble(pol,p,0,1,0), +if( DEBUGLEVEL_ell >= 5, print(" end of qp_soluble 1")); return(1)); - if( zpsoluble(polrecip(pol),p,1,p,0), -if( DEBUGLEVEL_ell >= 5, print("fin de qpsoluble 1")); + if( zp_soluble(polrecip(pol),p,1,p,0), +if( DEBUGLEVEL_ell >= 5, print(" end of qp_soluble 1")); return(1)); -if( DEBUGLEVEL_ell >= 5, print("fin de qpsoluble 0")); +if( DEBUGLEVEL_ell >= 5, print(" end of qp_soluble 0")); return(0); } -if( DEBUGLEVEL_ell >= 4, print("locallysoluble")); -{ -locallysoluble(pol) = -\\ teste l'existence locale de solutions de y^2 = pol(x,z) -local(plist,disc0,p,c,vc); +{locallysoluble(pol) = +\\ Determines if y^2 = pol(x,z) is everywhere locally soluble +my(c,disc0,plist,p,vc); -if( DEBUGLEVEL_ell >= 4, print("entree dans locallysoluble :",pol)); +if( DEBUGLEVEL_ell >= 4, print(" starting locallysoluble: ",pol)); -\\ place reelle - if( !(poldegree(pol)%2) && sign(pollead(pol)) < 0 +\\ real place + if( !(poldegree(pol)%2) && sign(pollead(pol)) < 0 && sign(polcoeff(pol,0)) < 0 && polsturm(pol) == 0, -if( DEBUGLEVEL_ell >= 3, print(" non ELS a l'infini")); -if( DEBUGLEVEL_ell >= 4, print("fin de locallysoluble")); +if( DEBUGLEVEL_ell >= 3, print(" not ELS at infinity")); +if( DEBUGLEVEL_ell >= 4, print(" end of locallysoluble")); return(0)); \\ -\\ places finies de plist */ +\\ finite places \\ pol *= denominator(content(pol))^2; c = content(pol); disc0 = poldisc(pol); plist = factor (abs(2*disc0)); -if( DEBUGLEVEL_ell >= 4, print("liste de premiers = ",plist)); +if( DEBUGLEVEL_ell >= 4, print(" list of bad primes = ",plist)); for( i = 1, #plist[,1], p = plist[i,1]; -if( DEBUGLEVEL_ell >= 4, print("p = ",p)); +if( DEBUGLEVEL_ell >= 4, print(" p = ",p)); vc = valuation(c,p); - if( vc >= 2, + if( vc >= 2, pol /= p^(2*(vc\2)); plist[i,2] -= 2*(vc\2)*(2*poldegree(pol)-2) ); if( poldegree(pol) == 4 && p != 2 && plist[i,2] < 2, next); - if( !qpsoluble(pol,p), -if( DEBUGLEVEL_ell >= 3, print(" non ELS en ",p)); -if( DEBUGLEVEL_ell >= 4, print("fin de locallysoluble")); + if( !qp_soluble(pol,p), +if( DEBUGLEVEL_ell >= 3, print(" not ELS at ",p)); +if( DEBUGLEVEL_ell >= 4, print(" end of locallysoluble")); return(0))); -if( DEBUGLEVEL_ell >= 2, print(" quartique ELS")); -if( DEBUGLEVEL_ell >= 4, print("fin de locallysoluble")); +if( DEBUGLEVEL_ell >= 2, print(" quartic ELS: Y^2 = ",pol)); +if( DEBUGLEVEL_ell >= 4, print(" end of locallysoluble")); return(1); } -if( DEBUGLEVEL_ell >= 4, print("redquartique")); -{ -redquartique(pol) = -\\ reduction d'une quartique. -\\ ou plus generalement d'un polynome de degre deg. -local(prec,prec0,d,disc2,test,normderiv,disc2v,r,q,M); +{LS2localimage(nf,gen,pp) = +my(p,LS2image,ph,ival,delta); + +if( DEBUGLEVEL_ell >= 4, print(" starting LS2localimage")); + + p = pp[1][1].p; + LS2image = matrix( if( p == 2, sum(i=1,#pp,1+#pp[i][3].cyc), 2*#pp), #gen); + + for( j = 1, #gen, + ph = []; + for( i = 1, #pp, + ival = idealval(nf,gen[j],pp[i][1]); + ph = concat(ph,[ival]); + delta = gen[j]/pp[i][2]^ival; + if( p == 2, + ph = concat(ph,ideallog(nf,delta,pp[i][3])~); + , ph = concat(ph,[1-nfpsquareodd(nf,delta,pp[i][4])]); + ) + ); + LS2image[,j] = ph~ + ); + LS2image *= Mod(1,2); -if( DEBUGLEVEL_ell >= 4, print("entree dans redquartique")); -if( DEBUGLEVEL_ell >= 3, print(" reduction de la quartique ",pol)); +if( DEBUGLEVEL_ell >= 4, print(" LS2image = ",lift(LS2image))); +if( DEBUGLEVEL_ell >= 4, print(" end of LS2localimage")); + return(LS2image); +} -\\ choix de la precision des calculs. - prec = prec0 = default(realprecision); - d = poldegree(pol); - disc2 = poldisc(pol)^2; - test = 0; - while( test == 0, -if( DEBUGLEVEL_ell >= 4, print(" precision = ",prec)); - r = polroots(pol); - normderiv = vector( d, i, norm(subst(pol',variable(pol),r[i]))); - disc2v = prod( i = 1, d, normderiv[i]) * pollead(pol)^(2*d-4); - test = abs(disc2v-disc2) < 10^(-prec\2); - if( !test, default(realprecision, prec *= 2)) +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +\\ GENERIC FUNCTIONS FOR ELLIPTIC CURVES \\ +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + +{ellhalf(ell,P)= +\\ returns all the points Q on ell such that 2Q = P. +my(pol2,ratroots,half,x2,y2,P2); + + if(#ell < 13, ell=ellinit(ell,1)); + + pol2 = Pol([4,ell.b2,2*ell.b4,ell.b6]); \\ 2-division polynomial + + if( P == [0], + ratroots = nfroots(,pol2); + half = vector(#ratroots,i,[ratroots[i],-(ell.a1*ratroots[i]+ell.a3)/2]); + half = concat( [[0]], half); + return(half) ); -\\ On n'utilise plus -\\ q = Vec(sum( i = 1, d, norm(x-r[i]))); -\\ mais la normalisation de Cremona-Stoll - q = Vec(sum( i = 1, d, norm(x-r[i]) / normderiv[i]^(1/(d-2)))); - M = QfbReduce([q[1],q[2]/2;q[2]/2,q[3]]); - pol = subst(pol,variable(pol),Pol(M[1,])/Pol(M[2,]))*Pol(M[2,])^poldegree(pol); + x2 = Pol([1,0,-ell.b4,-2*ell.b6,-ell.b8]); \\ x(2P) = x2/pol2 - if( prec != prec0, default(realprecision,prec0)); + half = []; + ratroots = nfroots(,x2-P[1]*pol2); + if( #ratroots == 0, return(half)); + for( i = 1, #ratroots, + y2 = ellordinate(ell,ratroots[i]); + for( j = 1, #y2, + P2 = [ratroots[i],y2[j]]; + if( ellpow(ell,P2,2) == P, half = concat(half,[P2])) + ) + ); -if( DEBUGLEVEL_ell >= 3, print(" quartique reduite = ",pol)); -if( DEBUGLEVEL_ell >= 4, print("sortie de redquartique")); + return(half); +} +{elltors2(ell)= +\\ Compute the 2-torsion subgroup of the elliptic curve ell. +my(tors2); - return([pol,M]); +if( DEBUGLEVEL_ell >= 3, print(" computing the 2-torsion")); + + tors2 = ellhalf(ell,[0]); + if( #tors2 == 1, + tors2 = [1, [], []], + if( #tors2 == 2, + tors2 = [2, [2], [tors2[2]]] + , tors2 = [4, [2,2], [tors2[2],tors2[3]]] + )); +if( DEBUGLEVEL_ell >= 3, print(" E[2] = ",tors2)); + return(tors2); } -if( DEBUGLEVEL_ell >= 4, print("reducemodsquares")); -{ -reducemodsquares(delta,d) = -\\ reduction du coefficient de x^d dans ( delta modulo les carres ) -local(deg,xx,z,qd,Qd,reduc); - - deg = poldegree(delta.mod); - xx = Mod(x,delta.mod); - z = subst(Pol(vector(deg,i,eval(Str("a"i)))),x,xx); - qd = polcoeff(lift(delta*z^2),d,x); - Qd = simplify(matrix(deg,deg,i,j,deriv(deriv(qd,eval(Str("a"i))),eval(Str("a"j)))/2)); +{elltorseven(ell)= +\\ Compute the 2-Sylow subgroup of the torsion of the elliptic curve ell. +my(torseven,P2); - reduc = IndefiniteLLL(Qd); - if( #reduc == 2, reduc = reduc[2][,1]); +if( DEBUGLEVEL_ell >= 4, print(" computing the 2^n-torsion")); + if(#ell < 13, ell=ellinit(ell,1)); + torseven = elltors2(ell); + + while( torseven[1] != 1, + P2 = ellhalf(ell,torseven[3][1]); + if( #P2 > 0, + torseven[1] *= 2; + torseven[2][1] *= 2; + torseven[3][1] = P2[1]; + next + ); + if( #torseven[3] == 1, break()); - return(delta*subst(Pol(reduc),x,xx)^2); + P2 = ellhalf(ell,torseven[3][2]); + if( #P2 > 0, + torseven[1] *= 2; + torseven[2][2] *= 2; + torseven[3][2] = P2[1]; + next + ); + P2 = ellhalf(ell,elladd(ell,torseven[3][1],torseven[3][2])); + if( #P2 > 0, + torseven[1] *= 2; + torseven[2][1] *= 2; + torseven[3][1] = P2[1]; + next + ); + break() + ); + +if( DEBUGLEVEL_ell >= 4, print(" E[2^n] = ",torseven)); + return(torseven); } -if( DEBUGLEVEL_ell >= 4, print("ellsort")); -{ -ellsort(listpts) = -\\ tri des points listpts sur une courbe elliptique -\\ suivant la hauteur naive. -local(n,v,aux,ord); +{ellsort(listpts) = +\\ Sorting the points listpts on an elliptic curve +\\ using the naive height. +my(n,v,aux,ord); v = vector(n = #listpts); - for( i = 1, n, + for( i = 1, n, if( listpts[i] == [0], v[i] = [0,0,0]; next); aux = denominator(listpts[i][2])/denominator(listpts[i][1]); v[i] = vecsort(abs([listpts[i][1]*aux^2, listpts[i][2]*aux^3,aux]),,4); ); - ord = vecsort(v,,3); + ord = Vec(vecsort(v,,3)); \\ ord = vecsort(v,,3); return(vector(n,i,listpts[ord[i]])); } -if( DEBUGLEVEL_ell >= 4, print("ellredgen")); -{ -ellredgen(ell,listgen,K=1) = -\\ reduction des generateurs de listgen -\\ sur la courbe ell = [a1,a2,a3,a4,a6] -\\ ou K*y^2 = x^3 + a2*x^2 + a4*x + a6 (lorsque a1 = a3 = 0); -local(d,sqrtK,urst,M,U,limgoodrelations,listgen2); - -if( DEBUGLEVEL_ell >= 3, print("Reduction des generateurs ",listgen)); -if( DEBUGLEVEL_ell >= 5, print("ell=",ell)); +{ellremovetorsion(ell,listgen) = +\\ Extracting the points of infinite order from listgen +my(d,extra); + +if( DEBUGLEVEL_ell >= 5, print(" removing torsion from ",listgen)); + d = #listgen; + extra = 0; + for( i = 1, d, +\\ points of order 1 or 2 + if( listgen[i] == [0] + || listgen[i] == ellpow(ell,listgen[i],-1) + , extra += 1<<(i-1); + next + ); +\\ detection of infinite order points by looking at +\\ 8*9*5*7*P modulo the prime 1048583 + if( ell.disc%1048583 != 0 + && denominator(listgen[i])%1048583 != 0 + && ellpow(ell,listgen[i]*Mod(1,1048583),2520) != [0] + , next + ); +\\ detection of torsion points by ellorder() + if( ellorder(ell,listgen[i]), + extra += 1<<(i-1) + ) + ); + if( extra, + listgen = vecextract(listgen,1<<#listgen-1-extra); + ); +if( DEBUGLEVEL_ell >= 5, print(" without torsion = ",listgen)); + return(listgen); +} +{ellredgen(ell0,listgen,K=1) = +\\ reduction of the generators of points in listgen +\\ on the elliptic curve ell = [a1,a2,a3,a4,a6] +\\ or K*y^2 = x^3 + a2*x^2 + a4*x + a6 (when a1 = a3 = 0); +\\ using the canonical height. +my(d,ell=ell0,sqrtK,urst,extra,M,U,listgen2,tors2,vt); + +if( DEBUGLEVEL_ell >= 3, print(" Reduction of the generators ",listgen)); +if( DEBUGLEVEL_ell >= 5, print(" ell=",ell)); d = #listgen; if( d == 0, return([])); - if( #ell < 19, ell = ellinit(ell)); +\\ removing torsion points from listgen + listgen = ellremovetorsion(ell0,listgen); + d = #listgen; + if( d == 0, return([])); + + if( #ell < 13, ell = ellinit(ell,1)); + if( K != 1, - if( ell.a1 != 0 || ell.a3 != 0, error(" ellredgen : a1*a3 != 0")); + if( ell.a1 != 0 || ell.a3 != 0, error(" ellredgen: a1*a3 != 0")); ell[2] *= K; ell[4] *= K^2; ell[5] *= K^3; ell[6] *= K; ell[7] *= K^2; ell[8] *= K^3; ell[9] *= K^4; ell[10] *= K^2; ell[11] *= K^3; ell[12] *= K^6; sqrtK = sqrt(K); - ell[14] *= K; - ell[15] /= sqrtK; ell[16] /= sqrtK; - ell[17] *= sqrtK; ell[18] *= sqrtK; - ell[19] /= K; + if( #ell == 19, + ell[14] *= K; + ell[15] /= sqrtK; ell[16] /= sqrtK; + ell[17] *= sqrtK; ell[18] *= sqrtK; + ell[19] /= K + ); for( i = 1, d, for( j = 1, #listgen[i], listgen[i][j] *= K^j)) ); +if( d == 1, + urst = [1,0,0,0]; +, + if( #ell < 19, ell = ellinit(ell)); ell = ellminimalmodel(ell,&urst); listgen = ellchangepoint(listgen,urst); +if( DEBUGLEVEL_ell >= 5, print(" ell = ",ell)); +if( DEBUGLEVEL_ell >= 5, print(" listgen = ",listgen)); -\\ Recherche des relations entre les points de listgen -\\ par recherche du noyau de la matrice des hauteurs - - M = ellheightmatrix(ell,listgen); -if( DEBUGLEVEL_ell >= 4, print("matrice des hauteurs = ",M)); - M = round( M*10^(default(realprecision)-10) ); - U = qflll(M,4); - U = concat(U[1],U[2]); +\\ Looking for relations between the points in listgen +\\ using LLL on the height matrix - /* BEGIN patch to work with PARI 2.4.4 */ - /* AUTHORS: John Cremona, Jeroen Demeyer (Sage Trac #11130) */ + extra = 1; + while( extra, + M = ellheightmatrix(ell,listgen); +if( DEBUGLEVEL_ell >= 4, print(" height matrix = ",M)); + if( abs(matdet(M)) > 10^(-default(realprecision)+10),break); + U = qflll(round(M*10^(default(realprecision)-10)),4); + U = concat(U[1],U[2]); if( DEBUGLEVEL_ell >= 4, print(" change of basis proposed by LLL = ",U)); - \\ The columns of U that have very small coefficients (coeff < 20) - \\ are either exact relations or reductions. These are the ones we - \\ want to keep, the other ones are irrelevant. - keep = 0; - for( i = 1, d, - if( vecmax(abs(U[,i])) < 20, keep += 1<<(i-1)) - ); - U = vecextract(U, keep); - /* END patch from Sage Ticket #11130 to work with PARI 2.4.4 */ +\\ the columns of U that have very small coefficients +\\ are either exact relations or reductions (coeff <= 20) +\\ the other ones are irrelevant. + extra = 0; + for( i = 1, d, + if( vecmax(abs(U[,i])) > 20, extra += 1<<(i-1)) + ); + U = vecextract(U,1<= 4, print(" change of basis 1 = ",U)); - U = completebasis(U); -if( DEBUGLEVEL_ell >= 4, print("changement de base = ",U)); + listgen2 = vector(d); + for( i = 1, d, + listgen2[i] = [0]; + for( j = 1, d, + listgen2[i] = elladd(ell,listgen2[i],ellpow(ell,listgen[j],U[j,i])))); + listgen = listgen2; + ); - listgen2 = vector(d); - for( i = 1, d, - listgen2[i] = [0]; - for( j = 1, d, - listgen2[i] = elladd(ell,listgen2[i],ellpow(ell,listgen[j],U[j,i])))); - listgen = listgen2; +\\ Extracting the points of infinite order -\\ Tri des points d'ordre infini +\\ removing torsion points from listgen + listgen = ellremovetorsion(ell,listgen); + d = #listgen; + if( d == 0, return([])); + ); - listgen2 = []; - for( i = 1, d, - if( !ellorder(ell,listgen[i]), - listgen2 = concat(listgen2,[listgen[i]]))); - listgen = listgen2; -if( DEBUGLEVEL_ell >= 3, print("points d'ordre infini = ",listgen)); - d = #listgen; - if( d == 0, return([])); +if( DEBUGLEVEL_ell >= 3, print(" infinite order points = ",listgen)); -\\ Reduction des points d'ordre infini +\\ Now, the points should be of infinite order and independant +\\ Reducing the points of infinite order if( d > 1, M = ellheightmatrix(ell,listgen); -if( DEBUGLEVEL_ell >= 4, print("matrice des hauteurs = ",M)); +if( DEBUGLEVEL_ell >= 4, print(" height matrix = ",M)); U = qflllgram(M); -if( DEBUGLEVEL_ell >= 4, print("changement de base = ",U)); +if( DEBUGLEVEL_ell >= 4, print(" change of basis 2 = ",U)); listgen2 = vector(d); for( i = 1, d, listgen2[i] = [0]; for( j = 1, d, listgen2[i] = elladd(ell,listgen2[i],ellpow(ell,listgen[j],U[j,i])))); - listgen = listgen2 + listgen = listgen2; ); - listgen = ellsort(listgen); -if( DEBUGLEVEL_ell >= 4, print("generateurs tries = ",listgen)); +if( DEBUGLEVEL_ell >= 3, print(" infinite order points = ",listgen)); + + listgen = ellchangepoint(listgen,ellinverturst(urst)); + +\\ Reducing modulo the 2-torsion + + tors2 = elltorseven(ell0); + if( tors2[1] > 1, + vt = vector(tors2[2][1],j,ellpow(ell0,tors2[3][1],j-1)); + if( #tors2[2] == 2, + vt = concat(vt,vector(#vt,j,elladd(ell0,vt[j],tors2[3][2]))) + ); + for( i = 1, d, + listgen[i] = ellsort(vector(#vt,j,elladd(ell0,listgen[i],vt[j])))[1]; + ); + ); - listgen = ellchangepointinverse(listgen,urst); +if( DEBUGLEVEL_ell >= 3, print(" infinite order points = ",listgen)); + if( K != 1, for( i = 1, d, for( j = 1, 2, listgen[i][j] /= K^j))); -\\ on ne garde que les points (x,y) avec y >= 0 +\\ keep only the points (x,y) with y >= 0 - if( ell.a1 == 0 && ell.a3 == 0, + if( ell0.a1 == 0 && ell0.a3 == 0, for( i = 1, d, if( #listgen[i] == 2, listgen[i][2] = abs(listgen[i][2])))); -if( DEBUGLEVEL_ell >= 2, print("generateurs reduits = ",listgen)); +if( DEBUGLEVEL_ell >= 2, print(" reduced generators = ",listgen)); return(listgen); } -if( DEBUGLEVEL_ell >= 4, print("ell2descent_gen")); -{ -ell2descent_gen(ell,ext,K=1,help=[],redflag=0) = -\\ si ell= K*y^2=P(x), alors ext est le buchinitfu de l'extension. -\\ theta est une racine de P. -\\ dans la suite ext est note L = Q(theta). -\\ help est une liste de points deja connus sur ell. -\\ ell est de la forme K*y^2=x^3+A*x^2+B*x+C */ -\\ ie ell=[0,A,0,B,C], avec A,B et C entiers */ -\\ -\\ si redflag != 0, on utilise la reduction modulo les carres. -\\ -local(A,B,C,S,SLprod,SLlist,aux,oddclass,LS2gen,fact,trouve,i,polrel,ttheta,polprime,KS2gen,LS2genunit,normLS2gen,normcoord,LS2coordtilda,LS2,listgen,listpoints,listpointstriv,listpointsmwr,list,m1,m2,lastloc,maskwhile,iwhile,zc,j,iaux,liftzc,den,ispointtriv,point,found,idealfactorzc,idealzc,baseidealzc,q2,sol,q1,param,pol,redq,q0,pointxx,point2,v,rang); +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +\\ FUNCTIONS FOR NUMBER FIELDS \\ +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -if( DEBUGLEVEL_ell >= 4, print("entree dans ell2descent_gen")); +{reducemodsquares(delta,d) = +\\ Uses LLL to find z such that delta*z^2 has a small coefficient in x^d. +\\ delta must be a t_POLMOD +my(deg,xx,z,qd,Qd,reduc); -\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -\\ construction de L(S,2) \\ -\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ - - if( #ell < 13, ell = ellinit(ell,1)); - - if( ell.a1 != 0 || ell.a3 != 0, - error(" ell2descent_gen : la courbe n'est pas sous la forme [0,a,0,b,c]")); - if( denominator(ell.a2) > 1 || denominator(ell.a4) > 1 || denominator(ell.a6) >1, - error(" ell2descent_gen : coefficients non entiers")); + deg = poldegree(component(delta,1)); \\ deg = poldegree(delta.mod); + xx = Mod('x,component(delta,1)); \\ xx = Mod(x,delta.mod); + z = subst(Pol(vector(deg,i,eval(Str("a"i)))),'x,xx); + qd = polcoeff(lift(delta*z^2),d,'x); + Qd = simplify(matrix(deg,deg,i,j,deriv(deriv(qd,eval(Str("a"i))),eval(Str("a"j)))/2)); - A = ell.a2; if( DEBUGLEVEL_ell >= 2, print("A = ",A)); - B = ell.a4; if( DEBUGLEVEL_ell >= 2, print("B = ",B)); - C = ell.a6; if( DEBUGLEVEL_ell >= 2, print("C = ",C)); + reduc = qflllgram_indef(Qd); + if( #reduc == 2, reduc = reduc[2][,1]); - polrel = Pol([1,A,B,C]); - if( !ext, -if( DEBUGLEVEL_ell >= 2, print("bnfinit(",polrel,")")); - ext = bnfinit(polrel,1)); - - S = -abs(K*ext.index); - SLprod = idealmul(ext,K,idealadd(ext,ext.pol',ext.index)); - SLlist = idealfactor(ext,SLprod)[,1]~; - aux = []; SLprod = 1; - for( i = 1, #SLlist, - if( !(K%SLlist[i][1]) || valuation(ext.index,SLlist[i][1]), - SLprod = idealmul(ext,SLprod,SLlist[i]); - aux = concat(aux,[SLlist[i]]))); - SLlist = aux; - oddclass = 0; + return(delta*subst(Pol(reduc),'x,xx)^2); +} +{bnfpSelmer(bnf,S=1,p) = +\\ p is a prime integer and bnf a big number field. +\\ Compute the p-Selmer group of the number field bnf +\\ relative to the prime ideals dividing S. +\\ This group is denoted by LS2 in the sequel. +\\ Returns [gen,S'] where gen is a vector containing the generators +\\ of the p-Selmer group, represented has elements of bnf modulo p-powers, +\\ and S' is the support of gen. +my(S1,oddclass,multS,Slist,LS2gen,newprimes,newprimesval,kerval); + +if( DEBUGLEVEL_ell >= 3, print(" Constructing the field Selmer group: L(S,",p,")")); + S1 = idealhnf(bnf,S); + + oddclass = 0; multS = 1; while( !oddclass, -\\ Constructoin de S: -if( DEBUGLEVEL_ell >= 4, print("SLlist = ",SLlist)); -\\ Construction des S-unites - LS2gen = bnfsunit(ext,SLlist); -if( DEBUGLEVEL_ell >= 4, print("LS2gen = ",LS2gen)); -\\ on ajoute la partie paire du groupe de classes. - oddclass = LS2gen[5][1]%2; + if( multS != 1, S1 = idealmul(bnf,S1,multS)); + Slist = idealfactor(bnf,S1)[,1]~; +if( DEBUGLEVEL_ell >= 4, print(" constructing the S-units ")); +if( DEBUGLEVEL_ell >= 4, print(" S1 = ",Slist)); + LS2gen = bnfsunit(bnf,Slist); + +\\ If the class group is divisible by p, +\\ need to enlarge S1. + oddclass = LS2gen[5].no % p; if( !oddclass, -if( DEBUGLEVEL_ell >= 3, print("Groupe de classes pair")); -if( DEBUGLEVEL_ell >= 4, print(LS2gen[5])); - S *= LS2gen[5][3][1][1,1]; - SLprod = idealmul(ext,SLprod,LS2gen[5][3][1]); - fact = idealfactor(ext,LS2gen[5][3][1])[,1]; - trouve = 0; i = 0; - while( !trouve, - i++; trouve = 1; - for( j = 1, #SLlist, - if( SLlist[j] == fact[i], trouve = 0; break))); - SLlist = concat(SLlist,[fact[i]])) +if( DEBUGLEVEL_ell >= 4, print(" class group divisible by p = ",LS2gen[5].no)); + multS = idealmul(bnf,S,LS2gen[5].gen[1]); + ) + ); + LS2gen = Mod(LS2gen[1],bnf.pol); + +\\ The valuation of the generators must be divisible by p outside S. + newprimes = []; + for( i = 1, #Slist, + if( idealadd(bnf,S,Slist[i]) == 1, + newprimes = concat(newprimes,[Slist[i]]))); +if( DEBUGLEVEL_ell >= 4, print(" newprimes = ",newprimes)); + newprimesval = matrix(#newprimes,#LS2gen,i,j, + idealval(bnf,LS2gen[j],newprimes[i])); +if( DEBUGLEVEL_ell >= 4, print(" newprimesval = ",newprimesval)); + kerval = lift(matker(newprimesval*Mod(1,p))); +if( DEBUGLEVEL_ell >= 4, print(" kerval = ",kerval)); + LS2gen = vector(#kerval,i, + prod( j = 1, #LS2gen, + LS2gen[j]^kerval[j,i])); + +\\ Add the units + LS2gen = concat(Mod(bnf[8][5],bnf.pol),LS2gen); \\ LS2gen = concat(bnf.fu,LS2gen); +\\ Add also the torsion unit if its order is divisible by p. + if( bnf[8][4][1]%p == 0, \\ if( bnf.tu[1]%p == 0, + LS2gen = concat( [Mod(bnf[8][4][2],bnf.pol)], LS2gen)); \\ LS2gen = concat( [Mod(bnf.tu[2],bnf.pol)], LS2gen)); +if( DEBUGLEVEL_ell >= 3, print(" #LS2gen = ",#LS2gen)); +if( DEBUGLEVEL_ell >= 4, print(" LS2gen = ",LS2gen)); + return([LS2gen,Slist]); +} +{kersign(gen,rootapprox) = +\\ Determine the kernel of the sign map +\\ restricted to the subgroup generated by gen, +\\ and relative to the real embedding corresponding to +\\ the root of pol contained in the interval rootapprox. +my(signs,elt,elt2,d,st,kers,compt); + +if( DEBUGLEVEL_ell >= 3, print(" Computing the kernel of the sign ",rootapprox)); + +\\ determination of the signs + + signs = vector(#gen); + for( i = 1, #gen, + elt = lift(gen[i]); +if( DEBUGLEVEL_ell >= 5, print(" Computing the sign of elt = ",elt)); + if( poldegree(elt) == 0, signs[i] = sign(simplify(elt)) < 0; next); + d = poldisc(elt); + if( poldegree(elt) == 2, + if( d <= 0, signs[i] = sign(pollead(elt)) < 0; next)); + elt2 = if( d == 0, elt/gcd(elt,elt'), elt); + st = 1; + compt = 0; + while( st, + st = polsturm(elt2,rootapprox[1],rootapprox[2]); + if( st, + rootapprox = polrealrootsimprove(component(gen[i],1),rootapprox); +\\ rootapprox = polrealrootsimprove(gen[i].mod,rootapprox); +\\ if the sign of elt is too difficult to determine, +\\ try a reduction modulo squares + if( compt++ == 5, gen[i] = reducemodsquares(gen[i]); i--; next(2)); +\\ if the sign of elt is still too difficult to determine, +\\ try the sign of 1/elt. + if( compt%5 == 0, gen[i] = 1/gen[i]; i--; next(2)) + )); + signs[i] = sign(subst(elt,variable(elt),rootapprox[2])) < 0 ); +if( DEBUGLEVEL_ell >= 4, print(" signs = ",signs)); -if( DEBUGLEVEL_ell >= 4, print("S = ",S)); +\\ construction of the kernel + kers = matker(Mat(signs*Mod(1,2)))*Mod(1,2); +if( DEBUGLEVEL_ell >= 4, print(" kers = ",lift(kers))); + return(kers); +} +{kernorm(gen,S,p) = +\\ gen is a generating set for a subgroup of K^* / K^p. +\\ Compute the kernel of the norm map. +\\ Uses the fact that all valuations are 0 mod p, +\\ except maybe at primes in S. +my(normgen,normmap,kern); + +if( DEBUGLEVEL_ell >= 3, print(" Computing the kernel of the norm map")); + + if( p == 2, S = concat([-1],S)); + normgen = norm(gen); +if( DEBUGLEVEL_ell >= 4, print(" normgen = ",normgen)); + +\\ matrix of the norm map + normmap = matrix(#S,#normgen,i,j, + if( i == 1 && p == 2, + sign(normgen[j]) < 0 + , valuation(normgen[j],S[i]))); +if( DEBUGLEVEL_ell >= 4, print(" normmap = ",normmap)); + +\\ construction of the kernel + kern = matker(normmap*Mod(1,p))*Mod(1,p); +if( DEBUGLEVEL_ell >= 4, print(" ker = ",lift(kern))); + return(kern); +} - ttheta = Mod(x,polrel); \\ ttheta est la racine de P(x) - polprime = Mod(polrel',polrel); +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +\\ FUNCTIONS FOR 2-DESCENT \\ +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + +{elllocalimage( nf, pp, K = 1) = +\\ pol is the cubic polynomial defining the elliptic curve, +\\ nf is nfinit(pol), +\\ p is a prime integer, and pp = ppinit(p). +\\ Returns the image of the p-adic points +\\ E(Qp)/2E(Qp) in Kp/Kp^2. +\\ The algorithm consists of choosing random p-adic points in E(Qp) +\\ until the number of images is equal to #E(Qp)[2] / |2|_p +my(X,p,prank,rac,pts,bound,essai,mrank,r,xx,delta,ph,delta2,localprec,ival); + +if( DEBUGLEVEL_ell >= 4, print(" starting elllocalimage")); + + X = Mod('x,nf.pol); + p = pp[1][1][1]; + prank = #pp - (p != 2); +if( DEBUGLEVEL_ell >= 4, print(" prank = ",prank)); + + rac = polrootsmodpn(K*nf.pol,p); +if( DEBUGLEVEL_ell >= 5, print(" rac = ",rac)); + + pts = matrix(0,0); + bound = p+6; + essai = 0; + mrank = 0; + while( mrank < prank, + + essai ++; + if( essai%16 == 0, + pts = matimage(pts); + bound *= p; + ); - KS2gen = factor(S)[,1]~; + r = random(#rac)+1; localprec = random(rac[r][2]+3)-2; + xx = rac[r][1]+p^localprec*random(bound); +if( DEBUGLEVEL_ell >= 5, print(" xx = ",xx)); + delta = K*(xx-X); + +\\ rem: K*pol(xx) = norm(delta) ( = y^2 for a point on the elliptic curve) + if( !psquare(K*subst(nf.pol,'x,xx),p), next); + ph = []; + for( i = 1, #pp, + ph = concat(ph,[ ival = idealval(nf,delta,pp[i][1])]); + delta2 = delta/pp[i][2]^ival; + if( p == 2, + ph = concat(ph,ideallog(nf,delta2,pp[i][3])~); + , ph = concat(ph,[1-nfpsquareodd(nf,delta2,pp[i][4])]) + ) + ); +if( DEBUGLEVEL_ell >= 5, print(" ph = ",ph)); -if( DEBUGLEVEL_ell >= 3, print("#KS2gen = ",#KS2gen)); -if( DEBUGLEVEL_ell >= 3, print("KS2gen = ",KS2gen)); + pts = concat(pts,ph~*Mod(1,2)); + mrank = matrank(pts*Mod(1,2)); +if( DEBUGLEVEL_ell >= 5, print(" pts = ",lift(pts))); +if( DEBUGLEVEL_ell >= 5, print(" matrank = ",mrank)); + ); - LS2genunit = ext.tufu; - LS2genunit = concat(LS2gen[1],LS2genunit); + pts = matimage(pts); +if( DEBUGLEVEL_ell >= 5, print(" essai = ",essai)); +if( DEBUGLEVEL_ell >= 4, print(" end of elllocalimage")); + return(pts); +} +{ell2descent_gen(ell,bnf,K=1,help=[],redflag=0) = +\\ This algorithm performs 2-descent on the elliptic curve ell +\\ when ell has trivial 2-torsion. - LS2genunit = subst(LS2genunit,x,ttheta); - LS2genunit = LS2genunit*Mod(1,polrel); -if( DEBUGLEVEL_ell >= 3, print("#LS2genunit = ",#LS2genunit)); -if( DEBUGLEVEL_ell >= 3, print("LS2genunit = ",LS2genunit)); +\\ ell must be of the form K*y^2=x^3+A*x^2+B*x+C +\\ ie ell=[0,A,0,B,C], with K,A,B,C integers. +\\ bnf is bnfinit(x^3+A*x^2+B*x+C,1). -\\ dans LS2gen, on ne garde que ceux dont la norme -\\ est un carre. +\\ +\\ help is a list of known points (maybe empty) on ell. +\\ if redflag != 0, reduces the elements +\\ of the field Selmer group modulo squares. - normLS2gen = norm(LS2genunit); -if( DEBUGLEVEL_ell >= 4, print("normLS2gen = ",normLS2gen)); +my(A,B,C,polrel,polprime,ttheta,badprimes,S,LS2,selmer,rootapprox,p,pp,locimage,LS2image,listpointstriv,listpoints,iwhile,expo,zc,liftzc,den,point,idealfactorzc,idealzc,baseidealzc,q2,sol,param,q1,pol,redq,q0,pointxx,point2,rang); -\\ matrice de l'application norme +if( DEBUGLEVEL_ell >= 4, print(" starting ell2descent_gen")); - normcoord = matrix(#KS2gen,#normLS2gen); - for( j = 1, #normLS2gen, - normcoord[1,j] = (sign(normLS2gen[j]) < 0); - for( i = 2, #KS2gen, - normcoord[i,j] = valuation(normLS2gen[j],KS2gen[i]))); -if( DEBUGLEVEL_ell >= 4, print("normcoord = ",normcoord)); + if( #ell < 13, ell = ellinit(ell,1)); -\\ construction du noyau de la norme + if( ell.a1 != 0 || ell.a3 != 0, + error(" ell2descent_gen: the curve is not of the form [0,a,0,b,c]")); + if( denominator(ell.a2) > 1 || denominator(ell.a4) > 1 || denominator(ell.a6) >1, + error(" ell2descent_gen: non integral coefficients")); - LS2coordtilda = lift(matker(normcoord*Mod(1,2))); -if( DEBUGLEVEL_ell >= 4, print("LS2coordtilda = ",LS2coordtilda)); - LS2 = vector(#LS2coordtilda[1,],i,0); - for( i = 1, #LS2coordtilda[1,], - aux = 1; - for( j = 1, #LS2coordtilda[,i], - if( sign(LS2coordtilda[j,i]), - aux *= LS2genunit[j])); - LS2[i] = aux - ); -if( DEBUGLEVEL_ell >= 3, print("LS2 = ",LS2)); -if( DEBUGLEVEL_ell >= 3, print("norm(LS2) = ",norm(LS2))); + A = ell.a2; if( DEBUGLEVEL_ell >= 2, print(" A = ",A)); + B = ell.a4; if( DEBUGLEVEL_ell >= 2, print(" B = ",B)); + C = ell.a6; if( DEBUGLEVEL_ell >= 2, print(" C = ",C)); + +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +\\ Construction of L(S,2) \\ +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -\\ Reduction des generateurs de LS2 +if( DEBUGLEVEL_ell >= 2, print(); print(" Computing L(S,2)")); - if( redflag, - for( i = 1, #LS2, - LS2[i] = reducemodsquares(LS2[i],2))); + polrel = Pol([1,A,B,C]); + polprime = polrel'; + ttheta = Mod('x,polrel); -\\ Fin de la construction de LS2 + if( !bnf, +if( DEBUGLEVEL_ell >= 3, print(" bnfinit(",polrel,")")); + bnf = bnfinit(polrel,1)); - listgen = LS2; -if( DEBUGLEVEL_ell >= 2, print("LS2gen = ",listgen)); -if( DEBUGLEVEL_ell >= 2, print("#LS2gen = ",#listgen)); - listpoints = []; + badprimes = abs(K*idealadd(bnf,polprime,bnf.index)); +if( DEBUGLEVEL_ell >= 5, print(" badprimes = ",badprimes[1,1])); + S = bnfpSelmer(bnf,badprimes,2); + LS2 = S[1]; S = S[2]; -if( DEBUGLEVEL_ell >= 3, print("(A,B,C) = ",[A,B,C])); +if( DEBUGLEVEL_ell >= 2, print(" L(S,2) = ",LS2)); + +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +\\ Construction of the Selmer group \\ +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + +if( DEBUGLEVEL_ell >= 2, print(); print(" Computing the Selmer group")); + +\\ elements with square norm + selmer = kernorm(LS2,vector(#S,i,S[i].p),2); +if( DEBUGLEVEL_ell >= 3, print(" selmer = ",lift(selmer))); + +\\ the first real embedding must be > 0 +\\ since the norm is a square, this is automatic +\\ if there is a single real embedding. + if( bnf.r1 == 3, + rootapprox = polrealrootsisolate(polrel)[1]; + selmer = matintersect(selmer,kersign(LS2,rootapprox))*Mod(1,2); +if( DEBUGLEVEL_ell >= 3, print(" selmer = ",lift(selmer))); + ); + +\\ p-adic points +if( DEBUGLEVEL_ell >= 3, print(" p-adic points")); + badprimes = factorint(badprimes[1,1]*2)[,1]; +if( DEBUGLEVEL_ell >= 2, print(" badprimes = ",badprimes)); + for( i = 1, #badprimes, + p = badprimes[i]; +if( DEBUGLEVEL_ell >= 4, print(" p = ",p)); + pp = ppinit(bnf.nf,p); + locimage = elllocalimage(bnf.nf,pp,K); + LS2image = LS2localimage(bnf.nf,LS2,pp); + locimage = matintersect(LS2image,locimage); + selmer = matintersect( + selmer, + concat( + matker(LS2image), + matinverseimage(LS2image,locimage)*Mod(1,2))); + selmer = matimage(selmer*Mod(1,2)); +if( DEBUGLEVEL_ell >= 4, print(" selmer = ",lift(selmer))); + if( !#selmer, break); + ); + +if( DEBUGLEVEL_ell >= 2, print(" selmer = ",lift(selmer))); +if( DEBUGLEVEL_ell >= 2, print(" Selmer rank = ",#selmer)); \\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -\\ Recherche de points triviaux. \\ +\\ Search for trivial points \\ \\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -if( DEBUGLEVEL_ell >= 2, print("Recherche de points triviaux sur la courbe")); - listpointstriv = ratpoint(K^3*subst(polrel,x,x/K),LIMTRIV,0,0); - for( i = 1, #listpointstriv, - if( #listpointstriv[i] == 3, - listpointstriv[i] = [0] - , for( j = 1, 2, listpointstriv[i][j] /= K^j)) - ); - listpointstriv = concat(help,listpointstriv); -if( DEBUGLEVEL_ell >= 1, print("Points triviaux sur la courbe = ",listpointstriv)); - - -\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -\\ parcours de L(S,2) \\ -\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ - - listpointsmwr = []; - list = [ 6, ell.disc, 0 ]; - m1 = 0; m2 = 0; lastloc = -1; - maskwhile = 1<<#listgen; + if( #selmer, +if( DEBUGLEVEL_ell >= 2, print(); print(" Search for trivial points on the curve")); + listpointstriv = ratpoint(K^3*subst(polrel,'x,'x/K),LIMTRIV,0); + for( i = 1, #listpointstriv, + if( #listpointstriv[i] == 3, + listpointstriv[i] = [0] + , for( j = 1, 2, listpointstriv[i][j] /= K^j)) + ); + listpointstriv = concat(help,listpointstriv); +if( DEBUGLEVEL_ell >= 2, print(" Trivial points on the curve = ",listpointstriv)); + ); + +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +\\ Run through the Selmer group \\ +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + +if( DEBUGLEVEL_ell >= 2, print(); print(" Run through the Selmer group")); + + listpoints = []; + selmer = lift(selmer); iwhile = 1; - while( iwhile < maskwhile, -if( DEBUGLEVEL_ell >= 4, print("iwhile = ",iwhile); print("listgen = ",listgen)); - zc = Mod(1,polrel); j = 1; iaux = iwhile; - while( iaux, - if( iaux%2, zc *= listgen[j]); - iaux >>= 1; j++); -if( DEBUGLEVEL_ell >= 2, print(); print("zc = ",zc)); + while( iwhile < 1<<#selmer, +if( DEBUGLEVEL_ell >= 2, print()); +if( DEBUGLEVEL_ell >= 4, print(" iwhile = ",iwhile)); + +\\ the next element zc as an algebraic number modulo squares + + expo = selmer*vectorv(#selmer,i,bittest(iwhile,i-1)); + zc = prod( i = 1, #LS2, LS2[i]^expo[i]); +if( DEBUGLEVEL_ell >= 2, print(" zc = ",zc)); liftzc = lift(zc); - if( redflag, + +\\ Reduction modulo squares + + if( redflag, zc = reducemodsquares(zc,2); liftzc = lift(zc); den = denominator(content(liftzc))^2; zc *= den; liftzc *= den; -if( DEBUGLEVEL_ell >= 2, print("zcred = ",zc)) +if( DEBUGLEVEL_ell >= 2, print(" zc reduced = ",zc)) ); -\\ Est-ce un point trivial ? - ispointtriv = 0; +\\ Does it come from a trivial point ? + for( i = 1, #listpointstriv, point = listpointstriv[i]; if( #point == 2, - if( nfissquare(ext.nf,K*(point[1]-x)*liftzc), -if( DEBUGLEVEL_ell >= 2, print(" vient du point trivial ",point)); - listpointsmwr = concat(listpointsmwr,[point]); - m1++; - if( degre(iwhile) > lastloc, m2++); - found = (ispointtriv = 1); - break + if( nfissquare(bnf.nf,K*(point[1]-'x)*liftzc), +if( DEBUGLEVEL_ell >= 2, print(" comes from the trivial point ",point)); + listpoints = concat(listpoints,[point]); + iwhile = 1 << (degre(iwhile)+1); + next(2) ))); - -\\ Ce n'est pas un point trivial - if( !ispointtriv, -\\ Il faut resoudre une forme quadratique -\\ q2 = matrix(3,3,i,j,trace(zc*ttheta^(i+j-2)/polprime)); -\\if( DEBUGLEVEL_ell >= 4, print("q2 = ",q2)); - idealfactorzc = idealfactor(ext,zc); - idealfactorzc[,2] *= -1; - idealfactorzc[,2] \= 2; - idealzc = idealfactorback(ext,idealfactorzc); - if( idealzc == 1, idealzc = matid(3)); - baseidealzc = vector(3,i,nfbasistoalg(ext,idealzc[,i])); - q2 = matrix(3,3,i,j,trace(zc*baseidealzc[i]*baseidealzc[j]/polprime)); -if( DEBUGLEVEL_ell >= 4, print("q2 = ",q2)); -\\ q2 *= ext.index; -\\ if( DEBUGLEVEL_ell >= 4, print("q2 = ",q2)); -if( DEBUGLEVEL_ell >= 4, print("q2/content(q2) = ",q2/content(q2))); - sol = Qfsolve(q2/content(q2)); -if( DEBUGLEVEL_ell >= 4,print("sol = ",sol)); - if( type(sol) == "t_INT", -if( DEBUGLEVEL_ell >= 3, print("non ELS en ",sol)); - iwhile++; next - ); - -\\ \\\\\\\\\\\ -\\ Construction de la quartique -\\ \\\\\\\\\\\ - q1 = -matrix(3,3,i,j,trace(zc*baseidealzc[i]*baseidealzc[j]*(ttheta+A)/polprime)); - param = Qfparam(q2,sol)*[x^2,x,1]~; - param /= content(param); - pol = param~*q1*param; -if( DEBUGLEVEL_ell >= 2, print(" quartique: ",K,"*Y^2 = ",pol)); - redq = redquartique(pol); -if( DEBUGLEVEL_ell >= 2, print(" reduite: ",K,"*Y^2 = ",redq[1])); - pol = redq[1]; - den = denominator(content(K*pol)); - pol *= den^2; - -\\ \\\\\\\\\\\ -\\ Recherche de points sur la quartique -\\ \\\\\\\\\\\ - - point = ratpoint(K*pol,LIM1,1,0); - if( point != [], - m1++; - if( #point == 2, point = concat(point,[1])); - point = concat(redq[2]*[point[1],point[3]]~,[point[2]/den]~); - param = subst(param,x,x/y)*y^2; - param = subst(subst(param,x,point[1]),y,point[2]); -if( DEBUGLEVEL_ell >= 2, print(" point sur la quartique = ",point)); - param *= K/point[3]; -if( DEBUGLEVEL_ell >= 3, print("reconstruction du point sur la courbe")); - q0 = matrix(3,3,i,j,trace(zc*baseidealzc[i]*baseidealzc[j]*(ttheta^2+A*ttheta+B)/polprime)); - pointxx = param~*q0*param/K; - point2 = [ pointxx, sqrtrat(subst(x^3+A*x^2+B*x+C,x,pointxx)/K)]; -if( DEBUGLEVEL_ell >= 1, print("point sur la courbe = ",point2)); - listpointsmwr = concat(listpointsmwr,[point2]); - if( degre(iwhile) > lastloc, m2++); - found = 1 - , - if( locallysoluble(K*pol), - if( degre(iwhile) > lastloc, m2++; lastloc = degre(iwhile)); - point = ratpoint(K*pol,LIM3,1,1); - if( #point > 0, - m1++; - if( #point == 2, point = concat(point,[1])); - point = concat(redq[2]*[point[1],point[3]]~,[point[2]/den]~); - param = subst(param,x,x/y)*y^2; - param = subst(subst(param,x,point[1]),y,point[2]); -if( DEBUGLEVEL_ell >= 3, print(" point sur la quartique = ",point)); - param *= K/point[3]; -if( DEBUGLEVEL_ell >= 3, print("reconstruction du point sur la courbe")); - q0 = matrix(3,3,i,j,trace(zc*baseidealzc[i]*baseidealzc[j]*(ttheta^2+A*ttheta+B)/polprime)); - pointxx = param~*q0*param/K; - point2 = [ pointxx, sqrtrat(subst(x^3+A*x^2+B*x+C,x,pointxx)/K)]; -if( DEBUGLEVEL_ell >= 1, print("point sur la courbe = ",point2)); - listpointsmwr = concat(listpointsmwr,[point2]); - found = 1 - ) - ) - ) + +if( DEBUGLEVEL_ell >= 2, print(" does not come from a trivial point")); + +\\ Construction of the quadratic form q2 +\\ Change the basis using the square factors of zc + + idealfactorzc = idealfactor(bnf,zc); + idealfactorzc[,2] *= -1; + idealfactorzc[,2] \= 2; +\\ idealzc = idealfactorback(bnf,idealfactorzc); + idealzc = matid(3); + for( i = 1, #idealfactorzc[,1], + idealzc = idealmul(bnf,idealzc,idealpow(bnf,idealfactorzc[i,1],idealfactorzc[i,2])); ); - if( found || ispointtriv, - found = 0; lastloc = -1; - v = 0; iaux = (iwhile>>1); - while( iaux, iaux >>= 1; v++); - maskwhile >>= 1; - listgen = vecextract(listgen,1<<#listgen-1<= 4, print(" q2 = ",q2)); +if( DEBUGLEVEL_ell >= 4, print(" q2/content(q2) = ",q2/content(q2))); + +\\ Solution of the quadratic equation q2=0 + + sol = qfsolve(q2/content(q2)); +if( DEBUGLEVEL_ell >= 4,print(" sol = ",sol)); + if( type(sol) == "t_INT", + error(" ell2descent_gen: WRONG ELEMENT IN THE SELMER GROUP, please report")); + + +\\ Parametrizing the solutions of q2=0 + + param = qfparam(q2,sol)*['x^2,'x,1]~; + param /= content(param); + +\\ Construction of the quartic + + q1 = -matrix(3,3,i,j,trace(zc*baseidealzc[i]*baseidealzc[j]*(ttheta+A)/polprime)); + pol = param~*q1*param; +if( DEBUGLEVEL_ell >= 2, print(" quartic: ",K,"*Y^2 = ",pol)); + redq = redquartic(pol); + pol = redq[1]; + den = denominator(content(K*pol)); + pol *= den^2; +if( DEBUGLEVEL_ell >= 2, print(" reduced: ",K,"*Y^2 = ",pol)); + +\\ Search for points on the quartic + + point = ratpoint(K*pol,LIM1,1); + if( point == [], point = ratpoint2(K*pol,LIM3,1)); + if( point == [], iwhile ++; next ); + + if( #point == 2, point = concat(point,[1])); +if( DEBUGLEVEL_ell >= 2, print(" point on the reduced quartic = ",point)); + point = concat(redq[2]*[point[1],point[3]]~,[point[2]/den]~); +if( DEBUGLEVEL_ell >= 2, print(" point on the quartic = ",point)); + +\\ Construction of the point on the elliptic curve from the point on the quartic + + param = subst(param,'x,'x/'y)*'y^2; + param = subst(subst(param,'x,point[1]),'y,point[2]); + param *= K/point[3]; +if( DEBUGLEVEL_ell >= 3, print(" reconstruction of the point on the curve")); + q0 = matrix(3,3,i,j,trace(zc*baseidealzc[i]*baseidealzc[j]*(ttheta^2+A*ttheta+B)/polprime)); + pointxx = param~*q0*param/K; + point2 = [ pointxx, sqrtrat(subst(polrel,'x,pointxx)/K)]; +if( DEBUGLEVEL_ell >= 1, print(" point on the curve = ",point2)); + listpoints = concat(listpoints,[point2]); + iwhile = 1 << (degre(iwhile)+1) ); +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +\\ Conclusion report \\ +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + + rang = #listpoints; + if( DEBUGLEVEL_ell >= 2, print(); - print("rang des points trouves = ",m1); - print("rang du groupe de Selmer = ",m2)); -if( DEBUGLEVEL_ell >= 1, - print("#S(E/Q)[2] = ",1<= 1, - print("#E(Q)/2E(Q) = ",1<= 1, print("listpoints = ",listpoints)); + for( i = 1, #listpoints, + if( subst(polrel,'x,listpoints[i][1])-K*listpoints[i][2]^2, + error(" ell2descent_gen: WRONG POINT = ",listpoints[i]," please report"))); + +\\ Reduction of the points + + listpoints = vecsort(listpoints,,2); + if( #listpoints >= 2 && ELLREDGENFLAG, + listpoints = ellredgen(ell,listpoints,K)); + +if( DEBUGLEVEL_ell >= 4, print(" end of ell2descent_gen")); + return([rang,#selmer,listpoints]); +} +{afficheselmer(m1,m2,tors2) = + + print("#E(Q)[2] = ",1<= ",1<= ",m1)); - rang = m1; - if( (m2-m1)%2, -if( DEBUGLEVEL_ell >= 1, - print(" III devrait etre un carre, donc "); - if( m2-m1 > 1, - print("#E(Q)/2E(Q) >= ",1<<(m1+1)); - print("#III(E/Q)[2] <= ",1<<(m2-m1-1)); - print("rang(E/Q) >= ",m1+1) - , - print("#E(Q)/2E(Q) = ",1<<(m1+1)); - print("#III(E/Q)[2] = 1"); - print("rang(E/Q) = ",m1+1))); - rang = m1+1 - ) + print("#E(Q)/2E(Q) >= ",1<<(m1+tors2)); + print("#III(E/Q)[2] <= ",1<<(m2-m1-tors2)); + print("rank(E/Q) >= ",m1) ); -if( DEBUGLEVEL_ell >= 1, print("listpointsmwr = ",listpointsmwr)); - for( i = 1, #listpointsmwr, - if( subst(polrel,x,listpointsmwr[i][1])-K*listpointsmwr[i][2]^2, - error(" ell2descent_gen : MAUVAIS POINT = ",listpointsmwr[i]))); - if( #listpointsmwr >= 2, - listpointsmwr = ellredgen(ell,listpointsmwr,K)); -if( DEBUGLEVEL_ell >= 4, print("fin de ell2descent_gen")); - return([rang,m2,listpointsmwr]); } -if( DEBUGLEVEL_ell >= 4, print("ellrank")); -{ -ellrank(ell,help=[]) = -\\ Algorithme de la 2-descente sur la courbe elliptique ell. -\\ help est une liste de points connus sur ell. -local(urst,urst1,den,eqell,tors2,bnf,rang,time1); +{ellrank(ell,help=[]) = +\\ Algorithm of 2-descent on the elliptic curve ell. +\\ help is a list of known points on ell. +my(urst,urst1,den,eqell,tors2,bnf,rang,time1); -if( DEBUGLEVEL_ell >= 3, print("entree dans ellrank")); +if( DEBUGLEVEL_ell >= 3, print(" starting ellrank")); if( #ell < 13, ell = ellinit(ell,1)); -\\ supprime les coefficients a1 et a3 +\\ kill the coefficients a1 and a3 urst = [1,0,0,0]; if( ell.a1 != 0 || ell.a3 != 0, urst1 = [1,0,-ell.a1/2,-ell.a3/2]; @@ -1160,7 +1589,7 @@ if( DEBUGLEVEL_ell >= 3, print("entree dans ellrank")); urst = ellcomposeurst(urst,urst1) ); -\\ supprime les denominateurs +\\ kill denominators while( (den = denominator([ell.a2,ell.a4,ell.a6])) > 1, den = factor(den); den[,2] = vectorv(#den[,2],i,1); den = factorback(den); @@ -1171,159 +1600,193 @@ if( DEBUGLEVEL_ell >= 3, print("entree dans ellrank")); help = ellchangepoint(help,urst); eqell = Pol([1,ell.a2,ell.a4,ell.a6]); -if( DEBUGLEVEL_ell >= 1, print("courbe elliptique : Y^2 = ",eqell)); +if( DEBUGLEVEL_ell >= 1, print(" Elliptic curve: Y^2 = ",eqell)); -\\ choix de l'algorithme suivant la 2-torsion +\\ Choice of the algorithm depending on the 2-torsion structure tors2 = ellhalf(ell,[0]); -if( DEBUGLEVEL_ell >= 1, print("E[2] = ",tors2)); +if( DEBUGLEVEL_ell >= 1, print(" E[2] = ",tors2)); - if( #tors2 == 1, \\ cas 1: 2-torsion triviale -if( DEBUGLEVEL_ell >= 3, print1("bnfinit ")); + if( #tors2 == 1, \\ case 1: 2-torsion trivial +if( DEBUGLEVEL_ell >= 3, print1(" bnfinit(",eqell,")")); if( DEBUGLEVEL_ell >= 4, gettime()); bnf = bnfinit(eqell,1); if( DEBUGLEVEL_ell >= 4, time1 = gettime()); -if( DEBUGLEVEL_ell >= 3, print("ok")); +if( DEBUGLEVEL_ell >= 3, print(" done")); rang = ell2descent_gen(ell,bnf,1,help); -if( DEBUGLEVEL_ell >= 4, print("temps dans bnfinit = ",time1)); -if( DEBUGLEVEL_ell >= 4, print("temps pour le reste = ",gettime())); +if( DEBUGLEVEL_ell >= 4, print(" time for bnfinit = ",time1)); +if( DEBUGLEVEL_ell >= 4, print(" time for the rest = ",gettime())); , - if( #tors2 >= 2, \\ cas 2: 2-torsion >= Z/2Z + if( #tors2 == 2 || !COMPLETE, \\ case 2: 2-torsion >= Z/2Z if( ell.a6 != 0, urst1 = [1,tors2[2][1],0,0]; ell = ellchangecurve(ell,urst1); urst = ellcomposeurst(urst,urst1) ); eqell = Pol([1,ell.a2,ell.a4,ell.a6]); -if( DEBUGLEVEL_ell >= 1, print("courbe elliptique : Y^2 = ",eqell)); +if( DEBUGLEVEL_ell >= 1, print(" Elliptic curve: Y^2 = ",eqell)); rang = ell2descent_viaisog(ell,help) - , \\ cas 3: 2-torsion = Z/2Z*Z/2Z -\\ rang = ell2descent_complete(tors2[2][1],tors2[3][2],tors2[4][3]) + , \\ case 3: 2-torsion = Z/2Z*Z/2Z + rang = ell2descent_complete(tors2[2][1],tors2[3][1],tors2[4][1]) )); - rang[3] = ellchangepointinverse(rang[3],urst); -if( DEBUGLEVEL_ell >= 3, print("fin de ellrank")); + rang[3] = ellchangepoint(rang[3],ellinverturst(urst)); +if( DEBUGLEVEL_ell >= 3, print(" end of ellrank")); -return(rang); + return(rang); } -if( DEBUGLEVEL_ell >= 4, print("ell2descent_complete")); -{ -ell2descent_complete(e1,e2,e3) = -\\ calcul du rang d'une courbe elliptique -\\ par la methode de 2-descente complete. -\\ Y^2 = (x-e1)*(x-e2)*(x-e3); -\\ en suivant la methode decrite par J.Silverman -\\ renvoie [r,s,v] avec -\\ r est une borne inferieure du rang de E(Q) -\\ s est le rang du 2-groupe de Selmer -\\ v est un systeme de points independants dans E(Q)/2E(Q) +{ell2descent_complete(e1,e2,e3,help) = +\\ Compute the rank of the elliptic curve +\\ E: Y^2 = (x-e1)*(x-e2)*(x-e3) +\\ using the complete 2-descent algorithm (see J.Silverman). +\\ Returns [r,s,v] with +\\ r is a lower bound for the rank of E(Q) +\\ s is the rank of Selmer[2] +\\ v is a system of independant points on E(Q)/2E(Q) -\\ e1, e2 et e3 sont des entiers. +\\ e1, e2, e3 must be integers. +\\ help is a list of known points on E. -local(d32,d31,d21,G1,G2,vect1,vect2,selmer,rang,listepoints,b1,b2,q1,q2,sol1,param1,param1x,sol2,quart,point,z1,solx,soly,strange); +my(ee,d32,d31,d21,G1,G2,G3,vect1,vect2,vect3,selmer,rang,listpoints,b1,b2,q1,sol1,param1,param1x,quart,point,z1,solx,soly,strange,ell); -if( DEBUGLEVEL_ell >= 2, print("Algorithme de la 2-descente complete")); +if( DEBUGLEVEL_ell >= 2, print(" Algorithm of complete 2-descent")); -\\ calcul des groupes G1 et G2 +\\ sort the integers e1, e2, e3 in increasing order + + ee = vecsort([e1,e2,e3]); + e1 = ee[1]; e2 = ee[2]; e3 = ee[3]; + +\\ Computation of the groups G1 and G2 d32 = e3-e2; d31 = e3-e1; d21 = e2-e1; - G1 = factor(-abs(d31*d21))[,1]; - G2 = factor(-abs(d32*d21))[,1]; + G1 = factor(d31*d21)[,1]; \\ (G1 > 0) + G2 = factor(-d32*d21)[,1]; \\ (G2 < 0) + G3 = d31*d32; -if( DEBUGLEVEL_ell >= 3, print("G1 = ",G1)); -if( DEBUGLEVEL_ell >= 3, print("G2 = ",G2)); +if( DEBUGLEVEL_ell >= 3, print(" G1 = ",G1)); +if( DEBUGLEVEL_ell >= 3, print(" G2 = ",G2)); -\\ parcours de G1*G2 +\\ Run through G1*G2 vect1 = vector(#G1,i,[0,1]); vect2 = vector(#G2,i,[0,1]); selmer = 0; rang = 0; - listepoints = []; + listpoints = []; forvec( X = vect1, b1 = prod( i = 1, #G1, G1[i]^X[i]); - forvec( Y = vect2, + +\\ b1*b2*b3 must be a square, where b3 is a divisor of d32*d31 + vect3 = vect2; + for( i = 2, #G2, + if( G3%G2[i] !=0, + vect3[i] = [1,1]*valuation(b1,G2[i]))); + + forvec( Y = vect3, b2 = prod( i = 1, #G2, G2[i]^Y[i]); -if( DEBUGLEVEL_ell >= 3, print("[b1,b2] = ",lift([b1,b2]))); +if( DEBUGLEVEL_ell >= 3, print(" [b1,b2] = ",lift([b1,b2]))); -\\ points triviaux provenant de la 2-torsion +\\ Trivial points coming from the 2-torsion if( b1==1 && b2==1, -if( DEBUGLEVEL_ell >= 4, print(" point trivial [0]")); +if( DEBUGLEVEL_ell >= 4, print(" trivial point [0]")); selmer++; rang++; next); if( issquare(-d21*b2) && issquare(d31*d21*b1), -if( DEBUGLEVEL_ell >= 3, print(" point trivial [e1,0]")); - selmer++; rang++; listepoints = concat(listepoints,[[e1,0]]); next); +if( DEBUGLEVEL_ell >= 3, print(" trivial point [e1,0]")); + selmer++; rang++; listpoints = concat(listpoints,[[e1,0]]); next); if( issquare(d21*b1) && issquare(-d32*d21*b2), -if( DEBUGLEVEL_ell >= 3, print(" point trivial [e2,0]")); - selmer++; rang++; listepoints = concat(listepoints,[[e2,0]]); next); +if( DEBUGLEVEL_ell >= 3, print(" trivial point [e2,0]")); + selmer++; rang++; listpoints = concat(listpoints,[[e2,0]]); next); if( issquare(d31*b1) && issquare(d32*b2), -if( DEBUGLEVEL_ell >= 3, print(" point trivial [e3,0]")); - selmer++; rang++; listepoints = concat(listepoints,[[e3,0]]); next); +if( DEBUGLEVEL_ell >= 3, print(" trivial point [e3,0]")); + selmer++; rang++; listpoints = concat(listpoints,[[e3,0]]); next); -\\ il faut resoudre 2 equations quadratiques: -\\ (1) b1*z1^2-b2*z2^2 = e2-e1 -\\ (2) b1*z1^2-b1*b2*z3^2 = e3-e1 -\\ on aura alors (x,y) = (b1*z1^2+e1,b1*b2*z1*z2*z3) +\\ Trivial points coming from help - q1 = matdiagonal([b1,-b2,-d21]); -if( DEBUGLEVEL_ell >= 3, print(" q1 = ",q1)); - q2 = matdiagonal([b1,-b1*b2,-d31]); -if( DEBUGLEVEL_ell >= 3, print(" q2 = ",q2)); + for( i = 1, #help, + if( #help[i] != 2 || help[i][2] == 0, next); + if( issquare(b1*(help[i][1]-e1)) && issquare(b2*(help[i][1]-e2)), +if( DEBUGLEVEL_ell >= 3, print(" trivial point from help ",help[i])); + selmer++; rang++; + listpoints = concat(listpoints,[help[i]]); next(2)); + ); -\\ solution de la premiere forme quadratique +\\ If one can solve 2 quadratic equations +\\ (1) q1: b1*z1^2-b2*z2^2 = e2-e1 +\\ (2) q2: b1*z1^2-b1*b2*z3^2 = e3-e1 +\\ then (x,y) = (b1*z1^2+e1,b1*b2*z1*z2*z3) is a point on E +\\ we also have +\\ (3) q3 = q1-q2: b1*b2*z3^2-b2*z2^2=e2-e3 - sol1 = Qfsolve(q1); +\\ Solution of the q1 + + q1 = matdiagonal([b1,-b2,-d21]); +if( DEBUGLEVEL_ell >= 3, print(" q1 = ",q1)); + sol1 = qfsolve(q1); if( type(sol1) == "t_INT", -if( DEBUGLEVEL_ell >= 3, print(" q1 non ELS en ",sol1)); - next); -if( DEBUGLEVEL_ell >= 3, print(" sol part de q1 = ",sol1)); - param1 = Qfparam(q1,sol1,1); -if( DEBUGLEVEL_ell >= 3, print(" param de q1 = ",param1)); - param1x = param1*[x^2,x,1]~; - - sol2 = Qfsolve(q2); - if( type(sol2) == "t_INT", -if( DEBUGLEVEL_ell >= 3, print(" q2 non ELS en ",sol2)); +if( DEBUGLEVEL_ell >= 3, print(" q1 not ELS at ",sol1)); next); +if( DEBUGLEVEL_ell >= 3, print(" solution of q1 = ",sol1)); + param1 = qfparam(q1,sol1,1); + param1 /= content(param1); +if( DEBUGLEVEL_ell >= 3, print(" parametrization of q1 = ",param1)); + param1x = param1*['x^2,'x,1]~; + +\\ Solution of the q2 +\\ only useful to detect local non solubility + +\\ my(q2,sol2); +\\ q2 = matdiagonal([b1,-b1*b2,-d31]); +\\if( DEBUGLEVEL_ell >= 3, print(" q2 = ",q2)); +\\ sol2 = qfsolve(q2); +\\ if( type(sol2) == "t_INT", +\\if( DEBUGLEVEL_ell >= 3, print(" q2 not ELS at ",sol2)); +\\ next); + +\\ Construction of the quartic + + quart = b1*b2/gcd(b1,b2)^2*(b1*param1x[1]^2-d31*param1x[3]^2); +if( DEBUGLEVEL_ell >= 3, print(" quart = ",quart)); - quart = b1*b2*(b1*param1x[1]^2-d31*param1x[3]^2); -if( DEBUGLEVEL_ell >= 3, print(" quart = ",quart)); +\\ Search for trivial points on the quartic -\\ la quartique est-elle localement soluble ? + point = []; +\\ point = ratpoint(quart,LIM1,1); - if( !locallysoluble(quart), -if( DEBUGLEVEL_ell >= 3, print(" quartique non ELS ")); +\\ Local solubility of the quartic + + if( point == [] && !locallysoluble(quart), +if( DEBUGLEVEL_ell >= 3, print(" quartic not ELS ")); next); -if( DEBUGLEVEL_ell >= 2, print(" y^2 = ",quart)); +if( DEBUGLEVEL_ell >= 2, print(" y^2 = ",quart)); selmer++; -\\ recherche de points sur la quartique. +\\ Search for points on the quartic - point = ratpoint(quart,LIM3,1); - if( point != [], -if( DEBUGLEVEL_ell >= 2, print("point trouve sur la quartique !!")); -if( DEBUGLEVEL_ell >= 3, print(point)); + if( point == [], point = ratpoint2(quart,LIM3,1)); + if( point != [], +if( DEBUGLEVEL_ell >= 2, print(" point found on the quartic !!")); +if( DEBUGLEVEL_ell >= 3, print(" ",point)); if( #point == 2, - z1 = subst(param1x[1],x,point[1])/subst(param1x[3],x,point[1]) + z1 = subst(param1x[1],'x,point[1])/subst(param1x[3],'x,point[1]) , z1 = param1[1,1]/param1[3,1]); solx = b1*z1^2+e1; soly = sqrtrat((solx-e1)*(solx-e2)*(solx-e3)); - listepoints = concat(listepoints,[[solx,soly]]); -if( DEBUGLEVEL_ell >= 1, print("point sur la courbe elliptique = ",[solx,soly])); + listpoints = concat(listpoints,[[solx,soly]]); +if( DEBUGLEVEL_ell >= 1, print(" point on the elliptic curve = ",[solx,soly])); rang++ , -if( DEBUGLEVEL_ell >= 2, print("aucun point trouve sur la quartique")) +if( DEBUGLEVEL_ell >= 2, print(" no point found on the quartic")) ) ) ); -\\ fin +\\ end -if( DEBUGLEVEL_ell >= 1, +if( DEBUGLEVEL_ell >= 1, print("#S^(2) = ",selmer)); if( rang > selmer/2, rang = selmer); if( DEBUGLEVEL_ell >= 1, @@ -1337,24 +1800,23 @@ if( DEBUGLEVEL_ell >= 1, selmer = valuation(selmer,2); if( DEBUGLEVEL_ell >= 1, if( strange, - print(selmer-2," >= rang >= ",rang) -, print("rang = ",rang)); - if( rang, print("points = ",listepoints)); + print(selmer-2," >= rank >= ",rang) +, print("rank = ",rang)); + if( rang, print("points = ",listpoints)); ); - ell = ellinit([0,-(e1+e2+e3),0,e1*e2+e2*e3+e3*e1,-e1*e2*e3]); - if( ELLREDGENFLAG, listepoints = ellredgen(ell,listepoints)); - listepoints = concat(ellsort(elltorseven(ell)[3]),listepoints); + ell = ellinit([0,-(e1+e2+e3),0,e1*e2+e2*e3+e3*e1,-e1*e2*e3],1); + listpoints = vecsort(listpoints,,2); + if( ELLREDGENFLAG, listpoints = ellredgen(ell,listpoints)); + listpoints = concat(ellsort(elltorseven(ell)[3]),listpoints); -return([rang,selmer,listepoints]); + return([rang,selmer,listpoints]); } -if( DEBUGLEVEL_ell >= 4, print("ellcount")); -{ -ellcount( c, d, KS2gen, listpointstriv=[]) = -local(found,listgen,listpointscount,m1,m2,lastloc,mask,i,d1,iaux,j,triv,pol,point,deuxpoints,v); +{ellcount( c, d, KS2gen, listpointstriv=[]) = +my(found,listgen,listpointscount,m1,m2,lastloc,mask,i,d1,iaux,j,triv,pol,point,qf,solqf,para,point1,v); -if( DEBUGLEVEL_ell >= 4, print("entree dans ellcount ",[c,d])); -if( DEBUGLEVEL_ell >= 4, print("KS2gen = ",KS2gen)); -if( DEBUGLEVEL_ell >= 4, print("listpointstriv = ",listpointstriv)); +if( DEBUGLEVEL_ell >= 4, print(" starting ellcount ",[c,d])); +if( DEBUGLEVEL_ell >= 4, print(" KS2gen = ",KS2gen)); +if( DEBUGLEVEL_ell >= 4, print(" listpointstriv = ",listpointstriv)); found = 0; listgen = KS2gen; @@ -1366,25 +1828,25 @@ if( DEBUGLEVEL_ell >= 4, print("listpointstriv = ",listpointstriv)); i = 1; while( i < mask, d1 = 1; iaux = i; j = 1; - while( iaux, + while( iaux, if( iaux%2, d1 *= listgen[j]); iaux >>= 1; j++); -if( DEBUGLEVEL_ell >= 2, print("d1 = ",d1)); +if( DEBUGLEVEL_ell >= 3, print(" d1 = ",d1)); triv = 0; for( j = 1, #listpointstriv, if( listpointstriv[j][1] && issquare(d1*listpointstriv[j][1]), listpointscount = concat(listpointscount,[listpointstriv[j]]); -if( DEBUGLEVEL_ell >= 2, print("point trivial")); +if( DEBUGLEVEL_ell >= 2, print(" trivial point")); triv = 1; m1++; if( degre(i) > lastloc, m2++); found = 1; lastloc = -1; break)); if( !triv, pol = Pol([d1,0,c,0,d/d1]); -if( DEBUGLEVEL_ell >= 3, print("quartique = y^2 = ",pol)); +if( DEBUGLEVEL_ell >= 3, print(" quartic = y^2 = ",pol)); point = ratpoint(pol,LIM1,1); if( point != [], -if( DEBUGLEVEL_ell >= 2, print("point sur la quartique")); -if( DEBUGLEVEL_ell >= 3, print(point)); +if( DEBUGLEVEL_ell >= 2, print(" point on the quartic")); +if( DEBUGLEVEL_ell >= 3, print( point)); m1++; listpointscount = concat(listpointscount,[d1*point[1]*point]); if( degre(i) > lastloc, m2++); @@ -1392,16 +1854,37 @@ if( DEBUGLEVEL_ell >= 3, print(point)); , if( locallysoluble(pol), if( degre(i) > lastloc, m2++; lastloc = degre(i)); - point = ratpoint(pol,LIM3,1); +\\ point = ratpoint2(pol,LIM3,1); +\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +\\ Instead of solving directly y^2 = d1*x^4+c*x^2+d/d1, +\\ we solve first y^2 = d1*X^2+c*X+d/d1, then solve the quartic X = x^2 +\\ which gives a new quartic + qf = 2*[d1,c/2,0;c/2,d/d1,0;0,0,-1]; + solqf = qfsolve(qf); + para = qfparam(qf,solqf,2)*['x^2,'x,1]~; +if( DEBUGLEVEL_ell >= 3, + print(" the conic y^2 = ",Pol([d1,c,d/d1])); + print(" is parametrized by [x,y] = "subst([para[1]/para[2],para[3]/para[2]],'x,'t))); + point1 = ratpoint2(para[1]*para[2],LIM3,1); + if( point1 != [], + if(#point1 == 2, + para = subst(para,'x,point1[1]) + , point1 = [1,point1[2]/point1[1]^2,0]; + para = vector(3,ii,polcoeff(para[ii],2)) + ); + point = [point1[2]/para[2],para[3]/para[2]]; + , point = []; + ); +\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ if( point != [], -if( DEBUGLEVEL_ell >= 2, print("point sur la quartique")); -if( DEBUGLEVEL_ell >= 3, print(point)); +if( DEBUGLEVEL_ell >= 2, print(" point on the quartic")); +if( DEBUGLEVEL_ell >= 3, print( point)); m1++; listpointscount = concat(listpointscount,[d1*point[1]*point]); if( degre(i) > lastloc, m2++); found = 1; lastloc = -1 , -if( DEBUGLEVEL_ell >= 2, print(" pas de point trouve sur la quartique")) +if( DEBUGLEVEL_ell >= 2, print(" no point found on the quartic")) )))); if( found, found = 0; @@ -1415,66 +1898,67 @@ if( DEBUGLEVEL_ell >= 2, print(" pas de point trouve sur la quartique")) for( i = 1, #listpointscount, if( #listpointscount[i] > 1, - if( subst(x^3+c*x^2+d*x,x,listpointscount[i][1])-listpointscount[i][2]^2 != 0, - error(" ellcount : MAUVAIS POINT ")))); -if( DEBUGLEVEL_ell >= 4, print("fin de ellcount")); + if( subst('x^3+c*'x^2+d*'x,'x,listpointscount[i][1])-listpointscount[i][2]^2 != 0, + error(" ellcount: WRONG POINT, please report ",i)))); +if( DEBUGLEVEL_ell >= 4, print(" end of ellcount")); + return([listpointscount,[m1,m2]]); } -if( DEBUGLEVEL_ell >= 4, print("ell2descent_viaisog")); -{ -ell2descent_viaisog(ell,help=[]) = -\\ Calcul du rang des courbes elliptiques avec 2-torsion -\\ par la methode des 2-isogenies. -\\ -\\ ell = [a1,a2,a3,a4,a6] -\\ y^2+a1xy+a3y=x^3+a2x^2+a4x+a6 +{ell2descent_viaisog(ell,help=[]) = +\\ Computation of the rank of the elliptic curve ell +\\ having rational 2-torsion, using the algorithm via 2-isogenies. \\ -\\ ell doit etre sous la forme +\\ ell must be on the form \\ y^2=x^3+ax^2+bx -> ell = [0,a,0,b,0] -\\ avec a et b entiers. -local(i,P,Pfact,tors,listpointstriv,apinit,bpinit,plist,KS2prod,oddclass,KS2gen,listpoints,pointgen,n1,n2,certain,np1,np2,listpoints2,aux1,aux2,certainp,rang,strange); +\\ with a and b integers. + +my(P,Pfact,tors,listpointstriv,KS2prod,KS2gen,listpoints,pointgen,n1,n2,certain,apinit,bpinit,np1,np2,listpoints2,aux1,aux2,certainp,rang,strange); -if( DEBUGLEVEL_ell >= 2, print("Algorithme de la 2-descente par isogenies")); +if( DEBUGLEVEL_ell >= 2, print(" Algorithm of 2-descent via isogenies")); if( #ell < 13, ell = ellinit(ell,1)); if( ell.disc == 0, - error(" ell2descent_viaisog : courbe singuliere !!")); - if( ell.a1 != 0 || ell.a3 != 0 || ell.a6 != 0, - error(" ell2descent_viaisog : la courbe n'est pas sous la forme [0,a,0,b,0]")); + error(" ell2descent_viaisog: singular curve !!")); + if( ell.a1 != 0 || ell.a3 != 0 || ell.a6 != 0, + error(" ell2descent_viaisog: the curve is not on the form [0,a,0,b,0]")); if( denominator(ell.a2) > 1 || denominator(ell.a4) > 1, - error(" ell2descent_viaisog : coefficients non entiers")); + error(" ell2descent_viaisog: non-integral coefficients")); + +\\ +\\ Working with the initial curve +\\ + +\\ Construction of trivial points: torsion P = Pol([1,ell.a2,ell.a4]); Pfact = factor(P)[,1]; tors = #Pfact; listpointstriv = concat(help,elltorseven(ell)[3]); - apinit = -2*ell.a2; bpinit = ell.a2^2-4*ell.a4; - - plist = factor(6*ell.disc)[,1]; +\\ Construction of trivial points: small naive height -if( DEBUGLEVEL_ell >= 3, print(" Recherche de points triviaux sur la courbe")); - P *= x; -if( DEBUGLEVEL_ell >= 3, print("Y^2 = ",P)); +if( DEBUGLEVEL_ell >= 3, print(" Search for trivial points on the curve")); + P *= 'x; +if( DEBUGLEVEL_ell >= 3, print(" Y^2 = ",P)); listpointstriv = concat( listpointstriv, ratpoint(P,LIMTRIV,0)); -if( DEBUGLEVEL_ell >= 1, print("points triviaux sur E(Q) = ",listpointstriv); print()); +if( DEBUGLEVEL_ell >= 1, print(" trivial points on E(Q) = ",listpointstriv); print()); KS2prod = -abs(ell.a4); - if( bpinit < 0, KS2prod = -KS2prod); + if( ell.a2^2-4*ell.a4 < 0, KS2prod *= -1); KS2gen = factor(KS2prod)[,1]; if( DEBUGLEVEL_ell >= 2, - print("#K(b,2)gen = ",#KS2gen); - print("K(b,2)gen = ",KS2gen)); + print(" #K(b,2)gen = ",#KS2gen); + print(" K(b,2)gen = ",KS2gen)); listpoints = ellcount(ell.a2,ell.a4,KS2gen,listpointstriv); pointgen = listpoints[1]; -if( DEBUGLEVEL_ell >= 1, print("points sur E(Q) = ",pointgen); print()); +if( DEBUGLEVEL_ell >= 1, print(" points on E(Q) = ",pointgen); print()); n1 = listpoints[2][1]; n2 = listpoints[2][2]; certain = (n1 == n2); if( DEBUGLEVEL_ell >= 1, - if( certain, + if( certain, print("[E(Q):phi'(E'(Q))] = ",1<= 1, print("#III(E'/Q)[phi'] <= ",1<<(n2-n1)); print()) ); +\\ +\\ Working with the isogeneous curve +\\ + + apinit = -2*ell.a2; bpinit = ell.a2^2-4*ell.a4; KS2prod = -abs(bpinit); - if( ell.a4 < 0, KS2prod = -KS2prod); + if( ell.a4 < 0, KS2prod *= -1); KS2gen = factor(KS2prod)[,1]; if( DEBUGLEVEL_ell >= 2, - print("#K(a^2-4b,2)gen = ",#KS2gen); - print("K(a^2-4b,2)gen = ",KS2gen)); + print(" #K(a^2-4b,2)gen = ",#KS2gen); + print(" K(a^2-4b,2)gen = ",KS2gen)); + +\\ Construction of trivial points: torsion P = Pol([1,apinit,bpinit]); listpointstriv = elltorseven([0,apinit,0,bpinit,0])[3]; + +\\ Construction of trivial points: small naive height -if( DEBUGLEVEL_ell >= 3, print(" Recherche de points triviaux sur la courbe")); - P *= x; -if( DEBUGLEVEL_ell >= 3, print("Y^2 = ",P)); +if( DEBUGLEVEL_ell >= 3, print(" Search for trivial points on the curve")); + P *= 'x; +if( DEBUGLEVEL_ell >= 3, print(" Y^2 = ",P)); listpointstriv = concat( listpointstriv, ratpoint(P,LIMTRIV,0)); -if( DEBUGLEVEL_ell >= 1, print("points triviaux sur E'(Q) = ",listpointstriv); print()); +if( DEBUGLEVEL_ell >= 1, print(" trivial points on E'(Q) = ",listpointstriv); print()); listpoints = ellcount(apinit,bpinit,KS2gen,listpointstriv); -if( DEBUGLEVEL_ell >= 1, print("points sur E'(Q) = ",listpoints[1])); + +if( DEBUGLEVEL_ell >= 1, print(" points on E'(Q) = ",listpoints[1])); np1 = listpoints[2][1]; np2 = listpoints[2][2]; listpoints2 = vector(#listpoints[1],i,0); for( i = 1, #listpoints[1], @@ -1513,7 +2007,7 @@ if( DEBUGLEVEL_ell >= 1, print("points sur E'(Q) = ",listpoints[1])); listpoints2[i][1] = aux2^2/aux1/4; listpoints2[i][2] = aux2*(bpinit-aux1)/aux1/8 , listpoints2[i] = listpoints[1][i])); -if( DEBUGLEVEL_ell >= 1, print("points sur E(Q) = ",listpoints2); print()); +if( DEBUGLEVEL_ell >= 1, print(" points on E(Q) = ",listpoints2); print()); pointgen = concat(pointgen,listpoints2); certainp = (np1 == np2); @@ -1538,17 +2032,17 @@ if( DEBUGLEVEL_ell >= 1, if( DEBUGLEVEL_ell >= 1, if( certain && certainp, print("#E(Q)/2E(Q) = ",(1<<(rang+tors))); - print("rang = ",rang); print() + print("rank = ",rang); print() , print("#E(Q)/2E(Q) >= ",(1<<(rang+tors))); print(); - print(rang," <= rang <= ",n2+np2-2); print() + print("",rang," <= rank <= ",n2+np2-2); print() )); strange = (n2+np2-n1-np1)%2; - if( strange, + if( strange, if( DEBUGLEVEL_ell >= 1, - print(" !!! III doit etre un carre !!!"); print("donc")); - if( certain, + print(" !!! III should be a square !!!"); print("hence")); + if( certain, np1++; certainp = (np1 == np2); if( DEBUGLEVEL_ell >= 1, @@ -1565,7 +2059,7 @@ if( DEBUGLEVEL_ell >= 1, if( certainp, n1++; certain = (n1 == n2); -if( DEBUGLEVEL_ell >= 1, +if( DEBUGLEVEL_ell >= 1, if( certain, print("[E(Q):phi'(E'(Q))] = ",1<= ",(1<<(rang+tors))); print(); - print(rang," <= rang <= ",n2+np2-2); print()) + print(rang," <= rank <= ",n2+np2-2); print()) )); -\\ fin de strange - +\\ end of strange + + pointgen = vecsort(pointgen,,2); if( ELLREDGENFLAG, pointgen = ellredgen(ell,pointgen)); pointgen = concat(ellsort(elltorseven(ell)[3]),pointgen); if( DEBUGLEVEL_ell >= 1, print("points = ",pointgen)); -if( DEBUGLEVEL_ell >= 3, print("fin de ell2descent_viaisog")); +if( DEBUGLEVEL_ell >= 3, print(" end of ell2descent_viaisog")); + return([rang,n2+np2-2+tors,pointgen]); } +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +\\ HELP MESSAGES \\ +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + +{ +\\ functions for elliptic curves + addhelp(ell2descent_complete, + "ell2descent_complete(e1,e2,e3): Performs a complete 2-descent on the elliptic curve y^2 = (x-e1)*(x-e2)*(x-e3). See ?ellrank for the format of the output."); + addhelp(ell2descent_gen, + "ell2descent_gen((E,bnf,k=1,help=[]): E is a vector of the form [0,A,0,B,C], (or the result of ellinit of such a vector) A,B,C integers such that x^3+A*x^2+B*x+C; bnf is the corresponding bnfinit(,1); Performs 2-descent on the elliptic curve Ek: k*y^2=x^3+A*x^2+B*x+C. See ?ellrank for the format of the output."); + addhelp(ell2descent_viaisog, + "ell2descent_viaisog(E,help=[]): E is an elliptic curve of the form [0,a,0,b,0], with a, b integers. Performs a 2-descent via isogeny on E. See ?ellrank for the format of the output."); + addhelp(ellrank, + "ellrank(E,help=[]): E is any elliptic curve defined over Q. Returns a vector [r,s,v], where r is a lower bound for the rank of E, s is the rank of its 2-Selmer group and v is a list of independant points in E(Q)/2E(Q). If help is a vector of nontrivial points on E, the result might be faster. This function might be used in conjunction with elltors2(E). See also ?default_ellQ"); + addhelp(ellhalf, + "ellhalf(E,P): returns the vector of all points Q on the elliptic curve E such that 2Q = P"); + addhelp(ellredgen, + "ellredgen(E,v): returns a vector of smallest possible points on the elliptic curve E generating the same subgroup as v, up to torsion."); + addhelp(ellsort, + "ellsort(v): v being a vector of points on some elliptic curve, returns the vector v sorted according to the naive height."); + addhelp(elltors2, + "elltors2(E): for an elliptic curve E, returns the group E(K)[2], where K is the field of definition of the coefficients of E (Q, R, Qp or Fp)."); + addhelp(elltorseven, + "elltorseven(E): for an elliptic curve E, returns 2-Sylow subgroup of E(K)_tors, where K is the field of definition of the coefficients of E: (Q, R, Qp or Fp)."); + + +\\ functions for polynomials + addhelp(locallysoluble, + "locallysoluble(pol): returns 1 if y^2=pol(x) is everywhere locally soluble, 0 otherwise."); + addhelp(ratpoint, + "ratpoint(pol,lim=1,singlepoint=1): search for rational points on y^2=pol(x), for about within the bounds given by lim. The coefficients of pol must be integral. If singlepoint=1, returns at most one point, otherwise as many as possible."); + addhelp(redquartic, + "redquartic(pol): reduction of the quartic pol using Cremona-Stoll algorithm. Returns [p,M], where p is the reduced quartic and M is the GL2(Z) transformation. Also works with other degree polynomials."); + + +\\ functions for number fields + addhelp(bnfpSelmer, + "bnfpSelmer(K,S,p): K being a number field given by bnfinit, S an ideal of K, and p a prime number, computes a set of generators of the group K(S,p) = { x in K^* / K^*^p, v_P(x) = 0 (mod p) for all P coprime to S}"); + addhelp(reducemodsquares, + "reducemodsquares(delta,d): delta being a t_POLMOD, returns another delta'=delta*z^2, such that delta' has a small coefficient in x^d."); + + +\\ others + addhelp(default_ellQ, + "default_ellQ(DEBUGLEVEL_ell, LIM1, LIM3, LIMTRIV, ELLREDGENFLAG, COMPLETE, MAXPROB, LIMBIGPRIME): set the value of the global variables used for ellrank() and other related functions. DEBUGLEVEL_ell: 0-5: choose the quantity of information printed during the computation (default=0: print nothing); LIM1 (resp LIM3): search limit for easy (resp hard) points on quartics; LIMTRIV: search limit for trivial points on elliptic curves; ELLREDGENFLAG: if != 0, try to reduce the generators at the end; COMPLETE: if != 0 and full 2-torsion, use complete 2-descent, otherwise via 2-isogeny; MAXPROB, LIMBIGPRIME: technical."); +/* addhelp(DEBUGLEVEL_ell, + "DEBUGLEVEL_ell: Choose a higher value of this global variable to have more details of the computations printed during the 2-descent algorithm. 0 = don't print anything; 1 = (default) just print the result; 2 = print more details including the Selmer group and the nontrivial quartics."); +*/ +} diff --git a/src/ext/pari/simon/ellcommon.gp b/src/ext/pari/simon/ellcommon.gp new file mode 100644 index 00000000000..968e4cf5cf5 --- /dev/null +++ b/src/ext/pari/simon/ellcommon.gp @@ -0,0 +1,126 @@ +\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +\\ Copyright (C) 2014 Denis Simon +\\ +\\ Distributed under the terms of the GNU General Public License (GPL) +\\ +\\ This code 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. +\\ +\\ The full text of the GPL is available at: +\\ +\\ http://www.gnu.org/licenses/ +\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + +/* + Auteur : + Denis SIMON -> simon@math.unicaen.fr + adresse du fichier : + www.math.unicaen.fr/~simon/ell.gp + + ********************************************* + * VERSION 13/01/2014 * + ********************************************* + +*/ + +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +\\ SCRIPT \\ +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +\\ COMMON FUNCTIONS TO ell.gp AND ellQ.gp \\ +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + +{ellcomposeurst(urst1,urst2) = +my(u1 = urst1[1], r1 = urst1[2], s1 = urst1[3], t1 = urst1[4], + u2 = urst2[1], r2 = urst2[2], s2 = urst2[3], t2 = urst2[4]); + [u1*u2,u1^2*r2+r1,u1*s2+s1,u1^3*t2+s1*u1^2*r2+t1]; +} +{ellinverturst(urst) = +my(u = urst[1], r = urst[2], s = urst[3], t = urst[4]); + [1/u,-r/u^2,-s/u,(r*s-t)/u^3]; +} +{mysubst(polsu,subsx) = + if( type(lift(polsu)) == "t_POL", + return(simplify(subst(lift(polsu),variable(lift(polsu)),subsx))) + , return(simplify(lift(polsu)))); +} +{degre(idegre) = +my(ideg = idegre, jdeg = 0); + + while( ideg >>= 1, jdeg++); + return(jdeg); +} +{nfrealsign(nf,a,i) = +\\ return the sign of the algebraic number a in the i-th real embedding. +my(nf_roots,ay,prec0); + + if( a == 0, return(0)); + + a = lift(a); + if( type(a) != "t_POL", + return(sign(a))); + + nf_roots = nf.roots; + prec0 = default(realprecision); + + ay = 0; + while( ay == 0 || precision(ay) < 10, + + ay = subst(a,variable(a),nf_roots[i]); + + if( ay == 0 || precision(ay) < 10, +if( DEBUGLEVEL_ell >= 3, + print(" **** Warning: doubling the real precision in nfrealsign **** ", + 2*default(realprecision))); + default(realprecision,2*default(realprecision)); + nf_roots = real(polroots(nf.pol)) + ) + ); + default(realprecision,prec0); + + return(sign(ay)); +} +{nfsqrt( nf, a) = +\\ if a is a square in the number field nf returns [sqrt(a)], otherwise []. +my(alift,ta,minpola,py,pfact); + + if( a==0 || a==1, return([a])); + + alift = lift(a); + ta = type(a); + if( !poldegree(alift), alift = polcoeff(alift,0)); + + if( type(alift) != "t_POL", + if( issquare(alift), return([sqrtrat(alift)]))); + + if( poldegree(nf.pol) <= 1, return([])); + if( ta == "t_POL", a = Mod(a,nf.pol)); + +\\ the norm should be a square + + if( !issquare(norm(a)), return([])); + +\\ the real embeddings must all be >0 + + minpola = minpoly(a); + if( polsturm(minpola,,0), return([])); + +\\ factorization over nf of the polynomial X^2-a + + if( variable(nf.pol) == 'x, + py = subst(nf.pol,'x,'y); + pfact = lift(factornf('x^2-mysubst(alift,Mod('y,py)),py)[1,1]) + , + pfact = lift(factornf('x^2-a,nf.pol)[1,1])); + if( poldegree(pfact) == 2, return([])); + return([subst(polcoeff(pfact,0),'y,Mod(variable(nf.pol),nf.pol))]); +} +{nfissquare(nf, a) = #nfsqrt(nf,a) > 0; +} +{sqrtrat(a) = + sqrtint(numerator(a))/sqrtint(denominator(a)); +} + diff --git a/src/ext/pari/simon/qfsolve.gp b/src/ext/pari/simon/qfsolve.gp index 4d480b0cfb3..6dcfae85971 100644 --- a/src/ext/pari/simon/qfsolve.gp +++ b/src/ext/pari/simon/qfsolve.gp @@ -1,5 +1,5 @@ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -\\ Copyright (C) 2007 Denis Simon +\\ Copyright (C) 2014 Denis Simon \\ \\ Distributed under the terms of the GNU General Public License (GPL) \\ @@ -13,336 +13,384 @@ \\ http://www.gnu.org/licenses/ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -\\ -\\ Auteur: -\\ Denis SIMON -> simon@math.unicaen.fr -\\ adresse du fichier: -\\ www.math.unicaen.fr/~simon/qfsolve.gp -\\ -\\ ********************************************* -\\ * VERSION 02/10/2009 * -\\ ********************************************* -\\ -\\ Programme de resolution des equations quadratiques -\\ langage: GP -\\ pour l'utiliser, lancer gp, puis taper -\\ \r qfsolve.gp -\\ -\\ Ce fichier contient 4 principales fonctions: -\\ -\\ - Qfsolve(G,factD): pour resoudre l'equation quadratique X^t*G*X = 0 -\\ G doit etre une matrice symetrique n*n, a coefficients dans Z. -\\ S'il n'existe pas de solution, la reponse est un entier -\\ indiquant un corps local dans lequel aucune solution n'existe -\\ (-1 pour les reels, p pour Q_p). -\\ Si on connait la factorisation de -abs(2*matdet(G)), -\\ on peut la passer par le parametre factD pour gagner du temps. -\\ -\\ - Qfparam(G,sol,fl): pour parametrer les solutions de la forme -\\ quadratique ternaire G, en utilisant la solution particuliere sol. -\\ si fl>0, la 'fl'eme forme quadratique est reduite. -\\ -\\ - IndefiniteLLL(G,c): pour resoudre ou reduire la forme quadratique -\\ G a coefficients entiers. Il s'agit d'un algorithme type LLL, avec la -\\ constante 1/4 simon@math.unicaen.fr + address of the file: + www.math.unicaen.fr/~simon/qfsolve.gp + + ********************************************* + * VERSION 09/01/2014 * + ********************************************* + + \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + \\ English help \\ + \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + + This package provides functions to solve quadratic equations over Q. + language: GP + It can be run under GP by the command + gp > \r qfsolve.gp + + This package contains 4 main functions: + + - qfsolve(G,{factD}): Solve over Q the quadratic equation X~*G*X = 0. + G must be a symmetric matrix n*n, with coefficients in Z. + The solution might be a single vector (vectorv) + or a matrix (whose columns generate a totally isotropic subspace). + If no solution exists, the output is a prime number + indicating that there is no solution in the local field Q_p + (-1 for the reals, p for Q_p). + factD is an optional parameter. If present, it must be equal to + the factorization of -abs(2*matdet(G)). This saves a lot of time. + + Example: + gp > G = [1,0,0;0,1,0;0,0,-34]; + gp > qfsolve(G) + %1 = [-3, -5, 1]~ + + - qfparam(G,sol,fl): Coefficients of quadratic forms that parametrize the + solutions of the ternary quadratic form G, using the particular + solution sol. + fl is optional and can be 1, 2, or 3, in which case the 'fl'th form is + reduced. The default is fl=3. + + Example: + gp > qfparam(G,[-3,-5,1]~) + %2 = + [ 3 -10 -3] + + [-5 -6 5] + + [ 1 0 1] + Indeed, the solutions can be parametrized as + [3*x^2 - 10*y*x - 3*y^2, -5*x^2 - 6*y*x + 5*y^2, x^2 + y^2]~ + + - qflllgram_indef(G,c): Solve or reduce the quadratic form G with + integral coefficients. G might be definite or indefinite. + This is an lll-type algorithm with a constant 1/4 G = [1,0,0;0,1,0;0,0,-34]; + gp > qfsolve(G) + %1 = [-3, -5, 1]~ + + - qfparam(G,sol,fl): pour parametrer les solutions de la forme + quadratique ternaire G, en utilisant la solution particuliere sol. + fl est optionnel et peut prendre les valeurs 1,2 ou 3. + Il indique que la 'fl'eme forme quadratique est reduite. + Par defaut, fl=3 + + Exemple: + gp > qfparam(G,[-3,-5,1]~) + %2 = + [ 3 -10 -3] + + [-5 -6 5] + + [ 1 0 1] + Ici, les solutions sont parametrees par + [3*x^2 - 10*y*x - 3*y^2, -5*x^2 - 6*y*x + 5*y^2, x^2 + y^2]~ + + - qflllgram_indef(G,c): pour resoudre ou reduire la forme quadratique + G a coefficients entiers. Il s'agit d'un algorithme type LLL, avec la + constante 1/4= 5, print("entree dans QfbReduce avec ",M)); - - a = M[1,1]; b = M[1,2]; c = M[2,2]; - - H = matid(2); test = 1; - while( test && a, - di = divrem(b,a); q = di[1]; r = di[2]; - if( 2*r > abs(a), r -= abs(a); q += sign(a)); - H[,2] -= q*H[,1]; - nextc = a; nextb = -r; nexta= (nextb-b)*q+c; +\\ use the variable DEBUGLEVEL_qfsolve : +\\ From 0 to 5 : choose a higher value to have +\\ more details printed. - if( test = abs(nexta) < abs(a), - c = nextc; b = nextb; a = nexta; - aux = H[,1]; H[,1] = -H[,2]; H[,2] = aux - ) - ); -if( DEBUGLEVEL_qfsolve >= 5, print("sortie de QfbReduce avec ",H)); -return(H); -} -{IndefiniteLLL(G,c=1,base=0) = -\\ Performs first a LLL reduction on a positive definite -\\ quadratic form QD bounding the indefinite G. -\\ Then finishes the reduction with IndefiniteLLL2. +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +\\ SCRIPT \\ +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -local(n,M,QD,M1,S,red); +{default_qfsolve(DEBUGLEVEL_qfsolve_val = 0) = - n = length(G); - M = matid(n); - QD = G; - for( i = 1, n-1, - if( !QD[i,i], -return(IndefiniteLLL2(G,c,base)) - ); - M1 = matid(n); - M1[i,] = -QD[i,]/QD[i,i]; - M1[i,i] = 1; - M = M*M1; - QD = M1~*QD*M1 - ); - M = M^(-1); - QD = M~*abs(QD)*M; - S = qflllgram(QD/content(QD)); - red = IndefiniteLLL2(S~*G*S,c,base); - if( type(red) == "t_COL", -return(S*red)); - if( length(red) == 3, -return([red[1],S*red[2],S*red[3]])); -return([red[1],S*red[2]]); + DEBUGLEVEL_qfsolve = DEBUGLEVEL_qfsolve_val; + print(" DEBUGLEVEL_qfsolve = ",DEBUGLEVEL_qfsolve); } -{IndefiniteLLL2(G,c=1,base=0) = -\\ following Cohen's book p. 86 -\\ but without b and bstar: works on G -\\ returns [H~*G*H,H] where det(H) = 1 and H~*G*H is reduced. -\\ Exit with a norm 0 vector if one such is found. -\\ If base == 1 and norm 0 is obtained, returns [H~*G*H,H,sol] where -\\ sol is a norm 0 vector and is the 1st column of H. -local(n,H,M,A,aux,sol,k,nextk,swap,q,di,HM,aux1,aux2,Mkk1,bk1new,Mkk1new,newG); +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +\\ TYPE CONVERSIONS \\ +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ - n = length(G); -if( DEBUGLEVEL_qfsolve >= 3, print("LLL dim ",n," avec G=",log(vecmax(abs(G)))/log(10))); -if( DEBUGLEVEL_qfsolve >= 4, print("LLL avec ");printp(G)); - - if( n <= 1, return([G,matid(n)])); - - H = M = matid(n); A = matrix(n,n); +\\ THIS FUNCTION WILL BE REPLACED BY matconcat(matdiagonal(v)) +\\ IN VERSION >= 2.6.0 +\\ build the matrix whose diagonal blocks are listed in the vector v. +{matdiagonalblock(v) = +my(M); +my(lv,lt=0); -\\ compute Gram-Schmidt + if( type(v) != "t_VEC" && type(v) != "t_COL", + error("wrong type in matdiagonalblock()")); - for( i = 1, n, - if( !(A[i,i] = G[i,i]), - if( base, - aux = H[,1]; H[,1] = H[,i]; H[,i] = -aux; - return([H~*G*H,H,H[,1]]) - , return(M[,i]))); - for( j = 1, i-1, - A[i,j] = G[i,j] - sum( k = 1, j-1, M[j,k]*A[i,k]); - M[i,j] = A[i,j]/A[j,j]; - A[i,i] -= M[i,j]*A[i,j]; - if( !A[i,i], - sol = (M^(-1))~[,i]; sol /= content(sol); - if( base, - H = completebasis(sol); - aux = H[,1]; H[,1] = H[,n]; H[,n]= -aux; - return([H~*G*H,H,H[,1]]) - , return(sol))) - ) + lv = length(v); + for( i = 1, lv, lt += length(v[i])); + M = matrix(lt,lt); + lt = 0; + for( i = 1, lv, + my( lvi = length(v[i])); + for( j = 1, lvi, + for( k = 1, lvi, + M[lt+j,lt+k] = v[i][j,k])); + lt += lvi ); +return(M); +} -\\ LLL loop - - k = 2; nextk = 1; - while( k <= n, - - swap = 1; - while( swap, - swap = 0; - -\\ red(k,k-1); - if( q = round(M[k,k-1]), - for( i = 1, k-2, M[k,i] -= q*M[k-1,i]); - M[k,k-1] -= q; - for( i = 1, n, - A[k,i] -= q*A[k-1,i]; - H[i,k] -= q*H[i,k-1] - ) - ); +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +\\ LINEAR ALGEBRA \\ +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -\\ preparation du swap(k,k-1) - - if( issquare( di = -A[k-1,k-1]*A[k,k]), -\\ di est le determinant de matr -\\ On trouve une solution - HM = (M^(-1))~; - aux1 = sqrtint(numerator(di)); - aux2 = sqrtint(denominator(di)); - sol = aux1*HM[,k-1]+aux2*A[k-1,k-1]*HM[,k]; - sol /= content(sol); - if( base, - H = H*completebasis(sol,1); - aux = H[,1]; H[,1] = H[,n]; H[,n] = -aux; - return([H~*G*H,H,H[,1]]) - , return(H*sol) - ) - ); +\\ Gives a unimodular matrix with the last column equal to v. +\\ redflag = 0 or 1. If redflag = 1, then the n-#v first columns are reduced. +{completebasis(v,redflag=0) = +my(Mv,U,re); +my(n); -\\ On reduit [k,k-1]. - Mkk1 = M[k,k-1]; - bk1new = Mkk1^2*A[k-1,k-1] + A[k,k]; - if( swap = abs(bk1new) < c*abs(A[k-1,k-1]), - Mkk1new = -Mkk1*A[k-1,k-1]/bk1new - ); + if( type(v) != "t_COL" && type(v) != "t_MAT", + error("wrong type in completebasis")); -\\ Calcul des nouvelles matrices apres le swap. - if( swap, - for( j = 1, n, - aux = H[j,k-1]; H[j,k-1] = H[j,k]; H[j,k] = -aux); - for( j = 1, k-2, - aux = M[k-1,j]; M[k-1,j] = M[k,j]; M[k,j] = -aux); - for( j = k+1, n, - aux = M[j,k]; M[j,k] = -M[j,k-1]+Mkk1*aux; M[j,k-1] = aux+Mkk1new*M[j,k]); - for( j = 1, n, if( j != k && j != k-1, - aux = A[k-1,j]; A[k-1,j] = A[k,j]; A[k,j] =- aux; - aux = A[j,k-1]; A[j,k-1] = Mkk1*aux+A[j,k]; A[j,k] = -aux-Mkk1new*A[j,k-1])); - - aux1 = A[k-1,k-1]; - aux2 = A[k,k-1]; - A[k,k-1] =-A[k-1,k] - Mkk1*aux1; - A[k-1,k-1]= A[k,k] + Mkk1*aux2; - A[k,k] = aux1 - Mkk1new*A[k,k-1]; - A[k-1,k] =-aux2 - Mkk1new*A[k-1,k-1]; - - M[k,k-1] = Mkk1new; - -if( DEBUGLEVEL_qfsolve >=4, newG=H~*G*H;print(vector(n,i,matdet(vecextract(newG,1<= 5, print("entree dans Qfparam")); - sol /= content(sol); -\\ construction de U telle que U[,3] est sol, et det(U) = +-1 - U = completebasis(sol,1); - G1 = U~*G*U; \\ G1 a un 0 en bas a droite. - G2 = [-2*G1[1,3],-2*G1[2,3],0; - 0,-2*G1[1,3],-2*G1[2,3]; - G1[1,1],2*G1[1,2],G1[2,2]]; - sol = U*G2; - if(fl && !issquare(matdet( U = [sol[fl,1],sol[fl,2]/2; - sol[fl,2]/2,sol[fl,3]])), - U = QfbReduce(U); - U = [U[1,1]^2,2*U[1,2]*U[1,1],U[1,2]^2; - U[2,1]*U[1,1],U[2,2]*U[1,1]+U[2,1]*U[1,2],U[1,2]*U[2,2]; - U[2,1]^2,2*U[2,1]*U[2,2],U[2,2]^2]; - sol = sol*U +\\ Given a symmetric matrix G over Z, compute the local invariant +\\ (=Witt invariant) of G at the prime p (at real place if p = -1) +\\ Assume that none of the determinant G[1..i,1..i] is 0. +{qflocalinvariant(G,p) = +my(vdet,diag); +my(n,c); + + n = length(G); +\\ Diagonalize G first. + vdet = vector( n+1, i, matdet(matrix(i-1,i-1,j,k,G[j,k]))); + diag = vector( n, i, vdet[i+1]*vdet[i]); + +\\ Then compute the product of the Hilbert symbols +\\ (diag[i],diag[j])_p for i < j + c = 1; + for( i = 1, n, + for( j = i+1, n, + c *= myhilbert( diag[i], diag[j], p))); +return(c); +} + +\\ G is a quadratic form, or a symmetrix matrix, +\\ or a list of quadratic forms with the same discriminant. +\\ If given, fa must be equal to factor(-abs(2*matdet(G)))[,1]. +{qflocalinvariants(G,fa=[]) = +my(vG,sol,vdet); +my(lG); + +if( DEBUGLEVEL_qfsolve >= 4, print(" starting qflocalinvariants ",G)); + +\\ convert G into a vector of symmetric matrices + if( type(G) == "t_VEC", vG = G , vG = [G]); + lG = length(vG); + for( j = 1, lG, + if( type(vG[j]) == "t_QFI" || type(vG[j]) == "t_QFR", + vG[j] = Mat(vG[j]))); + +\\ compute the factorization of -2*abs(det(G)) + if( !length(fa), + fa = (factor(-abs(2*matdet(vG[1])))[,1])); + +\\ in dimension 2, each invariant is a single Hilbert symbol. + if( length(vG[1]) == 2, + sol = matrix(length(fa),lG,i,j, + myhilbert(vG[j][1,1],-matdet(vG[1]),fa[i]) < 0); +if( DEBUGLEVEL_qfsolve >= 4, print(" end of qflocalinvariants")); + return([fa,sol]) ); -if( DEBUGLEVEL_qfsolve >= 5, print("sortie de Qfparam")); -return(sol); + + sol = matrix(length(fa),lG); + for( j = 1, lG, + my( n = length(vG[j])); +\\ in dimension n, we need to compute a product of n Hilbert symbols. + vdet = vector(n+1, i, matdet(matrix(i-1,i-1,k,m,vG[j][k,m]))); + for( i = 1, length(fa), + my( p = fa[i]); + my( h = 1); + for( k = 1, n-1, h *= myhilbert(-vdet[k],vdet[k+1],p)); + h *= myhilbert(vdet[n],vdet[n+1],p); + sol[i,j] = h < 0; + ) + ); +if( DEBUGLEVEL_qfsolve >= 4, print(" end of qflocalinvariants")); +return([fa,sol]); } -{LLLgoon3(G,c=1) = -\\ reduction LLL de la forme quadratique G (matrice de Gram) -\\ en dim 3 seulement avec detG = -1 et sign(G) = [1,2]; -local(red,U1,G2,bez,U2,G3,cc,U3); +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +\\ QUADRATIC FORMS REDUCTION \\ +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ - red = IndefiniteLLL(G,c,1); -\\ On trouve toujours un vecteur isotrope. - U1 = [0,0,1;0,1,0;1,0,0]; - G2 = U1~*red[1]*U1; -\\ la matrice G2 a un 0 dans le coin en bas a droite. - bez = bezout(G2[3,1],G2[3,2]); - U2 = [bez[1],G2[3,2]/bez[3],0;bez[2],-G2[3,1]/bez[3],0;0,0,-1]; - G3 = U2~*G2*U2; -\\ la matrice G3 a des 0 sous l'anti-diagonale. - cc = G3[1,1]%2; - U3 = [1,0,0; cc,1,0; - round(-(G3[1,1]+cc*(2*G3[1,2]+G3[2,2]*cc))/2/G3[1,3]), - round(-(G3[1,2]+cc*G3[2,2])/G3[1,3]),1]; -return([U3~*G3*U3,red[2]*U1*U2*U3]); +\\ M = [a,b;b;c] has integral coefficients. +\\ Gauss reduction of the binary quadratic form +\\ qf = (a,b,c)=a*X^2+2*b*X*Y+c*Y^2 +\\ Returns the reduction matrix with det = +1. +{qfbreduce(M) = +my(H,di,aux); +my(a,b,c,q,r,nexta,nextb,nextc); +my(test); + +if( DEBUGLEVEL_qfsolve >= 5, print(" starting qfbreduce with ",M)); + + a = M[1,1]; b = M[1,2]; c = M[2,2]; + + H = matid(2); test = 1; + while( test && a, + di = divrem(b,a); q = di[1]; r = di[2]; + if( 2*r > abs(a), r -= abs(a); q += sign(a)); + H[,2] -= q*H[,1]; + nextc = a; nextb = -r; nexta= (nextb-b)*q+c; + + test = abs(nexta) < abs(a); + if( test, + c = nextc; b = nextb; a = nexta; + aux = H[,1]; H[,1] = -H[,2]; H[,2] = aux + ) + ); + +if( DEBUGLEVEL_qfsolve >= 5, print(" end of qfbreduce with ",H)); +return(H); } -{completebasis(v,redflag=0) = -\\ Donne une matrice unimodulaire dont la derniere colonne est v. -\\ Si redflag <> 0, alors en plus on reduit le reste. -local(U,n,re); +\\ Performs first a LLL reduction on a positive definite +\\ quadratic form QD bounding the indefinite G. +\\ Then finishes the reduction with qfsolvetriv(). +{qflllgram_indef(G,c=1,base=0) = +my(M,QD,M1,S,red); +my(n); - U = (mathnf(Mat(v~),1)[2]~)^-1; - n = length(v~); - if( n==1 || !redflag, return(U)); - re = qflll(vecextract(U,1<= 4, print(" qflllgram_indef with G = ",G)); + n = length(G); + M = matid(n); + QD = G; + for( i = 1, n-1, + if( !QD[i,i], + return(qfsolvetriv(G,base)) + ); + M1 = matid(n); + M1[i,] = -QD[i,]/QD[i,i]; + M1[i,i] = 1; + M = (M*M1); + QD = (M1~*QD*M1) + ); + M = (M^(-1)); + QD = (M~*abs(QD)*M); + S = qflllgram(QD/content(QD)); + if( #S < n, S = completebasis(S)); + red = qfsolvetriv(S~*G*S,base); + if( type(red) == "t_COL", + red = (S*red); + return(red)); + red[2] = S*red[2]; + if( length(red) == 3, + red[3] = S*red[3]); +return(red); } -{LLLgoon(G,c=1) = -\\ reduction LLL de la forme quadratique G (matrice de Gram) -\\ ou l'on continue meme si on trouve un vecteur isotrope -local(red,U1,G2,U2,G3,n,U3,G4,U,V,B,U4,G5,U5,G6); +\\ LLL reduction of the quadratic form G (Gram matrix) +\\ where we go on, even if an isotropic vector is found. +{qflllgram_indefgoon(G,c=1) = +my(red,U1,G2,U2,G3,U3,G4,U,V,B,U4,G5,U5,G6); +my(n); - red = IndefiniteLLL(G,c,1); -\\ si on ne trouve pas de vecteur isotrope, il n'y a rien a faire. + red = qflllgram_indef(G,c,1); +\\ If no isotropic vector is found, nothing to do. if( length(red) == 2, return(red)); -\\ sinon : +\\ otherwise a solution is found: U1 = red[2]; G2 = red[1]; \\ On a G2[1,1] = 0 U2 = mathnf(Mat(G2[1,]),4)[2]; G3 = U2~*G2*U2; -\\ la matrice de G3 a des 0 sur toute la 1ere ligne, -\\ sauf un 'g' au bout a droite, avec g^2| det G. +\\ The first line of the matrix G3 only contains 0, +\\ except some 'g' on the right, where g^2| det G. n = length(G); U3 = matid(n); U3[1,n] = round(-G3[n,n]/G3[1,n]/2); G4 = U3~*G3*U3; -\\ le coeff G4[n,n] est reduit modulo 2g +\\ The coeff G4[n,n] is reduced modulo 2g U = vecextract(G4,[1,n],[1,n]); if( n == 2, V = matrix(2,0) @@ -354,236 +402,202 @@ local(red,U1,G2,U2,G3,n,U3,G4,U,V,B,U4,G5,U5,G6); U4[n,j] = B[2,j-1] ); G5 = U4~*G4*U4; -\\ la derniere colonne de G5 est reduite +\\ The last column of G5 is reduced if( n < 4, return([G5,U1*U2*U3*U4])); - red = LLLgoon(matrix(n-2,n-2,i,j,G5[i+1,j+1]),c); + red = qflllgram_indefgoon(matrix(n-2,n-2,i,j,G5[i+1,j+1]),c); U5 = matdiagonalblock([Mat(1),red[2],Mat(1)]); G6 = U5~*G5*U5; return([G6,U1*U2*U3*U4*U5]); } -{QfWittinvariant(G,p) = -\\ calcule l'invariant c (=invariant de Witt) d'une forme quadratique, -\\ p-adique (reel si p = -1) -local(n,det,diag,c); +\\ LLL reduction of the quadratic form G (Gram matrix) +\\ in dim 3 only, with detG = -1 and sign(G) = [2,1]; +{qflllgram_indefgoon2(G,c=1) = +my(red,U1,G2,bez,U2,G3,U3); +my(cc); - n = length(G); -\\ On diagonalise d'abord G - det = vector( n+1, i, matdet(matrix(i-1,i-1,j,k,G[j,k]))); - diag = vector( n, i, det[i+1]/det[i]); - -\\ puis on calcule les symboles de Hilbert - c = prod( i = 1, n, - prod( j = i+1, n, - hilbert( diag[i], diag[j], p))); -return(c); -} -{Qflisteinvariants(G,fa=[]) = -\\ G est une forme quadratique, ou une matrice symetrique, -\\ ou un vecteur contenant des formes quadratiques de meme discriminant. -\\ fa = factor(-abs(2*matdet(G)))[,1] est facultatif. - -local(l,sol,n,det); - -if( DEBUGLEVEL_qfsolve >= 4, print("entree dans Qflisteinvariants",G)); - if( type(G) != "t_VEC", G = [G]); - l = length(G); - for( j = 1, l, - if( type(G[j]) == "t_QFI" || type(G[j]) == "t_QFR", - G[j] = mymat(G[j]))); - - if( !length(fa), - fa = factor(-abs(2*matdet(G[1])))[,1]); - - if( length(G[1]) == 2, -\\ En dimension 2, chaque invariant est un unique symbole de Hilbert. - det = -matdet(G[1]); - sol = matrix(length(fa),l,i,j,hilbert(G[j][1,1],det,fa[i])<0); -if( DEBUGLEVEL_qfsolve >= 4, print("sortie de Qflisteinvariants")); - return([fa,sol]) - ); + red = qflllgram_indef(G,c,1); +\\ We always find an isotropic vector. + U1 = [0,0,1;0,1,0;1,0,0]; + G2 = U1~*red[1]*U1; +\\ G2 has a 0 at the bottom right corner. + bez = bezout(G2[3,1],G2[3,2]); + U2 = [bez[1],G2[3,2]/bez[3],0;bez[2],-G2[3,1]/bez[3],0;0,0,-1]; + G3 = U2~*G2*U2; +\\ G3 has 0 under the co-diagonal. + cc = (G3[1,1])%2; + U3 = [1,0,0; cc,1,0; + round(-(G3[1,1]+cc*(2*G3[1,2]+G3[2,2]*cc))/2/G3[1,3]), + round(-(G3[1,2]+cc*G3[2,2])/G3[1,3]),1]; - sol = matrix(length(fa),l); - for( j = 1, l, - n = length(G[j]); -\\ En dimension n, on calcule un produit de n symboles de Hilbert. - det = vector(n+1, i, matdet(matrix(i-1,i-1,k,m,G[j][k,m]))); - for( i = 1, length(fa), - sol[i,j] = prod( k = 1, n-1, hilbert(-det[k],det[k+1],fa[i]))*hilbert(det[n],det[n+1],fa[i]) < 0; - ) - ); -if( DEBUGLEVEL_qfsolve >= 4, print("sortie de Qflisteinvariants")); -return([fa,sol]); +return([U3~*G3*U3,red[2]*U1*U2*U3]); } -{Qfsolvemodp(G,p) = -\\ p a prime number. -\\ finds a solution mod p for the quadatic form G -\\ such that det(G) !=0 mod p and dim G = n>=3; -local(n,vdet,G2,sol,x1,x2,x3,N1,N2,N3,s,r); - n = length(G); - vdet = [0,0,0]; - for( i = 1, 3, - G2 = vecextract(G,1<=2. On suppose que G est symetrique a coefficients entiers. -\\ Renvoit [G',U,factd] avec U \in GLn(Q) telle que G'=U~*G*U*constante est entiere -\\ de determinant minimal. -\\ Renvoit p si la reduction est impossible a cause de la non-solubilite locale -\\ en p (seulement en dimension 3-4). -\\ factd est la factorisation de abs(det(G')) -\\ Si on connait la factorisation de matdet(G), on peut la donner en parametre -\\ pour gagner du temps. -local(n,U,factd,detG,i,vp,Ker,dimKer,Ker2,dimKer2,sol,aux,p,di,m); +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +\\ QUADRATIC FORMS MINIMIZATION \\ +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + +\\ Minimization of the quadratic form G, with nonzero determinant. +\\ of dimension n>=2. +\\ G must by symmetric and have integral coefficients. +\\ Returns [G',U,factd] with U in GLn(Q) such that G'=U~*G*U*constant +\\ is integral and has minimal determinant. +\\ In dimension 3 or 4, may return a prime p +\\ if the reduction at p is impossible because of the local non solvability. +\\ If given, factdetG must be equal to factor(abs(det(G))). +{qfminimize(G,factdetG) = +my(factd,U,Ker,Ker2,sol,aux,di); +my(p); +my(n,lf,i,vp,dimKer,dimKer2,m); n = length(G); - U = matid(n); factd = matrix(0,2); - detG = matdet(G); - if( !factdetG, factdetG = factor(detG)); - i = 1; - while(i <= length(factdetG[,1]), - p = factdetG[i,1]; - if( p == -1, i++; next); -if( DEBUGLEVEL_qfsolve >= 4, print("p=",p,"^",factdetG[i,2])); + if( !factdetG, factdetG = factor(matdet(G))); + + lf = length(factdetG[,1]); + i = 1; U = matid(n); + + while(i <= lf, vp = factdetG[i,2]; if( vp == 0, i++; next); -\\ Le cas vp=1 n'est minimisable que si n est impair. + p = factdetG[i,1]; + if( p == -1, i++; next); +if( DEBUGLEVEL_qfsolve >= 4, print(" p = ",p,"^",vp)); + +\\ The case vp = 1 can be minimized only if n is odd. if( vp == 1 && n%2 == 0, factd = concat(factd~, Mat([p,1])~)~; i++; next ); Ker = kermodp(G,p); dimKer = Ker[1]; Ker = Ker[2]; -\\ Rem: on a toujours dimKer <= vp -if( DEBUGLEVEL_qfsolve >= 4, print("dimKer = ",dimKer)); -\\ cas trivial: G est divisible par p. - if( dimKer == n, + +\\ Rem: we must have dimKer <= vp +if( DEBUGLEVEL_qfsolve >= 4, print(" dimKer = ",dimKer)); +\\ trivial case: dimKer = n + if( dimKer == n, +if( DEBUGLEVEL_qfsolve >= 4, print(" case 0: dimKer = n")); G /= p; factdetG[i,2] -= n; next ); G = Ker~*G*Ker; U = U*Ker; -\\ 1er cas: la dimension du noyau est plus petite que la valuation -\\ alors le noyau mod p contient un noyau mod p^2 + +\\ 1st case: dimKer < vp +\\ then the kernel mod p contains a kernel mod p^2 if( dimKer < vp, -if( DEBUGLEVEL_qfsolve >= 4, print("cas 1")); - Ker2 = kermodp(matrix(dimKer,dimKer,j,k,G[j,k]/p),p); - dimKer2 = Ker2[1]; Ker2 = Ker2[2]; - for( j = 1, dimKer2, Ker2[,j] /= p); - Ker2 = matdiagonalblock([Ker2,matid(n-dimKer)]); - G = Ker2~*G*Ker2; - U = U*Ker2; - factdetG[i,2] -= 2*dimKer2; -if( DEBUGLEVEL_qfsolve >= 4, print("fin cas 1")); +if( DEBUGLEVEL_qfsolve >= 4, print(" case 1: dimker < vp")); + if( dimKer == 1, +\\ G[,1] /= p; G[1,] /= p; + G[,1] /= p; G[1,] = G[1,]/p; + U[,1] /= p; + factdetG[i,2] -= 2 + , + Ker2 = kermodp(matrix(dimKer,dimKer,j,k,G[j,k]/p),p); + dimKer2 = Ker2[1]; Ker2 = Ker2[2]; + for( j = 1, dimKer2, Ker2[,j] /= p); + Ker2 = matdiagonalblock([Ker2,matid(n-dimKer)]); + G = Ker2~*G*Ker2; + U = U*Ker2; + factdetG[i,2] -= 2*dimKer2 +); + +if( DEBUGLEVEL_qfsolve >= 4, print(" end of case 1")); next ); -\\ Maintenant, vp = dimKer -\\ 2eme cas: la dimension du noyau est >=2 et contient un element de norme 0 mod p^2 - if( dimKer > 2 || - (dimKer == 2 && issquare(di=Mod((G[1,2]^2-G[1,1]*G[2,2])/p^2,p))), -\\ on cherche dans le noyau un elt de norme p^2... +\\ Now, we have vp = dimKer +\\ 2nd case: the dimension of the kernel is >=2 +\\ and contains an element of norm 0 mod p^2 + +\\ search for an element of norm p^2... in the kernel + if( dimKer > 2 || + (dimKer == 2 && issquare( di = Mod((G[1,2]^2-G[1,1]*G[2,2])/p^2,p))), if( dimKer > 2, -if( DEBUGLEVEL_qfsolve >= 4, print("cas 2.1")); +if( DEBUGLEVEL_qfsolve >= 4, print(" case 2.1")); dimKer = 3; - sol = Qfsolvemodp(matrix(3,3,j,k,G[j,k]/p),p) + sol = qfsolvemodp(matrix(3,3,j,k,G[j,k]/p),p) , -if( DEBUGLEVEL_qfsolve >= 4, print("cas 2.2")); - if( G[1,1]%p^2 == 0, +if( DEBUGLEVEL_qfsolve >= 4, print(" case 2.2")); + if( G[1,1]%p^2 == 0, sol = [1,0]~ , sol = [-G[1,2]/p+sqrt(di),Mod(G[1,1]/p,p)]~ ) ); - sol = centerlift(sol); sol /= content(sol); -if( DEBUGLEVEL_qfsolve >= 4, print("sol=",sol)); - Ker = vectorv(n, j, if( j<= dimKer, sol[j], 0)); \\ on complete avec des 0 + sol = centerlift(sol); + sol /= content(sol); +if( DEBUGLEVEL_qfsolve >= 4, print(" sol = ",sol)); + Ker = vectorv(n, j, if( j<= dimKer, sol[j], 0)); \\ fill with 0's Ker = completebasis(Ker,1); Ker[,n] /= p; G = Ker~*G*Ker; U = U*Ker; factdetG[i,2] -= 2; -if( DEBUGLEVEL_qfsolve >= 4, print("fin cas 2")); +if( DEBUGLEVEL_qfsolve >= 4, print(" end of case 2")); next ); -\\ Maintenant, vp = dimKer <= 2 -\\ et le noyau ne contient pas de vecteur de norme p^2... +\\ Now, we have vp = dimKer <= 2 +\\ and the kernel contains no vector with norm p^2... -\\ Dans certains cas, on peut echanger le noyau et l'image -\\ pour continuer a reduire. +\\ In some cases, exchanging the kernel and the image +\\ makes the minimization easy. m = (n-1)\2-1; if( ( vp == 1 && issquare(Mod(-(-1)^m*matdet(G)/G[1,1],p))) || ( vp == 2 && n%2 == 1 && n >= 5) || ( vp == 2 && n%2 == 0 && !issquare(Mod((-1)^m*matdet(G)/p^2,p))) - , -if( DEBUGLEVEL_qfsolve >= 4, print("cas 3")); + , +if( DEBUGLEVEL_qfsolve >= 4, print(" case 3")); Ker = matid(n); for( j = dimKer+1, n, Ker[j,j] = p); G = Ker~*G*Ker/p; U = U*Ker; factdetG[i,2] -= 2*dimKer-n; -if( DEBUGLEVEL_qfsolve >= 4, print("fin cas 3")); +if( DEBUGLEVEL_qfsolve >= 4, print(" end of case 3")); next ); -\\ On n'a pas pu minimiser. -\\ Si n == 3 ou n == 4 cela demontre la non-solubilite locale en p. - if( n == 3 || n == 4, -if( DEBUGLEVEL_qfsolve >= 1, print("pas de solution locale en ",p)); +\\ Minimization was not possible se far. +\\ If n == 3 or 4, this proves the local non-solubility at p. + if( n == 3 || n == 4, +if( DEBUGLEVEL_qfsolve >= 1, print(" no local solution at ",p)); return(p)); -if( DEBUGLEVEL_qfsolve >= 4, print("plus de minimisation possible")); +if( DEBUGLEVEL_qfsolve >= 4, print(" prime ",p," finished")); factd = concat(factd~,Mat([p,vp])~)~; i++ ); -\\print("Un=",log(vecmax(abs(U)))); - aux = qflll(U); -\\print("Ur=",log(vecmax(abs(U*aux)))); +\\ apply LLL to avoid coefficients explosion + aux = qflll(U/content(U)); return([aux~*G*aux,U*aux,factd]); } -{mymat(qfb) = qfb = Vec(qfb);[qfb[1],qfb[2]/2;qfb[2]/2,qfb[3]]; -} -{Qfbsqrtgauss(G,factdetG) = -\\ pour l'instant, ca ne marche que pour detG sans facteur carre -\\ sauf en 2, ou la valuation est 2 ou 3. -\\ factdetG contient la factorisation de 2*abs(disc G) -local(a,b,c,d,m,n,p,aux,Q1,M); -if( DEBUGLEVEL_qfsolve >=3, print("entree dans Qfbsqrtgauss avec",G,factdetG)); - G = Vec(G); - a = G[1]; b = G[2]/2; c = G[3]; d = a*c-b^2; - -\\ 1ere etape: on resout m^2 = a (d), m*n = -b (d), n^2 = c (d) + +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +\\ CLASS GROUP COMPUTATIONS \\ +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + +\\ Compute the square root of the quadratic form qfb. +\\ This function is not fully implemented. +\\ For the moment it only works for detqfb squarefree +\\ (except at 2, where the valuation is 2 or 3). +\\ factdet must be given and equal to factor(2*abs(det qfb)) +{qfbsqrt(qfb,factdet) = +my(G,m,n); +my(a,b,c,d,p); +my(aux,Q1,M); + +if( DEBUGLEVEL_qfsolve >=3, print(" starting qfbsqrt with ",qfb,factdet)); + G = Vec(qfb); + a = G[1]; b = (G[2]/2); c = G[3]; d = a*c-b^2; + +\\ 1st step: solve m^2 = a (d), m*n = -b (d), n^2 = c (d) m = n = Mod(1,1); - factdetG[1,2] -= 3; - for( i = 1, length(factdetG[,1]), - if( !factdetG[i,2], next); - p = factdetG[i,1]; + factdet[1,2] -= 3; + for( i = 1, length(factdet[,1]), + if( !factdet[i,2], next); + p = factdet[i,1]; if( gcd(a,p) == 1, aux = sqrt(Mod(a,p)); m = chinese(m,aux); @@ -594,38 +608,40 @@ if( DEBUGLEVEL_qfsolve >=3, print("entree dans Qfbsqrtgauss avec",G,factdetG)); m = chinese(m,-b/aux) ) ); - m = centerlift(m); n = centerlift(n); -if( DEBUGLEVEL_qfsolve >=4, print("m=",m); print("n=",n)); + m = centerlift(m); + n = centerlift(n); +if( DEBUGLEVEL_qfsolve >=4, print(" m = ",m); print(" n = ",n)); -\\ 2eme etape: on construit Q1 de det -1 tq Q1(x,y,0) = G(x,y) +\\ 2nd step: build Q1, with det=-1 such that Q1(x,y,0) = G(x,y) Q1 = [(n^2-c)/d, (m*n+b)/d, n ; (m*n+b)/d, (m^2-a)/d, m ; n, m, d ]; Q1 = -matadjoint(Q1); -\\ 3eme etape: on reduit Q1 jusqu'a [0,0,-1;0,1,0;-1,0,0] - M = LLLgoon3(Q1)[2][3,]; +\\ 3rd step: reduce Q1 to [0,0,-1;0,1,0;-1,0,0] + M = qflllgram_indefgoon2(Q1)[2][3,]; if( M[1] < 0, M = -M); -if( DEBUGLEVEL_qfsolve >=3, print("fin de Qfbsqrtgauss ")); +if( DEBUGLEVEL_qfsolve >=3, print(" end of qfbsqrt")); if( M[1]%2, return(Qfb(M[1],2*M[2],2*M[3])) , return(Qfb(M[3],-2*M[2],2*M[1]))); } -{class2(D,factdetG,Winvariants,U2) = -\\ On suit l'algorithme de Shanks/Bosma-Stevenhagen -\\ pour construire tout le 2-groupe de classes -\\ seulement pour D discriminant fondamental. -\\ lorsque D = 1(4), on travaille avec 4D. -\\ Si on connait la factorisation de abs(2*D), -\\ on peut la donner dans factdetG, et dans ce cas le reste -\\ de l'algorithme est polynomial. -\\ Si Winvariants est donne, l'algorithme s'arrete des qu'un element d'invariants=Winvariants -\\ est trouve. - -local(factD,n,rang,m,listgen,vD,p,vp,aux,invgen,im,Ker,Kerim,listgen2,G2,struct,E,compteur,red); - -if( DEBUGLEVEL_qfsolve >= 1, print("Construction du 2-groupe de classe de discriminant ",D)); - if( D%4 == 2 || D%4 == 3, print("Discriminant not congruent to 0,1 mod 4");return(0)); + +\\ Implementation of Shanks/Bosma-Stevenhagen algorithm +\\ to compute the 2-Sylow of the class group of discriminant D. +\\ Only works for D = fundamental discriminant. +\\ When D = 1(4), work with 4D. +\\ If given, factdetG must be equal to factor(abs(2*D)). +\\ Apart from this factorization, the algorithm is polynomial time. +\\ If Winvariants is given, the algorithm stops as soon as +\\ an element having these W-invariants is found. +{quadclass2(D,factdetG,Winvariants,U2) = +my(factD,listgen,E,invgen,im,Ker,Kerim,listgen2,G2,clgp2,red,auxg); +my(p,aux); +my(n,rang,m,vD,vp); + +if( DEBUGLEVEL_qfsolve >= 1, print(" Construction of the 2-class group of discriminant ",D)); + if( D%4 == 2 || D%4 == 3, error("quadclass2: Discriminant not congruent to 0,1 mod 4")); if( D==-4, return([[1],[Qfb(1,0,1)]])); @@ -635,21 +651,26 @@ if( DEBUGLEVEL_qfsolve >= 1, print("Construction du 2-groupe de classe de discri n = length(factD); rang = n-3; if(D>0, m = rang+1, m = rang); -if( DEBUGLEVEL_qfsolve >= 3, print("factD = ",factD)); - listgen = vector(max(0,m)); + if(m<0, m=0); +if( DEBUGLEVEL_qfsolve >= 3, print(" factD = ",factD)); + listgen = vector(m); - if( vD = valuation(D,2), + vD = valuation(D,2); + if( vD, E = Qfb(1,0,-D/4) , E = Qfb(1,1,(1-D)/4) ); -if( DEBUGLEVEL_qfsolve >= 3, print("E = ",E)); +if( DEBUGLEVEL_qfsolve >= 3, print(" E = ",E)); - if( type(Winvariants) == "t_COL" && (Winvariants == 0 || length(matinverseimage(U2*Mod(1,2),Winvariants))>0), return([[1],[E]])); + if( type(Winvariants) == "t_COL" + && (Winvariants == 0 + || length(matinverseimage(U2*Mod(1,2),Winvariants))>0) + , return([[1],[E]])); - for( i = 1, m, \\ on ne regarde pas factD[1]=-1, ni factD[2]=2 + for( i = 1, m, \\ no need to look at factD[1]=-1, nor factD[2]=2 p = factD[i+2]; vp = valuation(D,p); - aux = p^vp; + aux = (p^vp); if( vD, listgen[i] = Qfb(aux,0,-D/4/aux) , listgen[i] = Qfb(aux,aux,(aux-D/aux)/4)) @@ -659,17 +680,17 @@ if( DEBUGLEVEL_qfsolve >= 3, print("E = ",E)); if( vD == 3, m++; rang++; listgen = concat(listgen,[Qfb(2^(vD-2),0,-D/2^vD)])); -if( DEBUGLEVEL_qfsolve >= 3, print("listgen = ",listgen)); -if( DEBUGLEVEL_qfsolve >= 2, print("rang = ",rang)); +if( DEBUGLEVEL_qfsolve >= 3, print(" listgen = ",listgen)); +if( DEBUGLEVEL_qfsolve >= 2, print(" rank = ",rang)); if( !rang, return([[1],[E]])); - invgen = Qflisteinvariants(listgen,factD)[2]*Mod(1,2); -if( DEBUGLEVEL_qfsolve >= 3, printp("invgen = ",lift(invgen))); + invgen = qflocalinvariants(listgen,factD)[2]*Mod(1,2); +if( DEBUGLEVEL_qfsolve >= 3, print(" invgen = ",lift(invgen))); - struct = vector(m,i,2); + clgp2 = vector(m,i,2); im = lift(matinverseimage(invgen,matimage(invgen))); - while( (length(im) < rang) + while( (length(im) < rang) || (type(Winvariants) == "t_COL" && length(matinverseimage(concat(invgen,U2),Winvariants) == 0)), Ker = lift(matker(invgen)); Kerim = concat(Ker,im); @@ -680,26 +701,26 @@ if( DEBUGLEVEL_qfsolve >= 3, printp("invgen = ",lift(invgen))); if( Kerim[j,i], listgen2[i] = qfbcompraw(listgen2[i],listgen[j]))); if( norml2(Kerim[,i]) > 1, - red = QfbReduce(aux=mymat(listgen2[i])); - aux = red~*aux*red; - listgen2[i] = Qfb(aux[1,1],2*aux[1,2],aux[2,2])) + red = qfbreduce(auxg=Mat(listgen2[i])); + auxg = red~*auxg*red; + listgen2[i] = Qfb(auxg[1,1],2*auxg[1,2],auxg[2,2])) ); listgen = listgen2; invgen = invgen*Kerim; -if( DEBUGLEVEL_qfsolve >= 4, print("listgen = ",listgen)); -if( DEBUGLEVEL_qfsolve >= 4, printp("invgen = ",lift(invgen))); +if( DEBUGLEVEL_qfsolve >= 4, print(" listgen = ",listgen)); +if( DEBUGLEVEL_qfsolve >= 4, print(" invgen = ",lift(invgen))); for( i = 1, length(Ker), - G2 = Qfbsqrtgauss(listgen[i],factdetG); - struct[i] <<= 1; + G2 = qfbsqrt(listgen[i],factdetG); + clgp2[i] <<= 1; listgen[i] = G2; - invgen[,i] = Qflisteinvariants(G2,factD)[2][,1]*Mod(1,2) + invgen[,i] = qflocalinvariants(G2,factD)[2][,1]*Mod(1,2) ); -if( DEBUGLEVEL_qfsolve >= 3, print("listgen = ",listgen)); -if( DEBUGLEVEL_qfsolve >= 3, printp("invgen = ",lift(invgen))); -if( DEBUGLEVEL_qfsolve >= 3, print("struct = ",struct)); +if( DEBUGLEVEL_qfsolve >= 3, print(" listgen = ",listgen)); +if( DEBUGLEVEL_qfsolve >= 3, print(" invgen = ",lift(invgen))); +if( DEBUGLEVEL_qfsolve >= 3, print(" clgp2 = ",clgp2)); im = lift(matinverseimage(invgen,matimage(invgen))) ); @@ -711,105 +732,232 @@ if( DEBUGLEVEL_qfsolve >= 3, print("struct = ",struct)); if( im[j,i], listgen2[i] = qfbcompraw(listgen2[i],listgen[j]))); if( norml2(im[,i]) > 1, - red = QfbReduce(aux=mymat(listgen2[i])); - aux = red~*aux*red; - listgen2[i] = Qfb(aux[1,1],2*aux[1,2],aux[2,2])) + red = qfbreduce(auxg=Mat(listgen2[i])); + auxg = red~*auxg*red; + listgen2[i] = Qfb(auxg[1,1],2*auxg[1,2],auxg[2,2])) ); listgen = listgen2; \\ listgen = vector(rang,i,listgen[m-rang+i]); - struct = vector(rang,i,struct[m-rang+i]); + clgp2 = vector(rang,i,clgp2[m-rang+i]); -if( DEBUGLEVEL_qfsolve >= 2, print("listgen = ",listgen)); -if( DEBUGLEVEL_qfsolve >= 2, print("struct = ",struct)); +if( DEBUGLEVEL_qfsolve >= 2, print(" listgen = ",listgen)); +if( DEBUGLEVEL_qfsolve >= 2, print(" clgp2 = ",clgp2)); -return([struct,listgen]); +return([clgp2,listgen]); } -{Qfsolve(G,factD) = -\\ Resolution de la forme quadratique X^tGX=0 de dimension n >= 3. -\\ On suppose que G est entiere et primitive. -\\ La solution peut etre un vectorv ou une matrice. -\\ S'il n'y a pas de solution, alors renvoit un p tel -\\ qu'il n'existe pas de solution locale en p. -\\ -\\ Si on connait la factorisation de -abs(2*matdet(G)), -\\ on peut la passer par le parametre factD pour gagner du temps. -local(n,M,signG,d,Min,U,codim,aux,G1,detG1,M1,subspace1,G2,subspace2,M2,solG2,Winvariants,dQ,factd,U2,clgp2,V,detG2,dimseti,solG1,sol,Q); +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +\\ QUADRATIC EQUATIONS \\ +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -if( DEBUGLEVEL_qfsolve >= 1, print("entree dans Qfsolve")); +\\ Try to solve G = 0 with small coefficients +\\ This is proved to work if +\\ - det(G) = 1, dim <= 6 and G is LLL reduced \\ -\\ 1ere reduction des coefficients de G +\\ Returns [G,matid] if no solution is found. +\\ Exit with a norm 0 vector if one such is found. +\\ If base == 1 and norm 0 is obtained, returns [H~*G*H,H,sol] where +\\ sol is a norm 0 vector and is the 1st column of H. +{qfsolvetriv(G,base=0) = +my(n); +my(H,sol,GG); + + n = length(G); + H = matid(n); + +\\ case 1: A basis vector is isotropic + for( i = 1, n, + if( G[i,i] == 0, + sol = H[,i]; + if( base == 0, return(sol)); + H[,i] = H[,1]; H[,1] = sol; + return([H~*G*H,H,sol]) + ) + ); + +\\ case 2: G has a block +- [1,0;0,-1] on the diagonal + for( i = 2, n, + if( G[i-1,i] == 0 && G[i-1,i-1]*G[i,i] == -1, + H[i-1,i] = -1; sol = H[,i]; + if( base == 0, return(sol)); + H[,i] = H[,1]; H[,1] = sol; + return([H~*G*H,H,sol]) + ) + ); + +\\ case 3: a principal minor is 0 + for( i = 1, n, + GG = vecextract(G,1<=3; +{qfsolvemodp(G,p) = +my(vdet,G2,sol,x1,x2,x3,N1,N2,N3,s); +my(r); +my(n); + + n = length(G); + vdet = [0,0,0]; + for( i = 1, 3, + G2 = vecextract(G,1<= 1, +\\ solves over Z the quadratic equation X^tGX = 0. +\\ G is assumed to have integral coprime coefficients. +\\ The solution might be a vectorv or a matrix. +\\ If no solution exists, returns an integer, that can +\\ be a prime p such that there is no local solution at p, +\\ or -1 if there is no real solution, +\\ or 0 in some rare cases. \\ +\\ If given, factD must be equal to factor(-abs(2*matdet(G))). +{qfsolve(G,factD=0) = +my(M,signG,Min,U,G1,auxg,M1,subspace1,G2,subspace2,M2,solG2,Winvariants,factd,U2,clgp2,V,solG1,sol,Q); +my(d,di,aux,detG1,dQ,detG2); +my(n,codim,dimseti); +if( DEBUGLEVEL_qfsolve >= 1, print(" starting qfsolve")); + + if( type(G) != "t_MAT", error(" wrong type in qfsolve: should be a t_MAT")); n = length(G); - M = IndefiniteLLL(G); + if( n == 0, error(" dimension should be > 0")); + if( n != length(G[,1]), error(" not a square matrix in qfsolve")); + +\\ Trivial case: det = 0 + + d = matdet(G); + + if( d == 0, +if( DEBUGLEVEL_qfsolve >= 1, print(" trivial case: det = 0")); + return(matker(G))); + +\\ Small dimension: n <= 2 + + if( n == 1, +if( DEBUGLEVEL_qfsolve >= 1, print(" trivial case: dim = 1")); + return(0)); + if( n == 2, +if( DEBUGLEVEL_qfsolve >= 1, print(" trivial case: dim = 2")); + if( !issquare(-d), return(0)); + di = sqrtint(-d); + return([-G[1,2]+di,G[1,1]]~) + ); + +\\ +\\ 1st reduction of the coefficients of G +\\ + + M = qflllgram_indef(G); if( type(M) == "t_COL", -if( DEBUGLEVEL_qfsolve >= 1, print("solution ",M)); +if( DEBUGLEVEL_qfsolve >= 1, print(" solution ",M)); +if( DEBUGLEVEL_qfsolve >= 1, print(" end of qfsolve")); return(M)); G = M[1]; M = M[2]; -\\ Solubilite reelle +\\ Real solubility signG = qfsign(G); if( signG[1] == 0 || signG[2] == 0, -if( DEBUGLEVEL_qfsolve >= 1, print("pas de solution reelle")); +if( DEBUGLEVEL_qfsolve >= 1, print(" no real solution")); +if( DEBUGLEVEL_qfsolve >= 1, print(" end of qfsolve")); return(-1)); if( signG[1] < signG[2], G = -G; signG = signG*[0,1;1,0]); -\\ Factorisation du determinant - d = matdet(G); - if( !factD, -if( DEBUGLEVEL_qfsolve >= 1, print("factorisation du determinant")); +\\ Factorization of the determinant + if( !factD, +if( DEBUGLEVEL_qfsolve >= 1, print1(" factorization of the determinant = ")); factD = factor(-abs(2*d)); + factD[1,2] = 0; + factD[2,2] --; if( DEBUGLEVEL_qfsolve >= 1, print(factD)) ); - factD[1,2] = 0; - factD[2,2] --; \\ -\\ Minimisation et solubilite locale. +\\ Minimization and local solubility \\ -if( DEBUGLEVEL_qfsolve >= 1, print("minimisation du determinant")); - Min = Qfminim(G,factD); +if( DEBUGLEVEL_qfsolve >= 1, print(" minimization of the determinant")); + Min = qfminimize(G,factD); if( type(Min) == "t_INT", -if( DEBUGLEVEL_qfsolve >= 1, print("pas de solution locale en ",Min)); +if( DEBUGLEVEL_qfsolve >= 1, print(" no local solution at ",Min)); +if( DEBUGLEVEL_qfsolve >= 1, print(" end of qfsolve")); return(Min)); M = M*Min[2]; G = Min[1]; -\\ Min[3] contient la factorisation de abs(matdet(G)); +\\ Min[3] contains the factorization of abs(matdet(G)); -if( DEBUGLEVEL_qfsolve >= 4, print("G minime = ",G)); -if( DEBUGLEVEL_qfsolve >= 4, print("d=",d)); +if( DEBUGLEVEL_qfsolve >= 4, print(" G minim = ",G)); +if( DEBUGLEVEL_qfsolve >= 4, print(" d = ",d)); -\\ Maintenant, on sait qu'il y a des solutions locales -\\ (sauf peut-etre en 2 si n==4), -\\ si n==3, det(G) = +-1 -\\ si n==4, ou si n est impair, det(G) est sans facteur carre. -\\ si n>=6, det(G) toutes les valuations sont <=2. +\\ Now, we know that local solutions exist +\\ (except maybe at 2 if n==4), +\\ if n==3, det(G) = +-1 +\\ if n==4, or n is odd, det(G) is squarefree. +\\ if n>=6, det(G) has all its valuations <=2. -\\ Reduction de G et recherche de solution triviales -\\ par exemple quand det G=+-1, il y en a toujours. +\\ Reduction of G and search for trivial solutions. +\\ When det G=+-1, such trivial solutions always exist. -if( DEBUGLEVEL_qfsolve >= 1, print("reduction")); - U = IndefiniteLLL(G); +if( DEBUGLEVEL_qfsolve >= 1, print(" reduction")); + U = qflllgram_indef(G); if(type(U) == "t_COL", -if( DEBUGLEVEL_qfsolve >= 1, print("solution ",M*U)); +if( DEBUGLEVEL_qfsolve >= 1, print(" solution = ",M*U)); +if( DEBUGLEVEL_qfsolve >= 1, print(" end of qfsolve")); return(M*U)); G = U[1]; M = M*U[2]; \\ -\\ Quand n >= 6 est pair, il faut passer en dimension n+1 -\\ pour supprimer tous les carres de det(G). +\\ If n >= 6 is even, need to increment the dimension by 1 +\\ to suppress all the squares of det(G). \\ if( n >= 6 && n%2 == 0 && matsize(Min[3])[1] != 0, -if( DEBUGLEVEL_qfsolve >= 1, print("On passe en dimension ",n+1)); +if( DEBUGLEVEL_qfsolve >= 1, print(" increase the dimension by 1 = ",n+1)); codim = 1; n++; -\\ On calcule le plus grand diviseur carre de d. - aux = prod( i = 1, matsize(Min[3])[1], if( Min[3][i,1] == 2, Min[3][i,1], 1)); -\\ On choisit le signe de aux pour que la signature de G1 -\\ soit la plus equilibree possible. +\\ largest square divisor of d. + aux = 1; + for( i = 1, matsize(Min[3])[1], + if( Min[3][i,1] == 2, aux *= Min[3][i,1])); +\\ Choose the sign of aux such that the signature of G1 +\\ is as balanced as possible if( signG[1] > signG[2], signG[2] ++; aux = -aux , signG[1] ++ @@ -819,7 +967,7 @@ if( DEBUGLEVEL_qfsolve >= 1, print("On passe en dimension ",n+1)); for( i = 2, length(factD[,1]), factD[i,2] = valuation(detG1,factD[i,1])); factD[2,2]--; - Min = Qfminim(G1,factD); + Min = qfminimize(G1,factD); G1 = Min[1]; M1 = Min[2]; subspace1 = matrix(n,n-1,i,j, i == j) @@ -827,161 +975,226 @@ if( DEBUGLEVEL_qfsolve >= 1, print("On passe en dimension ",n+1)); G1 = G; subspace1 = M1 = matid(n) ); -\\ Maintenant d est sans facteur carre. +\\ Now, d is squarefree -\\ -\\ Si d n'est pas +-1, il faut passer en dimension n+2 +\\ +\\ If d is not +-1, need to increment the dimension by 2 \\ if( matsize(Min[3])[1] == 0, \\ if( abs(d) == 1, -if( DEBUGLEVEL_qfsolve >= 2, print(" detG2 = 1")); +if( DEBUGLEVEL_qfsolve >= 2, print(" detG2 = 1")); G2 = G1; subspace2 = M2 = matid(n); - solG2 = LLLgoon(G2,1) + solG2 = qflllgram_indefgoon(G2) , -if( DEBUGLEVEL_qfsolve >= 1, print("On passe en dimension ",n+2)); +if( DEBUGLEVEL_qfsolve >= 1, print(" increase the dimension by 2 = ",n+2)); codim += 2; subspace2 = matrix( n+2, n, i, j, i == j); - d = prod( i = 1, matsize(Min[3])[1],Min[3][i,1]); \\ d = abs(matdet(G1)); + d = 1; + for( i = 1, matsize(Min[3])[1], + d *= Min[3][i,1]); \\ d = abs(matdet(G1)); if( signG[2]%2 == 1, d = -d); \\ d = matdet(G1); - if( Min[3][1,1] == 2, factD = [-1], factD = [-1,2]); \\ si d est pair ... + if( Min[3][1,1] == 2, factD = [-1], factD = [-1,2]); \\ if d is even ... factD = concat(factD, Min[3][,1]~); -if( DEBUGLEVEL_qfsolve >= 4, print("factD=",factD)); +if( DEBUGLEVEL_qfsolve >= 4, print(" factD = ",factD)); -\\ Solubilite locale en 2 (c'est le seul cas qui restait a traiter !!) +\\ Solubility at 2 (this is the only remaining bad prime). if( n == 4 && d%8 == 1, - if( QfWittinvariant(G,2) == 1, -if( DEBUGLEVEL_qfsolve >= 1, print("pas de solution locale en 2")); + if( qflocalinvariant(G,2) == 1, +if( DEBUGLEVEL_qfsolve >= 1, print(" no local solution at 2")); +if( DEBUGLEVEL_qfsolve >= 1, print(" end of qfsolve")); return(2))); \\ -\\ Construction d'une forme Q de dim 2, a partir de ces invariants. +\\ Build a binary quadratic form with given invariants \\ Winvariants = vectorv(length(factD)); -\\ choix de la signature de Q. -\\ invariant reel et signe du discriminant. +\\ choose the signature of Q. +\\ (real invariant and sign of the discriminant) dQ = abs(d); if( signG[1] ==signG[2], dQ = dQ; Winvariants[1] = 0); \\ signQ = [1,1]; if( signG[1] > signG[2], dQ =-dQ; Winvariants[1] = 0); \\ signQ = [2,0]; if( n == 4 && dQ%4 != 1, dQ *= 4); if( n >= 5, dQ *= 8); -\\ invariants p-adiques -\\ pour p = 2, on ne choisit pas. - if( n == 4, -if( DEBUGLEVEL_qfsolve >= 1, print("calcul des invariants locaux de G1")); - aux = Qflisteinvariants(-G1,factD)[2][,1]; - for( i = 3, length(factD), Winvariants[i] = aux[i]) +\\ p-adic invariants +\\ for p = 2, the choice is fixed from the product formula + if( n == 4, +if( DEBUGLEVEL_qfsolve >= 1, print(" compute the local invariants of G1")); + auxg = qflocalinvariants(-G1,factD)[2][,1]; + for( i = 3, length(factD), Winvariants[i] = auxg[i]) , - aux = (-1)^((n-3)/2)*dQ/d; \\ ici aux = 8 ou -8 - for( i = 3, length(factD), Winvariants[i] = hilbert(aux,factD[i],factD[i]) > 0) + aux = ((-1)^((n-3)/2)*dQ/d); \\ ici aux = 8 ou -8 + for( i = 3, length(factD), + Winvariants[i] = myhilbert(aux,factD[i],factD[i]) > 0) ); Winvariants[2] = sum( i = 1, length(factD), Winvariants[i])%2; if( DEBUGLEVEL_qfsolve >= 1, - print("Recherche d'un forme binaire de discriminant = ",dQ); - print("et d'invariants de Witt = ",Winvariants)); + print(" Search for a binary quadratic form of discriminant = ",dQ); + print(" and Witt invariants = ",Winvariants)); -\\ On construit le 2-groupe de classes de disc dQ, -\\ jusqu'a obtenir une combinaison des generateurs qui donne les bons invariants. -\\ En dim 4, il faut chercher parmi les formes du type q, 2*q -\\ car Q peut etre imprimitive. +\\ Construction of the 2-class group of discriminant dQ +\\ until some product of the generators gives the desired invariants. +\\ In dim 4, need to look among the forms of the type q or 2*q +\\ because Q might be imprimitive. factd = matrix(length(factD)-1,2); for( i = 1, length(factD)-1, factd[i,1] = factD[i+1]; factd[i,2] = valuation(dQ,factd[i,1])); factd[1,2]++; - U2 = matrix(length(factD), n == 4, i,j, hilbert(2,dQ,factD[i])<0); - clgp2 = class2(dQ,factd,Winvariants,U2); -if( DEBUGLEVEL_qfsolve >= 4, print("clgp2=",clgp2)); + U2 = matrix(length(factD), n == 4, i,j, myhilbert(2,dQ,factD[i])<0); + clgp2 = quadclass2(dQ,factd,Winvariants,U2); +if( DEBUGLEVEL_qfsolve >= 4, print(" clgp2 = ",clgp2)); clgp2 = clgp2[2]; - U = Qflisteinvariants(clgp2,factD)[2]; + U = qflocalinvariants(clgp2,factD)[2]; if( n == 4, U = concat(U,U2)); -if( DEBUGLEVEL_qfsolve >= 4, printp("U=",U)); +if( DEBUGLEVEL_qfsolve >= 4, print(" U = ",U)); V = lift(matinverseimage(U*Mod(1,2),Winvariants*Mod(1,2))); - if( !length(V), next); -if( DEBUGLEVEL_qfsolve >= 4, print("V=",V)); +if( DEBUGLEVEL_qfsolve >= 4, print(" V = ",V)); if( dQ%2 == 1, Q = qfbprimeform(4*dQ,1), Q = qfbprimeform(dQ,1)); - for( i = 1, length(clgp2), + for( i = 1, length(clgp2), if( V[i], Q = qfbcompraw(Q,clgp2[i]))); - Q = mymat(Q); - if( norml2(V) > 1, aux = QfbReduce(Q); Q = aux~*Q*aux); + Q = Mat(Q); + if( norml2(V) > 1, auxg = qfbreduce(Q); Q = auxg~*Q*auxg); if( n == 4 && V[length(V)], Q*= 2); -if( DEBUGLEVEL_qfsolve >= 2, print("Q=",Q)); -if( DEBUGLEVEL_qfsolve >= 3, print("invariants de Witt de Q=",Qflisteinvariants(Q,factD))); +if( DEBUGLEVEL_qfsolve >= 2, print(" Q = ",Q)); +if( DEBUGLEVEL_qfsolve >= 3, print(" Witt invariants of Q = ",qflocalinvariants(Q,factD))); \\ -\\ Construction d'une forme de dim=n+2 potentiellement unimodulaire +\\ Build a form of dim=n+2 potentially unimodular \\ G2 = matdiagonalblock([G1,-Q]); -if( DEBUGLEVEL_qfsolve >= 4, print("G2=",G2)); +if( DEBUGLEVEL_qfsolve >= 4, print(" G2 = ",G2)); -if( DEBUGLEVEL_qfsolve >= 2, print("minimisation de la forme quadratique de dimension ",length(G2))); -\\ Minimisation de G2 +if( DEBUGLEVEL_qfsolve >= 2, print(" minimization of the form of dimension ",length(G2))); +\\ Minimization of G2 detG2 = matdet(G2); factd = matrix(length(factD)-1,2); for( i = 1, length(factD)-1, factd[i,2] = valuation(detG2, factd[i,1] = factD[i+1])); -if( DEBUGLEVEL_qfsolve >= 3, print("det(G2) = ",factd)); - Min = Qfminim(G2,factd); +if( DEBUGLEVEL_qfsolve >= 3, print(" det(G2) = ",factd)); + Min = qfminimize(G2,factd); M2 = Min[2]; G2 = Min[1]; -if( abs(matdet(G2)) > 2, print("******* ERREUR dans Qfsolve: det(G2) <> +-1 *******",matdet(G2));return(0)); -if( DEBUGLEVEL_qfsolve >= 4, print("G2=",G2)); +if( abs(matdet(G2)) > 2, error("qfsolve: det(G2) <> +-1 *******")); +if( DEBUGLEVEL_qfsolve >= 4, print(" G2 = ",G2)); -\\ Maintenant det(G2) = +-1 +\\ Now, we have det(G2) = +-1 -\\ On construit un seti pour G2 (Sous-Espace Totalement Isotrope) -if( DEBUGLEVEL_qfsolve >= 2, print("recherche d'un espace de solutions pour G2")); - solG2 = LLLgoon(G2,1); +\\ Find a seti for G2 (Totally isotropic subspace, Sous-Espace Totalement Isotrope) +if( DEBUGLEVEL_qfsolve >= 2, print(" Search a subspace of solutions for G2")); + solG2 = qflllgram_indefgoon(G2); if( matrix(codim+1,codim+1,i,j,solG2[1][i,j]) != 0, -if( DEBUGLEVEL_qfsolve >= 2, print(" pas assez de solutions dans G2"));return(0)) + error("qfsolve: not enough solutions in G2")); ); -\\ G2 doit avoir un espace de solutions de dimension > codim +\\ G2 must have a subspace of solutions of dimension > codim dimseti = 0; while( matrix(dimseti+1,dimseti+1,i,j,solG2[1][i,j]) == 0, dimseti ++); if( dimseti <= codim, -print("dimseti = ",dimseti," <= codim = ",codim); -print("************* ERREUR : pas assez de solutions pour G2"); return(0)); + error("qfsolve: not enough solutions for G2")); solG2 = matrix(length(G2),dimseti,i,j,solG2[2][i,j]); -if( DEBUGLEVEL_qfsolve >= 3, print("solG2=",solG2)); +if( DEBUGLEVEL_qfsolve >= 3, print(" solG2 = ",solG2)); -\\ La solution de G1 se trouve a la fois dans solG2 et dans subspace2 -if( DEBUGLEVEL_qfsolve >= 1, print("Reconstruction de la solution de G1")); +\\ The solution of G1 is simultaneously in solG2 and subspace2 +if( DEBUGLEVEL_qfsolve >= 1, print(" Reconstruction of a solution of G1")); solG1 = matintersect(subspace2,M2*solG2); solG1 = subspace2~*solG1; -if( DEBUGLEVEL_qfsolve >= 3, print("solG1 = ",solG1)); +if( DEBUGLEVEL_qfsolve >= 3, print(" solG1 = ",solG1)); -\\ La solution de G se trouve a la fois dans solG et dans subspace1 -if( DEBUGLEVEL_qfsolve >= 1, print("Reconstruction de la solution de G")); +\\ The solution of G is simultaneously in solG and subspace1 +if( DEBUGLEVEL_qfsolve >= 1, print(" Reconstruction of a solution of G")); sol = matintersect(subspace1,M1*solG1); sol = subspace1~*sol; sol = M*sol; sol /= content(sol); if( length(sol) == 1, sol = sol[,1]); -if( DEBUGLEVEL_qfsolve >= 3, print("sol = ",sol)); -if( DEBUGLEVEL_qfsolve >= 1, print("fin de Qfsolve")); +if( DEBUGLEVEL_qfsolve >= 3, print(" sol = ",sol)); +if( DEBUGLEVEL_qfsolve >= 1, print(" end of qfsolve")); return(sol); } -{matdiagonalblock(v) = -local(lv,lt,M); - lv = length(v); - lt = sum( i = 1, lv, length(v[i])); - M = matrix(lt,lt); - lt = 0; - for( i = 1, lv, - for( j = 1, length(v[i]), - for( k = 1, length(v[i]), - M[lt+j,lt+k] = v[i][j,k])); - lt += length(v[i]) + +\\ G is a symmetric 3x3 matrix, and sol a solution of sol~*G*sol=0. +\\ Returns a parametrization of the solutions with the good invariants, +\\ as a matrix 3x3, where each line contains +\\ the coefficients of each of the 3 quadratic forms. +\\ If fl!=0, the fl-th form is reduced. +{qfparam(G,sol,fl=3) = +my(U,G1,G2); + +if( DEBUGLEVEL_qfsolve >= 5, print(" starting qfparam")); + sol /= content(sol); +\\ build U such that U[,3] = sol, and det(U) = +-1 + U = completebasis(sol,1); + G1 = U~*G*U; \\ G1 has a 0 at the bottom right corner + G2 = [-2*G1[1,3],-2*G1[2,3],0; + 0,-2*G1[1,3],-2*G1[2,3]; + G1[1,1],2*G1[1,2],G1[2,2]]; + sol = U*G2; + if(fl, + U = qflllgram_indef([sol[fl,1],sol[fl,2]/2; sol[fl,2]/2,sol[fl,3]],1,1)[2]; + U = [U[1,1]^2,2*U[1,2]*U[1,1],U[1,2]^2; + U[2,1]*U[1,1],U[2,2]*U[1,1]+U[2,1]*U[1,2],U[1,2]*U[2,2]; + U[2,1]^2,2*U[2,1]*U[2,2],U[2,2]^2]; + sol = sol*U ); -return(M); +if( DEBUGLEVEL_qfsolve >= 5, print(" end of qfparam")); +return(sol); +} + +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +\\ HELP MESSAGES \\ +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + +{ +addhelp(default_qfsolve, + "default_qfsolve(DEBUGLEVEL_qfsolve): + output or set the value of the global variable DEBUGLEVEL_qfsolve. + The higher the value, the more information you get about intermediate + results concerning functions related to qfsolve. + default is 0: print nothing."); +addhelp(qflllgram_indef, + "qflllgram_indef(G,{c}): Solve or reduce the quadratic form G with integral coefficients. G might be definite or indefinite. This is an lll-type algorithm with a constant 1/4 G=[1637490518557, -9118398255553, -17114399686722; -9118398255553, -40039266946520, 44178901566187; -17114399686722, 44178901566187, 150094052078168]; + gp > qflllgram_indef(G) + %1 = [-24749181067550, 1904107022307, -3382470700136]~ +"); +addhelp(qfsolve, + "Given a square matrix G of dimension n >= 1, solve over Q the quadratic equation X^tGX = 0. G is assumed to have integral coprime coefficients. + The solution might be a single vector (vectorv) or a matrix (whose columns generate a totally isotropic subspace). + If no solution exists, returns an integer, that can be a prime p such that there is no local solution at p, or -1 if there is no real solution, or 0 in some rare cases. + To save time, a second optional parameter factD can be given and must be equal to factor(-abs(2*matdet(G))). + Example: + gp > G = [1,0,0;0,1,0;0,0,-34]; + gp > qfsolve(G) + %1 = [-3, -5, 1]~"); +addhelp(qfparam, + "qfparam(G,sol,{fl}): Coefficients of quadratic forms that parametrize the + solutions of the ternary quadratic form G, using the particular + solution sol. + fl is optional and can be 1, 2, or 3, in which case the 'fl'th form is + reduced. The default is fl=3. + + Example: + gp > G = [1,0,0;0,1,0;0,0,-34]; + gp > qfparam(G,qfsolve(G)) + %2 = + [ 3 -10 -3] + + [-5 -6 5] + + [ 1 0 1] + Indeed, the solutions can be parametrized as + [3*x^2 - 10*y*x - 3*y^2, -5*x^2 - 6*y*x + 5*y^2, x^2 + y^2]~"); } diff --git a/src/ext/pari/simon/resultant3.gp b/src/ext/pari/simon/resultant3.gp index 14b9046d808..2c1e44e2e12 100644 --- a/src/ext/pari/simon/resultant3.gp +++ b/src/ext/pari/simon/resultant3.gp @@ -1,235 +1,307 @@ -\\ Ce fichier gp contient des fonctions pour calculer -\\ le resultant de trois polynomes p1,p2,p3 homogenes -\\ en trois variables (toujours x,y,z), ainsi que -\\ le discriminant d'un polynome homogene en ces trois variables. -\\ L'algorithme utilise est celui du sous-resultant. +\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +\\ Copyright (C) 2014 Denis Simon \\ -\\ *********************************************** -\\ * Auteur: Denis SIMON * -\\ * mail: desimon@math.unicaen.fr.fr * -\\ * date: 12 Dec 2003 * -\\ *********************************************** +\\ Distributed under the terms of the GNU General Public License (GPL) \\ -\\ exemple d'utilisation : -\\ -\\ ? p1=x^2-3*z^2+y*z;p2=x-y+15*z;p3=y^2*x+z^3-x*y*z+x^2*z; -\\ ? resultant3([p1,p2,p3]) -\\ %2 = 521784 -\\ ? discriminant3(p3) -\\ %3 = -63 -\\ -\\ la fonction hom sert a rendre homogene un polynome en x et y: -\\ ? ell=y^2-y-x^3+x^2; -\\ ? discriminant3(hom(ell)) -\\ %5 = -11 +\\ This code 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. \\ +\\ The full text of the GPL is available at: \\ +\\ http://www.gnu.org/licenses/ +\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + +/* + Auteur : + Denis SIMON -> simon@math.unicaen.fr + adresse du fichier : + www.math.unicaen.fr/~simon/resultant3.gp + + ********************************************* + * VERSION 13/01/2014 * + ********************************************* + + Ce fichier gp contient des fonctions pour calculer + le resultant de trois polynomes p1, p2, p3 homogenes + en trois variables (toujours x,y,z), ainsi que + le discriminant d'un polynome homogene en ces trois variables. + L'algorithme utilise est celui du sous-resultant. + + + exemple d'utilisation : + + ? p1=x^2-3*z^2+y*z;p2=x-y+15*z;p3=y^2*x+z^3-x*y*z+x^2*z; + ? resultant3([p1,p2,p3]) + %2 = 521784 + ? discriminant3(p3) + %3 = -63 + + la fonction hom sert a rendre homogene un polynome en x et y: + ? ell=y^2-y-x^3+x^2; + ? discriminant3(hom(ell)) + %5 = -11 + +*/ + +global(DEBUGLEVEL_res):small; + + DEBUGLEVEL_res = 0; \\ si DEBUGLEVEL_res = 1 : afficher des resultats intermediaires. -{hom(p)= -p=subst(subst(z^100*p,x,x/z),y,y/z); -p/=z^myvaluation(p,z); +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +\\ SCRIPT \\ +\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + +{default_res( + DEBUGLEVEL_res_val:small = 0 + ) = + + DEBUGLEVEL_res = DEBUGLEVEL_res_val; + print(" DEBUGLEVEL_res = ",DEBUGLEVEL_res); +} +{hom(p) = + p = substvec(p,['x,'y],['x/'z,'y/'z]); + p /= 'z^valuation(p,'z); return(p); } -\\ +{degreetot(p) = \\ degre d'un polynome homogene. -\\ -{degreetot(p)= -local(auxdeg,auxp); -auxdeg=poldegree(p,x);auxp=pollead(p,x); -auxdeg+=poldegree(auxp,y);auxp=pollead(auxp,y); -auxdeg+=poldegree(auxp,z);auxp=pollead(auxp,z); +my(auxdeg,auxp); + + auxdeg = poldegree(p,'x); auxp = pollead(p,'x); + auxdeg += poldegree(auxp,'y); auxp = pollead(auxp,'y); + auxdeg += poldegree(auxp,'z); auxp = pollead(auxp,'z); return(auxdeg); } -\\ -{ex(vec,i,j)= -local(aux); -aux=vec[i];vec[i]=vec[j];vec[j]=aux; +{ex( vec, i, j) = +my(aux); + aux = vec[i]; vec[i] = vec[j]; vec[j] = aux; return(vec); } -{myvaluation(p,var)= -local(valp); -valp=0; -while(polcoeff(p,valp,var)==0,valp++); -return(valp); -} -{myvaluation2(p,var)= -local(pp,valp); -pp=p; -valp=0; -while(subst(pp,var,0)==0,valp++;pp/=var); -return(valp); +{mycontent(p) = +my(vz,co,dco); + vz = valuation(p,'z); + p = subst(p,'z,1); + co = content(p); + dco = poldegree(co,'y); + if( dco, co = subst(co,'y,'y/'z)*'z^dco); +return(co*'z^vz); } -{mycontent(p)= -local(vz,co,dco); -vz=myvaluation(p,z); -p=subst(p,z,1); -co=content(p); -dco=poldegree(co,y); -if(dco,co=subst(co,y,y/z)*z^dco); -return(co*z^vz); -} -{resultant2(p,q)= -local(dp,dq,valp,valq,auxr,auxp,auxq,res); -if(p==0 || q==0,return(0)); -dp=degreetot(p);dq=degreetot(q); -valp=myvaluation(p,y); -valq=myvaluation(q,y); -if(valp && valq,return(0)); -auxr=1; -if(valp, - if(dq%2 && valp%2,auxr=-1); - auxr*=pollead(q,x)^valp); -if(valq,auxr=pollead(p,x)^valq); -auxp=subst(p,y,1); -auxq=subst(q,y,1); -res=auxr*polresultant(auxp,auxq,x); +{myresultant2( p, q) = +my(dp,dq,valp,valq,auxr,auxp,auxq,res); + + if( p==0 || q==0, return(0)); + dp = degreetot(p); valp = valuation(p,'y); + dq = degreetot(q); valq = valuation(q,'y); + if( valp && valq, return(0)); + auxr = 1; + if( valp, + if(dq%2 && valp%2, auxr = -1); + auxr *= pollead(q,'x)^valp + ); + if( valq, + auxr = pollead(p,'x)^valq + ); + auxp = subst(p,'y,1); + auxq = subst(q,'y,1); + res = auxr*polresultant(auxp,auxq,'x); return(res); } -{resultantcomp(vp=[x,y,z])= +{resultantcomp(vp=['x,'y,'z]) = \\ les vp[i] sont des pol homogenes en x,y et z. \\ vp[3] ne depend que de y et z. -local(p,q,rt,dp,dq,drt,vy,vz,lrt,lp,res,aux,res2,dres2); -p=vp[1];q=vp[2];rt=vp[3]; -if(p==0 || q==0 || rt==0,return(0)); -dp=degreetot(p);dq=degreetot(q);drt=degreetot(rt); -if(drt==0,return(rt^(dp*dq))); -vy=myvaluation(rt,y);vz=myvaluation(rt,z); -rt=subst(rt,y,1);if(vz,rt/=z^vz); -lrt=polcoeff(rt,drt,z);lp=polcoeff(p,dp,x); -res=1; -if(lp==0, - aux=p;p=q;q=aux; - aux=dp;dp=dq;dq=aux; - if(dp%2 && dq%2 && drt%2,res=-res); - lp=polcoeff(p,dp,x); - if(lp==0,return(0))); -if(vy, - if(dp%2 && dq%2, res2=-1,res2=1); - res2*=resultant2(subst(subst(p,y,0),z,y),subst(subst(q,y,0),z,y)); - if(res2==0,return(0)); - res*=res2^vy); -if(vz, - res2=resultant2(subst(p,z,0),subst(q,z,0)); - if(res2==0,return(0)); - res*=res2^vz); -drt-=(vy+vz); -if(drt==0,return(res*rt^(dp*dq))); -res2=polresultant(subst(p,y,1),subst(q,y,1),x); -dres2=poldegree(res2,z); -res2=polresultant(rt,res2,z); -res*=res2; -if(dq!=poldegree(subst(q,y,1),x),res*=lp^(drt*(dq-poldegree(subst(q,y,1),x)))); -if(dres2!=dp*dq,res*=pollead(rt,z)^(dp*dq-dres2)); +my(p,q,rt,dp,dq,drt,vy,vz,lrt,lp,res,aux,res2,dres2); + + p = vp[1]; q = vp[2]; rt = vp[3]; + if( p==0 || q==0 || rt==0, return(0)); + dp = degreetot(p); dq = degreetot(q); drt = degreetot(rt); + if( drt == 0, return(rt^(dp*dq))); + vy = valuation(rt,'y); vz = valuation(rt,'z); + rt = subst(rt,'y,1); if( vz, rt /= 'z^vz); + lrt = polcoeff(rt,drt,'z); lp = polcoeff(p,dp,'x); + res = 1; + if( lp == 0, + aux = p; p = q; q = aux; + aux = dp; dp = dq; dq = aux; + if( dp%2 && dq%2 && drt%2, res = -res); + lp = polcoeff(p,dp,'x); + if( lp == 0, return(0)) + ); + if( vy, + if( dp%2 && dq%2, res2 = -1, res2 = 1); + res2 *= myresultant2(subst(subst(p,'y,0),'z,'y),subst(subst(q,'y,0),'z,'y)); + res2 *= myresultant2(subst(subst(p,'y,0),'z,'y),subst(subst(q,'y,0),'z,'y)); + if( res2 == 0, return(0)); + res *= res2^vy + ); + if( vz, + res2 = myresultant2(subst(p,'z,0),subst(q,'z,0)); + if( res2 == 0, return(0)); + res *= res2^vz + ); + drt -= vy+vz; + if( drt == 0, return(res*rt^(dp*dq))); + res2 = polresultant(subst(p,'y,1),subst(q,'y,1),'x); + dres2 = poldegree(res2,'z); + res2 = polresultant(rt,res2,'z); + res *= res2; + if( dq != poldegree(subst(q,'y,1),'x), + res *= lp^(drt*(dq-poldegree(subst(q,'y,1),'x)))); + if( dres2 != dp*dq, + res *= pollead(rt,'z)^(dp*dq-dres2)); return(res); } -{resultant3(vp=[x,y,z],fl)= +{resultant3(vp=['x,'y,'z]) = \\ resultant de 3 polynomes homogenes en x,y,z. -\\ fl=1 pour afficher des resultats intermediaires. \\ on travaille sur la variable x. -local(vdt,vdx,prodd,s,denom,nume,lp,p0,q0,r0,dd,cq,rm,res); +my(vdt,vdx,prodd,s,denom,nume,lp,p0,q0,r0,dd,cq,rm,res,delta); -for(i=1,3,if(vp[i]==0,return(0))); -vdt=vector(3,i,degreetot(vp[i])); -vdx=vector(3,i,poldegree(vp[i],x)); -if(vecmin(vdt-vdx),return(0)); + for( i = 1, 3, + if( vp[i] == 0, return(0))); + vdt = vector(3,i,degreetot(vp[i])); + vdx = vector(3,i,poldegree(vp[i],'x)); + if( vecmin(vdt-vdx), return(0)); \\ en effet, dans ce cas, les polynomes sont dans l'ideal -prodd=prod(i=1,3,vdt[i]); -s=1; -denom=1;nume=1; + prodd = prod( i = 1, 3, vdt[i]); + s = 1; + denom = 1; nume = 1; + \\ on echange pour que vdx[1] >= vdx[2] >= vdx[3] -if(vdx[1]0, la 'fl'eme forme quadratique est reduite. +# For the documentation of the corresponding GP functions, see +# src/ext/pari/simon/qfsolve.gp. def qfsolve(G, factD=None): r""" @@ -67,6 +58,10 @@ def qfsolve(G, factD=None): Otherwise, returns `-1` if no solutions exists over the reals or a prime `p` if no solution exists over the `p`-adic field `\QQ_p`. + ALGORITHM: + + Uses Denis Simon's GP script ``qfsolve``. + EXAMPLES:: sage: from sage.quadratic_forms.qfsolve import qfsolve @@ -91,12 +86,12 @@ def qfsolve(G, factD=None): sage: M = Matrix(QQ, [[3, 0, 0, 0], [0, 5, 0, 0], [0, 0, -7, 0], [0, 0, 0, -11]]) sage: qfsolve(M) - (-3, 4, 3, 2) + (3, -4, -3, -2) """ gp = _gp_for_simon() if factD is not None: raise NotImplementedError, "qfsolve not implemented with parameter factD" - ret = gp('Qfsolve(%s)' % G._pari_init_()) + ret = gp('qfsolve(%s)' % G._pari_init_()) if str(ret.type()) == 't_COL': # Need explicit str(), see #15522 return tuple(QQ(r) for r in ret) return ZZ(ret) @@ -119,7 +114,7 @@ def qfparam(G, sol): ALGORITHM: - Uses Denis Simon's pari script Qfparam. + Uses Denis Simon's GP script ``qfparam``. EXAMPLES:: @@ -130,13 +125,13 @@ def qfparam(G, sol): [-12 0 -1] sage: sol = qfsolve(M); sage: ret = qfparam(M, sol); ret - (-t^2 - 12, 24*t, 24*t^2) + (-12*t^2 - 1, 24*t, 24) sage: ret[0].parent() is QQ['t'] True """ gp = _gp_for_simon() R = QQ['t'] t = R.gen() - s = 'Qfparam((%s), (%s)~)*[t^2,t,1]~' % (G._pari_init_(), list(sol)) + s = 'qfparam((%s), (%s)~)*[t^2,t,1]~' % (G._pari_init_(), list(sol)) ret = gp(s) return tuple(R(str(r)) for r in ret) diff --git a/src/sage/schemes/elliptic_curves/ell_number_field.py b/src/sage/schemes/elliptic_curves/ell_number_field.py index 62af7c3f6a4..22c956cc164 100644 --- a/src/sage/schemes/elliptic_curves/ell_number_field.py +++ b/src/sage/schemes/elliptic_curves/ell_number_field.py @@ -219,45 +219,48 @@ def simon_two_descent(self, verbose=0, lim1=5, lim3=50, limtriv=10, maxprob=20, Elliptic Curve defined by y^2 = x^3 + x + a over Number Field in a with defining polynomial x^2 + 7 sage: v = E.simon_two_descent(verbose=1); v - courbe elliptique : Y^2 = x^3 + Mod(1, y^2 + 7)*x + Mod(y, y^2 + 7) - points triviaux sur la courbe = [[1, 1, 0], [Mod(1/2*y + 3/2, y^2 + 7), Mod(-y - 2, y^2 + 7), 1]] + elliptic curve: Y^2 = x^3 + Mod(1, y^2 + 7)*x + Mod(y, y^2 + 7) + Trivial points on the curve = [[1, 1, 0], [Mod(1/2*y + 3/2, y^2 + 7), Mod(-y - 2, y^2 + 7), 1]] #S(E/K)[2] = 2 #E(K)/2E(K) = 2 #III(E/K)[2] = 1 - rang(E/K) = 1 - listpointsmwr = [[Mod(1/2*y + 3/2, y^2 + 7), Mod(-y - 2, y^2 + 7), 1]] + rank(E/K) = 1 + listpoints = [[Mod(1/2*y + 3/2, y^2 + 7), Mod(-y - 2, y^2 + 7), 1]] (1, 1, [(1/2*a + 3/2 : -a - 2 : 1)]) - sage: v = E.simon_two_descent(verbose=2) # random output + sage: v = E.simon_two_descent(verbose=2) K = bnfinit(y^2 + 7); a = Mod(y,K.pol); bnfellrank(K, [0,0,0,1,a]); - courbe elliptique : Y^2 = x^3 + Mod(1, y^2 + 7)*x + Mod(y, y^2 + 7) - A = 0 - B = Mod(1, y^2 + 7) - C = Mod(y, y^2 + 7) - LS2gen = [Mod(Mod(-5, y^2 + 7)*x^2 + Mod(-3*y, y^2 + 7)*x + Mod(8, y^2 + 7), x^3 + Mod(1, y^2 + 7)*x + Mod(y, y^2 + 7)), Mod(Mod(1, y^2 + 7)*x^2 + Mod(1/2*y - 1/2, y^2 + 7)*x - 1, x^3 + Mod(1, y^2 + 7)*x + Mod(y, y^2 + 7))] - #LS2gen = 2 - Recherche de points triviaux sur la courbe - points triviaux sur la courbe = [[1, 1, 0], [Mod(1/2*y + 3/2, y^2 + 7), Mod(-y - 2, y^2 + 7), 1]] - zc = Mod(Mod(-5, y^2 + 7)*x^2 + Mod(-3*y, y^2 + 7)*x + Mod(8, y^2 + 7), x^3 + Mod(1, y^2 + 7)*x + Mod(y, y^2 + 7)) - symbole de Hilbert (Mod(2, y^2 + 7),Mod(-5, y^2 + 7)) = -1 - zc = Mod(Mod(1, y^2 + 7)*x^2 + Mod(1/2*y - 1/2, y^2 + 7)*x + Mod(-1, y^2 + 7), x^3 + Mod(1, y^2 + 7)*x + Mod(y, y^2 + 7)) - symbole de Hilbert (Mod(-2*y + 2, y^2 + 7),Mod(1, y^2 + 7)) = 0 - sol de Legendre = [1, 0, 1]~ - zc*z1^2 = Mod(Mod(2*y - 2, y^2 + 7)*x + Mod(2*y + 10, y^2 + 7), x^3 + Mod(1, y^2 + 7)*x + Mod(y, y^2 + 7)) - quartique : (-1/2*y + 1/2)*Y^2 = x^4 + (-3*y - 15)*x^2 + (-8*y - 16)*x + (-11/2*y - 15/2) - reduite: Y^2 = (-1/2*y + 1/2)*x^4 - 4*x^3 + (-3*y + 3)*x^2 + (2*y - 2)*x + (1/2*y + 3/2) - non ELS en [2, [0, 1]~, 1, 1, [1, 1]~] - zc = Mod(Mod(1, y^2 + 7)*x^2 + Mod(1/2*y + 1/2, y^2 + 7)*x + Mod(-1, y^2 + 7), x^3 + Mod(1, y^2 + 7)*x + Mod(y, y^2 + 7)) - vient du point trivial [Mod(1/2*y + 3/2, y^2 + 7), Mod(-y - 2, y^2 + 7), 1] - m1 = 1 - m2 = 1 + elliptic curve: Y^2 = x^3 + Mod(1, y^2 + 7)*x + Mod(y, y^2 + 7) + A = 0 + B = Mod(1, y^2 + 7) + C = Mod(y, y^2 + 7) + Computing L(S,2) + L(S,2) = [Mod(Mod(-1, y^2 + 7)*x^2 + Mod(-1/2*y + 1/2, y^2 + 7)*x + 1, x^3 + Mod(1, y^2 + 7)*x + Mod(y, y^2 + 7)), Mod(Mod(-1, y^2 + 7)*x^2 + Mod(-1/2*y - 1/2, y^2 + 7)*x + 1, x^3 + Mod(1, y^2 + 7)*x + Mod(y, y^2 + 7)), Mod(-1, x^3 + Mod(1, y^2 + 7)*x + Mod(y, y^2 + 7)), Mod(Mod(-1/2*y + 1/2, y^2 + 7)*x + Mod(-1/2*y + 3/2, y^2 + 7), x^3 + Mod(1, y^2 + 7)*x + Mod(y, y^2 + 7)), Mod(Mod(1, y^2 + 7)*x + Mod(1/2*y + 3/2, y^2 + 7), x^3 + Mod(1, y^2 + 7)*x + Mod(y, y^2 + 7)), Mod(Mod(-1, y^2 + 7)*x + Mod(-1/2*y + 3/2, y^2 + 7), x^3 + Mod(1, y^2 + 7)*x + Mod(y, y^2 + 7))] + Computing the Selmer group + #LS2gen = 2 + LS2gen = [Mod(Mod(-5, y^2 + 7)*x^2 + Mod(-3*y, y^2 + 7)*x + Mod(8, y^2 + 7), x^3 + Mod(1, y^2 + 7)*x + Mod(y, y^2 + 7)), Mod(Mod(1, y^2 + 7)*x^2 + Mod(1/2*y - 1/2, y^2 + 7)*x - 1, x^3 + Mod(1, y^2 + 7)*x + Mod(y, y^2 + 7))] + Search for trivial points on the curve + Trivial points on the curve = [[1, 1, 0], [Mod(1/2*y + 3/2, y^2 + 7), Mod(-y - 2, y^2 + 7), 1]] + zc = Mod(Mod(-5, y^2 + 7)*x^2 + Mod(-3*y, y^2 + 7)*x + Mod(8, y^2 + 7), x^3 + Mod(1, y^2 + 7)*x + Mod(y, y^2 + 7)) + Hilbert symbol (Mod(2, y^2 + 7),Mod(-5, y^2 + 7)) = + zc = Mod(Mod(1, y^2 + 7)*x^2 + Mod(1/2*y - 1/2, y^2 + 7)*x + Mod(-1, y^2 + 7), x^3 + Mod(1, y^2 + 7)*x + Mod(y, y^2 + 7)) + Hilbert symbol (Mod(-2*y + 2, y^2 + 7),Mod(1, y^2 + 7)) = + sol of quadratic equation = [1, 0, 1]~ + zc*z1^2 = Mod(Mod(2*y - 2, y^2 + 7)*x + Mod(2*y + 10, y^2 + 7), x^3 + Mod(1, y^2 + 7)*x + Mod(y, y^2 + 7)) + quartic: (-1/2*y + 1/2)*Y^2 = x^4 + (-3*y - 15)*x^2 + (-8*y - 16)*x + (-11/2*y - 15/2) + reduced: Y^2 = (-1/2*y + 1/2)*x^4 - 4*x^3 + (-3*y + 3)*x^2 + (2*y - 2)*x + (1/2*y + 3/2) + not ELS at [2, [0, 1]~, 1, 1, [1, 1]~] + zc = Mod(Mod(1, y^2 + 7)*x^2 + Mod(1/2*y + 1/2, y^2 + 7)*x + Mod(-1, y^2 + 7), x^3 + Mod(1, y^2 + 7)*x + Mod(y, y^2 + 7)) + comes from the trivial point [Mod(1/2*y + 3/2, y^2 + 7), Mod(-y - 2, y^2 + 7), 1] + m1 = 1 + m2 = 1 #S(E/K)[2] = 2 #E(K)/2E(K) = 2 #III(E/K)[2] = 1 - rang(E/K) = 1 - listpointsmwr = [[Mod(1/2*y + 3/2, y^2 + 7), Mod(-y - 2, y^2 + 7), 1]] + rank(E/K) = 1 + listpoints = [[Mod(1/2*y + 3/2, y^2 + 7), Mod(-y - 2, y^2 + 7), 1]] v = [1, 1, [[Mod(1/2*y + 3/2, y^2 + 7), Mod(-y - 2, y^2 + 7)]]] sage: v (1, 1, [(1/2*a + 3/2 : -a - 2 : 1)]) @@ -283,7 +286,7 @@ def simon_two_descent(self, verbose=0, lim1=5, lim3=50, limtriv=10, maxprob=20, *** in function bnfellrank: ...eqtheta,rnfeq,bbnf];rang= *** bnfell2descent_gen(b *** ^-------------------- - *** in function bnfell2descent_gen: ...riv,r=nfsqrt(nf,norm(zc)) + *** in function bnfell2descent_gen: ...und,r=nfsqrt(nf,norm(zc)) *** [1];if(DEBUGLEVEL_el *** ^-------------------- *** array index (1) out of allowed range [none]. diff --git a/src/sage/schemes/elliptic_curves/ell_rational_field.py b/src/sage/schemes/elliptic_curves/ell_rational_field.py index 857061b562f..ee8a34ca9a3 100644 --- a/src/sage/schemes/elliptic_curves/ell_rational_field.py +++ b/src/sage/schemes/elliptic_curves/ell_rational_field.py @@ -1461,11 +1461,11 @@ def simon_two_descent(self, verbose=0, lim1=5, lim3=50, limtriv=10, maxprob=20, sage: E = EllipticCurve('389a1') sage: set_random_seed(0) sage: E.simon_two_descent() - (2, 2, [(1 : 0 : 1), (-11/9 : -55/27 : 1)]) + (2, 2, [(1 : 0 : 1), (-11/9 : 28/27 : 1)]) sage: E = EllipticCurve('5077a1') sage: set_random_seed(0) sage: E.simon_two_descent() - (3, 3, [(1 : -1 : 1), (2 : 0 : 1), (0 : 2 : 1)]) + (3, 3, [(1 : 0 : 1), (2 : 0 : 1), (0 : 2 : 1)]) In this example Simon's program does not find any points, though it does correctly compute the rank of the 2-Selmer group. @@ -1485,11 +1485,11 @@ def simon_two_descent(self, verbose=0, lim1=5, lim3=50, limtriv=10, maxprob=20, sage: E = EllipticCurve([1, -1, 0, -79, 289]) sage: set_random_seed(0) sage: E.simon_two_descent() - (4, 4, [(4 : 3 : 1), (5 : -2 : 1), (6 : -1 : 1), (8 : 7 : 1)]) + (4, 4, [(6 : -1 : 1), (4 : 3 : 1), (5 : -2 : 1), (8 : 7 : 1)]) sage: E = EllipticCurve([0, 0, 1, -79, 342]) sage: set_random_seed(0) sage: E.simon_two_descent() # long time (9s on sage.math, 2011) - (5, 5, [(5 : 8 : 1), (4 : 9 : 1), (3 : 11 : 1), (-1 : 20 : 1), (-6 : -25 : 1)]) + (5, 5, [(7 : 11 : 1), (-1 : 20 : 1), (0 : 18 : 1), (3 : 11 : 1), (-3 : 23 : 1)]) sage: E = EllipticCurve([1, 1, 0, -2582, 48720]) sage: set_random_seed(0) sage: r, s, G = E.simon_two_descent(); r,s @@ -1507,11 +1507,11 @@ def simon_two_descent(self, verbose=0, lim1=5, lim3=50, limtriv=10, maxprob=20, sage: E = EllipticCurve([1,0,0,-6664,86543]) sage: E.simon_two_descent() - (2, 3, [(-73 : -394 : 1), (323/4 : 1891/8 : 1)]) + (2, 3, [(-1/4 : 2377/8 : 1), (323/4 : 1891/8 : 1)]) sage: E.rank() 2 sage: E.gens() - [(-73 : -394 : 1), (323/4 : 1891/8 : 1)] + [(-1/4 : 2377/8 : 1), (323/4 : 1891/8 : 1)] Example where the lower bound is known to be 1 despite that the algorithm has not found any @@ -1529,7 +1529,7 @@ def simon_two_descent(self, verbose=0, lim1=5, lim3=50, limtriv=10, maxprob=20, sage: E = EllipticCurve([3,0]) sage: E.simon_two_descent() - (1, 2, [(3 : 6 : 1)]) + (1, 2, [(1 : 2 : 1)]) """ verbose = int(verbose) diff --git a/src/sage/schemes/elliptic_curves/gp_simon.py b/src/sage/schemes/elliptic_curves/gp_simon.py index 06b3aef86eb..19ce2db15fa 100644 --- a/src/sage/schemes/elliptic_curves/gp_simon.py +++ b/src/sage/schemes/elliptic_curves/gp_simon.py @@ -52,9 +52,7 @@ def simon_two_descent(E, verbose=0, lim1=5, lim3=50, limtriv=10, maxprob=20, lim sage: import sage.schemes.elliptic_curves.gp_simon sage: E=EllipticCurve('389a1') sage: sage.schemes.elliptic_curves.gp_simon.simon_two_descent(E) - [2, 2, [(1 : 0 : 1), (-11/9 : -55/27 : 1)]] - sage: E.simon_two_descent() - (2, 2, [(1 : 0 : 1), (-11/9 : -55/27 : 1)]) + [2, 2, [(1 : 0 : 1), (-11/9 : 28/27 : 1)]] TESTS:: diff --git a/src/sage/schemes/hyperelliptic_curves/mestre.py b/src/sage/schemes/hyperelliptic_curves/mestre.py index 03207d0a75c..fbca19f1992 100644 --- a/src/sage/schemes/hyperelliptic_curves/mestre.py +++ b/src/sage/schemes/hyperelliptic_curves/mestre.py @@ -69,7 +69,7 @@ def HyperellipticCurve_from_invariants(i, reduced=True, precision=None, ... NotImplementedError: Reduction of hyperelliptic curves not yet implemented. See trac #14755 and #14756. sage: HyperellipticCurve_from_invariants([3840,414720,491028480,2437709561856],reduced = False) - Hyperelliptic Curve over Rational Field defined by y^2 = -x^6 + 4410*x^5 - 540*x^4 + 4320*x^3 - 19440*x^2 + 46656*x - 46656 + Hyperelliptic Curve over Rational Field defined by y^2 = -46656*x^6 + 46656*x^5 - 19440*x^4 + 4320*x^3 - 540*x^2 + 4410*x - 1 sage: HyperellipticCurve_from_invariants([21, 225/64, 22941/512, 1]) Traceback (most recent call last): ... diff --git a/src/sage/schemes/plane_conics/con_field.py b/src/sage/schemes/plane_conics/con_field.py index c1fb190d39f..00a6c3c89d3 100644 --- a/src/sage/schemes/plane_conics/con_field.py +++ b/src/sage/schemes/plane_conics/con_field.py @@ -145,7 +145,7 @@ def cache_point(self, p): (15/8 : 17/8 : 1) sage: c.cache_point(c.rational_point(read_cache = False)) sage: c.rational_point() - (1 : 1 : 0) + (-1 : 1 : 0) """ if isinstance(p, (tuple, list)): p = self.point(p) @@ -882,7 +882,7 @@ def point(self, v, check=True): (15/8 : 17/8 : 1) sage: d = Conic([1, -1, 1]) sage: d.rational_point() - (1 : 1 : 0) + (-1 : 1 : 0) """ if is_Vector(v): v = Sequence(v) diff --git a/src/sage/schemes/plane_conics/con_rational_field.py b/src/sage/schemes/plane_conics/con_rational_field.py index 19f0c1f00c6..16ebd6065fc 100644 --- a/src/sage/schemes/plane_conics/con_rational_field.py +++ b/src/sage/schemes/plane_conics/con_rational_field.py @@ -96,7 +96,7 @@ def has_rational_point(self, point = False, obstruction = False, The parameter ``algorithm`` specifies the algorithm to be used: - - ``'qfsolve'`` -- Use Denis Simon's pari script Qfsolve + - ``'qfsolve'`` -- Use Denis Simon's GP script ``qfsolve`` (see ``sage.quadratic_forms.qfsolve.qfsolve``) - ``'rnfisnorm'`` -- Use PARI's function rnfisnorm @@ -314,7 +314,7 @@ def parametrization(self, point=None, morphism=True): ALGORITHM: - Uses Denis Simon's pari script Qfparam. + Uses Denis Simon's GP script ``qfparam``. See ``sage.quadratic_forms.qfsolve.qfparam``. EXAMPLES :: @@ -325,12 +325,12 @@ def parametrization(self, point=None, morphism=True): From: Projective Space of dimension 1 over Rational Field To: Projective Conic Curve over Rational Field defined by x^2 + y^2 - z^2 Defn: Defined on coordinates by sending (x : y) to - (2*x*y : x^2 - y^2 : x^2 + y^2), + (2*x*y : -x^2 + y^2 : x^2 + y^2), Scheme morphism: - From: Projective Conic Curve over Rational Field defined by x^2 + y^2 - z^2 - To: Projective Space of dimension 1 over Rational Field - Defn: Defined on coordinates by sending (x : y : z) to - (1/2*x : -1/2*y + 1/2*z)) + From: Projective Conic Curve over Rational Field defined by x^2 + y^2 - z^2 + To: Projective Space of dimension 1 over Rational Field + Defn: Defined on coordinates by sending (x : y : z) to + (1/2*x : 1/2*y + 1/2*z)) An example with ``morphism = False`` :: From 74a606dbcbcf19fb1e2087eca432c5e2eca04ec7 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Tue, 11 Feb 2014 16:22:00 -0800 Subject: [PATCH 091/163] Minor formatting review changes. --- src/sage/homology/simplicial_complex.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/sage/homology/simplicial_complex.py b/src/sage/homology/simplicial_complex.py index 61197a94c25..b77331dcd5c 100644 --- a/src/sage/homology/simplicial_complex.py +++ b/src/sage/homology/simplicial_complex.py @@ -486,7 +486,7 @@ def face(self, n): if n >= 0 and n <= self.dimension(): return Simplex(self.__tuple[:n] + self.__tuple[n+1:]) else: - raise IndexError("%s does not have an nth face for n=%s." % (self, n)) + raise IndexError("{} does not have an nth face for n={}.".format(self, n)) def faces(self): """ @@ -3242,9 +3242,8 @@ def fixed_complex(self, G): INPUT: - - `G` -- a subgroup of the automorphism group of the - simplicial complex or a list of elements of the - automorphism group + - ``G`` -- a subgroup of the automorphism group of the simplicial + complex or a list of elements of the automorphism group OUTPUT: From cf8b120400f6489b9cef903592e76a9320bdd118 Mon Sep 17 00:00:00 2001 From: Julian Rueth Date: Wed, 12 Feb 2014 08:44:44 +0100 Subject: [PATCH 092/163] Trac 13274: Added QQ._factor_univariate_polynomial --- .../rings/polynomial/polynomial_element.pyx | 4 +- src/sage/rings/rational_field.py | 47 +++++++++++++++++++ 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index 6e22c1f090d..52e6f7e0e57 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -3190,12 +3190,10 @@ cdef class Polynomial(CommutativeAlgebraElement): from sage.rings.finite_rings.constructor import is_FiniteField from sage.rings.finite_rings.integer_mod_ring import is_IntegerModRing from sage.rings.integer_ring import is_IntegerRing - from sage.rings.rational_field import is_RationalField n = None - if is_IntegerModRing(R) or is_IntegerRing(R) or is_RationalField(R): - + if is_IntegerModRing(R) or is_IntegerRing(R): try: G = list(self._pari_with_name().factor()) except PariError: diff --git a/src/sage/rings/rational_field.py b/src/sage/rings/rational_field.py index f28915ffcd9..dc955e8818e 100644 --- a/src/sage/rings/rational_field.py +++ b/src/sage/rings/rational_field.py @@ -987,6 +987,53 @@ def _sage_input_(self, sib, coerced): """ return sib.name('QQ') + def _factor_univariate_polynomial(self, f): + """ + Factor the univariate polynomial ``f``. + + INPUT: + + - ``f`` -- a univariate polynomial defined over the rationals + + OUTPUT: + + - A factorization of ``f`` over the rationals into a unit and monic + irreducible factors + + .. NOTE:: + + This is a helper method for + :meth:`sage.rings.polynomial.polynomial_element.Polynomial.factor`. + + This method calls PARI to compute the factorization. + + TESTS:: + + sage: R. = QQ[] + sage: QQ._factor_univariate_polynomial( x ) + x + sage: QQ._factor_univariate_polynomial( 2*x ) + (2) * x + sage: QQ._factor_univariate_polynomial( (x^2 - 1/4)^4 ) + (x - 1/2)^4 * (x + 1/2)^4 + sage: QQ._factor_univariate_polynomial( (2*x + 1) * (3*x^2 - 5)^2 ) + (18) * (x + 1/2) * (x^2 - 5/3)^2 + sage: f = prod((k^2*x^k + k)^(k-1) for k in primes(10)) + sage: QQ._factor_univariate_polynomial(f) + (1751787911376562500) * (x^2 + 1/2) * (x^3 + 1/3)^2 * (x^5 + 1/5)^4 * (x^7 + 1/7)^6 + sage: QQ._factor_univariate_polynomial( 10*x^5 - 1 ) + (10) * (x^5 - 1/10) + sage: QQ._factor_univariate_polynomial( 10*x^5 - 10 ) + (10) * (x - 1) * (x^4 + x^3 + x^2 + x + 1) + + """ + G = list(f._pari_with_name().factor()) + + # normalize the leading coefficients + F = [(f.parent()(g).monic(), int(e)) for (g,e) in zip(*G)] + + from sage.structure.factorization import Factorization + return Factorization(F, f.leading_coefficient()) QQ = RationalField() Q = QQ From 115c8fcc196567a2f18c8dd3508cbee0ec11f809 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Wed, 12 Feb 2014 09:13:20 +0100 Subject: [PATCH 093/163] Fix version and checksum for Cython 0.20.1 --- build/pkgs/cython/checksums.ini | 6 +++--- build/pkgs/cython/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/cython/checksums.ini b/build/pkgs/cython/checksums.ini index 2dfc5f980bc..3d1846c338d 100644 --- a/build/pkgs/cython/checksums.ini +++ b/build/pkgs/cython/checksums.ini @@ -1,4 +1,4 @@ tarball=Cython-VERSION.tar.gz -sha1=e159219be7449d514d5964a91a474cecd3a927a9 -md5=e330ff28980ef87359c49e68af9aec40 -cksum=1438694019 +sha1=e0f2c2094722bada54f24c33f5c792411778ba4f +md5=52431696c64e618036537c4d9aa79d99 +cksum=3488695300 diff --git a/build/pkgs/cython/package-version.txt b/build/pkgs/cython/package-version.txt index 851c7b6943e..847e9aef6d1 100644 --- a/build/pkgs/cython/package-version.txt +++ b/build/pkgs/cython/package-version.txt @@ -1 +1 @@ -0.20.1rc1 +0.20.1 From d34a77ab7abe4072349e10e0154a598da94b7c31 Mon Sep 17 00:00:00 2001 From: Peter Bruin Date: Wed, 12 Feb 2014 12:39:51 +0000 Subject: [PATCH 094/163] increase bound in precision check in ell.gp --- src/ext/pari/simon/ell.gp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ext/pari/simon/ell.gp b/src/ext/pari/simon/ell.gp index 503daf21636..c93535adcd7 100644 --- a/src/ext/pari/simon/ell.gp +++ b/src/ext/pari/simon/ell.gp @@ -233,11 +233,11 @@ local(nf_roots,ay,prec0); prec0 = default(realprecision); ay = 0; - while( ay == 0 || precision(ay) < 10, + while( ay == 0 || precision(ay) < 38, ay = subst(a,variable(a),nf_roots[i]); - if( ay == 0 || precision(ay) < 10, + if( ay == 0 || precision(ay) < 38, if( DEBUGLEVEL_ell >= 3, print(" **** Warning: doubling the real precision in nfrealsign **** ", 2*default(realprecision))); From b662aba98ad4122a82fc135cf9b5dbf58de2ba0e Mon Sep 17 00:00:00 2001 From: Peter Bruin Date: Wed, 12 Feb 2014 14:52:01 +0000 Subject: [PATCH 095/163] add/fix doctests for simon_two_descent --- .../elliptic_curves/ell_number_field.py | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/ell_number_field.py b/src/sage/schemes/elliptic_curves/ell_number_field.py index 22c956cc164..37fb78810ce 100644 --- a/src/sage/schemes/elliptic_curves/ell_number_field.py +++ b/src/sage/schemes/elliptic_curves/ell_number_field.py @@ -273,24 +273,25 @@ def simon_two_descent(self, verbose=0, lim1=5, lim3=50, limtriv=10, maxprob=20, sage: E.simon_two_descent() # long time (3s on sage.math, 2013), points can vary (1, 3, [...]) - A failure in the PARI/GP script ell.gp (VERSION 25/03/2009) is reported:: + Check that the bug reported in :trac:`15483` is fixed:: + + sage: K. = QuadraticField(229) + sage: c4 = 2173 - 235*(1 - s)/2 + sage: c6 = -124369 + 15988*(1 - s)/2 + sage: E = EllipticCurve([-c4/48, -c6/864]) + sage: E.simon_two_descent() + (0, 0, []) + + sage: R. = QQ[] + sage: L. = NumberField(t^3 - 9*t^2 + 13*t - 4) + sage: E1 = EllipticCurve(L,[1-g*(g-1),-g^2*(g-1),-g^2*(g-1),0,0]) + sage: E1.rank() # long time (about 5 s) + 0 sage: K = CyclotomicField(43).subfields(3)[0][0] sage: E = EllipticCurve(K, '37') sage: E.simon_two_descent() # long time (4s on sage.math, 2013) - Traceback (most recent call last): - ... - RuntimeError: - *** at top-level: ans=bnfellrank(K,[0,0,1, - *** ^-------------------- - *** in function bnfellrank: ...eqtheta,rnfeq,bbnf];rang= - *** bnfell2descent_gen(b - *** ^-------------------- - *** in function bnfell2descent_gen: ...und,r=nfsqrt(nf,norm(zc)) - *** [1];if(DEBUGLEVEL_el - *** ^-------------------- - *** array index (1) out of allowed range [none]. - An error occurred while running Simon's 2-descent program + (3, 3, [(-1 : 0 : 1), (1/2*zeta43_0^2 + 3/2*zeta43_0 - 2 : -zeta43_0^2 - 4*zeta43_0 + 3 : 1), (-zeta43_0 + 2 : -1/2*zeta43_0^2 + 3/2*zeta43_0 : 1)]) """ From 9cf030d93c04738161fdae4aec6914371a63f4b2 Mon Sep 17 00:00:00 2001 From: David Roe Date: Wed, 12 Feb 2014 14:54:44 -0700 Subject: [PATCH 096/163] Use fraction field of polynomial ring for fraction field of Laurent polynomial ring --- src/sage/rings/fraction_field.py | 12 +++++++++--- .../rings/polynomial/laurent_polynomial_ring.py | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/sage/rings/fraction_field.py b/src/sage/rings/fraction_field.py index 96912f3c630..f622b29ee11 100644 --- a/src/sage/rings/fraction_field.py +++ b/src/sage/rings/fraction_field.py @@ -271,6 +271,8 @@ def _coerce_map_from_(self, S): sage: T = PolynomialRing(ZZ, 'x') sage: R.gen() + FractionField(T).gen() 2*x + sage: 1/R.gen() + 1/x """ from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ @@ -293,9 +295,13 @@ def _coerce_map_from_(self, S): # special treatment for LaurentPolynomialRings if isinstance(S, LaurentPolynomialRing_generic): - return CallableConvertMap(S, self, \ - lambda x: self._element_class(self, *x.to_fraction()), - parent_as_first_arg=False) + def converter(x,y=None): + if y is None: + return self._element_class(self, *x.to_fraction()) + xnum, xden = x.to_fraction() + ynum, yden = y.to_fraction() + return self._element_class(self, xnum*yden, xden*ynum) + return CallableConvertMap(S, self, converter, parent_as_first_arg=False) if isinstance(S, FractionField_generic) and \ self._R.has_coerce_map_from(S.ring()): diff --git a/src/sage/rings/polynomial/laurent_polynomial_ring.py b/src/sage/rings/polynomial/laurent_polynomial_ring.py index f768d5551cc..f80b26d4ff6 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ring.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ring.py @@ -767,6 +767,20 @@ def change_ring(self, base_ring=None, names=None, sparse=False, order=None): else: return LaurentPolynomialRing(base_ring, self._n, names, order = order) + def fraction_field(self): + """ + The fraction field is the same as the fraction field of the + polynomial ring. + + EXAMPLES:: + + sage: L. = LaurentPolynomialRing(QQ) + sage: L.fraction_field() + Fraction Field of Multivariate Polynomial Ring in x over Rational Field + sage: (x^-1 + 2) / (x - 1) + (2*x + 1)/(x^2 - x) + """ + return self.polynomial_ring().fraction_field() class LaurentPolynomialRing_mpair(LaurentPolynomialRing_generic): def __init__(self, R, prepend_string, names): From 00393f332216d6d2b009842b02e1f9384ad0d807 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 13 Feb 2014 16:04:23 +0100 Subject: [PATCH 097/163] trac #15345 corrected doctests in hall algebra --- src/sage/algebras/hall_algebra.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/sage/algebras/hall_algebra.py b/src/sage/algebras/hall_algebra.py index 847bf416c7f..661b448701d 100644 --- a/src/sage/algebras/hall_algebra.py +++ b/src/sage/algebras/hall_algebra.py @@ -122,14 +122,14 @@ class HallAlgebra(CombinatorialFreeModule): sage: R. = LaurentPolynomialRing(ZZ) sage: H = HallAlgebra(R, q) sage: I = H.monomial_basis() - sage: H(I[2,1]) - H[2, 1] + ((-q^3+1)/(-q+1))*H[1, 1, 1] - sage: H[2]*H[2] - Traceback (most recent call last): - ... - TypeError: unsupported operand parent(s) for '-': - 'Hall algebra with q=q over Univariate Laurent Polynomial Ring in q over Integer Ring' - and '' + sage: hi = H(I[2,1]); hi + H[2, 1] + (q^2+q+1)*H[1, 1, 1] + sage: hi.parent() is H + True + sage: h22 = H[2]*H[2]; h22 + H[4] + (q-1)*H[3, 1] + (q^2+q)*H[2, 2] + sage: h22.parent() is H + True EXAMPLES:: From 9a7657bb5ce501543b7359e7bf19764d2b11e3cc Mon Sep 17 00:00:00 2001 From: Nathann Cohen Date: Fri, 14 Feb 2014 11:51:52 +0100 Subject: [PATCH 098/163] trac #15482: Broken doctest --- src/doc/en/thematic_tutorials/linear_programming.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/en/thematic_tutorials/linear_programming.rst b/src/doc/en/thematic_tutorials/linear_programming.rst index 85ffe2f5ab0..96180971e5f 100644 --- a/src/doc/en/thematic_tutorials/linear_programming.rst +++ b/src/doc/en/thematic_tutorials/linear_programming.rst @@ -178,7 +178,7 @@ And because any immutable object can be used as a key, doubly indexed variables :: - sage: p.add_constraint(y[3,2] + x[5] == 6) + sage: p.add_constraint(x[3,2] + x[5] == 6) Typed variables and bounds From 702217500e8b557b96b5cfaad3ddd24592933006 Mon Sep 17 00:00:00 2001 From: Burcin Erocal Date: Fri, 14 Feb 2014 16:09:29 +0100 Subject: [PATCH 099/163] trac 9634: Make the top level binomial function symbolic. --- src/sage/all.py | 1 + src/sage/combinat/all.py | 14 ++- src/sage/combinat/alternating_sign_matrix.py | 3 +- .../quiver_mutation_type.py | 3 +- src/sage/combinat/combination.py | 3 +- src/sage/combinat/composition_signed.py | 3 +- src/sage/combinat/lyndon_word.py | 3 +- src/sage/combinat/partition.py | 3 +- src/sage/combinat/permutation.py | 3 +- src/sage/combinat/sf/ns_macdonald.py | 3 +- src/sage/combinat/skew_tableau.py | 2 +- src/sage/combinat/species/misc.py | 2 +- src/sage/combinat/species/product_species.py | 2 +- src/sage/combinat/species/series.py | 3 +- src/sage/combinat/symmetric_group_algebra.py | 3 +- src/sage/combinat/words/shuffle_product.py | 2 +- src/sage/functions/all.py | 2 +- src/sage/functions/other.py | 92 ++++++++++++++++++- .../matrix/matrix_integer_dense_saturation.py | 3 +- src/sage/rings/all.py | 26 +++++- src/sage/rings/arith.py | 1 + .../elliptic_curves/ell_finite_field.py | 2 +- src/sage/schemes/elliptic_curves/heegner.py | 2 +- .../hyperelliptic_finite_field.py | 3 +- src/sage/symbolic/expression.pyx | 9 +- 25 files changed, 161 insertions(+), 32 deletions(-) diff --git a/src/sage/all.py b/src/sage/all.py index 7578e1c35e3..0328ad62ce4 100644 --- a/src/sage/all.py +++ b/src/sage/all.py @@ -50,6 +50,7 @@ import os, sys import operator +import math from sage.env import SAGE_ROOT, SAGE_DOC, SAGE_LOCAL, DOT_SAGE, SAGE_ENV diff --git a/src/sage/combinat/all.py b/src/sage/combinat/all.py index ac929c87182..69fabffe6ef 100644 --- a/src/sage/combinat/all.py +++ b/src/sage/combinat/all.py @@ -1,4 +1,16 @@ -from combinat import * +from combinat import bell_number, catalan_number, euler_number, fibonacci, \ + lucas_number1, lucas_number2, stirling_number1, stirling_number2, \ + CombinatorialObject, CombinatorialClass, FilteredCombinatorialClass, \ + UnionCombinatorialClass, MapCombinatorialClass, \ + InfiniteAbstractCombinatorialClass, \ + hurwitz_zeta, combinations, combinations_iterator, \ + number_of_combinations, arrangements, number_of_arrangements, \ + derangements, number_of_derangements, tuples, number_of_tuples, \ + unordered_tuples, number_of_unordered_tuples, permutations, \ + permutations_iterator, number_of_permutations, cyclic_permutations, \ + cyclic_permutations_iterator, bell_polynomial, fibonacci_sequence, \ + fibonacci_xrange, bernoulli_polynomial + from expnums import expnums from sage.combinat.crystals.all import * diff --git a/src/sage/combinat/alternating_sign_matrix.py b/src/sage/combinat/alternating_sign_matrix.py index 3900bc8eaa6..b91e1414311 100644 --- a/src/sage/combinat/alternating_sign_matrix.py +++ b/src/sage/combinat/alternating_sign_matrix.py @@ -37,7 +37,8 @@ from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets from sage.matrix.matrix_space import MatrixSpace from sage.matrix.constructor import matrix -from sage.rings.all import ZZ, factorial +from sage.rings.all import ZZ +from sage.rings.arith import factorial from sage.rings.integer import Integer from sage.combinat.posets.lattices import LatticePoset from sage.combinat.gelfand_tsetlin_patterns import GelfandTsetlinPatternsTopRow diff --git a/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py b/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py index 1067ad18453..ae3ecf8136a 100644 --- a/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py +++ b/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py @@ -21,9 +21,8 @@ from sage.misc.all import cached_method from sage.rings.all import ZZ, infinity from sage.graphs.all import Graph, DiGraph -from sage.rings.all import binomial +from sage.rings.arith import binomial, Euler_Phi from sage.all import prod -from sage.rings.arith import Euler_Phi from sage.matrix.all import matrix class QuiverMutationTypeFactory(SageObject): diff --git a/src/sage/combinat/combination.py b/src/sage/combinat/combination.py index 15632511d20..64797df1c95 100644 --- a/src/sage/combinat/combination.py +++ b/src/sage/combinat/combination.py @@ -17,7 +17,8 @@ #***************************************************************************** from sage.interfaces.all import gap -from sage.rings.all import ZZ, Integer, binomial +from sage.rings.all import ZZ, Integer +from sage.rings.arith import binomial from combinat import CombinatorialClass from choose_nk import rank, from_rank from integer_vector import IntegerVectors diff --git a/src/sage/combinat/composition_signed.py b/src/sage/combinat/composition_signed.py index 28006048285..f6272c44c2a 100644 --- a/src/sage/combinat/composition_signed.py +++ b/src/sage/combinat/composition_signed.py @@ -18,7 +18,8 @@ from composition import Compositions_n, Composition import cartesian_product -from sage.rings.all import binomial, Integer +from sage.rings.all import Integer +from sage.rings.arith import binomial import __builtin__ class SignedCompositions(Compositions_n): diff --git a/src/sage/combinat/lyndon_word.py b/src/sage/combinat/lyndon_word.py index ee83b74fb47..66d29cd78bf 100644 --- a/src/sage/combinat/lyndon_word.py +++ b/src/sage/combinat/lyndon_word.py @@ -19,7 +19,8 @@ from combinat import CombinatorialClass from sage.combinat.composition import Composition, Compositions -from sage.rings.all import factorial, divisors, gcd, moebius, Integer +from sage.rings.all import divisors, gcd, moebius, Integer +from sage.rings.arith import factorial from sage.misc.misc import prod import __builtin__ import necklace diff --git a/src/sage/combinat/partition.py b/src/sage/combinat/partition.py index 138b66f68ea..ff04597e6f8 100644 --- a/src/sage/combinat/partition.py +++ b/src/sage/combinat/partition.py @@ -299,7 +299,8 @@ from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets from sage.sets.non_negative_integers import NonNegativeIntegers -from sage.rings.all import QQ, ZZ, NN, factorial, gcd +from sage.rings.all import QQ, ZZ, NN, gcd +from sage.rings.arith import factorial from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.integer import Integer from sage.rings.infinity import infinity diff --git a/src/sage/combinat/permutation.py b/src/sage/combinat/permutation.py index b6f4064e293..b5b0173da11 100644 --- a/src/sage/combinat/permutation.py +++ b/src/sage/combinat/permutation.py @@ -226,7 +226,8 @@ from sage.structure.global_options import GlobalOptions from sage.interfaces.all import gap -from sage.rings.all import ZZ, Integer, PolynomialRing, factorial +from sage.rings.all import ZZ, Integer, PolynomialRing +from sage.rings.arith import factorial from sage.matrix.all import matrix from sage.combinat.tools import transitive_ideal import sage.combinat.subword as subword diff --git a/src/sage/combinat/sf/ns_macdonald.py b/src/sage/combinat/sf/ns_macdonald.py index f75c9dd49fc..7de1ceb1d97 100644 --- a/src/sage/combinat/sf/ns_macdonald.py +++ b/src/sage/combinat/sf/ns_macdonald.py @@ -5,7 +5,8 @@ from sage.combinat.words.word import Word from sage.combinat.combination import Combinations from sage.combinat.permutation import Permutation -from sage.rings.all import QQ, PolynomialRing, prod +from sage.rings.all import QQ, PolynomialRing +from sage.misc.misc import prod from sage.combinat.backtrack import GenericBacktracker import copy diff --git a/src/sage/combinat/skew_tableau.py b/src/sage/combinat/skew_tableau.py index 369bcfb7b9d..bf85d0a0224 100644 --- a/src/sage/combinat/skew_tableau.py +++ b/src/sage/combinat/skew_tableau.py @@ -36,7 +36,7 @@ from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets from sage.rings.all import Integer, QQ, ZZ -from sage.functions.all import factorial +from sage.rings.arith import factorial from sage.matrix.all import zero_matrix from sage.combinat.combinat import CombinatorialObject diff --git a/src/sage/combinat/species/misc.py b/src/sage/combinat/species/misc.py index 96432742de3..f3bfd007e68 100644 --- a/src/sage/combinat/species/misc.py +++ b/src/sage/combinat/species/misc.py @@ -16,7 +16,7 @@ # http://www.gnu.org/licenses/ #***************************************************************************** from sage.groups.all import PermutationGroup, PermutationGroup_generic, PermutationGroupElement, SymmetricGroup -from sage.rings.all import prod +from sage.misc.misc import prod from functools import wraps def change_support(perm, support, change_perm=None): diff --git a/src/sage/combinat/species/product_species.py b/src/sage/combinat/species/product_species.py index e79e8ce748c..a37f074ddf1 100644 --- a/src/sage/combinat/species/product_species.py +++ b/src/sage/combinat/species/product_species.py @@ -370,7 +370,7 @@ def _equation(self, var_mapping): sage: S.algebraic_equation_system() [node0 - z^2] """ - from sage.rings.all import prod + from sage.misc.misc import prod return prod(var_mapping[operand] for operand in self._state_info) diff --git a/src/sage/combinat/species/series.py b/src/sage/combinat/species/series.py index 4fcd576b133..a59fe02278b 100644 --- a/src/sage/combinat/species/series.py +++ b/src/sage/combinat/species/series.py @@ -30,7 +30,8 @@ #***************************************************************************** from stream import Stream, Stream_class from series_order import bounded_decrement, increment, inf, unk -from sage.rings.all import Integer, prod +from sage.rings.all import Integer +from sage.misc.misc import prod from functools import partial from sage.misc.misc import repr_lincomb, is_iterator diff --git a/src/sage/combinat/symmetric_group_algebra.py b/src/sage/combinat/symmetric_group_algebra.py index 4ac5f560698..fc2eadc74c1 100644 --- a/src/sage/combinat/symmetric_group_algebra.py +++ b/src/sage/combinat/symmetric_group_algebra.py @@ -15,7 +15,8 @@ import partition from tableau import Tableau, StandardTableaux_size, StandardTableaux_shape, StandardTableaux from sage.interfaces.all import gap -from sage.rings.all import factorial, QQ, PolynomialRing +from sage.rings.all import QQ, PolynomialRing +from sage.rings.arith import factorial from sage.matrix.all import matrix from sage.modules.all import vector from sage.groups.perm_gps.permgroup_named import SymmetricGroup diff --git a/src/sage/combinat/words/shuffle_product.py b/src/sage/combinat/words/shuffle_product.py index 0cbcd2993eb..177c1881a65 100644 --- a/src/sage/combinat/words/shuffle_product.py +++ b/src/sage/combinat/words/shuffle_product.py @@ -18,7 +18,7 @@ #***************************************************************************** from sage.combinat.words.word import Word_class from sage.combinat.combinat import CombinatorialClass -from sage.rings.all import binomial +from sage.rings.arith import binomial from sage.combinat.integer_vector import IntegerVectors from sage.combinat.subset import Subsets from sage.combinat.composition import Compositions_n, Compositions diff --git a/src/sage/functions/all.py b/src/sage/functions/all.py index ca9d41fc966..7fe1a3365ae 100644 --- a/src/sage/functions/all.py +++ b/src/sage/functions/all.py @@ -15,7 +15,7 @@ -from other import ( ceil, floor, gamma, psi, factorial, beta, +from other import ( ceil, floor, gamma, psi, factorial, beta, binomial, abs_symbolic, erf, sqrt, log_gamma, gamma_inc, incomplete_gamma, arg, real_part, real, diff --git a/src/sage/functions/other.py b/src/sage/functions/other.py index 341a2ae8c12..ed13c5d6b55 100644 --- a/src/sage/functions/other.py +++ b/src/sage/functions/other.py @@ -7,7 +7,7 @@ from sage.symbolic.pynac import py_factorial_py from sage.libs.pari.gen import pari from sage.symbolic.all import SR -from sage.rings.all import Integer, Rational, RealField, RR, ComplexField +from sage.rings.all import Integer, Rational, RealField, RR, ZZ, ComplexField from sage.rings.complex_number import is_ComplexNumber from sage.misc.latex import latex import math @@ -1425,8 +1425,7 @@ def __init__(self): sage: binomial(k,i) binomial(k, i) - We can use a ``hold`` parameter to prevent automatic evaluation, - but only using method notation:: + We can use a ``hold`` parameter to prevent automatic evaluation:: sage: SR(5).binomial(3, hold=True) binomial(5, 3) @@ -1443,7 +1442,7 @@ def __init__(self): binomial(n,k) sage: _.sage() binomial(n, k) - sage: sage.functions.other.binomial._maxima_init_() # temporary workaround until we can get symbolic binomial to import in global namespace, if that's desired + sage: binomial._maxima_init_() 'binomial' Test pickling:: @@ -1454,6 +1453,91 @@ def __init__(self): GinacFunction.__init__(self, "binomial", nargs=2, conversions=dict(maxima='binomial', mathematica='Binomial')) + def _binomial_sym(self, n, k): + """ + Expand the binomial formula symbolically when the second argument + is an integer. + + EXAMPLES:: + + sage: binomial._binomial_sym(x, 3) + 1/6*(x - 1)*(x - 2)*x + sage: binomial._binomial_sym(x, x) + Traceback (most recent call last): + ... + ValueError: second argument must be an integer + sage: binomial._binomial_sym(x, SR(3)) + 1/6*(x - 1)*(x - 2)*x + + sage: binomial._binomial_sym(x, 0r) + 1 + sage: binomial._binomial_sym(x, -1) + 0 + """ + if isinstance(k, Expression): + if k.is_integer(): + k = k.pyobject() + else: + raise ValueError("second argument must be an integer") + + if k < 0: + return s_parent(k)(0) + if k == 0: + return s_parent(k)(1) + if k == 1: + return n + + from sage.misc.misc import prod + return prod([n-i for i in xrange(k)])/factorial(k) + + def _eval_(self, n, k): + """ + EXAMPLES:: + + sage: binomial._eval_(5, 3) + 10 + sage: type(binomial._eval_(5, 3)) + + sage: type(binomial._eval_(5., 3)) + + sage: binomial._eval_(x, 3) + 1/6*(x - 1)*(x - 2)*x + sage: binomial._eval_(x, x-2) + 1/2*(x - 1)*x + sage: n = var('n') + sage: binomial._eval_(x, n) is None + True + """ + if not isinstance(k, Expression): + if not isinstance(n, Expression): + n, k = coercion_model.canonical_coercion(n, k) + return self._evalf_(n, k, s_parent(n)) + if k in ZZ: + return self._binomial_sym(n, k) + if (n - k) in ZZ: + return self._binomial_sym(n, n-k) + + return None + + def _evalf_(self, n, k, parent=None, algorithm=None): + """ + EXAMPLES:: + + sage: binomial._evalf_(5.r, 3) + 10.0 + sage: type(binomial._evalf_(5.r, 3)) + + sage: binomial._evalf_(1/2,1/1) + 1/2 + sage: binomial._evalf_(10^20+1/1,10^20) + 100000000000000000001 + sage: binomial._evalf_(SR(10**7),10**7) + 1 + sage: binomial._evalf_(3/2,SR(1/1)) + 3/2 + """ + return sage.rings.arith.binomial(n, k) + binomial = Function_binomial() class Function_beta(GinacFunction): diff --git a/src/sage/matrix/matrix_integer_dense_saturation.py b/src/sage/matrix/matrix_integer_dense_saturation.py index 0b50a060f7e..08e42b76e15 100644 --- a/src/sage/matrix/matrix_integer_dense_saturation.py +++ b/src/sage/matrix/matrix_integer_dense_saturation.py @@ -2,7 +2,8 @@ Saturation over ZZ """ -from sage.rings.all import ZZ, gcd, binomial, GF +from sage.rings.all import ZZ, gcd, GF +from sage.rings.arith import binomial from sage.matrix.constructor import identity_matrix, random_matrix from sage.misc.misc import verbose from sage.misc.randstate import current_randstate diff --git a/src/sage/rings/all.py b/src/sage/rings/all.py index ef62f1c2d8f..7389443dee0 100644 --- a/src/sage/rings/all.py +++ b/src/sage/rings/all.py @@ -135,7 +135,31 @@ from contfrac import continued_fraction, CFF, ContinuedFractionField # Arithmetic -from arith import * +from arith import algdep, bernoulli, is_prime, is_prime_power, \ + is_pseudoprime, is_pseudoprime_small_power, valuation, \ + prime_powers, primes_first_n, eratosthenes, primes, \ + next_prime_power, next_probable_prime, next_prime, \ + previous_prime, previous_prime_power, random_prime, \ + divisors, sigma, gcd, GCD, lcm, LCM, xlcm, xgcd, \ + inverse_mod, get_gcd, get_inverse_mod, power_mod, \ + rational_reconstruction, mqrr_rational_reconstruction, \ + trial_division, factor, prime_divisors, odd_part, prime_to_m_part, \ + is_square, is_squarefree, euler_phi, crt, CRT, CRT_list, CRT_basis, \ + CRT_vectors, multinomial, multinomial_coefficients, \ + kronecker_symbol, kronecker, legendre_symbol, \ + primitive_root, nth_prime, quadratic_residues, moebius, \ + farey, continued_fraction_list, convergent, convergents, \ + continuant, number_of_divisors, hilbert_symbol, hilbert_conductor, \ + hilbert_conductor_inverse, falling_factorial, rising_factorial, \ + integer_ceil, integer_floor, two_squares, four_squares, \ + subfactorial, is_power_of_two, differences, \ + sort_complex_numbers_for_display, \ + fundamental_discriminant, squarefree_divisors, \ + Sigma, radical, Euler_Phi, binomial_coefficients, jacobi_symbol, \ + Moebius, Hirzebruch_Jung_continued_fraction_list, dedekind_sum, \ + prime_factors + + from fast_arith import prime_range from bernoulli_mod_p import bernoulli_mod_p, bernoulli_mod_p_single diff --git a/src/sage/rings/arith.py b/src/sage/rings/arith.py index ffe4149009b..325f06dc424 100644 --- a/src/sage/rings/arith.py +++ b/src/sage/rings/arith.py @@ -3101,6 +3101,7 @@ def binomial(x, m, **kwds): EXAMPLES:: + sage: from sage.rings.arith import binomial sage: binomial(5,2) 10 sage: binomial(2,0) diff --git a/src/sage/schemes/elliptic_curves/ell_finite_field.py b/src/sage/schemes/elliptic_curves/ell_finite_field.py index 6ada87e6e32..1c48d001dd7 100644 --- a/src/sage/schemes/elliptic_curves/ell_finite_field.py +++ b/src/sage/schemes/elliptic_curves/ell_finite_field.py @@ -1944,7 +1944,7 @@ def supersingular_j_polynomial(p): J = polygen(GF(p),'j') if p<13: return J.parent().one() - from sage.rings.all import binomial + from sage.rings.arith import binomial from sage.misc.all import prod m=(p-1)//2 X,T = PolynomialRing(GF(p),2,names=['X','T']).gens() diff --git a/src/sage/schemes/elliptic_curves/heegner.py b/src/sage/schemes/elliptic_curves/heegner.py index 92eefd36db7..bc8aa49e9e0 100644 --- a/src/sage/schemes/elliptic_curves/heegner.py +++ b/src/sage/schemes/elliptic_curves/heegner.py @@ -6951,7 +6951,7 @@ def heegner_sha_an(self, D, prec=53): # You can think this through or just type something like # f = function('f',x); g = function('g',x); diff(f*g,6) # into Sage to be convinced. - L = rings.binomial(rE + rF, rE) * (L_E * L_F / (rings.factorial(rE+rF)) ) + L = arith.binomial(rE + rF, rE) * (L_E * L_F / (arith.factorial(rE+rF)) ) # - ||omega||^2 -- the period. It is twice the volume of the # period lattice. See the following paper for a derivation: diff --git a/src/sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py b/src/sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py index 8000b8afe1b..e9f29ed6056 100644 --- a/src/sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py +++ b/src/sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py @@ -20,7 +20,8 @@ # http://www.gnu.org/licenses/ #***************************************************************************** -from sage.rings.all import ZZ, RR, binomial +from sage.rings.all import ZZ, RR +from sage.rings.arith import binomial import hyperelliptic_generic from sage.schemes.hyperelliptic_curves.hypellfrob import hypellfrob from sage.misc.cachefunc import cached_method diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index 573289d7edd..7046d4f8862 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -7063,7 +7063,7 @@ cdef class Expression(CommutativeRingElement): sage: SR(5).binomial(SR(3)) 10 sage: x.binomial(SR(3)) - 1/6*x^3 - 1/2*x^2 + 1/3*x + 1/6*(x - 1)*(x - 2)*x sage: x.binomial(y) binomial(x, y) @@ -7080,13 +7080,10 @@ cdef class Expression(CommutativeRingElement): sage: a = SR(5).binomial(3, hold=True); a.simplify() 10 - We do not currently support a ``hold`` parameter in functional - notation:: + The ``hold`` parameter is also supported in functional notation:: sage: binomial(5,3, hold=True) - Traceback (most recent call last): - ... - TypeError: binomial() got an unexpected keyword argument 'hold' + binomial(5, 3) TESTS: From 1803137ae4c88a1e6015e5b58498947c906c92af Mon Sep 17 00:00:00 2001 From: Robert Miller Date: Fri, 14 Feb 2014 17:02:24 +0100 Subject: [PATCH 100/163] trac #9494: marked mpoly_all() as not tested --- src/sage/tests/benchmark.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/sage/tests/benchmark.py b/src/sage/tests/benchmark.py index d723101105b..7ce705bab20 100644 --- a/src/sage/tests/benchmark.py +++ b/src/sage/tests/benchmark.py @@ -1956,6 +1956,17 @@ def mpoly_all(include_maple=False): * Singular (i.e., Sage) does shockingly well. * mathematica is sometimes amazing. * macaulay2 is also quite bad (though not as bad as maple). + + EXAMPLE:: + + sage: from sage.tests.benchmark import mpoly_all + sage: mpoly_all() # not tested + + ... + ...System min avg max trials cpu or wall + ... + * sage... + """ systems = ['sage', 'magma', 'mathematica', 'macaulay2'] if include_maple: From f2e9d657fe345449be2d7479065f7dea36209607 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Fri, 14 Feb 2014 08:26:45 -0800 Subject: [PATCH 101/163] Fixed documentation for hall_algebra.py. --- src/sage/algebras/hall_algebra.py | 95 +++++++++++++++++++++++-------- 1 file changed, 70 insertions(+), 25 deletions(-) diff --git a/src/sage/algebras/hall_algebra.py b/src/sage/algebras/hall_algebra.py index 661b448701d..b5a356e8c57 100644 --- a/src/sage/algebras/hall_algebra.py +++ b/src/sage/algebras/hall_algebra.py @@ -113,24 +113,6 @@ class HallAlgebra(CombinatorialFreeModule): See section 2.3 in [Schiffmann]_, and sections II.2 and III.3 in [Macdonald1995]_ (where our `I_{\lambda}` is called `u_{\lambda}`). - .. WARNING:: - - We could work in a Laurent polynomial ring, but currently Laurent - polynomials do not simplify if possible. Instead we typically must - use the fraction field of `\ZZ[q]`. See :trac:`11726`. :: - - sage: R. = LaurentPolynomialRing(ZZ) - sage: H = HallAlgebra(R, q) - sage: I = H.monomial_basis() - sage: hi = H(I[2,1]); hi - H[2, 1] + (q^2+q+1)*H[1, 1, 1] - sage: hi.parent() is H - True - sage: h22 = H[2]*H[2]; h22 - H[4] + (q-1)*H[3, 1] + (q^2+q)*H[2, 2] - sage: h22.parent() is H - True - EXAMPLES:: sage: R. = ZZ[] @@ -202,6 +184,27 @@ class HallAlgebra(CombinatorialFreeModule): sage: H[2,1] * H[2,1] H[4, 2] + H[3, 3] + H[4, 1, 1] - H[3, 2, 1] - H[3, 1, 1, 1] + TESTS: + + The coefficients are actually Laurent polynomials in general, so we don't + have to work over the fraction field of `\ZZ[q]`. This didn't work before + :trac:`15345`:: + + sage: R. = LaurentPolynomialRing(ZZ) + sage: H = HallAlgebra(R, q) + sage: I = H.monomial_basis() + sage: hi = H(I[2,1]); hi + H[2, 1] + (q^2+q+1)*H[1, 1, 1] + sage: hi.parent() is H + True + sage: h22 = H[2]*H[2]; h22 + H[4] + (q-1)*H[3, 1] + (q^2+q)*H[2, 2] + sage: h22.parent() is H + True + sage: e = SymmetricFunctions(R).e() + sage: e(H[1,1,1]) + (q^-3)*e[3] + REFERENCES: .. [Schiffmann] Oliver Schiffmann. *Lectures on Hall algebras*. @@ -219,7 +222,10 @@ def __init__(self, base_ring, q, prefix='H'): sage: R = PolynomialRing(ZZ, 'q').fraction_field() sage: q = R.gen() sage: H = HallAlgebra(R, q) - sage: TestSuite(H).run() + sage: TestSuite(H).run() # long time + sage: R. = LaurentPolynomialRing(ZZ) + sage: H = HallAlgebra(R, q) + sage: TestSuite(H).run() # long time """ self._q = q try: @@ -329,6 +335,14 @@ def coproduct_on_basis(self, la): sage: H.coproduct_on_basis(Partition([2,1])) H[] # H[2, 1] + ((q^2-1)/q^2)*H[1] # H[1, 1] + 1/q*H[1] # H[2] + ((q^2-1)/q^2)*H[1, 1] # H[1] + 1/q*H[2] # H[1] + H[2, 1] # H[] + + sage: R. = LaurentPolynomialRing(ZZ) + sage: H = HallAlgebra(R, q) + sage: H.coproduct_on_basis(Partition([2])) + H[] # H[2] + (1-q^-1)*H[1] # H[1] + H[2] # H[] + sage: H.coproduct_on_basis(Partition([2,1])) + H[] # H[2, 1] + (1-q^-2)*H[1] # H[1, 1] + (q^-1)*H[1] # H[2] + + (1-q^-2)*H[1, 1] # H[1] + (q^-1)*H[2] # H[1] + H[2, 1] # H[] """ S = self.tensor_square() if all(x == 1 for x in la): @@ -353,6 +367,13 @@ def antipode_on_basis(self, la): 1/q*H[2] + 1/q*H[1, 1] sage: H.antipode_on_basis(Partition([2])) -1/q*H[2] + ((q^2-1)/q)*H[1, 1] + + sage: R. = LaurentPolynomialRing(ZZ) + sage: H = HallAlgebra(R, q) + sage: H.antipode_on_basis(Partition([1,1])) + (q^-1)*H[2] + (q^-1)*H[1, 1] + sage: H.antipode_on_basis(Partition([2])) + (-q^-1)*H[2] + (q-q^-1)*H[1, 1] """ if all(x == 1 for x in la): r = len(la) @@ -482,8 +503,7 @@ class HallAlgebraMonomials(CombinatorialFreeModule): EXAMPLES: - We could work in a Laurent polynomial ring, but pending :trac:`11726`, - we use the fraction field of `\ZZ[q]` instead. + We use the fraction field of `\ZZ[q]` for our initial example:: sage: R = PolynomialRing(ZZ, 'q').fraction_field() sage: q = R.gen() @@ -497,6 +517,17 @@ class HallAlgebraMonomials(CombinatorialFreeModule): sage: all(I(H(I[p])) == I[p] for i in range(7) for p in Partitions(i)) True + Since Laurent polynomials are sufficient, we run the same check with + the Laurent polynomial ring `\ZZ[q, q^{-1}]`:: + + sage: R. = LaurentPolynomialRing(ZZ) + sage: H = HallAlgebra(R, q) + sage: I = H.monomial_basis() + sage: all(H(I(H[p])) == H[p] for i in range(6) for p in Partitions(i)) # long time + True + sage: all(I(H(I[p])) == I[p] for i in range(6) for p in Partitions(i)) # long time + True + We can also convert to the symmetric functions. The natural basis corresponds to the Hall-Littlewood basis (up to a renormalization and an inversion of the `q` parameter), and this basis corresponds @@ -505,9 +536,9 @@ class HallAlgebraMonomials(CombinatorialFreeModule): sage: Sym = SymmetricFunctions(R) sage: e = Sym.e() sage: e(I[2,1]) - 1/q*e[2, 1] + (q^-1)*e[2, 1] sage: e(I[4,2,2,1]) - 1/q^8*e[4, 2, 2, 1] + (q^-8)*e[4, 2, 2, 1] sage: HLP = Sym.hall_littlewood(q).P() sage: H(I[2,1]) H[2, 1] + (q^2+q+1)*H[1, 1, 1] @@ -522,9 +553,9 @@ class HallAlgebraMonomials(CombinatorialFreeModule): sage: H = HallAlgebra(ZZ, 3) sage: I = H.monomial_basis() - sage: I[2,1]*I[1,1] + sage: i_elt = I[2,1]*I[1,1]; i_elt I[2, 1, 1, 1] - sage: H(_) + sage: H(i_elt) H[4, 1] + 7*H[3, 2] + 37*H[3, 1, 1] + 136*H[2, 2, 1] + 1495*H[2, 1, 1, 1] + 62920*H[1, 1, 1, 1, 1] """ @@ -541,6 +572,9 @@ def __init__(self, base_ring, q, prefix='I'): sage: q = R.gen() sage: I = HallAlgebra(R, q).monomial_basis() sage: TestSuite(I).run() + sage: R. = LaurentPolynomialRing(ZZ) + sage: I = HallAlgebra(R, q).monomial_basis() + sage: TestSuite(I).run() """ self._q = q try: @@ -642,6 +676,12 @@ def coproduct_on_basis(self, a): sage: I.coproduct_on_basis(Partition([2,1])) I[] # I[2, 1] + 1/q*I[1] # I[1, 1] + I[1] # I[2] + 1/q*I[1, 1] # I[1] + I[2] # I[1] + I[2, 1] # I[] + + sage: R. = LaurentPolynomialRing(ZZ) + sage: I = HallAlgebra(R, q).monomial_basis() + sage: I.coproduct_on_basis(Partition([2,1])) + I[] # I[2, 1] + (q^-1)*I[1] # I[1, 1] + I[1] # I[2] + + (q^-1)*I[1, 1] # I[1] + I[2] # I[1] + I[2, 1] # I[] """ S = self.tensor_square() return S.prod(S.sum_of_terms([( (Partition([r]), Partition([n-r]) ), self._q**(-r*(n-r)) ) @@ -662,6 +702,11 @@ def antipode_on_basis(self, a): 1/q*I[1, 1] - I[2] sage: I.antipode_on_basis(Partition([2,1])) -1/q*I[1, 1, 1] + I[2, 1] + + sage: R. = LaurentPolynomialRing(ZZ) + sage: I = HallAlgebra(R, q).monomial_basis() + sage: I.antipode_on_basis(Partition([2,1])) + (-q^-1)*I[1, 1, 1] + I[2, 1] """ H = HallAlgebra(self.base_ring(), self._q) cur = self.one() From 8d541055054316406c45eb4ad44a068670bfe916 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Fri, 14 Feb 2014 08:47:33 -0800 Subject: [PATCH 102/163] Renamed to_fraction to _fraction_pair. --- src/sage/rings/fraction_field.py | 6 +++--- src/sage/rings/polynomial/laurent_polynomial.pyx | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/sage/rings/fraction_field.py b/src/sage/rings/fraction_field.py index f622b29ee11..01ac07fbc28 100644 --- a/src/sage/rings/fraction_field.py +++ b/src/sage/rings/fraction_field.py @@ -297,9 +297,9 @@ def _coerce_map_from_(self, S): if isinstance(S, LaurentPolynomialRing_generic): def converter(x,y=None): if y is None: - return self._element_class(self, *x.to_fraction()) - xnum, xden = x.to_fraction() - ynum, yden = y.to_fraction() + return self._element_class(self, *x._fraction_pair()) + xnum, xden = x._fraction_pair() + ynum, yden = y._fraction_pair() return self._element_class(self, xnum*yden, xden*ynum) return CallableConvertMap(S, self, converter, parent_as_first_arg=False) diff --git a/src/sage/rings/polynomial/laurent_polynomial.pyx b/src/sage/rings/polynomial/laurent_polynomial.pyx index 31b721e673b..620f869386e 100644 --- a/src/sage/rings/polynomial/laurent_polynomial.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial.pyx @@ -492,9 +492,10 @@ cdef class LaurentPolynomial_mpair(CommutativeAlgebraElement): self._compute_polydict() return self._prod.dict() - def to_fraction(self): + def _fraction_pair(self): """ - Return one representation of self as a pair (numerator, denominator) + Return one representation of ``self`` as a pair + ``(numerator, denominator)``. Here both the numerator and the denominator are polynomials. @@ -504,7 +505,7 @@ cdef class LaurentPolynomial_mpair(CommutativeAlgebraElement): sage: L. = LaurentPolynomialRing(QQ) sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7 - sage: f.to_fraction() + sage: f._fraction_pair() (4*x^7*y^7*z + 3*x^3*y^8*z^2 + 2*x^4*y^7 + x^6*z^2, y^7*z^2) """ ring = self.parent().polynomial_ring() From 8a898ef77fbd5929c389febfd8ebee4397eac654 Mon Sep 17 00:00:00 2001 From: Darij Grinberg Date: Fri, 14 Feb 2014 15:51:19 -0800 Subject: [PATCH 103/163] taking powers of tropical zero (i.e., infinity) now possible --- src/sage/rings/semirings/tropical_semiring.pyx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/sage/rings/semirings/tropical_semiring.pyx b/src/sage/rings/semirings/tropical_semiring.pyx index 087ae99a98c..3191d7024d1 100644 --- a/src/sage/rings/semirings/tropical_semiring.pyx +++ b/src/sage/rings/semirings/tropical_semiring.pyx @@ -372,9 +372,25 @@ cdef class TropicalSemiringElement(RingElement): -4 sage: elt**(3/7) 6/7 + sage: elt**0 + 0 + + sage: elt = T.infinity() + sage: elt**0 + 0 + sage: elt**(1/2) + +infinity + sage: elt*33 + +infinity """ cdef TropicalSemiringElement self, x self = base + if self._val is None: + if exp > 0: + return self + elif exp == 0: + return self.parent().one() + raise ZeroDivisionError("Tropical division by infinity") x = self._new() x._val = exp*self._val return x From 897870953880e0b9a88444201892d8fda56a625d Mon Sep 17 00:00:00 2001 From: Darij Grinberg Date: Fri, 14 Feb 2014 15:57:57 -0800 Subject: [PATCH 104/163] further doc fixes --- src/sage/rings/semirings/tropical_semiring.pyx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sage/rings/semirings/tropical_semiring.pyx b/src/sage/rings/semirings/tropical_semiring.pyx index 3191d7024d1..c20e3190b6f 100644 --- a/src/sage/rings/semirings/tropical_semiring.pyx +++ b/src/sage/rings/semirings/tropical_semiring.pyx @@ -446,7 +446,7 @@ class TropicalSemiring(Parent, UniqueRepresentation): Specifically do not use ``sum(...)`` as this converts `0` to `0` as a tropical element, which is not the same as :meth:`zero`. Instead - use the ``sum`` method:: + use the ``sum`` method of the tropical semiring:: sage: T = TropicalSemiring(QQ) @@ -490,10 +490,10 @@ class TropicalSemiring(Parent, UniqueRepresentation): -6/7 Note that "zero" and "one" are the additive and multiplicative - identities of the tropical semiring. In other words, - they are **not** `0 \in R` and `1 \in R` respectively, but instead - the (tropical) additive and multiplicative identities `+\infty` and `0` - respectively:: + identities of the tropical semiring. In general, they are **not** + the elements `0` and `1` of `R`, respectively, even if such elements + exist (e.g., for `R = \ZZ`), but instead the (tropical) additive and + multiplicative identities `+\infty` and `0` respectively:: sage: T.zero() + T(3) == T(3) True @@ -538,7 +538,7 @@ class TropicalSemiring(Parent, UniqueRepresentation): def _coerce_map_from_(self, S): """ - Canonical coercion of into ``self`` from ``S``. + Canonical coercion into ``self`` from ``S``. The only objects that canonically coerce to a tropical semiring are tropical semirings whose base rings have a coercion. From a85b961c35675e8cb3451e0cc24d1251b7cc2f2c Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Fri, 14 Feb 2014 21:19:56 -0800 Subject: [PATCH 105/163] A few other tweaks. --- src/sage/rings/semirings/tropical_semiring.pyx | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/sage/rings/semirings/tropical_semiring.pyx b/src/sage/rings/semirings/tropical_semiring.pyx index c20e3190b6f..5cbd47260e6 100644 --- a/src/sage/rings/semirings/tropical_semiring.pyx +++ b/src/sage/rings/semirings/tropical_semiring.pyx @@ -389,7 +389,7 @@ cdef class TropicalSemiringElement(RingElement): if exp > 0: return self elif exp == 0: - return self.parent().one() + return self.parent().multiplicative_identity() raise ZeroDivisionError("Tropical division by infinity") x = self._new() x._val = exp*self._val @@ -402,9 +402,9 @@ cdef class TropicalSemiringElement(RingElement): EXAMPLES:: sage: T = TropicalSemiring(QQ) - sage: T.one().multiplicative_order() + sage: T.multiplicative_identity().multiplicative_order() 1 - sage: T.zero().multiplicative_order() + sage: T.additive_identity().multiplicative_order() +Infinity """ if self.is_one(): @@ -460,8 +460,8 @@ class TropicalSemiring(Parent, UniqueRepresentation): INPUT: - - ``base`` -- The base ordered additive semigroup `R`. - - ``use_min`` -- (Default: ``True``) If ``True``, then the semiring uses + - ``base`` -- the base ordered additive semigroup `R` + - ``use_min`` -- (default: ``True``) if ``True``, then the semiring uses `a \oplus b = \min(a, b)`; otherwise uses `a \oplus b = \max(a, b)` EXAMPLES:: @@ -499,6 +499,10 @@ class TropicalSemiring(Parent, UniqueRepresentation): True sage: T.one() * T(3) == T(3) True + sage: T.zero() == T(0) + False + sage: T.one() == T(1) + False """ def __init__(self, base, use_min=True): r""" @@ -523,7 +527,7 @@ class TropicalSemiring(Parent, UniqueRepresentation): sage: TropicalSemiring(QQ) Tropical semiring over Rational Field """ - return "Tropical semiring over %s"%self.base() + return "Tropical semiring over {}".format(self.base()) def _latex_(self): r""" From accb798f68dbcd0e7f2b24654b8728c2746170fc Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Sat, 15 Feb 2014 16:53:27 +0100 Subject: [PATCH 106/163] Trac #11785: Provide an interface to Maxima's rectform(). --- src/doc/en/reference/calculus/index.rst | 1 + src/sage/symbolic/complexity_measures.py | 36 +++++++++++ src/sage/symbolic/expression.pyx | 81 ++++++++++++++++++++++++ 3 files changed, 118 insertions(+) create mode 100644 src/sage/symbolic/complexity_measures.py diff --git a/src/doc/en/reference/calculus/index.rst b/src/doc/en/reference/calculus/index.rst index a917cc347c5..a0065797cea 100644 --- a/src/doc/en/reference/calculus/index.rst +++ b/src/doc/en/reference/calculus/index.rst @@ -16,6 +16,7 @@ Symbolic Calculus sage/calculus/test_sympy sage/calculus/tests sage/symbolic/expression_conversions + sage/symbolic/complexity_measures sage/calculus/wester sage/calculus/desolvers sage/gsl/dwt diff --git a/src/sage/symbolic/complexity_measures.py b/src/sage/symbolic/complexity_measures.py new file mode 100644 index 00000000000..1b5823e38bf --- /dev/null +++ b/src/sage/symbolic/complexity_measures.py @@ -0,0 +1,36 @@ +""" +Complexity Measures + +Some measures of symbolic expression complexity. Each complexity +measure is expected to take a symbolic expression as an argument, and +return a number. +""" + +def string_length(expr): + """ + Returns the length of ``expr`` after converting it to a string. + + INPUT: + + - ``expr`` -- the expression whose complexity we want to measure. + + OUTPUT: + + A real number representing the complexity of ``expr``. + + RATIONALE: + + If the expression is longer on-screen, then a human would probably + consider it more complex. + + EXAMPLES: + + This expression has three characters, ``x``, ``^``, and ``2``:: + + sage: from sage.symbolic.complexity_measures import string_length + sage: f = x^2 + sage: string_length(f) + 3 + + """ + return len(str(expr)) diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index 573289d7edd..7fe6109fca1 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -143,6 +143,7 @@ import sage.rings.integer import sage.rings.rational from sage.structure.element cimport ModuleElement, RingElement, Element from sage.symbolic.getitem cimport OperandsWrapper +from sage.symbolic.complexity_measures import string_length from sage.symbolic.function import get_sfunction_from_serial, SymbolicFunction from sage.rings.rational import Rational # Used for sqrt. from sage.misc.derivative import multi_derivative @@ -7829,6 +7830,86 @@ cdef class Expression(CommutativeRingElement): full_simplify = simplify_full + + def simplify_rectform(self, complexity_measure = string_length): + r""" + Attempt to simplify this expression by expressing it in the + form `a + bi` where both `a` and `b` are real. This + transformation is generally not a simplification, so we use + the given ``complexity_measure`` to discard + non-simplifications. + + INPUT: + + - ``self`` -- the expression to simplify. + + - ``complexity_measure`` -- (default: + ``sage.symbolic.complexity_measures.string_length``) a + function taking a symbolic expression as an argument and + returning a measure of that expressions complexity. If + ``None`` is supplied, the simplification will be performed + regardless of the result. + + OUTPUT: + + If the transformation produces a simpler expression (according + to ``complexity_measure``) then that simpler expression is + returned. Otherwise, the original expression is returned. + + ALGORITHM: + + We first call :meth:`rectform()` on the given + expression. Then, the supplied complexity measure is used to + determine whether or not the result is simpler than the + original expression. + + EXAMPLES: + + The exponential form of `\tan(x)`:: + + sage: f = ( e^(I*x) - e^(-I*x) ) / ( I*e^(I*x) + I*e^(-I*x) ) + sage: f.simplify_rectform() + sin(x)/cos(x) + + This should not be expanded with Euler's formula since the + resulting expression is longer when considered as a string, + and the default ``complexity_measure`` uses string length to + determine which expression is simpler:: + + sage: f = e^(I*x) + sage: f.simplify_rectform() + e^(I*x) + + However, if we pass ``None`` as our complexity measure, it + is:: + + sage: f = e^(I*x) + sage: f.simplify_rectform(complexity_measure = None) + I*sin(x) + cos(x) + + TESTS: + + When given ``None``, we should always call :meth:`rectform()` + and return the result:: + + sage: polynomials = QQ['x'] + sage: f = SR(polynomials.random_element()) + sage: g = f.simplify_rectform(complexity_measure = None) + sage: bool(g == f.rectform()) + True + + """ + simplified_expr = self.rectform() + + if complexity_measure is None: + return simplified_expr + + if complexity_measure(simplified_expr) < complexity_measure(self): + return simplified_expr + else: + return self + + def simplify_trig(self,expand=True): r""" Optionally expands and then employs identities such as From b2001c09f8407c6b256e7d49e67e449ef8cbc78c Mon Sep 17 00:00:00 2001 From: Ralf Stephan Date: Sat, 15 Feb 2014 17:06:51 +0100 Subject: [PATCH 107/163] trac #11785: reviewers patch: change doctest expected string ordering --- src/sage/symbolic/expression.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index 7fe6109fca1..9985e63fb73 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -7885,7 +7885,7 @@ cdef class Expression(CommutativeRingElement): sage: f = e^(I*x) sage: f.simplify_rectform(complexity_measure = None) - I*sin(x) + cos(x) + cos(x) + I*sin(x) TESTS: From 0c0a749f13b2dbbb8e5525316f287c18e50350d0 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Sat, 15 Feb 2014 10:27:51 -0800 Subject: [PATCH 108/163] Added lift() method. --- .../rings/semirings/tropical_semiring.pyx | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/sage/rings/semirings/tropical_semiring.pyx b/src/sage/rings/semirings/tropical_semiring.pyx index 087ae99a98c..92e01be45da 100644 --- a/src/sage/rings/semirings/tropical_semiring.pyx +++ b/src/sage/rings/semirings/tropical_semiring.pyx @@ -396,6 +396,26 @@ cdef class TropicalSemiringElement(RingElement): from sage.rings.infinity import infinity return infinity + cpdef ModuleElement lift(self): + """ + Return the value of ``self`` lifted to the base. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: elt = T(2) + sage: elt.lift() + 2 + sage: elt.lift().parent() is QQ + True + sage: T.additive_identity().lift().parent() + The Infinity Ring + """ + if self._val is None: + from sage.rings.infinity import infinity + return infinity + return self._val + class TropicalSemiring(Parent, UniqueRepresentation): r""" The tropical semiring. From 92dd64a7619a1baa2f57a91308e4e2e299226dd1 Mon Sep 17 00:00:00 2001 From: Ralf Stephan Date: Sun, 16 Feb 2014 10:39:22 +0100 Subject: [PATCH 109/163] trac 10218: improve dev man sections on reviewing --- src/doc/en/developer/trac.rst | 13 +++++++++++++ src/doc/en/developer/walk_through.rst | 4 ++++ 2 files changed, 17 insertions(+) diff --git a/src/doc/en/developer/trac.rst b/src/doc/en/developer/trac.rst index 2494d8bad5f..dff464d64e7 100644 --- a/src/doc/en/developer/trac.rst +++ b/src/doc/en/developer/trac.rst @@ -464,6 +464,12 @@ look. If you think there are issues with the patch, explain them in the comment box and change the status to "needs work". Browse the tickets on the trac server to see how things are done. +If you change the patch yourself, you must make a commit in your own +name and mark the commit as a reviewer's patch. This must be reviewed +itself, for example by the author of the original patch. + +For more advice on reviewing, please see [WSblog]. + .. note:: "The perfect is the enemy of the good" @@ -475,6 +481,13 @@ tickets on the trac server to see how things are done. want the patch written differently, your suggestion should be a clear and actionable request. +.. SEEALSO:: + + :ref:`Review Walkthrough ` + +REFERENCES: + +.. [WSblog] William Stein, How to Referee Sage Trac Tickets, http://sagemath.blogspot.com/2010/10/how-to-referee-sage-trac-tickets.html (Caveat: mercurial was replaced with git) Closing Tickets diff --git a/src/doc/en/developer/walk_through.rst b/src/doc/en/developer/walk_through.rst index 79c76be90f4..ce504c47df6 100644 --- a/src/doc/en/developer/walk_through.rst +++ b/src/doc/en/developer/walk_through.rst @@ -286,6 +286,10 @@ you need a new feature or if your branch conflicts. Reviewing ========= +This section gives an example how to review using the ``sage`` command. +For a detailed discussion of Sage's review process, +see :ref:`Reviewing Patches `. + Now suppose you want to review the existing work on a ticket, such as the one you created in the last section. For definiteness, suppose you want to review #12270. You would do that as follows:: From c3e72445517e297998cf9adbdb13852b7e88acc0 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Sun, 16 Feb 2014 15:59:07 -0800 Subject: [PATCH 110/163] Added are_linearly_dependent. --- src/sage/modules/free_module.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/sage/modules/free_module.py b/src/sage/modules/free_module.py index 0a765d28b86..9310915e7eb 100644 --- a/src/sage/modules/free_module.py +++ b/src/sage/modules/free_module.py @@ -1942,6 +1942,35 @@ def zero(self): res.set_immutable() return res + def are_linearly_dependent(self, vecs): + """ + Return ``True`` if the vectors ``vecs`` are linearly dependent and + ``False`` otherwise. + + EXAMPLES:: + + sage: M = QQ^3 + sage: vecs = [M([1,2,3]), M([4,5,6])] + sage: M.are_linearly_dependent(vecs) + False + sage: vecs.append(M([3,3,3])) + sage: M.are_linearly_dependent(vecs) + True + + sage: R. = QQ[] + sage: M = FreeModule(R, 2) + sage: vecs = [M([x^2+1, x+1]), M([x+2, 2*x+1])] + sage: M.are_linearly_dependent(vecs) + False + sage: vecs.append(M([-2*x+1, -2*x^2+1])) + sage: M.are_linearly_dependent(vecs) + True + """ + from sage.matrix.constructor import matrix + A = matrix(vecs) + A.echelonize() + return any(row.is_zero() for row in A.rows()) + def _magma_init_(self, magma): """ EXAMPLES:: From 850abdcc3ce6d76d04d2bf9cbefc6aa7a2aec603 Mon Sep 17 00:00:00 2001 From: Paul Zimmermann Date: Mon, 17 Feb 2014 16:39:09 +0100 Subject: [PATCH 111/163] trac 9505: coeff(f,x*y) does not work --- src/sage/symbolic/expression.pyx | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index 573289d7edd..0cc154d26c9 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -4912,8 +4912,30 @@ cdef class Expression(CommutativeRingElement): sage: f.coefficient(x, 0) sqrt(x)*sin(y) + z^z + TESTS:: + + Check if :trac:`9505` is fixed:: + + sage: var('x,y,z') + (x, y, z) + sage: f = x*y*z^2 + sage: f.coeff(x*y) + z^2 + sage: f.coeff(x*y, 2) + Traceback (most recent call last): + ... + TypeError: n <> 1 only allowed for s being a variable + """ cdef Expression ss = self.coerce_in(s) + if n <> 1 and not is_a_symbol(ss._gobj): + raise TypeError, "n <> 1 only allowed for s being a variable" + # the following is a temporary fix for GiNaC bug #9505 + if is_a_mul(ss._gobj): # necessarily n=1 here + res = self + for i from 0 <= i < ss._gobj.nops(): + res = res.coeff(new_Expression_from_GEx(self._parent, ss._gobj.op(i))) + return res return new_Expression_from_GEx(self._parent, self._gobj.coeff(ss._gobj, n)) coeff = coefficient From e67e16f7d9d8ea3474297c710c963e48894d0a2c Mon Sep 17 00:00:00 2001 From: Mike Hansen Date: Tue, 18 Feb 2014 08:21:57 +0100 Subject: [PATCH 112/163] #5383: isinstance(PrincipalIdealDomain) should be replaced with a method .is_principal_ideal_domain() --- src/sage/modules/free_module.py | 2 +- src/sage/modules/free_quadratic_module.py | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/sage/modules/free_module.py b/src/sage/modules/free_module.py index 0a765d28b86..7e329929e9f 100644 --- a/src/sage/modules/free_module.py +++ b/src/sage/modules/free_module.py @@ -378,7 +378,7 @@ def create_object(self, version, key): elif base_ring.is_field(): return FreeModule_ambient_field(base_ring, rank, sparse=sparse) - elif isinstance(base_ring, principal_ideal_domain.PrincipalIdealDomain): + elif base_ring in PrincipalIdealDomains(): return FreeModule_ambient_pid(base_ring, rank, sparse=sparse) elif isinstance(base_ring, sage.rings.number_field.order.Order) \ diff --git a/src/sage/modules/free_quadratic_module.py b/src/sage/modules/free_quadratic_module.py index 787dca6308a..ca53aadfed9 100644 --- a/src/sage/modules/free_quadratic_module.py +++ b/src/sage/modules/free_quadratic_module.py @@ -82,8 +82,7 @@ import sage.rings.integral_domain as integral_domain import sage.rings.integer import sage.structure.parent_gens as gens - - +from sage.categories.principal_ideal_domains import PrincipalIdealDomains import free_module ############################################################################### @@ -169,7 +168,7 @@ def FreeQuadraticModule( M = FreeQuadraticModule_ambient_field( base_ring, rank, sparse=sparse, inner_product_matrix=inner_product_matrix) - elif isinstance(base_ring, principal_ideal_domain.PrincipalIdealDomain): + elif base_ring in PrincipalIdealDomains(): M = FreeQuadraticModule_ambient_pid( base_ring, rank, sparse=sparse, inner_product_matrix=inner_product_matrix) From 454bac134f5e186d2e85c33ba0715b96d73530e5 Mon Sep 17 00:00:00 2001 From: Burcin Erocal Date: Tue, 18 Feb 2014 08:56:29 +0100 Subject: [PATCH 113/163] trac 10136: Unify top level log and ln functions. --- src/sage/functions/log.py | 232 +++++++++++++++++-------------- src/sage/symbolic/expression.pyx | 11 +- 2 files changed, 132 insertions(+), 111 deletions(-) diff --git a/src/sage/functions/log.py b/src/sage/functions/log.py index 822baa2d6c5..35f71b86eac 100644 --- a/src/sage/functions/log.py +++ b/src/sage/functions/log.py @@ -169,16 +169,12 @@ def __init__(self): sage: ln(complex(-1)) 3.141592653589793j - We do not currently support a ``hold`` parameter in functional - notation:: - - sage: log(SR(-1),hold=True) - Traceback (most recent call last): - ... - TypeError: log() got an unexpected keyword argument 'hold' - - This is possible with method notation:: + The ``hold`` parameter can be used to prevent automatic evaluation:: + sage: log(-1,hold=True) + log(-1) + sage: log(-1) + I*pi sage: I.log(hold=True) log(I) sage: I.log(hold=True).simplify() @@ -222,106 +218,132 @@ def __init__(self): 3.141592653589793j """ GinacFunction.__init__(self, 'log', latex_name=r'\log', - conversions=dict(maxima='log')) + conversions=dict(maxima='log')) -ln = function_log = Function_log() + def __call__(self, *args, **kwds): + """ + Return the logarithm of x to the given base. + + Calls the ``log`` method of the object x when computing + the logarithm, thus allowing use of logarithm on any object + containing a ``log`` method. In other words, log works + on more than just real numbers. + + EXAMPLES:: + + sage: log(e^2) + 2 + + To change the base of the logarithm, add a second parameter:: + + sage: log(1000,10) + 3 + + You can use + :class:`RDF`, + :class:`~sage.rings.real_mpfr.RealField` or ``n`` to get a + numerical real approximation:: + + sage: log(1024, 2) + 10 + sage: RDF(log(1024, 2)) + 10.0 + sage: log(10, 4) + log(10)/log(4) + sage: RDF(log(10, 4)) + 1.66096404744 + sage: log(10, 2) + log(10)/log(2) + sage: n(log(10, 2)) + 3.32192809488736 + sage: log(10, e) + log(10) + sage: n(log(10, e)) + 2.30258509299405 + + The log function works for negative numbers, complex + numbers, and symbolic numbers too, picking the branch + with angle between `-pi` and `pi`:: + + sage: log(-1+0*I) + I*pi + sage: log(CC(-1)) + 3.14159265358979*I + sage: log(-1.0) + 3.14159265358979*I + + For input zero, the following behavior occurs:: + + sage: log(0) + -Infinity + sage: log(CC(0)) + -infinity + sage: log(0.0) + -infinity + + The log function also works in finite fields as long as the + argument lies in the multiplicative group generated by the base:: + + sage: F = GF(13); g = F.multiplicative_generator(); g + 2 + sage: a = F(8) + sage: log(a,g); g^log(a,g) + 3 + 8 + sage: log(a,3) + Traceback (most recent call last): + ... + ValueError: No discrete log of 8 found to base 3 + sage: log(F(9), 3) + 2 + + The log function also works for p-adics (see documentation for + p-adics for more information):: + + sage: R = Zp(5); R + 5-adic Ring with capped relative precision 20 + sage: a = R(16); a + 1 + 3*5 + O(5^20) + sage: log(a) + 3*5 + 3*5^2 + 3*5^4 + 3*5^5 + 3*5^6 + 4*5^7 + 2*5^8 + 5^9 + + 5^11 + 2*5^12 + 5^13 + 3*5^15 + 2*5^16 + 4*5^17 + 3*5^18 + + 3*5^19 + O(5^20) + + + TESTS: + + Check if :trac:`10136` is fixed:: + + sage: log(x).operator() is log + True + sage: log(x).operator() is ln + True + + sage: log(1000, 10, base=5) + Traceback (most recent call last): + ... + TypeError: Symbolic function log must be called as log(x), + log(x, base=b) or log(x, b) + """ + base = kwds.pop('base', None) + if base is None: + if len(args) == 1: + return GinacFunction.__call__(self, *args, **kwds) + # second argument is base + base = args[1] + args = args[:1] + + if len(args) != 1: + raise TypeError("Symbolic function log must be called as " + "log(x), log(x, base=b) or log(x, b)") -def log(x, base=None): - """ - Return the logarithm of x to the given base. - - Calls the ``log`` method of the object x when computing - the logarithm, thus allowing use of logarithm on any object - containing a ``log`` method. In other words, log works - on more than just real numbers. - - EXAMPLES:: - - sage: log(e^2) - 2 - - To change the base of the logarithm, add a second parameter:: - - sage: log(1000,10) - 3 - - You can use :class:`RDF`, - :class:`~sage.rings.real_mpfr.RealField` or ``n`` to get a numerical real - approximation:: - - sage: log(1024, 2) - 10 - sage: RDF(log(1024, 2)) - 10.0 - sage: log(10, 4) - log(10)/log(4) - sage: RDF(log(10, 4)) - 1.66096404744 - sage: log(10, 2) - log(10)/log(2) - sage: n(log(10, 2)) - 3.32192809488736 - sage: log(10, e) - log(10) - sage: n(log(10, e)) - 2.30258509299405 - - The log function works for negative numbers, complex - numbers, and symbolic numbers too, picking the branch - with angle between `-pi` and `pi`:: - - sage: log(-1+0*I) - I*pi - sage: log(CC(-1)) - 3.14159265358979*I - sage: log(-1.0) - 3.14159265358979*I - - For input zero, the following behavior occurs:: - - sage: log(0) - -Infinity - sage: log(CC(0)) - -infinity - sage: log(0.0) - -infinity - - The log function also works in finite fields as long as the argument lies - in the multiplicative group generated by the base:: - - sage: F = GF(13); g = F.multiplicative_generator(); g - 2 - sage: a = F(8) - sage: log(a,g); g^log(a,g) - 3 - 8 - sage: log(a,3) - Traceback (most recent call last): - ... - ValueError: No discrete log of 8 found to base 3 - sage: log(F(9), 3) - 2 - - The log function also works for p-adics (see documentation for - p-adics for more information):: - - sage: R = Zp(5); R - 5-adic Ring with capped relative precision 20 - sage: a = R(16); a - 1 + 3*5 + O(5^20) - sage: log(a) - 3*5 + 3*5^2 + 3*5^4 + 3*5^5 + 3*5^6 + 4*5^7 + 2*5^8 + 5^9 + 5^11 + 2*5^12 + 5^13 + 3*5^15 + 2*5^16 + 4*5^17 + 3*5^18 + 3*5^19 + O(5^20) - """ - if base is None: - try: - return x.log() - except AttributeError: - return ln(x) - else: try: - return x.log(base) + return args[0].log(base) except (AttributeError, TypeError): - return log(x) / log(base) + return GinacFunction.__call__(self, *args, **kwds) / \ + GinacFunction.__call__(self, base, **kwds) + +ln = log = function_log = Function_log() class Function_polylog(GinacFunction): diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index 573289d7edd..56e7e11bf77 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -6931,13 +6931,12 @@ cdef class Expression(CommutativeRingElement): sage: a = I.log(hold=True); a.simplify() 1/2*I*pi - We do not currently support a ``hold`` parameter in functional - notation:: + The ``hold`` parameter also works in functional notation:: - sage: log(SR(-1),hold=True) - Traceback (most recent call last): - ... - TypeError: log() got an unexpected keyword argument 'hold' + sage: log(-1,hold=True) + log(-1) + sage: log(-1) + I*pi TESTS:: From 42a352a4d39b1ad9ddf7bb75c9bf8e3dc8ba67a0 Mon Sep 17 00:00:00 2001 From: Ralf Stephan Date: Tue, 18 Feb 2014 09:20:07 +0100 Subject: [PATCH 114/163] 10136 reviewer's patch: adapt ext/fast_callable to new reality; fixes patchbot fail --- src/sage/ext/fast_callable.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/ext/fast_callable.pyx b/src/sage/ext/fast_callable.pyx index 93c3e87d07d..a9083b80d92 100644 --- a/src/sage/ext/fast_callable.pyx +++ b/src/sage/ext/fast_callable.pyx @@ -1522,7 +1522,7 @@ cpdef dict get_builtin_functions(): sage: from sage.ext.fast_callable import get_builtin_functions sage: builtins = get_builtin_functions() sage: sorted(list(builtins.values())) - ['abs', 'abs', 'acos', 'acosh', 'add', 'asin', 'asinh', 'atan', 'atanh', 'ceil', 'cos', 'cosh', 'cot', 'csc', 'div', 'exp', 'floor', 'floordiv', 'inv', 'log', 'log', 'mul', 'neg', 'pow', 'sec', 'sin', 'sinh', 'sqrt', 'sub', 'tan', 'tanh'] + ['abs', 'abs', 'acos', 'acosh', 'add', 'asin', 'asinh', 'atan', 'atanh', 'ceil', 'cos', 'cosh', 'cot', 'csc', 'div', 'exp', 'floor', 'floordiv', 'inv', 'log', 'mul', 'neg', 'pow', 'sec', 'sin', 'sinh', 'sqrt', 'sub', 'tan', 'tanh'] sage: builtins[sin] 'sin' sage: builtins[ln] From dfaa88920b4be4ff22103008c086fb1837144400 Mon Sep 17 00:00:00 2001 From: Burcin Erocal Date: Tue, 18 Feb 2014 10:08:12 +0100 Subject: [PATCH 115/163] trac 10849: add doctests for fix to number field element comparison --- src/sage/symbolic/expression.pyx | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index 573289d7edd..fef3b5bddd7 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -2956,6 +2956,16 @@ cdef class Expression(CommutativeRingElement): sage: g = expand(iterkate(7)) sage: g.nops() 480 + + Check if :trac:`10849` is fixed:: + + sage: t = I.pyobject().parent()(-1/2) + sage: t > 0 + False + sage: t = I*x-1/2; t + I*x - 1/2 + sage: t.subs(x=I*x).subs(x=0).is_positive() + False """ return (left)._cmp(right) From ab293b23647b01c03eae0e5c0a9f189ebcc2cc3c Mon Sep 17 00:00:00 2001 From: Peter Bruin Date: Tue, 18 Feb 2014 14:53:04 +0000 Subject: [PATCH 116/163] fix resizing of GP results vector when stack overflow occurs --- src/sage/interfaces/gp.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/sage/interfaces/gp.py b/src/sage/interfaces/gp.py index 91531ce8212..a34b9781684 100644 --- a/src/sage/interfaces/gp.py +++ b/src/sage/interfaces/gp.py @@ -572,6 +572,18 @@ def _next_var_name(self): 4 sage: g._next_var_name() 'sage[5]' + + TESTS: + + The vector of results is correctly resized when the stack has + to be enlarged during this operation:: + + sage: g = Gp(stacksize=10^4,init_list_length=12000) # long time + sage: for n in [1..13000]: # long time + ....: a = g(n) # long time + sage: g('length(sage)') # long time + 24000 + """ self.__seq += 1 if self.__seq >= self.__var_store_len: @@ -579,7 +591,9 @@ def _next_var_name(self): self.eval('sage=vector(%s,k,0);'%self.__init_list_length) self.__var_store_len = self.__init_list_length else: - self.eval('sage=concat(sage, vector(%s,k,0));'%self.__var_store_len) + self.eval('sage0=concat(sage, vector(%s,k,0));'%self.__var_store_len) + self.eval('sage=sage0;') + self.eval('kill(sage0);') self.__var_store_len *= 2 verbose("doubling PARI/sage object vector: %s"%self.__var_store_len) return 'sage[%s]'%self.__seq From c8770e15df28dad32768a09f4319cf1ccdb5695f Mon Sep 17 00:00:00 2001 From: David Roe Date: Wed, 19 Feb 2014 15:41:39 +0100 Subject: [PATCH 117/163] Trac #12117: Update aurifeuillian factorization in sage.rings.factorint --- src/sage/rings/factorint.pyx | 120 +++++++++++++++++++++++------------ 1 file changed, 81 insertions(+), 39 deletions(-) diff --git a/src/sage/rings/factorint.pyx b/src/sage/rings/factorint.pyx index 0ca522ce6b0..920befab295 100644 --- a/src/sage/rings/factorint.pyx +++ b/src/sage/rings/factorint.pyx @@ -25,11 +25,12 @@ from sage.rings.fast_arith import prime_range from sage.structure.factorization_integer import IntegerFactorization from math import floor from sage.misc.superseded import deprecated_function_alias +from sage.misc.misc_c import prod cdef extern from "limits.h": long LONG_MAX -cpdef aurifeuillian(n, m, F=None): +cpdef aurifeuillian(n, m, F=None, bint check=True): r""" Return Aurifeuillian factors `F_n^\pm(m^2n)` @@ -78,35 +79,47 @@ cpdef aurifeuillian(n, m, F=None): arXiv:1004.5466v1 [math.NT] """ - from sage.rings.arith import euler_phi, kronecker_symbol - from sage.functions.log import exp - from sage.rings.real_mpfr import RealField - if not n.is_squarefree(): - raise ValueError, "n has to be square-free" - if n < 2: - raise ValueError, "n has to be greater than 1" - if m < 1: - raise ValueError, "m has to be positive" + from sage.rings.arith import euler_phi + from sage.rings.real_mpfi import RealIntervalField + if check: + if not n.is_squarefree(): + raise ValueError, "n has to be square-free" + if n < 2: + raise ValueError, "n has to be greater than 1" + if m < 1: + raise ValueError, "m has to be positive" x = m**2*n - y = euler_phi(2*n)//2 - if F == None: - from sage.misc.functional import cyclotomic_polynomial + cdef Py_ssize_t y = euler_phi(2*n)//2 + if F is None: + from sage.rings.polynomial.cyclotomic import cyclotomic_value if n%2: if n%4 == 3: s = -1 else: s = 1 - F = cyclotomic_polynomial(n)(s*x) + F = cyclotomic_value(n, s*x) else: - F = (-1)**euler_phi(n//2)*cyclotomic_polynomial(n//2)(-x**2) - tmp = sum([kronecker_symbol(n,2*j+1)/((2*j+1)*x**j) for j in range(y)]) - R = RealField(300) - Fm = R(F.sqrt()*R(-1/m*tmp).exp()).round() - return [Fm, Integer(round(F//Fm))] + F = cyclotomic_value(n//2, -x**2) + if n == 2: + F = -F + cdef Py_ssize_t j + tmp = 0 + for j in range(y): + tmp += n.kronecker(2*j + 1) / ((2*j + 1) * x**j) + prec = Integer(150) + R = RealIntervalField(prec) + Fm = R(F).sqrt() * R(-1/m*tmp).exp() + while Fm.upper().round() != Fm.lower().round(): + prec *= 2 + R = RealIntervalField(prec) + Fm = R(F).sqrt() * R(-1/m*tmp).exp() + Fm = Fm.upper().round() + assert (not check or Fm.divides(F)) + return [Fm, F // Fm] base_exponent = deprecated_function_alias(12116, lambda n: n.perfect_power()) -cpdef factor_aurifeuillian(n): +cpdef factor_aurifeuillian(n, check=True): r""" Return Aurifeuillian factors of `n` if `n = x^{(2k-1)x} \pw 1` (where the sign is '-' if x = 1 mod 4, and '+' otherwise) else `n` @@ -134,36 +147,65 @@ cpdef factor_aurifeuillian(n): True sage: fa(2^4+1) [17] + sage: fa((6^2*3)^3+1) + [109, 91, 127] + + TESTS:: + + sage: for n in [2,3,5,6,30,31,33]: + ... for m in [8,96,109201283]: + ... s = -1 if n % 4 == 1 else 1 + ... y = (m^2*n)^n + s + ... F = fa(y) + ... assert(len(F) > 0 and prod(F) == y) REFERENCES: .. http://mathworld.wolfram.com/AurifeuilleanFactorization.html + .. Brent, On computing factors of cyclotomic polynomials, Theorem 3 + arXiv:1004.5466v1 [math.NT] """ if n in [-2, -1, 0, 1, 2]: return [n] cdef int exp = 1 - for x in [-1, 1]: - b = n + x - b, exp = b.perfect_power() + for s in [-1, 1]: + x, exp = (n - s).perfect_power() if exp > 1: - if not b.is_prime(): - continue - m = b**((exp+b)/(2*b)-1) - if m != floor(m): - continue - if b == 2: - if x == -1: - return aurifeuillian(b, m, n) + # factorization is possible if x = m^2 * n and exp = n, n squarefree + # We have the freedom to replace exp by exp/a and x by x^a. If a is even, + # n = 1 and we've gotten nowhere. So set n as the squarefree part of x, + # and m^2 the remainder. We can replace exp by exp/(2a+1) as long as we + # replace (m^2 * n) by (m^2 * n)^(2a + 1) = (m^(2a + 1) * n^a)^2 * n. + # In particular, n needs to be a divisor of both x and exp (as well as being squarefree). + a_guess = x.gcd(exp) + m = x // a_guess + # n_guess is small, so we can factor it. + a = 1 + for p, e in a_guess.factor(): + v = m.valuation(p) + if v + e % 2: + # one factor of p remains in a. + a *= p + if e > 1: + m *= p**(e-1) else: - return [2**(exp/2)-1, 2**(exp/2)+1] - F = b**(exp/b)-x - result = [F] + aurifeuillian(b, m, n/F) - prod = 1 - for a in result: - prod *= a - if prod == n: - return result + # all factors of p go to m + m *= p**e + if a == 1 or (a % 4 == 1 and s == 1) or (a % 4 != 1 and s == -1): continue + m, r = m.sqrtrem() + if r: continue + exp_adjust = exp // a + if exp_adjust % 2 == 0: continue + m = m**exp_adjust * a**(exp_adjust//2) + F = aurifeuillian(a, m, check=False) + rem = prod(F) + if check and not rem.divides(n): + raise RuntimeError("rem=%s, F=%s, n=%s, m=%s"%(rem, F, n, m)) + rem = n // rem + if rem != 1: + return [rem] + F + return F return [n] def factor_cunningham(m, proof=None): From 34a93eb66ffa84b46905e91863edfe81ad085219 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Wed, 19 Feb 2014 10:46:09 -0800 Subject: [PATCH 118/163] Cleaned up documentation in Aurifeuillian factorization methods. --- src/sage/rings/factorint.pyx | 52 +++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/src/sage/rings/factorint.pyx b/src/sage/rings/factorint.pyx index 920befab295..e32844bb801 100644 --- a/src/sage/rings/factorint.pyx +++ b/src/sage/rings/factorint.pyx @@ -32,17 +32,20 @@ cdef extern from "limits.h": cpdef aurifeuillian(n, m, F=None, bint check=True): r""" - Return Aurifeuillian factors `F_n^\pm(m^2n)` + Return the Aurifeuillian factors `F_n^\pm(m^2n)`. + + This is based off Theorem 3 of [Brent93]_. INPUT: - - ``n`` - integer - - ``m`` - integer - - ``F`` - integer (default: None) + - ``n`` -- integer + - ``m`` -- integer + - ``F`` -- integer (default: ``None``) + - ``check`` -- boolean (default: ``True``) OUTPUT: - List of factors + List of factors. EXAMPLES:: @@ -70,24 +73,25 @@ cpdef aurifeuillian(n, m, F=None, bint check=True): .. NOTE:: - There is no need to set `F`. It's only for increasing speed - of factor_aurifeuillian(). + There is no need to set `F`. It's only for increasing speed + of :meth:`factor_aurifeuillian()`. REFERENCES: - .. Brent, On computing factors of cyclotomic polynomials, Theorem 3 - arXiv:1004.5466v1 [math.NT] - + .. [Brent93] Richard P. Brent. + *On computing factors of cyclotomic polynomials*. + Mathematics of Computation. **61** (1993). No. 203. pp 131-149. + :arXiv:`1004.5466v1`. http://www.jstor.org/stable/2152941 """ from sage.rings.arith import euler_phi from sage.rings.real_mpfi import RealIntervalField if check: if not n.is_squarefree(): - raise ValueError, "n has to be square-free" + raise ValueError("n has to be square-free") if n < 2: - raise ValueError, "n has to be greater than 1" + raise ValueError("n has to be greater than 1") if m < 1: - raise ValueError, "m has to be positive" + raise ValueError("m has to be positive") x = m**2*n cdef Py_ssize_t y = euler_phi(2*n)//2 if F is None: @@ -126,13 +130,13 @@ cpdef factor_aurifeuillian(n, check=True): INPUT: - - ``n`` - integer + - ``n`` -- integer OUTPUT: - List of factors of `n` found by Aurifeuillian factorization. + List of factors of `n` found by Aurifeuillian factorization. - EXAMPLES: + EXAMPLES:: sage: from sage.rings.factorint import factor_aurifeuillian as fa sage: fa(2^6+1) @@ -153,18 +157,16 @@ cpdef factor_aurifeuillian(n, check=True): TESTS:: sage: for n in [2,3,5,6,30,31,33]: - ... for m in [8,96,109201283]: - ... s = -1 if n % 4 == 1 else 1 - ... y = (m^2*n)^n + s - ... F = fa(y) - ... assert(len(F) > 0 and prod(F) == y) + ....: for m in [8,96,109201283]: + ....: s = -1 if n % 4 == 1 else 1 + ....: y = (m^2*n)^n + s + ....: F = fa(y) + ....: assert(len(F) > 0 and prod(F) == y) REFERENCES: - .. http://mathworld.wolfram.com/AurifeuilleanFactorization.html - - .. Brent, On computing factors of cyclotomic polynomials, Theorem 3 - arXiv:1004.5466v1 [math.NT] + - http://mathworld.wolfram.com/AurifeuilleanFactorization.html + - [Brent93]_ Theorem 3 """ if n in [-2, -1, 0, 1, 2]: return [n] From e4307b38942719c161de03e161b06f29f9ff5fed Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Wed, 19 Feb 2014 10:53:00 -0800 Subject: [PATCH 119/163] Some other misc docstring tweaks. --- src/sage/rings/factorint.pyx | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/sage/rings/factorint.pyx b/src/sage/rings/factorint.pyx index e32844bb801..8632992b23e 100644 --- a/src/sage/rings/factorint.pyx +++ b/src/sage/rings/factorint.pyx @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*-* r""" Integer factorization functions @@ -45,7 +46,7 @@ cpdef aurifeuillian(n, m, F=None, bint check=True): OUTPUT: - List of factors. + A list of factors. EXAMPLES:: @@ -214,18 +215,18 @@ def factor_cunningham(m, proof=None): r""" Return factorization of self obtained using trial division for all primes in the so called Cunningham table. This is - efficient if self has some factors of type $b^n+1$ or $b^n-1$, - with $b$ in $\{2,3,5,6,7,10,11,12\}$. + efficient if self has some factors of type `b^n+1` or `b^n-1`, + with `b` in `\{2,3,5,6,7,10,11,12\}`. You need to install an optional package to use this method, this can be done with the following command line: - ``sage -i cunningham_tables`` + ``sage -i cunningham_tables``. INPUT: - - ``proof`` - bool (default: None) whether or not to - prove primality of each factor, this is only for factors - not in the Cunningham table. + - ``proof`` -- bool (default: ``None``); whether or not to + prove primality of each factor, this is only for factors + not in the Cunningham table EXAMPLES:: @@ -260,7 +261,7 @@ cpdef factor_trial_division(m, long limit=LONG_MAX): INPUT: - - ``limit`` - integer (default: LONG_MAX) that fits in a C signed long + - ``limit`` -- integer (default: ``LONG_MAX``) that fits in a C signed long EXAMPLES:: @@ -310,19 +311,19 @@ cpdef factor_using_pari(n, int_=False, debug_level=0, proof=None): INPUT: - - ``int_`` -- (default: ``False``), whether the factors are - of type ``int`` instead of ``Integer`` + - ``int_`` -- (default: ``False``), whether the factors are + of type ``int`` instead of ``Integer`` - - ``debug_level`` -- (default: 0), debug level of the call - to PARI + - ``debug_level`` -- (default: 0), debug level of the call + to PARI - - ``proof`` -- (default: ``None``), whether the factors are - required to be proven prime; if ``None``, the global default - is used + - ``proof`` -- (default: ``None``), whether the factors are + required to be proven prime; if ``None``, the global default + is used OUTPUT: - - a list of pairs + A list of pairs. EXAMPLES:: From 2ffeeb72890fc52b937b259f0f4ca6792a2d5b1d Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Thu, 20 Feb 2014 08:06:40 -0800 Subject: [PATCH 120/163] Slight changes to cliquer install script. --- build/pkgs/cliquer/spkg-install | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/build/pkgs/cliquer/spkg-install b/build/pkgs/cliquer/spkg-install index 86b445883ad..820890a46aa 100755 --- a/build/pkgs/cliquer/spkg-install +++ b/build/pkgs/cliquer/spkg-install @@ -1,11 +1,5 @@ #!/usr/bin/env bash -if [ "$SAGE_LOCAL" = "" ]; then - echo "SAGE_LOCAL undefined ... exiting"; - echo "Maybe run 'sage -sh'?" - exit 1 -fi - OPTIMIZATION_FLAGS="-O3 -funroll-loops -fomit-frame-pointer" # Work around a bug in gcc 4.6.0: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48774 if [ "`testcc.sh $CC`" = GCC ] ; then @@ -53,13 +47,15 @@ for patch in ../patches/*.patch; do patch -p1 <"$patch" if [ $? -ne 0 ]; then echo >&2 "Error applying '$patch'" - return 1 + exit 1 fi done -set -e - $MAKE +if [ $? -ne 0 ]; then + echo >&2 "Failed to compile cliquer" + exit 1 +fi rm -rf "$SAGE_LOCAL/include/cliquer/" mkdir "$SAGE_LOCAL/include/cliquer/" From 0b0e75ecb4eb41b505d0557af22059051513f946 Mon Sep 17 00:00:00 2001 From: Ralf Stephan Date: Thu, 20 Feb 2014 17:35:24 +0100 Subject: [PATCH 121/163] Trac #9870: fix due to merge --- src/sage/combinat/all.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/combinat/all.py b/src/sage/combinat/all.py index 3d296dd8e3c..d808ffc9196 100644 --- a/src/sage/combinat/all.py +++ b/src/sage/combinat/all.py @@ -3,7 +3,7 @@ CombinatorialObject, CombinatorialClass, FilteredCombinatorialClass, \ UnionCombinatorialClass, MapCombinatorialClass, \ InfiniteAbstractCombinatorialClass, \ - hurwitz_zeta, combinations, combinations_iterator, \ + combinations, combinations_iterator, \ number_of_combinations, arrangements, number_of_arrangements, \ derangements, number_of_derangements, tuples, number_of_tuples, \ unordered_tuples, number_of_unordered_tuples, permutations, \ From 112d7ef3c7b0015369c463f8406550d30d6bb3c7 Mon Sep 17 00:00:00 2001 From: Clemens Heuberger Date: Fri, 21 Feb 2014 09:15:23 +0200 Subject: [PATCH 122/163] Fixed indentation error in docstring of class sage.combinat.finite_state_machine.FiniteStateMachine --- src/sage/combinat/finite_state_machine.py | 94 +++++++++++------------ 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/src/sage/combinat/finite_state_machine.py b/src/sage/combinat/finite_state_machine.py index efdaaba6e47..8ca1aea29d7 100644 --- a/src/sage/combinat/finite_state_machine.py +++ b/src/sage/combinat/finite_state_machine.py @@ -1337,60 +1337,60 @@ class FiniteStateMachine(SageObject): NotImplementedError - TESTS:: + TESTS:: - sage: a = FSMState('S_a', 'a') - sage: b = FSMState('S_b', 'b') - sage: c = FSMState('S_c', 'c') - sage: d = FSMState('S_d', 'd') - sage: FiniteStateMachine({a:[b, c], b:[b, c, d], - ....: c:[a, b], d:[a, c]}) - Finite state machine with 4 states + sage: a = FSMState('S_a', 'a') + sage: b = FSMState('S_b', 'b') + sage: c = FSMState('S_c', 'c') + sage: d = FSMState('S_d', 'd') + sage: FiniteStateMachine({a:[b, c], b:[b, c, d], + ....: c:[a, b], d:[a, c]}) + Finite state machine with 4 states - We have several constructions which lead to the same finite - state machine:: + We have several constructions which lead to the same finite + state machine:: - sage: A = FSMState('A') - sage: B = FSMState('B') - sage: C = FSMState('C') - sage: FSM1 = FiniteStateMachine( - ....: {A:{B:{'word_in':0, 'word_out':1}, - ....: C:{'word_in':1, 'word_out':1}}}) - sage: FSM2 = FiniteStateMachine({A:{B:(0, 1), C:(1, 1)}}) - sage: FSM3 = FiniteStateMachine( - ....: {A:{B:FSMTransition(A, B, 0, 1), - ....: C:FSMTransition(A, C, 1, 1)}}) - sage: FSM4 = FiniteStateMachine({A:[(B, 0, 1), (C, 1, 1)]}) - sage: FSM5 = FiniteStateMachine( - ....: {A:[FSMTransition(A, B, 0, 1), FSMTransition(A, C, 1, 1)]}) - sage: FSM6 = FiniteStateMachine( - ....: [{'from_state':A, 'to_state':B, 'word_in':0, 'word_out':1}, - ....: {'from_state':A, 'to_state':C, 'word_in':1, 'word_out':1}]) - sage: FSM7 = FiniteStateMachine([(A, B, 0, 1), (A, C, 1, 1)]) - sage: FSM8 = FiniteStateMachine( - ....: [FSMTransition(A, B, 0, 1), FSMTransition(A, C, 1, 1)]) - - sage: FSM1 == FSM2 == FSM3 == FSM4 == FSM5 == FSM6 == FSM7 == FSM8 - True + sage: A = FSMState('A') + sage: B = FSMState('B') + sage: C = FSMState('C') + sage: FSM1 = FiniteStateMachine( + ....: {A:{B:{'word_in':0, 'word_out':1}, + ....: C:{'word_in':1, 'word_out':1}}}) + sage: FSM2 = FiniteStateMachine({A:{B:(0, 1), C:(1, 1)}}) + sage: FSM3 = FiniteStateMachine( + ....: {A:{B:FSMTransition(A, B, 0, 1), + ....: C:FSMTransition(A, C, 1, 1)}}) + sage: FSM4 = FiniteStateMachine({A:[(B, 0, 1), (C, 1, 1)]}) + sage: FSM5 = FiniteStateMachine( + ....: {A:[FSMTransition(A, B, 0, 1), FSMTransition(A, C, 1, 1)]}) + sage: FSM6 = FiniteStateMachine( + ....: [{'from_state':A, 'to_state':B, 'word_in':0, 'word_out':1}, + ....: {'from_state':A, 'to_state':C, 'word_in':1, 'word_out':1}]) + sage: FSM7 = FiniteStateMachine([(A, B, 0, 1), (A, C, 1, 1)]) + sage: FSM8 = FiniteStateMachine( + ....: [FSMTransition(A, B, 0, 1), FSMTransition(A, C, 1, 1)]) + + sage: FSM1 == FSM2 == FSM3 == FSM4 == FSM5 == FSM6 == FSM7 == FSM8 + True - It is possible to skip ``FSMTransition`` in the example above. + It is possible to skip ``FSMTransition`` in the example above. - Some more tests for different input-data:: + Some more tests for different input-data:: - sage: FiniteStateMachine({'a':{'a':[0, 0], 'b':[1, 1]}, - ....: 'b':{'b':[1, 0]}}) - Finite state machine with 2 states + sage: FiniteStateMachine({'a':{'a':[0, 0], 'b':[1, 1]}, + ....: 'b':{'b':[1, 0]}}) + Finite state machine with 2 states - sage: a = FSMState('S_a', 'a') - sage: b = FSMState('S_b', 'b') - sage: c = FSMState('S_c', 'c') - sage: d = FSMState('S_d', 'd') - sage: t1 = FSMTransition(a, b) - sage: t2 = FSMTransition(b, c) - sage: t3 = FSMTransition(b, d) - sage: t4 = FSMTransition(c, d) - sage: FiniteStateMachine([t1, t2, t3, t4]) - Finite state machine with 4 states + sage: a = FSMState('S_a', 'a') + sage: b = FSMState('S_b', 'b') + sage: c = FSMState('S_c', 'c') + sage: d = FSMState('S_d', 'd') + sage: t1 = FSMTransition(a, b) + sage: t2 = FSMTransition(b, c) + sage: t3 = FSMTransition(b, d) + sage: t4 = FSMTransition(c, d) + sage: FiniteStateMachine([t1, t2, t3, t4]) + Finite state machine with 4 states """ #************************************************************************* From ddca280e94f7f53180ceed35df5cda4e384fbb4b Mon Sep 17 00:00:00 2001 From: Daniel Krenn Date: Thu, 20 Feb 2014 21:56:02 +0200 Subject: [PATCH 123/163] function 'residue' added --- src/sage/symbolic/expression.pyx | 36 ++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index 8813e1b6373..c0d09893c25 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -3467,6 +3467,42 @@ cdef class Expression(CommutativeRingElement): sig_off() return new_Expression_from_GEx(self._parent, x) + def residue(self, x, a): + """ + Calculates the residue at `x=a`. + + INPUT: + + - ``x`` - a symbolic variable + + - ``a`` - a symbolic expression + + OUTPUT: + + The residue of ``self``. + + This function calculates the residue of ``self`` at `x=a`, + i.e., the coefficient of `1/(x-a)` of the series expansion of + ``self`` around `a`. + + EXAMPLES:: + + sage: (1/x).residue(x, 0) + 1 + sage: (1/x).residue(x, oo) + -1 + sage: (1/x^2).residue(x, 0) + 0 + sage: var('q, n, z') + (q, n, z) + sage: (-z^(-n-1)/(1-z/q)^2).residue(z, q).simplify_full() + (n + 1)/q^n + """ + if a == infinity: + return (-self.subs({x: 1/x}) / x**2).residue(x, 0) + s = self.parent().var('s') + return self.series(x == a, 1).subs({x: s + a}).coefficient(s, -1) + def taylor(self, *args): r""" Expands this symbolic expression in a truncated Taylor or From 6a8cac86ea51241ac89e0a46f9039200a7427684 Mon Sep 17 00:00:00 2001 From: Frederic Chapoton Date: Tue, 11 Jun 2013 19:05:00 +0000 Subject: [PATCH 124/163] trac 14720 pade approximation of formal power series --- src/sage/rings/power_series_poly.pyx | 67 ++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/src/sage/rings/power_series_poly.pyx b/src/sage/rings/power_series_poly.pyx index b2153b5fb24..f7aef6054f5 100644 --- a/src/sage/rings/power_series_poly.pyx +++ b/src/sage/rings/power_series_poly.pyx @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- """ Power Series Methods @@ -1090,6 +1091,72 @@ cdef class PowerSeries_poly(PowerSeries): g = g.add_bigoh(out_prec) return PowerSeries_poly(out_parent, g, out_prec, check=False) + def pade(self, m, n): + r""" + Returns the Padé approximant of ``self`` of index `(m, n)`. + + The Padé approximant of index `(m, n)` of a formal power + series `f` is the quotient `Q/P` of two polynomials `Q` and `P` + such that `deg(Q)\leq m`, `deg(P)\leq n` and + + .. MATH:: + + f(z) - Q(z)/P(z) = O(z^{m+n+1}). + + See :wikipedia:`Padé\_approximant` + + INPUT: + + - ``m``, ``n`` -- integers, describing the degrees of the polynomials + + OUTPUT: + + a ratio of two polynomials + + .. NOTE:: + + This is a first implementation and may be rather slow. + + ALGORITHM: + + This method uses the formula as a quotient of two determinants. + + EXAMPLES:: + + sage: z = PowerSeriesRing(QQ, 'z').gen() + sage: exp(z).pade(4, 0) + 1/24*z^4 + 1/6*z^3 + 1/2*z^2 + z + 1 + sage: exp(z).pade(1, 1) + (-z - 2)/(z - 2) + sage: exp(z).pade(3, 3) + (-z^3 - 12*z^2 - 60*z - 120)/(z^3 - 12*z^2 + 60*z - 120) + sage: log(1-z).pade(4, 4) + (25/6*z^4 - 130/3*z^3 + 105*z^2 - 70*z)/(z^4 - 20*z^3 + 90*z^2 - 140*z + 70) + sage: sqrt(1+z).pade(3, 2) + (1/6*z^3 + 3*z^2 + 8*z + 16/3)/(z^2 + 16/3*z + 16/3) + """ + from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing + from sage.matrix.constructor import Matrix + fps = self.parent() + anneau = PolynomialRing(fps.base_ring(), str(fps.gen())) + z = anneau.gen() + c = self.list() + mat = Matrix(anneau, n+1, n+1) + for i in range(1, n+1): + for j in range(n+1): + mat[i, j] = c[m + i - j] + for j in range(n+1): + mat[0, j] = z**j + resu_v = mat.determinant() + lead_v = resu_v.leading_coefficient() + resu_v = resu_v/lead_v + for j in range(n+1): + mat[0, j] = z**j*(self.truncate(max(m-j+1, 0))) + resu_u = mat.determinant() + lead_u = resu_u.leading_coefficient() + resu_u = resu_u/lead_u + return lead_u/lead_v * resu_u/resu_v + def make_powerseries_poly_v0(parent, f, prec, is_gen): """ From e47ca08e90a40bc6f1a1f5c71f1487cd0f9409c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 20 Dec 2013 11:03:34 +0100 Subject: [PATCH 125/163] trac #14720 minor changes --- src/sage/rings/power_series_poly.pyx | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/sage/rings/power_series_poly.pyx b/src/sage/rings/power_series_poly.pyx index f7aef6054f5..7ee2aa905e3 100644 --- a/src/sage/rings/power_series_poly.pyx +++ b/src/sage/rings/power_series_poly.pyx @@ -1131,31 +1131,32 @@ cdef class PowerSeries_poly(PowerSeries): sage: exp(z).pade(3, 3) (-z^3 - 12*z^2 - 60*z - 120)/(z^3 - 12*z^2 + 60*z - 120) sage: log(1-z).pade(4, 4) - (25/6*z^4 - 130/3*z^3 + 105*z^2 - 70*z)/(z^4 - 20*z^3 + 90*z^2 - 140*z + 70) + (25/6*z^4 - 130/3*z^3 + 105*z^2 - 70*z)/(z^4 - 20*z^3 + 90*z^2 + - 140*z + 70) sage: sqrt(1+z).pade(3, 2) (1/6*z^3 + 3*z^2 + 8*z + 16/3)/(z^2 + 16/3*z + 16/3) """ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.matrix.constructor import Matrix fps = self.parent() - anneau = PolynomialRing(fps.base_ring(), str(fps.gen())) - z = anneau.gen() + polyring = PolynomialRing(fps.base_ring(), str(fps.gen())) + z = polyring.gen() c = self.list() - mat = Matrix(anneau, n+1, n+1) - for i in range(1, n+1): - for j in range(n+1): + mat = Matrix(polyring, n + 1, n + 1) + for i in range(1, n + 1): + for j in range(n + 1): mat[i, j] = c[m + i - j] - for j in range(n+1): - mat[0, j] = z**j + for j in range(n + 1): + mat[0, j] = z ** j resu_v = mat.determinant() lead_v = resu_v.leading_coefficient() - resu_v = resu_v/lead_v - for j in range(n+1): - mat[0, j] = z**j*(self.truncate(max(m-j+1, 0))) + resu_v = resu_v / lead_v + for j in range(n + 1): + mat[0, j] = z ** j * (self.truncate(max(m - j + 1, 0))) resu_u = mat.determinant() lead_u = resu_u.leading_coefficient() - resu_u = resu_u/lead_u - return lead_u/lead_v * resu_u/resu_v + resu_u = resu_u / lead_u + return lead_u / lead_v * resu_u / resu_v def make_powerseries_poly_v0(parent, f, prec, is_gen): From 77fedfa5f0b6c2e2b04724d9852f2f7550966dae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 4 Feb 2014 21:01:32 +0100 Subject: [PATCH 126/163] trac #14720 enhancements, to be continued --- src/sage/rings/power_series_poly.pyx | 32 ++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/power_series_poly.pyx b/src/sage/rings/power_series_poly.pyx index 7ee2aa905e3..20e9c6aaa79 100644 --- a/src/sage/rings/power_series_poly.pyx +++ b/src/sage/rings/power_series_poly.pyx @@ -1103,6 +1103,8 @@ cdef class PowerSeries_poly(PowerSeries): f(z) - Q(z)/P(z) = O(z^{m+n+1}). + The formal power series `f` must be known up to order `n + m + 1`. + See :wikipedia:`Padé\_approximant` INPUT: @@ -1113,14 +1115,20 @@ cdef class PowerSeries_poly(PowerSeries): a ratio of two polynomials - .. NOTE:: + .. WARNING:: - This is a first implementation and may be rather slow. + The current implementation uses a very slow algorithm and is not + suitable for high orders. ALGORITHM: This method uses the formula as a quotient of two determinants. + .. SEEALSO:: + + :func:`sage.matrix.berlekamp_massey`, + :meth:`sage.rings.polynomial.polynomial_zmod_flint.Polynomial_zmod_flint.rational_reconstruct` + EXAMPLES:: sage: z = PowerSeriesRing(QQ, 'z').gen() @@ -1135,11 +1143,27 @@ cdef class PowerSeries_poly(PowerSeries): - 140*z + 70) sage: sqrt(1+z).pade(3, 2) (1/6*z^3 + 3*z^2 + 8*z + 16/3)/(z^2 + 16/3*z + 16/3) + + With real coefficients:: + + sage: R. = RR[[]] + sage: f = exp(2*z) + sage: f.pade(3,3) + ??? + + When precision is too low:: + + sage: f = z+O(z**6) + sage: f.pade(4,4) + Traceback (most recent call last): + ... + ValueError: the precision of the series is not large enough """ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.matrix.constructor import Matrix - fps = self.parent() - polyring = PolynomialRing(fps.base_ring(), str(fps.gen())) + if self.precision_absolute() < n + m + 2: + raise ValueError("the precision of the series is not large enough") + polyring = self.parent()._poly_ring() z = polyring.gen() c = self.list() mat = Matrix(polyring, n + 1, n + 1) From 06b3fc1ae37916b9a69842e7f148d252bad5069d Mon Sep 17 00:00:00 2001 From: Ralf Stephan Date: Fri, 21 Feb 2014 15:58:37 +0100 Subject: [PATCH 127/163] Trac #9505: reviewer's patch: fix doc --- src/sage/symbolic/expression.pyx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index ee874445147..6d787cc7dd1 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -4912,7 +4912,7 @@ cdef class Expression(CommutativeRingElement): sage: f.coefficient(x, 0) sqrt(x)*sin(y) + z^z - TESTS:: + TESTS: Check if :trac:`9505` is fixed:: @@ -4925,7 +4925,6 @@ cdef class Expression(CommutativeRingElement): Traceback (most recent call last): ... TypeError: n <> 1 only allowed for s being a variable - """ cdef Expression ss = self.coerce_in(s) if n <> 1 and not is_a_symbol(ss._gobj): From bd93f3a6a543bc6368960067b649ea5448c52206 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 21 Feb 2014 16:32:22 +0100 Subject: [PATCH 128/163] trac #14720 truncation added to handle the case of real coefficients --- src/sage/rings/power_series_poly.pyx | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/sage/rings/power_series_poly.pyx b/src/sage/rings/power_series_poly.pyx index 20e9c6aaa79..ee34285d4e2 100644 --- a/src/sage/rings/power_series_poly.pyx +++ b/src/sage/rings/power_series_poly.pyx @@ -1143,18 +1143,22 @@ cdef class PowerSeries_poly(PowerSeries): - 140*z + 70) sage: sqrt(1+z).pade(3, 2) (1/6*z^3 + 3*z^2 + 8*z + 16/3)/(z^2 + 16/3*z + 16/3) + sage: exp(2*z).pade(3, 3) + (-z^3 - 6*z^2 - 15*z - 15)/(z^3 - 6*z^2 + 15*z - 15) With real coefficients:: sage: R. = RR[[]] sage: f = exp(2*z) - sage: f.pade(3,3) - ??? + sage: f.pade(3, 3) + (-0.99999999999...*z^3 - 5.9999999999...*z^2 - 14.999999999...*z + - 14.999999999...)/(z^3 - 5.9999999999...*z^2 + 14.999999999...*z + - 14.999999999...) When precision is too low:: - sage: f = z+O(z**6) - sage: f.pade(4,4) + sage: f = z + O(z**6) + sage: f.pade(4, 4) Traceback (most recent call last): ... ValueError: the precision of the series is not large enough @@ -1172,12 +1176,12 @@ cdef class PowerSeries_poly(PowerSeries): mat[i, j] = c[m + i - j] for j in range(n + 1): mat[0, j] = z ** j - resu_v = mat.determinant() + resu_v = mat.determinant().truncate(n + 1) lead_v = resu_v.leading_coefficient() resu_v = resu_v / lead_v for j in range(n + 1): mat[0, j] = z ** j * (self.truncate(max(m - j + 1, 0))) - resu_u = mat.determinant() + resu_u = mat.determinant().truncate(m + 1) lead_u = resu_u.leading_coefficient() resu_u = resu_u / lead_u return lead_u / lead_v * resu_u / resu_v From d5f5d586fa2e897cc90b545d600fb85a4016aadc Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Fri, 21 Feb 2014 23:35:19 +0100 Subject: [PATCH 129/163] import Polynomial into globals --- src/sage/rings/polynomial/all.py | 2 +- src/sage/schemes/elliptic_curves/constructor.py | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sage/rings/polynomial/all.py b/src/sage/rings/polynomial/all.py index ebd1d56dc92..cf7d7f76a2a 100644 --- a/src/sage/rings/polynomial/all.py +++ b/src/sage/rings/polynomial/all.py @@ -24,7 +24,7 @@ # Univariate Polynomial Rings from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing, MPolynomialRing from sage.rings.polynomial.polynomial_ring import polygen, polygens, is_PolynomialRing -from sage.rings.polynomial.polynomial_element import is_Polynomial +from sage.rings.polynomial.polynomial_element import is_Polynomial, Polynomial # Multivariate Polynomial Rings from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing diff --git a/src/sage/schemes/elliptic_curves/constructor.py b/src/sage/schemes/elliptic_curves/constructor.py index 825ac712ec6..6aba291e078 100644 --- a/src/sage/schemes/elliptic_curves/constructor.py +++ b/src/sage/schemes/elliptic_curves/constructor.py @@ -952,9 +952,10 @@ def projective_point(p): sage: projective_point([F(4), F(8), F(2)]) [4, 8, 2] """ + from sage.rings.integer import GCD_list, LCM_list try: - p_gcd = rings.integer.GCD_list([x.numerator() for x in p]) - p_lcm = rings.integer.LCM_list([x.denominator() for x in p]) + p_gcd = GCD_list([x.numerator() for x in p]) + p_lcm = LCM_list([x.denominator() for x in p]) except AttributeError: return p scale = p_lcm / p_gcd From cd6dd4410085f2029ef0c22c400a3c379c1d6b7f Mon Sep 17 00:00:00 2001 From: Peter Bruin Date: Sat, 22 Feb 2014 14:54:33 +0000 Subject: [PATCH 130/163] Added _factor_univariate_polynomial() for QQbar and AA --- .../rings/polynomial/polynomial_element.pyx | 29 ------ src/sage/rings/qqbar.py | 88 +++++++++++++++++++ 2 files changed, 88 insertions(+), 29 deletions(-) diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index 5f1a80ccdbf..e0d01bc6f56 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -3073,12 +3073,6 @@ cdef class Polynomial(CommutativeAlgebraElement): sage: R. = QQbar[] sage: (x^8-1).factor() (x - 1) * (x - 0.7071067811865475? - 0.7071067811865475?*I) * (x - 0.7071067811865475? + 0.7071067811865475?*I) * (x - I) * (x + I) * (x + 0.7071067811865475? - 0.7071067811865475?*I) * (x + 0.7071067811865475? + 0.7071067811865475?*I) * (x + 1) - sage: (12*x^2-4).factor() - (12) * (x - 0.5773502691896258?) * (x + 0.5773502691896258?) - sage: R(-1).factor() - -1 - sage: EllipticCurve('11a1').change_ring(QQbar).division_polynomial(5).factor() - (5) * (x - 16) * (x - 5) * (x - 1.959674775249769?) * (x - 1.427050983124843? - 3.665468789467727?*I) * (x - 1.427050983124843? + 3.665468789467727?*I) * (x + 0.9549150281252629? - 0.8652998037182486?*I) * (x + 0.9549150281252629? + 0.8652998037182486?*I) * (x + 1.927050983124843? - 1.677599044300515?*I) * (x + 1.927050983124843? + 1.677599044300515?*I) * (x + 2.959674775249769?) * (x + 6.545084971874737? - 7.106423590645660?*I) * (x + 6.545084971874737? + 7.106423590645660?*I) Factoring polynomials over the algebraic reals (see :trac:`8544`):: @@ -3086,14 +3080,6 @@ cdef class Polynomial(CommutativeAlgebraElement): sage: R. = AA[] sage: (x^8+1).factor() (x^2 - 1.847759065022574?*x + 1.000000000000000?) * (x^2 - 0.7653668647301795?*x + 1.000000000000000?) * (x^2 + 0.7653668647301795?*x + 1.000000000000000?) * (x^2 + 1.847759065022574?*x + 1.000000000000000?) - sage: R(3).factor() - 3 - sage: (12*x^2-4).factor() - (12) * (x - 0.5773502691896258?) * (x + 0.5773502691896258?) - sage: (12*x^2+4).factor() - (12) * (x^2 + 0.3333333333333334?) - sage: EllipticCurve('11a1').change_ring(AA).division_polynomial(5).factor() - (5) * (x - 16.00000000000000?) * (x - 5.000000000000000?) * (x - 1.959674775249769?) * (x + 2.959674775249769?) * (x^2 - 2.854101966249685?*x + 15.47213595499958?) * (x^2 + 1.909830056250526?*x + 1.660606461254312?) * (x^2 + 3.854101966249685?*x + 6.527864045000421?) * (x^2 + 13.09016994374948?*x + 93.33939353874569?) TESTS: @@ -3350,21 +3336,6 @@ cdef class Polynomial(CommutativeAlgebraElement): f = pari(v).Polrev() G = list(f.factor()) - elif is_AlgebraicField(R): - Rx = self.parent() - return Factorization([(Rx([-r,1]),e) for r,e in self.roots()], - unit=self.leading_coefficient()) - - elif is_AlgebraicRealField(R): - from sage.rings.qqbar import QQbar - Rx = self.parent() - rr = self.roots() - cr = [(r,e) for r,e in self.roots(QQbar) if r.imag()>0] - return Factorization( - [(Rx([-r,1]),e) for r,e in rr] + - [(Rx([r.norm(),-2*r.real(),1]),e) for r,e in cr], - unit=self.leading_coefficient()) - elif is_NumberField(R): if R.degree() == 1: factors = self.change_ring(QQ).factor() diff --git a/src/sage/rings/qqbar.py b/src/sage/rings/qqbar.py index 972fc1c4980..75fd2b0d6af 100644 --- a/src/sage/rings/qqbar.py +++ b/src/sage/rings/qqbar.py @@ -959,6 +959,54 @@ def polynomial_root(self, poly, interval, multiplicity=1): return AlgebraicReal(ANRoot(poly, interval, multiplicity)) + def _factor_univariate_polynomial(self, f): + """ + Factor the univariate polynomial ``f``. + + INPUT: + + - ``f`` -- a univariate polynomial defined over the real algebraic field + + OUTPUT: + + - A factorization of ``f`` over the real algebraic numbers into a unit + and monic irreducible factors + + .. NOTE:: + + This is a helper method for + :meth:`sage.rings.polynomial.polynomial_element.Polynomial.factor`. + + TESTS:: + + sage: R. = AA[] + sage: AA._factor_univariate_polynomial(x) + x + sage: AA._factor_univariate_polynomial(2*x) + (2) * x + sage: AA._factor_univariate_polynomial((x^2 + 1)^2) + (x^2 + 1)^2 + sage: AA._factor_univariate_polynomial(x^8 + 1) + (x^2 - 1.847759065022574?*x + 1.000000000000000?) * (x^2 - 0.7653668647301795?*x + 1.000000000000000?) * (x^2 + 0.7653668647301795?*x + 1.000000000000000?) * (x^2 + 1.847759065022574?*x + 1.000000000000000?) + sage: AA._factor_univariate_polynomial(R(3)) + 3 + sage: AA._factor_univariate_polynomial(12*x^2 - 4) + (12) * (x - 0.5773502691896258?) * (x + 0.5773502691896258?) + sage: AA._factor_univariate_polynomial(12*x^2 + 4) + (12) * (x^2 + 0.3333333333333334?) + sage: AA._factor_univariate_polynomial(EllipticCurve('11a1').change_ring(AA).division_polynomial(5)) + (5) * (x - 16.00000000000000?) * (x - 5.000000000000000?) * (x - 1.959674775249769?) * (x + 2.959674775249769?) * (x^2 - 2.854101966249685?*x + 15.47213595499958?) * (x^2 + 1.909830056250526?*x + 1.660606461254312?) * (x^2 + 3.854101966249685?*x + 6.527864045000421?) * (x^2 + 13.09016994374948?*x + 93.33939353874569?) + + """ + rr = f.roots() + cr = [(r,e) for r,e in f.roots(QQbar) if r.imag()>0] + + from sage.structure.factorization import Factorization + return Factorization( + [(f.parent()([-r,1]),e) for r,e in rr] + + [(f.parent()([r.norm(),-2*r.real(),1]),e) for r,e in cr], + unit=f.leading_coefficient()) + def is_AlgebraicRealField(F): r""" Check whether ``F`` is an :class:`~AlgebraicRealField` instance. For internal use. @@ -1355,6 +1403,46 @@ def random_element(self, poly_degree=2, *args, **kwds): m = sage.misc.prandom.randint(0, len(roots)-1) return roots[m] + def _factor_univariate_polynomial(self, f): + """ + Factor the univariate polynomial ``f``. + + INPUT: + + - ``f`` -- a univariate polynomial defined over the algebraic field + + OUTPUT: + + - A factorization of ``f`` over the algebraic numbers into a unit and + monic irreducible factors + + .. NOTE:: + + This is a helper method for + :meth:`sage.rings.polynomial.polynomial_element.Polynomial.factor`. + + TESTS:: + + sage: R. = QQbar[] + sage: QQbar._factor_univariate_polynomial(x) + x + sage: QQbar._factor_univariate_polynomial(2*x) + (2) * x + sage: QQbar._factor_univariate_polynomial((x^2 + 1)^2) + (x - I)^2 * (x + I)^2 + sage: QQbar._factor_univariate_polynomial(x^8 - 1) + (x - 1) * (x - 0.7071067811865475? - 0.7071067811865475?*I) * (x - 0.7071067811865475? + 0.7071067811865475?*I) * (x - I) * (x + I) * (x + 0.7071067811865475? - 0.7071067811865475?*I) * (x + 0.7071067811865475? + 0.7071067811865475?*I) * (x + 1) + sage: QQbar._factor_univariate_polynomial(12*x^2 - 4) + (12) * (x - 0.5773502691896258?) * (x + 0.5773502691896258?) + sage: QQbar._factor_univariate_polynomial(R(-1)) + -1 + sage: QQbar._factor_univariate_polynomial(EllipticCurve('11a1').change_ring(QQbar).division_polynomial(5)) + (5) * (x - 16) * (x - 5) * (x - 1.959674775249769?) * (x - 1.427050983124843? - 3.665468789467727?*I) * (x - 1.427050983124843? + 3.665468789467727?*I) * (x + 0.9549150281252629? - 0.8652998037182486?*I) * (x + 0.9549150281252629? + 0.8652998037182486?*I) * (x + 1.927050983124843? - 1.677599044300515?*I) * (x + 1.927050983124843? + 1.677599044300515?*I) * (x + 2.959674775249769?) * (x + 6.545084971874737? - 7.106423590645660?*I) * (x + 6.545084971874737? + 7.106423590645660?*I) + + """ + from sage.structure.factorization import Factorization + return Factorization([(f.parent()([-r,1]),e) for r,e in f.roots()], unit=f.leading_coefficient()) + def is_AlgebraicField(F): r""" Check whether ``F`` is an :class:`~AlgebraicField` instance. From ce12073c2fc0c5bb031fa79d94d395be433b6a50 Mon Sep 17 00:00:00 2001 From: Peter Bruin Date: Sat, 22 Feb 2014 15:02:03 +0000 Subject: [PATCH 131/163] Added _factor_univariate_polynomial() for CDF and RDF --- src/sage/rings/complex_double.pyx | 47 ++++++++++++++ .../rings/polynomial/polynomial_element.pyx | 43 ------------- src/sage/rings/real_double.pyx | 64 +++++++++++++++++++ 3 files changed, 111 insertions(+), 43 deletions(-) diff --git a/src/sage/rings/complex_double.pyx b/src/sage/rings/complex_double.pyx index bc9018790e4..3ca3ca1811b 100644 --- a/src/sage/rings/complex_double.pyx +++ b/src/sage/rings/complex_double.pyx @@ -611,6 +611,53 @@ cdef class ComplexDoubleField_class(sage.rings.ring.Field): # x._set_multiplicative_order( n ) # not implemented for CDF return x + def _factor_univariate_polynomial(self, f): + """ + Factor the univariate polynomial ``f``. + + INPUT: + + - ``f`` -- a univariate polynomial defined over the double precision + complex numbers + + OUTPUT: + + - A factorization of ``f`` over the double precision complex numbers + into a unit and monic irreducible factors + + .. NOTE:: + + This is a helper method for + :meth:`sage.rings.polynomial.polynomial_element.Polynomial.factor`. + + TESTS:: + + sage: R. = CDF[] + sage: CDF._factor_univariate_polynomial(x) + x + sage: CDF._factor_univariate_polynomial(2*x) + (2.0) * x + sage: CDF._factor_univariate_polynomial(x^2) + x^2 + sage: f = x^2 + 1 + sage: F = CDF._factor_univariate_polynomial(f) + sage: [f(t[0][0]).abs() for t in F] # abs tol 1e-9 + [5.55111512313e-17, 6.66133814775e-16] + sage: f = (x^2 + 2*R(I))^3 + sage: F = f.factor() + sage: [f(t[0][0]).abs() for t in F] # abs tol 1e-9 + [1.979365054e-14, 1.97936298566e-14, 1.97936990747e-14, 3.6812407475e-14, 3.65211563729e-14, 3.65220890052e-14] + + """ + unit = f.leading_coefficient() + f *= ~unit + roots = f.roots() + from sage.misc.flatten import flatten + roots = flatten([[r]*m for r, m in roots]) + from sage.structure.factorization import Factorization + x = f.parent().gen() + return Factorization([(x - a, 1) for a in roots], unit) + cdef ComplexDoubleElement new_ComplexDoubleElement(): """ diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index e0d01bc6f56..8cbf2f2d2a2 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -3369,49 +3369,6 @@ cdef class Polynomial(CommutativeAlgebraElement): n = pari.set_real_precision(int(3.5*R.prec()) + 1) G = list(self._pari_with_name().factor()) - elif sage.rings.complex_double.is_ComplexDoubleField(R): - unit = self.leading_coefficient() - f = (~unit)*self - roots = f.roots(multiplicities=False) - assert len(roots) == self.degree() # all roots appear with multiplicity one - x = self.parent().gen() - v = [(x - a, 1) for a in roots] - return Factorization(v, unit) - - elif sage.rings.real_double.is_RealDoubleField(R): - roots = self.roots(sage.rings.complex_double.CDF, multiplicities=False) - assert len(roots) == self.degree() # all roots appear with multiplicity one - G = [[],[]] - real_roots = [] - non_real_roots = [] - for r in roots: - if r.imag().is_zero(): - for i in xrange(len(real_roots)): - if real_roots[i][0] == r: - real_roots[i][1] += 1 - r = None - break - if r is not None: - real_roots.append([r,1]) - else: - for i in xrange(len(non_real_roots)): - if non_real_roots[i][0] == r or non_real_roots[i][0] == r.conj(): - non_real_roots[i][1] += 1 - r = None - break - if r is not None: - non_real_roots.append([r,1]) - x = self.parent().objgen()[1] - for r in real_roots: - G[0].append( x - r[0].real() ) - G[1].append( r[1] ) - for z in non_real_roots: - a = ( z[0] + z[0].conj() ).real() - b = ( z[0]*(z[0].conj()) ).real() - G[0].append( x**2 - a*x + b ) - assert z[1] % 2 == 0, "Bug in root finding code over RDF" - G[1].append( z[1] // 2 ) - elif sage.rings.complex_field.is_ComplexField(R): # This is a hack to make the polynomial have complex coefficients, since # otherwise PARI will factor over RR. diff --git a/src/sage/rings/real_double.pyx b/src/sage/rings/real_double.pyx index f5fbb42507d..55dcb4fddf5 100644 --- a/src/sage/rings/real_double.pyx +++ b/src/sage/rings/real_double.pyx @@ -546,6 +546,70 @@ cdef class RealDoubleField_class(Field): nan = NaN + def _factor_univariate_polynomial(self, f): + """ + Factor the univariate polynomial ``f``. + + INPUT: + + - ``f`` -- a univariate polynomial defined over the double precision + real numbers + + OUTPUT: + + - A factorization of ``f`` over the double precision real numbers + into a unit and monic irreducible factors + + .. NOTE:: + + This is a helper method for + :meth:`sage.rings.polynomial.polynomial_element.Polynomial.factor`. + + TESTS:: + + sage: R. = RDF[] + sage: RDF._factor_univariate_polynomial(x) + x + sage: RDF._factor_univariate_polynomial(2*x) + (2.0) * x + sage: RDF._factor_univariate_polynomial(x^2) + x^2 + sage: RDF._factor_univariate_polynomial(x^2 + 1) + x^2 + 1.0 + sage: RDF._factor_univariate_polynomial(x^2 - 1) + (x - 1.0) * (x + 1.0) + + The implementation relies on the ``roots()`` method which often reports + roots not to be real even though they are:: + + sage: f = (x-1)^3 + sage: f.roots() # random output (unfortunately) + [1.00000859959, 0.999995700205 + 7.44736245561e-06*I, 0.999995700205 - 7.44736245561e-06*I] + + This leads to the following incorrect factorization:: + + sage: f.factor() # random output (unfortunately) + (1.0*x - 1.00000859959) * (1.0*x^2 - 1.99999140041*x + 0.999991400484) + + """ + roots = f.roots(sage.rings.complex_double.CDF) + + # collect real roots and conjugate pairs of non-real roots + real_roots = [(r, e) for r, e in roots if r.imag().is_zero()] + non_real_roots = {r: e for r, e in roots if not r.imag().is_zero()} + assert all([non_real_roots[r.conj()] == e for r, e in non_real_roots.items()]), "Bug in root finding code over RDF - roots must always come in conjugate pairs" + non_real_roots = [(r, e) for r, e in non_real_roots.items() if r.imag() > 0] + + # turn the roots into irreducible factors + x = f.parent().gen() + real_factors = [(x - r.real(), e) for r, e in real_roots] + non_real_factors = [(x**2 - (r + r.conj()).real()*x + (r*r.conj()).real(), e) for r, e in non_real_roots] + + # make the factors monic + from sage.structure.factorization import Factorization + return Factorization([(g.monic(), e) for g, e in real_factors + non_real_factors], f.leading_coefficient()) + + cdef class RealDoubleElement(FieldElement): """ An approximation to a real number using double precision floating From 9a3765b9842c6f01aa9b687242eba62e3ce58cb0 Mon Sep 17 00:00:00 2001 From: Marc Mezzarobba Date: Sat, 22 Feb 2014 17:54:47 +0100 Subject: [PATCH 132/163] pade(): minor docstring changes * Formatting * Broken link * Make one test more robust against numerical noise --- src/sage/rings/power_series_poly.pyx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/sage/rings/power_series_poly.pyx b/src/sage/rings/power_series_poly.pyx index ee34285d4e2..fd1a42e45f6 100644 --- a/src/sage/rings/power_series_poly.pyx +++ b/src/sage/rings/power_series_poly.pyx @@ -1097,7 +1097,7 @@ cdef class PowerSeries_poly(PowerSeries): The Padé approximant of index `(m, n)` of a formal power series `f` is the quotient `Q/P` of two polynomials `Q` and `P` - such that `deg(Q)\leq m`, `deg(P)\leq n` and + such that `\deg(Q)\leq m`, `\deg(P)\leq n` and .. MATH:: @@ -1126,8 +1126,8 @@ cdef class PowerSeries_poly(PowerSeries): .. SEEALSO:: - :func:`sage.matrix.berlekamp_massey`, - :meth:`sage.rings.polynomial.polynomial_zmod_flint.Polynomial_zmod_flint.rational_reconstruct` + * :mod:`sage.matrix.berlekamp_massey`, + * :meth:`sage.rings.polynomial.polynomial_zmod_flint.Polynomial_zmod_flint.rational_reconstruct` EXAMPLES:: @@ -1146,14 +1146,14 @@ cdef class PowerSeries_poly(PowerSeries): sage: exp(2*z).pade(3, 3) (-z^3 - 6*z^2 - 15*z - 15)/(z^3 - 6*z^2 + 15*z - 15) + TESTS: + With real coefficients:: sage: R. = RR[[]] sage: f = exp(2*z) - sage: f.pade(3, 3) - (-0.99999999999...*z^3 - 5.9999999999...*z^2 - 14.999999999...*z - - 14.999999999...)/(z^3 - 5.9999999999...*z^2 + 14.999999999...*z - - 14.999999999...) + sage: f.pade(3, 3) # abs tol 1e-10 + (-1.0*z^3 - 6.0*z^2 - 15.0*z - 15.0)/(z^3 - 6.0*z^2 + 15.0*z - 15.0) When precision is too low:: From ae62ecaa973952ef96268e697d6525ba5512d307 Mon Sep 17 00:00:00 2001 From: Marc Mezzarobba Date: Sat, 22 Feb 2014 18:58:11 +0100 Subject: [PATCH 133/163] Various improvements to expr.residue() * Avoid hardcoding a variable name (the previous version could give incorrect results when applied to an expression containing 's') * Lower series expansion order * Add some tests --- src/sage/symbolic/expression.pyx | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index c0d09893c25..5dcf2503db7 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -3469,7 +3469,7 @@ cdef class Expression(CommutativeRingElement): def residue(self, x, a): """ - Calculates the residue at `x=a`. + Calculates the residue of ``self`` at `x=a`. INPUT: @@ -3493,15 +3493,25 @@ cdef class Expression(CommutativeRingElement): -1 sage: (1/x^2).residue(x, 0) 0 + sage: (1/sin(x)).residue(x, 0) + 1 sage: var('q, n, z') (q, n, z) sage: (-z^(-n-1)/(1-z/q)^2).residue(z, q).simplify_full() (n + 1)/q^n + sage: var('s') + s + sage: zeta(s).residue(s, 1) # not tested - #15846 + 1 + + TESTS:: + + sage: (exp(x)/sin(x)^4).residue(x,0) + 5/6 """ if a == infinity: return (-self.subs({x: 1/x}) / x**2).residue(x, 0) - s = self.parent().var('s') - return self.series(x == a, 1).subs({x: s + a}).coefficient(s, -1) + return self.subs({x: x+a}).series(x == 0, 0).coefficient(x, -1) def taylor(self, *args): r""" From 03b583e67560a7d2491d75d1bb1a5178c393b5ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 22 Feb 2014 21:59:36 +0100 Subject: [PATCH 134/163] trac #15307 typo in file --- src/doc/en/faq/faq-usage.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/en/faq/faq-usage.rst b/src/doc/en/faq/faq-usage.rst index 74d83bd49a9..006ccc13ffb 100644 --- a/src/doc/en/faq/faq-usage.rst +++ b/src/doc/en/faq/faq-usage.rst @@ -125,7 +125,7 @@ You can load a Python script in a Sage session with the command **load**. For ex load("simple.py") -and repeat this command every time that we change the fiel simple.py. However, if we type:: +and repeat this command every time that we change the file simple.py. However, if we type:: attach("simple.py") From 9ab4bd04dfac93d95c7b169be62a3054f2eef850 Mon Sep 17 00:00:00 2001 From: Marc Mezzarobba Date: Sat, 22 Feb 2014 22:09:01 +0100 Subject: [PATCH 135/163] #13981 reviewer patch * fix a typo * use compile-time constants for slightly faster table access --- src/sage/rings/integer.pyx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index 300b372bef6..11717974750 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -5967,7 +5967,7 @@ cdef class int_to_Z(Morphism): sage: type(1 + 2r) - This is intented for internal use by the coersion system, + This is intented for internal use by the coercion system, to facilitate fast expressions mixing ints and more complex Python types. Note that (as with all morphisms) the input is forcably coerced to the domain ``int`` if it is not @@ -6340,8 +6340,8 @@ cdef Integer one = the_integer_ring._one_element # pool of small integer for fast sign computation # Use the same defaults as Python, documented at http://docs.python.org/2/c-api/int.html#PyInt_FromLong -cdef long small_pool_min = -5 -cdef long small_pool_max = 256 +DEF small_pool_min = -5 +DEF small_pool_max = 256 # we could use the above zero and one here cdef list small_pool = [Integer(k) for k in range(small_pool_min, small_pool_max+1)] From 7e86783229f55e02a208c767747219d73261cdb0 Mon Sep 17 00:00:00 2001 From: Punarbasu Purkayastha Date: Sun, 23 Feb 2014 15:35:47 +0800 Subject: [PATCH 136/163] fix broken documentation build. --- src/sage/rings/number_field/totallyreal_rel.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/number_field/totallyreal_rel.py b/src/sage/rings/number_field/totallyreal_rel.py index 805fe28abd6..da090b1bc0e 100644 --- a/src/sage/rings/number_field/totallyreal_rel.py +++ b/src/sage/rings/number_field/totallyreal_rel.py @@ -678,10 +678,9 @@ def enumerate_totallyreal_fields_rel(F, m, B, a = [], verbose=0, OUTPUT: - - the list of fields with entries ``[d,fabs,f]``, where - ``d`` is the discriminant, ``fabs`` is an absolute defining polynomial, - and ``f`` is a defining polynomial relative to ``F``, - sorted by discriminant. + - the list of fields with entries ``[d,fabs,f]``, where ``d`` is the + discriminant, ``fabs`` is an absolute defining polynomial, and ``f`` + is a defining polynomial relative to ``F``, sorted by discriminant. - if ``return_seqs`` is ``True``, then the first field of the list is a list containing the count of four items as explained below From 2ed965da5a0259b408bc5857b0ffad11c6e6165c Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Sun, 23 Feb 2014 16:19:42 +0000 Subject: [PATCH 137/163] added a check for NULL and a doctest. This is to avoid SEGFAULT due to Coin returning NULL in getColSolution() if solve() was not called. --- src/sage/numerical/backends/coin_backend.pyx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/sage/numerical/backends/coin_backend.pyx b/src/sage/numerical/backends/coin_backend.pyx index 4083c795454..d90a114f693 100644 --- a/src/sage/numerical/backends/coin_backend.pyx +++ b/src/sage/numerical/backends/coin_backend.pyx @@ -822,11 +822,21 @@ cdef class CoinBackend(GenericBackend): 0.0 sage: p.get_variable_value(1) # optional - Coin 1.5 + sage: p = MixedIntegerLinearProgram("Coin") # optional - Coin + sage: x = p.new_variable(dim=1) # optional - Coin + sage: p.set_min(x[0], 0.0) # optional - Coin + sage: p.get_values(x) # optional - Coin + {0: 0.0} """ cdef double * solution + cdef double v solution = self.model.solver().getColSolution() - return solution[variable] + if solution == NULL: + v = 0.0 + return v + else: + return solution[variable] cpdef int ncols(self): r""" From 769af0ef523f8bf31b1ae7d39c98f613603828d6 Mon Sep 17 00:00:00 2001 From: Erik Quaeghebeur Date: Sun, 23 Feb 2014 21:24:25 +0100 Subject: [PATCH 138/163] fix forgotten space --- src/sage/numerical/mip.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/numerical/mip.pyx b/src/sage/numerical/mip.pyx index 55075c1c990..89c42137ac5 100644 --- a/src/sage/numerical/mip.pyx +++ b/src/sage/numerical/mip.pyx @@ -202,7 +202,7 @@ cdef class MixedIntegerLinearProgram(SageObject): - Gurobi (``solver="Gurobi"``). See the `Gurobi `_ web site. - - PPL (``solver="PPL"``). See the `PPL`_ + - PPL (``solver="PPL"``). See the `PPL `_ web site. - If ``solver=None`` (default), the default solver is used (see From 511b9ff92b50bb84b9673556ccc6aa879bfa9e93 Mon Sep 17 00:00:00 2001 From: Daniel Krenn Date: Mon, 24 Feb 2014 11:06:51 +0200 Subject: [PATCH 139/163] changed to support x==a syntax for consistency with .series() --- src/sage/symbolic/expression.pyx | 39 +++++++++++++++++++------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index 5dcf2503db7..38053c4960d 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -3467,50 +3467,57 @@ cdef class Expression(CommutativeRingElement): sig_off() return new_Expression_from_GEx(self._parent, x) - def residue(self, x, a): + def residue(self, symbol): """ - Calculates the residue of ``self`` at `x=a`. + Calculates the residue of ``self`` with respect to ``symbol``. INPUT: - - ``x`` - a symbolic variable - - - ``a`` - a symbolic expression + - ``symbol`` - a symbolic variable or symbolic equality such + as ``x == 5``. If an equality is given, the expansion is + around the value on the right hand side of the equality, + otherwise at ``0``. OUTPUT: The residue of ``self``. - This function calculates the residue of ``self`` at `x=a`, - i.e., the coefficient of `1/(x-a)` of the series expansion of - ``self`` around `a`. + Say, ``symbol`` is ``x == a``, then this function calculates + the residue of ``self`` at `x=a`, i.e., the coefficient of + `1/(x-a)` of the series expansion of ``self`` around `a`. EXAMPLES:: - sage: (1/x).residue(x, 0) + sage: (1/x).residue(x == 0) 1 - sage: (1/x).residue(x, oo) + sage: (1/x).residue(x == oo) -1 - sage: (1/x^2).residue(x, 0) + sage: (1/x^2).residue(x == 0) 0 - sage: (1/sin(x)).residue(x, 0) + sage: (1/sin(x)).residue(x == 0) 1 sage: var('q, n, z') (q, n, z) - sage: (-z^(-n-1)/(1-z/q)^2).residue(z, q).simplify_full() + sage: (-z^(-n-1)/(1-z/q)^2).residue(z == q).simplify_full() (n + 1)/q^n sage: var('s') s - sage: zeta(s).residue(s, 1) # not tested - #15846 + sage: zeta(s).residue(s == 1) # not tested - #15846 1 TESTS:: - sage: (exp(x)/sin(x)^4).residue(x,0) + sage: (exp(x)/sin(x)^4).residue(x == 0) 5/6 """ + if symbol.is_relational(): + x = symbol.lhs() + a = symbol.rhs() + else: + x = symbol + a = 0 if a == infinity: - return (-self.subs({x: 1/x}) / x**2).residue(x, 0) + return (-self.subs({x: 1/x}) / x**2).residue(x == 0) return self.subs({x: x+a}).series(x == 0, 0).coefficient(x, -1) def taylor(self, *args): From 413ab852e0a7fb6fde21415886de404e10c331f9 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Mon, 24 Feb 2014 12:02:46 +0100 Subject: [PATCH 140/163] Make sure PolyBoRi hashes return Py_ssize_t --- src/sage/rings/polynomial/pbori.pyx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sage/rings/polynomial/pbori.pyx b/src/sage/rings/polynomial/pbori.pyx index ed29494e3cd..8ef2febe8ca 100644 --- a/src/sage/rings/polynomial/pbori.pyx +++ b/src/sage/rings/polynomial/pbori.pyx @@ -2358,7 +2358,7 @@ cdef class BooleanMonomial(MonoidElement): sage: {m:1} #indirect doctest {x*y: 1} """ - return self._pbmonom.stableHash() + return (self._pbmonom.stableHash()) def stable_hash(self): """ @@ -2377,7 +2377,7 @@ cdef class BooleanMonomial(MonoidElement): This function is part of the upstream PolyBoRi interface. In Sage all hashes are stable. """ - return self._pbmonom.stableHash() + return (self._pbmonom.stableHash()) def ring(self): """ @@ -3954,7 +3954,7 @@ cdef class BooleanPolynomial(MPolynomial): sage: {x:1} # indirect doctest {x: 1} """ - return self._pbpoly.stableHash() + return (self._pbpoly.stableHash()) def __len__(self): r""" @@ -4664,7 +4664,7 @@ cdef class BooleanPolynomial(MPolynomial): This function is part of the upstream PolyBoRi interface. In Sage all hashes are stable. """ - return self._pbpoly.stableHash() + return (self._pbpoly.stableHash()) def ring(self): """ @@ -5677,7 +5677,7 @@ cdef class BooleSet: sage: {s:1} {{{x1,x2}, {x2,x3}}: 1} """ - return self._pbset.stableHash() + return (self._pbset.stableHash()) def __mod__(self, BooleSet vs): """ @@ -5748,7 +5748,7 @@ cdef class BooleSet: This function is part of the upstream PolyBoRi interface. In Sage all hashes are stable. """ - return self._pbset.stableHash() + return (self._pbset.stableHash()) def divide(self, BooleanMonomial rhs): """ From a7fbaca952aad9c17a5df07475a1d1121ab55848 Mon Sep 17 00:00:00 2001 From: Julian Rueth Date: Tue, 25 Feb 2014 01:08:17 +0100 Subject: [PATCH 141/163] replaced all occurences of GPLv2 with GPLv2+ --- src/sage/combinat/words/abstract_word.py | 8 ++++---- src/sage/combinat/words/alphabet.py | 8 ++++---- src/sage/combinat/words/finite_word.py | 8 ++++---- src/sage/combinat/words/infinite_word.py | 8 ++++---- src/sage/combinat/words/morphism.py | 8 ++++---- src/sage/combinat/words/notes/word_inheritance_howto.txt | 8 ++++---- src/sage/combinat/words/paths.py | 8 ++++---- src/sage/combinat/words/suffix_trees.py | 8 ++++---- src/sage/combinat/words/word.py | 8 ++++---- src/sage/combinat/words/word_datatypes.pyx | 9 ++++----- src/sage/combinat/words/word_generators.py | 8 ++++---- src/sage/combinat/words/word_infinite_datatypes.py | 9 ++++----- src/sage/combinat/words/word_options.py | 9 ++++----- src/sage/combinat/words/words.py | 8 ++++---- src/sage/plot/plot3d/transform.pyx | 8 ++++---- 15 files changed, 60 insertions(+), 63 deletions(-) diff --git a/src/sage/combinat/words/abstract_word.py b/src/sage/combinat/words/abstract_word.py index 5880d51ac85..df07108b821 100644 --- a/src/sage/combinat/words/abstract_word.py +++ b/src/sage/combinat/words/abstract_word.py @@ -24,10 +24,10 @@ # Copyright (C) 2008-2010 Sebastien Labbe , # 2008-2010 Franco Saliola # -# Distributed under the terms of the GNU General Public License version 2 (GPLv2) -# -# The full text of the GPLv2 is available at: -# +# 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. # http://www.gnu.org/licenses/ #***************************************************************************** from sage.structure.sage_object import SageObject diff --git a/src/sage/combinat/words/alphabet.py b/src/sage/combinat/words/alphabet.py index da5576b5442..ac6fc9fd96a 100644 --- a/src/sage/combinat/words/alphabet.py +++ b/src/sage/combinat/words/alphabet.py @@ -25,10 +25,10 @@ #***************************************************************************** # Copyright (C) 2008 Franco Saliola # -# Distributed under the terms of the GNU General Public License version 2 (GPLv2) -# -# The full text of the GPLv2 is available at: -# +# 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. # http://www.gnu.org/licenses/ #***************************************************************************** from sage.categories.sets_cat import Sets diff --git a/src/sage/combinat/words/finite_word.py b/src/sage/combinat/words/finite_word.py index 7a6b2fb1763..99e0bb0fd96 100644 --- a/src/sage/combinat/words/finite_word.py +++ b/src/sage/combinat/words/finite_word.py @@ -185,10 +185,10 @@ # 2008-2012 Sébastien Labbé , # 2008-2010 Franco Saliola # -# Distributed under the terms of the GNU General Public License version 2 (GPLv2) -# -# The full text of the GPLv2 is available at: -# +# 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. # http://www.gnu.org/licenses/ #***************************************************************************** from itertools import islice, izip, cycle diff --git a/src/sage/combinat/words/infinite_word.py b/src/sage/combinat/words/infinite_word.py index 2720060a859..4072dd6a63d 100644 --- a/src/sage/combinat/words/infinite_word.py +++ b/src/sage/combinat/words/infinite_word.py @@ -67,10 +67,10 @@ # Copyright (C) 2008 Sebastien Labbe , # Franco Saliola # -# Distributed under the terms of the GNU General Public License version 2 (GPLv2) -# -# The full text of the GPLv2 is available at: -# +# 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. # http://www.gnu.org/licenses/ #***************************************************************************** from sage.combinat.words.abstract_word import Word_class diff --git a/src/sage/combinat/words/morphism.py b/src/sage/combinat/words/morphism.py index 32c71934e0a..ee1db97e366 100644 --- a/src/sage/combinat/words/morphism.py +++ b/src/sage/combinat/words/morphism.py @@ -78,10 +78,10 @@ #***************************************************************************** # Copyright (C) 2008 Sebastien Labbe # -# Distributed under the terms of the GNU General Public License version 2 (GPLv2) -# -# The full text of the GPLv2 is available at: -# +# 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. # http://www.gnu.org/licenses/ #***************************************************************************** import itertools diff --git a/src/sage/combinat/words/notes/word_inheritance_howto.txt b/src/sage/combinat/words/notes/word_inheritance_howto.txt index 56c62c1a82f..77888a55aac 100644 --- a/src/sage/combinat/words/notes/word_inheritance_howto.txt +++ b/src/sage/combinat/words/notes/word_inheritance_howto.txt @@ -2,10 +2,10 @@ #***************************************************************************** # Copyright (C) 2009 Franco Saliola # -# Distributed under the terms of the GNU General Public License version 2 (GPLv2) -# -# The full text of the GPLv2 is available at: -# +# 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. # http://www.gnu.org/licenses/ #***************************************************************************** diff --git a/src/sage/combinat/words/paths.py b/src/sage/combinat/words/paths.py index d263b6b94b0..68c258f85ff 100644 --- a/src/sage/combinat/words/paths.py +++ b/src/sage/combinat/words/paths.py @@ -167,10 +167,10 @@ # Copyright (C) 2008 Arnaud bergeron , # Copyrigth (C) 2009 Sebastien Labbe , # -# Distributed under the terms of the GNU General Public License version 2 (GPLv2) -# -# The full text of the GPLv2 is available at: -# +# 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. # http://www.gnu.org/licenses/ #***************************************************************************** diff --git a/src/sage/combinat/words/suffix_trees.py b/src/sage/combinat/words/suffix_trees.py index f9c81166822..bdbfa47a969 100644 --- a/src/sage/combinat/words/suffix_trees.py +++ b/src/sage/combinat/words/suffix_trees.py @@ -4,10 +4,10 @@ #***************************************************************************** # Copyright (C) 2008 Franco Saliola # -# Distributed under the terms of the GNU General Public License version 2 (GPLv2) -# -# The full text of the GPLv2 is available at: -# +# 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. # http://www.gnu.org/licenses/ #***************************************************************************** from sage.structure.sage_object import SageObject diff --git a/src/sage/combinat/words/word.py b/src/sage/combinat/words/word.py index f233c0cc37c..598d9a5d84f 100644 --- a/src/sage/combinat/words/word.py +++ b/src/sage/combinat/words/word.py @@ -16,10 +16,10 @@ # Sébastien Labbé , # Franco Saliola # -# Distributed under the terms of the GNU General Public License version 2 (GPLv2) -# -# The full text of the GPLv2 is available at: -# +# 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. # http://www.gnu.org/licenses/ #***************************************************************************** from sage.combinat.words.abstract_word import Word_class diff --git a/src/sage/combinat/words/word_datatypes.pyx b/src/sage/combinat/words/word_datatypes.pyx index a96b1a18c92..30668e0d1e7 100644 --- a/src/sage/combinat/words/word_datatypes.pyx +++ b/src/sage/combinat/words/word_datatypes.pyx @@ -5,11 +5,10 @@ Datatypes for finite words # Copyright (C) 2009 Franco Saliola # Vincent Delecroix <20100.delecroix@gmail.com> # -# Distributed under the terms of the GNU General Public License version 2 -# (GPLv2) -# -# The full text of the GPLv2 is available at: -# +# 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. # http://www.gnu.org/licenses/ #***************************************************************************** diff --git a/src/sage/combinat/words/word_generators.py b/src/sage/combinat/words/word_generators.py index 479ec421e7d..dbfeaab7882 100644 --- a/src/sage/combinat/words/word_generators.py +++ b/src/sage/combinat/words/word_generators.py @@ -47,10 +47,10 @@ # Arnaud Bergeron , # Amy Glen # -# Distributed under the terms of the GNU General Public License version 2 (GPLv2) -# -# The full text of the GPLv2 is available at: -# +# 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. # http://www.gnu.org/licenses/ #***************************************************************************** from itertools import cycle, count diff --git a/src/sage/combinat/words/word_infinite_datatypes.py b/src/sage/combinat/words/word_infinite_datatypes.py index 2de3140babb..d82b2c1dd1d 100644 --- a/src/sage/combinat/words/word_infinite_datatypes.py +++ b/src/sage/combinat/words/word_infinite_datatypes.py @@ -5,11 +5,10 @@ # Copyright (C) 2009 Franco Saliola # Vincent Delecroix <20100.delecroix@gmail.com> # -# Distributed under the terms of the GNU General Public License version 2 -# (GPLv2) -# -# The full text of the GPLv2 is available at: -# +# 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. # http://www.gnu.org/licenses/ #***************************************************************************** from sage.combinat.words.word_datatypes import WordDatatype diff --git a/src/sage/combinat/words/word_options.py b/src/sage/combinat/words/word_options.py index e1212b01564..d5c0c373480 100644 --- a/src/sage/combinat/words/word_options.py +++ b/src/sage/combinat/words/word_options.py @@ -4,11 +4,10 @@ #***************************************************************************** # Copyright (C) 2009 Franco Saliola # -# Distributed under the terms of the GNU General Public License version 2 -# (GPLv2) -# -# The full text of the GPLv2 is available at: -# +# 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. # http://www.gnu.org/licenses/ #***************************************************************************** import copy diff --git a/src/sage/combinat/words/words.py b/src/sage/combinat/words/words.py index 82aa7d87766..e9d5e94461a 100644 --- a/src/sage/combinat/words/words.py +++ b/src/sage/combinat/words/words.py @@ -28,10 +28,10 @@ # Sébastien Labbé , # Franco Saliola # -# Distributed under the terms of the GNU General Public License version 2 (GPLv2) -# -# The full text of the GPLv2 is available at: -# +# 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. # http://www.gnu.org/licenses/ #***************************************************************************** from sage.combinat.combinat import InfiniteAbstractCombinatorialClass diff --git a/src/sage/plot/plot3d/transform.pyx b/src/sage/plot/plot3d/transform.pyx index 4270f6dd77d..0d2f02d8dff 100644 --- a/src/sage/plot/plot3d/transform.pyx +++ b/src/sage/plot/plot3d/transform.pyx @@ -1,10 +1,10 @@ #***************************************************************************** # Copyright (C) 2007 Robert Bradshaw # -# Distributed under the terms of the GNU General Public License version 2 (GPLv2) -# -# The full text of the GPLv2 is available at: -# +# 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. # http://www.gnu.org/licenses/ #***************************************************************************** cdef extern from *: From 55270d775d1ffce5a7e1c9e798c415af4c3e95df Mon Sep 17 00:00:00 2001 From: Anne Schilling Date: Sun, 19 Jan 2014 23:07:00 -0800 Subject: [PATCH 142/163] First implementation of weak crystals --- src/sage/combinat/crystals/weak_crystal.py | 255 +++++++++++++++++++++ src/sage/combinat/k_tableau.py | 27 ++- 2 files changed, 275 insertions(+), 7 deletions(-) create mode 100644 src/sage/combinat/crystals/weak_crystal.py diff --git a/src/sage/combinat/crystals/weak_crystal.py b/src/sage/combinat/crystals/weak_crystal.py new file mode 100644 index 00000000000..625dce2713c --- /dev/null +++ b/src/sage/combinat/crystals/weak_crystal.py @@ -0,0 +1,255 @@ +r""" +Weak crystal +""" +#***************************************************************************** +# Copyright (C) 2014 Anne Schilling +# +# Distributed under the terms of the GNU General Public License (GPL) +# http://www.gnu.org/licenses/ +#****************************************************************************** + +from sage.structure.parent import Parent +from sage.structure.element_wrapper import ElementWrapper +from sage.structure.unique_representation import UniqueRepresentation +from sage.categories.classical_crystals import ClassicalCrystals +from sage.categories.enumerated_sets import EnumeratedSets +from sage.combinat.root_system.cartan_type import CartanType +from sage.combinat.integer_vector import IntegerVectors +from sage.combinat.k_tableau import WeakTableaux, WeakTableau + +class WeakCrystal(UniqueRepresentation, Parent): + r""" + This is an implementation of the weak crystal on affine factorizations + with a cut-point, as introduced by Morse and Schilling. + + EXAMPLES:: + + sage: from sage.combinat.crystals.weak_crystal import WeakCrystal + sage: W = WeakCrystal([[3,1,1],[1]],3,3) + sage: W.list() + [[1, s2, s3*s2*s1], + [1, s3*s2, s3*s1], + [1, s3*s2*s1, s3], + [s3, s2, s3*s1], + [s3, s2*s1, s3], + [s3*s2, s1, s3], + [s3*s2*s1, 1, s3], + [s3*s2*s1, s3, 1], + [s3*s2, 1, s3*s1], + [s3*s2, s3, s1], + [s3*s2, s3*s1, 1], + [s2, 1, s3*s2*s1], + [s2, s3, s2*s1], + [s2, s3*s2, s1], + [s2, s3*s2*s1, 1]] + + We can compute the highest weight elements:: + + sage: hw = [w for w in W if w.is_highest_weight()] + sage: hw + [[1, s2, s3*s2*s1]] + sage: hw[0].weight() + (3, 1, 0) + + And show that this crystal is isomorphic to the tableau model of the same weight:: + + sage: C = CrystalOfTableaux(['A',2],shape=[3,1]) + sage: GC = C.digraph() + sage: GW = W.digraph() + sage: GC.is_isomorphic(GW, edge_labels=True) + True + + The crystal operators themselves move elements between adjacent factors:: + + sage: b = hw[0];b + [1, s2, s3*s2*s1] + sage: b.f(1) + [1, s3*s2, s3*s1] + + TESTS:: + + sage: TestSuite(W).run(verbose = True) + running ._test_an_element() . . . pass + running ._test_category() . . . pass + running ._test_elements() . . . + Running the test suite of self.an_element() + running ._test_category() . . . pass + running ._test_eq() . . . pass + running ._test_not_implemented_methods() . . . pass + running ._test_pickling() . . . pass + running ._test_stembridge_local_axioms() . . . pass + pass + running ._test_elements_eq_reflexive() . . . pass + running ._test_elements_eq_symmetric() . . . pass + running ._test_elements_eq_transitive() . . . pass + running ._test_elements_neq() . . . pass + running ._test_enumerated_set_contains() . . . pass + running ._test_enumerated_set_iter_cardinality() . . . pass + running ._test_enumerated_set_iter_list() . . . pass + running ._test_eq() . . . pass + running ._test_fast_iter() . . . pass + running ._test_not_implemented_methods() . . . pass + running ._test_pickling() . . . pass + running ._test_some_elements() . . . pass + running ._test_stembridge_local_axioms() . . . pass + """ + @staticmethod + def __classcall_private__(cls, skew_shape, k, n, x = None): + """ + Classcall to mend the input. + + TESTS:: + + sage: from sage.combinat.crystals.weak_crystal import WeakCrystal + sage: WeakCrystal([[3,1],[1]],3,4) + Weak crystal on affine factorizations of type A4 of shape [[3, 1], [1]] + """ + skew_shape = tuple(tuple(l) for l in skew_shape) + return super(WeakCrystal, cls).__classcall__(cls, skew_shape, k, n, x) + + def __init__(self, skew_shape, k, n, x=None): + """ + EXAMPLES:: + + sage: from sage.combinat.crystals.weak_crystal import WeakCrystal + sage: W = WeakCrystal([[3,2],[2]],3,4,0) + sage: W.x + 0 + sage: W = WeakCrystal([[3,2],[2]],3,4) + sage: W.x + 1 + """ + Parent.__init__(self, category = ClassicalCrystals()) + self.n = n + self.k = k + self.skew_shape = skew_shape + cartan_type = CartanType(['A',n-1]) + self._cartan_type = cartan_type + generators = [ t.to_core_tableau().to_factorized_permutation_tableau() + for mu in IntegerVectors(sum(skew_shape[0])-sum(skew_shape[1]), n) + for t in WeakTableaux(k, skew_shape, mu, representation='bounded')] + self.module_generators = [self(t) for t in generators] + if x is None: + if generators != []: + x = min( set(range(k+1)).difference(set( + sum([i.reduced_word() for i in generators[0]],[])))) + else: + x = 0 + self.x = x + + def _repr_(self): + """ + EXAMPLES:: + + sage: from sage.combinat.crystals.weak_crystal import WeakCrystal + sage: WeakCrystal([[3,1],[1]],3,4) + Weak crystal on affine factorizations of type A4 of shape [[3, 1], [1]] + """ + return "Weak crystal on affine factorizations of type A%s of shape %s"%(self.n, [[i for i in w] for w in self.skew_shape]) + + # temporary workaround while an_element is overriden by Parent + _an_element_ = EnumeratedSets.ParentMethods._an_element_ + + class Element(ElementWrapper): + + def e(self, i): + r""" + Returns the action of `e_i` on ``self``. + + EXAMPLES:: + + sage: from sage.combinat.crystals.weak_crystal import WeakCrystal + sage: W = WeakCrystal(tuple([tuple([3,1]),tuple([1])]),3,4) + sage: t = W(W.module_generators[1]); t + [1, 1, s3, s2*s1] + sage: t.e(1) + [1, 1, 1, s3*s2*s1] + """ + assert i in self.index_set() + x = self.parent().x + k = self.parent().k + n = self.parent().n + b = self.bracketing(i) + if b[0] == []: + return None + a = min(b[0]) + left = [j for j in (self.value[n-i-1]).reduced_word() if j != (a+x)%(k+1)] + right = [(j-x)%(k+1) for j in (self.value[n-i]).reduced_word()] + m = max([j for j in range(a) if (j+x)%(k+1) not in left]) + right += [m+1] + right.sort(reverse=True) + right = [(j+x)%(k+1) for j in right] + t = [self.value[j].reduced_word() for j in range(n-i-1)] + [left] + [right] + [self.value[j].reduced_word() for j in range(n-i+1,n)] + t = WeakTableau([self.value[j].reduced_word() for j in range(n-i-1)] + + [left] + [right] + + [self.value[j].reduced_word() for j in range(n-i+1,n)], + self.parent().k, inner_shape = self.value._inner_shape, + representation='factorized_permutation') + return self.parent()(t) + + def f(self, i): + r""" + Returns the action of `f_i` on ``self``. + + EXAMPLES:: + + sage: from sage.combinat.crystals.weak_crystal import WeakCrystal + sage: W = WeakCrystal(tuple([tuple([3,1]),tuple([1])]),3,4) + sage: t = W(W.module_generators[1]); t + [1, 1, s3, s2*s1] + sage: t.f(2) + [1, s3, 1, s2*s1] + sage: t.f(1) + [1, 1, s3*s2, s1] + """ + assert i in self.index_set() + x = self.parent().x + k = self.parent().k + n = self.parent().n + b = self.bracketing(i) + if b[1] == []: + return None + a = max(b[1]) + right = [j for j in (self.value[n-i]).reduced_word() if j != (a+x)%(k+1)] + left = [(j-x)%(k+1) for j in (self.value[n-i-1]).reduced_word()] + m = min([j for j in range(a+1,k+2) if (j+x)%(k+1) not in right]) + left += [m-1] + left.sort(reverse=True) + left = [(j+x)%(k+1) for j in left] + t = [self.value[j].reduced_word() for j in range(n-i-1)] + [left] + [right] + [self.value[j].reduced_word() for j in range(n-i+1,n)] + t = WeakTableau([self.value[j].reduced_word() for j in range(n-i-1)] + + [left] + [right] + + [self.value[j].reduced_word() for j in range(n-i+1,n)], + self.parent().k, inner_shape = self.value._inner_shape, + representation='factorized_permutation') + return self.parent()(t) + + def bracketing(self, i): + r""" + Removes all bracketed letters between `i`-th and `i+1`-th entry. + + EXAMPLES:: + + sage: from sage.combinat.crystals.weak_crystal import WeakCrystal + sage: W = WeakCrystal(tuple([tuple([3,1]),tuple([1])]),3,4) + sage: t = W(W.module_generators[1]) + sage: t.bracketing(1) + [[3], [2, 1]] + """ + n = self.parent().n + x = self.parent().x + k = self.parent().k + right = (self.value[n-i]).reduced_word() + left = (self.value[n-i-1]).reduced_word() + right_n = [(j-x)%(k+1) for j in right] + left_n = [(j-x)%(k+1) for j in left] + left_unbracketed = [] + while left_n != []: + m = max(left_n) + left_n.remove(m) + l = [j for j in right_n if j>m] + if l != []: + right_n.remove(min(l)) + else: + left_unbracketed += [m] + return [[j for j in left_unbracketed],[j for j in right_n]] diff --git a/src/sage/combinat/k_tableau.py b/src/sage/combinat/k_tableau.py index aee089c604e..4c9d1b371cf 100644 --- a/src/sage/combinat/k_tableau.py +++ b/src/sage/combinat/k_tableau.py @@ -403,9 +403,13 @@ def intermediate_shapes(self): [[2], [2, 1], [3, 1, 1], [4, 1, 1], [5, 2, 1]] """ if self.parent()._representation in ['core', 'bounded']: - return intermediate_shapes(self) + shapes = [] + t = SkewTableau(list(self)) + for i in range(len(self.weight())+1): + shapes += [ t.restrict(i).outer_shape()] + return shapes else: - return intermediate_shapes(self.to_core_tableau()) + return self.to_core_tableau().intermediate_shapes() def pp(self): r""" @@ -798,7 +802,10 @@ def check(self): ValueError: The tableau is not semistandard! """ if not self.parent()._weight == WeakTableau_bounded.from_core_tableau(self._list,self.k).weight(): - raise ValueError("The weight of the parent does not agree with the weight of the tableau!") + w = WeakTableau_bounded.from_core_tableau(self._list,self.k).weight() + wp = self.parent()._weight + if not tuple([wp[i] for i in range(len(w))]) == w: + raise ValueError("The weight of the parent does not agree with the weight of the tableau!") t = SkewTableau(list(self)) if not t in SemistandardSkewTableaux(): raise ValueError("The tableau is not semistandard!") @@ -1525,7 +1532,10 @@ def check(self): if not t in SemistandardSkewTableaux(): raise ValueError("The tableaux is not semistandard!") if not self.parent()._weight == tuple(t.weight()): - raise ValueError("The weight of the parent does not agree with the weight of the tableau!") + w = tuple(t.weight()) + wp = self.parent()._weight + if not tuple([wp[i] for i in range(len(w))]) == w: + raise ValueError("The weight of the parent does not agree with the weight of the tableau!") outer = t.outer_shape() inner = t.inner_shape() if self.parent()._outer_shape != outer: @@ -1594,7 +1604,8 @@ def to_core_tableau(self): for j in range(len(l)): l_new += [l[j] + [i]*(p[j]-len(l[j]))] l = l_new - return WeakTableau_core(l, self.k) + return WeakTableaux_core(self.k, self.shape_core(), self.weight())(l) + #return WeakTableau_core(l, self.k) @classmethod def from_core_tableau(cls, t, k): @@ -2181,8 +2192,10 @@ def __iter__(self): sage: T.list() [[s0, s4, s3, s4*s2], [s0, s3, s4, s3*s2], [s3, s0, s4, s3*s2]] """ - for t in WeakTableaux_core(self.k, self.shape(), self._weight): - yield WeakTableau_factorized_permutation.from_core_tableau(t, self.k) + for t in WeakTableaux_bounded(self.k, [self._outer_shape.to_bounded_partition(),self._inner_shape.to_bounded_partition()], self._weight): + yield t.to_core_tableau().to_factorized_permutation_tableau() + #for t in WeakTableaux_core(self.k, self.shape(), self._weight): + # yield WeakTableau_factorized_permutation.from_core_tableau(t, self.k) Element = WeakTableau_factorized_permutation From 0671e71a9872578d974fee6d178613c9192183b4 Mon Sep 17 00:00:00 2001 From: Anne Schilling Date: Sun, 23 Feb 2014 16:40:17 -0800 Subject: [PATCH 143/163] renamed weak crystal to affine factorization crystal --- ...eak_crystal.py => affine_factorization.py} | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) rename src/sage/combinat/crystals/{weak_crystal.py => affine_factorization.py} (85%) diff --git a/src/sage/combinat/crystals/weak_crystal.py b/src/sage/combinat/crystals/affine_factorization.py similarity index 85% rename from src/sage/combinat/crystals/weak_crystal.py rename to src/sage/combinat/crystals/affine_factorization.py index 625dce2713c..4f7b8eccad5 100644 --- a/src/sage/combinat/crystals/weak_crystal.py +++ b/src/sage/combinat/crystals/affine_factorization.py @@ -1,5 +1,5 @@ r""" -Weak crystal +Type A crystal on affine factorizations """ #***************************************************************************** # Copyright (C) 2014 Anne Schilling @@ -17,15 +17,15 @@ from sage.combinat.integer_vector import IntegerVectors from sage.combinat.k_tableau import WeakTableaux, WeakTableau -class WeakCrystal(UniqueRepresentation, Parent): +class AffineFactorizationCrystal(UniqueRepresentation, Parent): r""" This is an implementation of the weak crystal on affine factorizations with a cut-point, as introduced by Morse and Schilling. EXAMPLES:: - sage: from sage.combinat.crystals.weak_crystal import WeakCrystal - sage: W = WeakCrystal([[3,1,1],[1]],3,3) + sage: from sage.combinat.crystals.affine_factorization import AffineFactorizationCrystal + sage: W = AffineFactorizationCrystal([[3,1,1],[1]],3,3) sage: W.list() [[1, s2, s3*s2*s1], [1, s3*s2, s3*s1], @@ -100,22 +100,22 @@ def __classcall_private__(cls, skew_shape, k, n, x = None): TESTS:: - sage: from sage.combinat.crystals.weak_crystal import WeakCrystal - sage: WeakCrystal([[3,1],[1]],3,4) + sage: from sage.combinat.crystals.affine_factorization import AffineFactorizationCrystal + sage: AffineFactorizationCrystal([[3,1],[1]],3,4) Weak crystal on affine factorizations of type A4 of shape [[3, 1], [1]] """ skew_shape = tuple(tuple(l) for l in skew_shape) - return super(WeakCrystal, cls).__classcall__(cls, skew_shape, k, n, x) + return super(AffineFactorizationCrystal, cls).__classcall__(cls, skew_shape, k, n, x) def __init__(self, skew_shape, k, n, x=None): """ EXAMPLES:: - sage: from sage.combinat.crystals.weak_crystal import WeakCrystal - sage: W = WeakCrystal([[3,2],[2]],3,4,0) + sage: from sage.combinat.crystals.affine_factorization import AffineFactorizationCrystal + sage: W = AffineFactorizationCrystal([[3,2],[2]],3,4,0) sage: W.x 0 - sage: W = WeakCrystal([[3,2],[2]],3,4) + sage: W = AffineFactorizationCrystal([[3,2],[2]],3,4) sage: W.x 1 """ @@ -141,8 +141,8 @@ def _repr_(self): """ EXAMPLES:: - sage: from sage.combinat.crystals.weak_crystal import WeakCrystal - sage: WeakCrystal([[3,1],[1]],3,4) + sage: from sage.combinat.crystals.affine_factorization import AffineFactorizationCrystal + sage: AffineFactorizationCrystal([[3,1],[1]],3,4) Weak crystal on affine factorizations of type A4 of shape [[3, 1], [1]] """ return "Weak crystal on affine factorizations of type A%s of shape %s"%(self.n, [[i for i in w] for w in self.skew_shape]) @@ -158,8 +158,8 @@ def e(self, i): EXAMPLES:: - sage: from sage.combinat.crystals.weak_crystal import WeakCrystal - sage: W = WeakCrystal(tuple([tuple([3,1]),tuple([1])]),3,4) + sage: from sage.combinat.crystals.affine_factorization import AffineFactorizationCrystal + sage: W = AffineFactorizationCrystal(tuple([tuple([3,1]),tuple([1])]),3,4) sage: t = W(W.module_generators[1]); t [1, 1, s3, s2*s1] sage: t.e(1) @@ -193,8 +193,8 @@ def f(self, i): EXAMPLES:: - sage: from sage.combinat.crystals.weak_crystal import WeakCrystal - sage: W = WeakCrystal(tuple([tuple([3,1]),tuple([1])]),3,4) + sage: from sage.combinat.crystals.affine_factorization import AffineFactorizationCrystal + sage: W = AffineFactorizationCrystal(tuple([tuple([3,1]),tuple([1])]),3,4) sage: t = W(W.module_generators[1]); t [1, 1, s3, s2*s1] sage: t.f(2) @@ -230,8 +230,8 @@ def bracketing(self, i): EXAMPLES:: - sage: from sage.combinat.crystals.weak_crystal import WeakCrystal - sage: W = WeakCrystal(tuple([tuple([3,1]),tuple([1])]),3,4) + sage: from sage.combinat.crystals.affine_factorization import AffineFactorizationCrystal + sage: W = AffineFactorizationCrystal(tuple([tuple([3,1]),tuple([1])]),3,4) sage: t = W(W.module_generators[1]) sage: t.bracketing(1) [[3], [2, 1]] From 763ebf20c265e03b177cd97d1c66ac511a87c51a Mon Sep 17 00:00:00 2001 From: Anne Schilling Date: Mon, 24 Feb 2014 11:06:04 -0800 Subject: [PATCH 144/163] fixed rep --- src/sage/combinat/crystals/affine_factorization.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/combinat/crystals/affine_factorization.py b/src/sage/combinat/crystals/affine_factorization.py index 4f7b8eccad5..08d7d696661 100644 --- a/src/sage/combinat/crystals/affine_factorization.py +++ b/src/sage/combinat/crystals/affine_factorization.py @@ -102,7 +102,7 @@ def __classcall_private__(cls, skew_shape, k, n, x = None): sage: from sage.combinat.crystals.affine_factorization import AffineFactorizationCrystal sage: AffineFactorizationCrystal([[3,1],[1]],3,4) - Weak crystal on affine factorizations of type A4 of shape [[3, 1], [1]] + Crystal on affine factorizations of type A4 of shape [[3, 1], [1]] """ skew_shape = tuple(tuple(l) for l in skew_shape) return super(AffineFactorizationCrystal, cls).__classcall__(cls, skew_shape, k, n, x) @@ -143,9 +143,9 @@ def _repr_(self): sage: from sage.combinat.crystals.affine_factorization import AffineFactorizationCrystal sage: AffineFactorizationCrystal([[3,1],[1]],3,4) - Weak crystal on affine factorizations of type A4 of shape [[3, 1], [1]] + Crystal on affine factorizations of type A4 of shape [[3, 1], [1]] """ - return "Weak crystal on affine factorizations of type A%s of shape %s"%(self.n, [[i for i in w] for w in self.skew_shape]) + return "Crystal on affine factorizations of type A%s of shape %s"%(self.n, [[i for i in w] for w in self.skew_shape]) # temporary workaround while an_element is overriden by Parent _an_element_ = EnumeratedSets.ParentMethods._an_element_ From eb56f063b5cb644f41711f1ec629ab4041e6432a Mon Sep 17 00:00:00 2001 From: Anne Schilling Date: Tue, 25 Feb 2014 16:48:07 -0800 Subject: [PATCH 145/163] finished affine factorization crystal --- .../combinat/crystals/affine_factorization.py | 216 ++++++++++++------ 1 file changed, 143 insertions(+), 73 deletions(-) diff --git a/src/sage/combinat/crystals/affine_factorization.py b/src/sage/combinat/crystals/affine_factorization.py index 08d7d696661..b92f5ced53b 100644 --- a/src/sage/combinat/crystals/affine_factorization.py +++ b/src/sage/combinat/crystals/affine_factorization.py @@ -14,40 +14,55 @@ from sage.categories.classical_crystals import ClassicalCrystals from sage.categories.enumerated_sets import EnumeratedSets from sage.combinat.root_system.cartan_type import CartanType -from sage.combinat.integer_vector import IntegerVectors -from sage.combinat.k_tableau import WeakTableaux, WeakTableau +from sage.combinat.root_system.weyl_group import WeylGroup class AffineFactorizationCrystal(UniqueRepresentation, Parent): r""" - This is an implementation of the weak crystal on affine factorizations - with a cut-point, as introduced by Morse and Schilling. + This is an implementation of the crystal on affine factorizations + with a cut-point, as introduced by Morse and Schilling, + ``Crystal operators and flag Gromov-Witten invariants". + + INPUT: + + - ``w`` -- an element in an (affine) Weyl group or a skew shape of `k`-bounded partitions (if `k` was specified) + - ``n`` -- the number of factors in the factorization + - ``x`` -- (default: None) the cut point; if not specified it is determined as the minimal missing residue in ``w`` + - ``k`` -- (default: None) positive integer, specifies that ``w`` is `k`-bounded or a `k+1`-core when specified EXAMPLES:: sage: from sage.combinat.crystals.affine_factorization import AffineFactorizationCrystal - sage: W = AffineFactorizationCrystal([[3,1,1],[1]],3,3) - sage: W.list() - [[1, s2, s3*s2*s1], - [1, s3*s2, s3*s1], - [1, s3*s2*s1, s3], - [s3, s2, s3*s1], - [s3, s2*s1, s3], - [s3*s2, s1, s3], - [s3*s2*s1, 1, s3], - [s3*s2*s1, s3, 1], - [s3*s2, 1, s3*s1], - [s3*s2, s3, s1], - [s3*s2, s3*s1, 1], - [s2, 1, s3*s2*s1], - [s2, s3, s2*s1], - [s2, s3*s2, s1], - [s2, s3*s2*s1, 1]] + sage: W = WeylGroup(['A',3,1], prefix='s') + sage: w = W.from_reduced_word([2,3,2,1]) + sage: B = AffineFactorizationCrystal(w,3); B + Crystal on affine factorizations of type A3 associated to s2*s3*s2*s1 + sage: B.list() + [(1, s2, s3*s2*s1), + (1, s3*s2, s3*s1), + (1, s3*s2*s1, s3), + (s3, s2, s3*s1), + (s3, s2*s1, s3), + (s3*s2, s1, s3), + (s3*s2*s1, 1, s3), + (s3*s2*s1, s3, 1), + (s3*s2, 1, s3*s1), + (s3*s2, s3, s1), + (s3*s2, s3*s1, 1), + (s2, 1, s3*s2*s1), + (s2, s3, s2*s1), + (s2, s3*s2, s1), + (s2, s3*s2*s1, 1)] + + We can also access the crystal by specifying a skew shape in terms of `k`-bounded partitions:: + + sage: AffineFactorizationCrystal([[3,1,1],[1]], 3, k=3) + Crystal on affine factorizations of type A3 associated to s2*s3*s2*s1 We can compute the highest weight elements:: - sage: hw = [w for w in W if w.is_highest_weight()] + sage: hw = [w for w in B if w.is_highest_weight()] sage: hw - [[1, s2, s3*s2*s1]] + [(1, s2, s3*s2*s1)] sage: hw[0].weight() (3, 1, 0) @@ -55,20 +70,20 @@ class AffineFactorizationCrystal(UniqueRepresentation, Parent): sage: C = CrystalOfTableaux(['A',2],shape=[3,1]) sage: GC = C.digraph() - sage: GW = W.digraph() - sage: GC.is_isomorphic(GW, edge_labels=True) + sage: GB = B.digraph() + sage: GC.is_isomorphic(GB, edge_labels=True) True The crystal operators themselves move elements between adjacent factors:: sage: b = hw[0];b - [1, s2, s3*s2*s1] + (1, s2, s3*s2*s1) sage: b.f(1) - [1, s3*s2, s3*s1] + (1, s3*s2, s3*s1) TESTS:: - sage: TestSuite(W).run(verbose = True) + sage: TestSuite(B).run(verbose = True) running ._test_an_element() . . . pass running ._test_category() . . . pass running ._test_elements() . . . @@ -94,47 +109,68 @@ class AffineFactorizationCrystal(UniqueRepresentation, Parent): running ._test_stembridge_local_axioms() . . . pass """ @staticmethod - def __classcall_private__(cls, skew_shape, k, n, x = None): + def __classcall_private__(cls, w, n, x = None, k = None): """ Classcall to mend the input. TESTS:: sage: from sage.combinat.crystals.affine_factorization import AffineFactorizationCrystal - sage: AffineFactorizationCrystal([[3,1],[1]],3,4) - Crystal on affine factorizations of type A4 of shape [[3, 1], [1]] + sage: A = AffineFactorizationCrystal([[3,1],[1]], 4, k=3); A + Crystal on affine factorizations of type A4 associated to s3*s2*s1 + sage: AC = AffineFactorizationCrystal([Core([4,1],4),Core([1],4)], 4, k=3) + sage: AC == A + True """ - skew_shape = tuple(tuple(l) for l in skew_shape) - return super(AffineFactorizationCrystal, cls).__classcall__(cls, skew_shape, k, n, x) + if k is not None: + from sage.combinat.core import Core + from sage.combinat.partition import Partition + W = WeylGroup(['A',k,1], prefix='s') + if isinstance(w[0], Core): + w = [w[0].to_bounded_partition(), w[1].to_bounded_partition()] + else: + w = [Partition(w[0]), Partition(w[1])] + w0 = W.from_reduced_word(w[0].from_kbounded_to_reduced_word(k)) + w1 = W.from_reduced_word(w[1].from_kbounded_to_reduced_word(k)) + w = w0*(w1.inverse()) + return super(AffineFactorizationCrystal, cls).__classcall__(cls, w, n, x, k) - def __init__(self, skew_shape, k, n, x=None): + def __init__(self, w, n, x = None, k = None): """ EXAMPLES:: sage: from sage.combinat.crystals.affine_factorization import AffineFactorizationCrystal - sage: W = AffineFactorizationCrystal([[3,2],[2]],3,4,0) - sage: W.x - 0 - sage: W = AffineFactorizationCrystal([[3,2],[2]],3,4) - sage: W.x + sage: B = AffineFactorizationCrystal([[3,2],[2]],4,x=0,k=3) + Traceback (most recent call last): + ... + ValueError: x cannot be in reduced word of s0*s3*s2 + + sage: B = AffineFactorizationCrystal([[3,2],[2]],4,k=3) + sage: B.x 1 + sage: B.w + s0*s3*s2 + sage: B.k + 3 + sage: B.n + 4 """ Parent.__init__(self, category = ClassicalCrystals()) self.n = n - self.k = k - self.skew_shape = skew_shape + self.k = w.parent().n-1 + self.w = w cartan_type = CartanType(['A',n-1]) self._cartan_type = cartan_type - generators = [ t.to_core_tableau().to_factorized_permutation_tableau() - for mu in IntegerVectors(sum(skew_shape[0])-sum(skew_shape[1]), n) - for t in WeakTableaux(k, skew_shape, mu, representation='bounded')] + generators = [tuple(p) for p in affine_factorizations(w, n)] self.module_generators = [self(t) for t in generators] if x is None: if generators != []: - x = min( set(range(k+1)).difference(set( + x = min( set(range(self.k+1)).difference(set( sum([i.reduced_word() for i in generators[0]],[])))) else: x = 0 + if x in set(w.reduced_word()): + raise ValueError, "x cannot be in reduced word of %s"%w self.x = x def _repr_(self): @@ -142,10 +178,15 @@ def _repr_(self): EXAMPLES:: sage: from sage.combinat.crystals.affine_factorization import AffineFactorizationCrystal - sage: AffineFactorizationCrystal([[3,1],[1]],3,4) - Crystal on affine factorizations of type A4 of shape [[3, 1], [1]] + sage: W = WeylGroup(['A',3,1], prefix='s') + sage: w = W.from_reduced_word([3,2,1]) + sage: AffineFactorizationCrystal(w,4) + Crystal on affine factorizations of type A4 associated to s3*s2*s1 + + sage: AffineFactorizationCrystal([[3,1],[1]], 4, k=3) + Crystal on affine factorizations of type A4 associated to s3*s2*s1 """ - return "Crystal on affine factorizations of type A%s of shape %s"%(self.n, [[i for i in w] for w in self.skew_shape]) + return "Crystal on affine factorizations of type A%s associated to %s"%(self.n, self.w) # temporary workaround while an_element is overriden by Parent _an_element_ = EnumeratedSets.ParentMethods._an_element_ @@ -159,13 +200,14 @@ def e(self, i): EXAMPLES:: sage: from sage.combinat.crystals.affine_factorization import AffineFactorizationCrystal - sage: W = AffineFactorizationCrystal(tuple([tuple([3,1]),tuple([1])]),3,4) - sage: t = W(W.module_generators[1]); t - [1, 1, s3, s2*s1] + sage: B = AffineFactorizationCrystal([[3,1],[1]], 4, k=3) + sage: t = B(B.module_generators[1]); t + (1, 1, s3, s2*s1) sage: t.e(1) - [1, 1, 1, s3*s2*s1] + (1, 1, 1, s3*s2*s1) """ assert i in self.index_set() + W = self.parent().w.parent() x = self.parent().x k = self.parent().k n = self.parent().n @@ -179,13 +221,8 @@ def e(self, i): right += [m+1] right.sort(reverse=True) right = [(j+x)%(k+1) for j in right] - t = [self.value[j].reduced_word() for j in range(n-i-1)] + [left] + [right] + [self.value[j].reduced_word() for j in range(n-i+1,n)] - t = WeakTableau([self.value[j].reduced_word() for j in range(n-i-1)] - + [left] + [right] - + [self.value[j].reduced_word() for j in range(n-i+1,n)], - self.parent().k, inner_shape = self.value._inner_shape, - representation='factorized_permutation') - return self.parent()(t) + t = [self.value[j] for j in range(n-i-1)] + [W.from_reduced_word(left)] + [W.from_reduced_word(right)] + [self.value[j] for j in range(n-i+1,n)] + return self.parent()(tuple(t)) def f(self, i): r""" @@ -194,15 +231,16 @@ def f(self, i): EXAMPLES:: sage: from sage.combinat.crystals.affine_factorization import AffineFactorizationCrystal - sage: W = AffineFactorizationCrystal(tuple([tuple([3,1]),tuple([1])]),3,4) - sage: t = W(W.module_generators[1]); t - [1, 1, s3, s2*s1] + sage: B = AffineFactorizationCrystal([[3,1],[1]], 4, k=3) + sage: t = B(B.module_generators[1]); t + (1, 1, s3, s2*s1) sage: t.f(2) - [1, s3, 1, s2*s1] + (1, s3, 1, s2*s1) sage: t.f(1) - [1, 1, s3*s2, s1] + (1, 1, s3*s2, s1) """ assert i in self.index_set() + W = self.parent().w.parent() x = self.parent().x k = self.parent().k n = self.parent().n @@ -216,13 +254,8 @@ def f(self, i): left += [m-1] left.sort(reverse=True) left = [(j+x)%(k+1) for j in left] - t = [self.value[j].reduced_word() for j in range(n-i-1)] + [left] + [right] + [self.value[j].reduced_word() for j in range(n-i+1,n)] - t = WeakTableau([self.value[j].reduced_word() for j in range(n-i-1)] - + [left] + [right] - + [self.value[j].reduced_word() for j in range(n-i+1,n)], - self.parent().k, inner_shape = self.value._inner_shape, - representation='factorized_permutation') - return self.parent()(t) + t = [self.value[j] for j in range(n-i-1)] + [W.from_reduced_word(left)] + [W.from_reduced_word(right)] + [self.value[j] for j in range(n-i+1,n)] + return self.parent()(tuple(t)) def bracketing(self, i): r""" @@ -231,8 +264,9 @@ def bracketing(self, i): EXAMPLES:: sage: from sage.combinat.crystals.affine_factorization import AffineFactorizationCrystal - sage: W = AffineFactorizationCrystal(tuple([tuple([3,1]),tuple([1])]),3,4) - sage: t = W(W.module_generators[1]) + sage: B = AffineFactorizationCrystal([[3,1],[1]], 3, k=3, x=4) + sage: t = B(B.module_generators[1]); t + (1, s3, s2*s1) sage: t.bracketing(1) [[3], [2, 1]] """ @@ -253,3 +287,39 @@ def bracketing(self, i): else: left_unbracketed += [m] return [[j for j in left_unbracketed],[j for j in right_n]] + + +def affine_factorizations(w, l): + r""" + Return all factorizations of `w` into `l` factors. + + INPUT: + + - ``w` -- an (affine) permutation or element of the (affine) Weyl group + - ``l`` -- nonegative integer + + EXAMPLES:: + + sage: W = WeylGroup(['A',3,1], prefix='s') + sage: w = W.from_reduced_word([3,2,3,1,0,1]) + sage: from sage.combinat.crystals.affine_factorization import affine_factorizations + sage: affine_factorizations(w,4) + [[s2, s3, s0, s2*s1*s0], + [s2, s3, s2*s0, s1*s0], + [s2, s3, s2*s1*s0, s1], + [s2, s3*s2, s0, s1*s0], + [s2, s3*s2, s1*s0, s1], + [s2, s3*s2*s1, s0, s1], + [s3*s2, s3, s0, s1*s0], + [s3*s2, s3, s1*s0, s1], + [s3*s2, s3*s1, s0, s1], + [s3*s2*s1, s3, s0, s1]] + """ + if l==0: + if w.is_one(): + return [[]] + else: + return [] + else: + return [[u]+p for (u,v) in w.left_pieri_factorizations() for p in affine_factorizations(v,l-1) ] + From 31a592db1ee25b2803ea3a05b0cedb86cc3dffa8 Mon Sep 17 00:00:00 2001 From: Anne Schilling Date: Tue, 25 Feb 2014 16:50:59 -0800 Subject: [PATCH 146/163] reverted changes in k_tableaux --- src/sage/combinat/k_tableau.py | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/src/sage/combinat/k_tableau.py b/src/sage/combinat/k_tableau.py index 4c9d1b371cf..aee089c604e 100644 --- a/src/sage/combinat/k_tableau.py +++ b/src/sage/combinat/k_tableau.py @@ -403,13 +403,9 @@ def intermediate_shapes(self): [[2], [2, 1], [3, 1, 1], [4, 1, 1], [5, 2, 1]] """ if self.parent()._representation in ['core', 'bounded']: - shapes = [] - t = SkewTableau(list(self)) - for i in range(len(self.weight())+1): - shapes += [ t.restrict(i).outer_shape()] - return shapes + return intermediate_shapes(self) else: - return self.to_core_tableau().intermediate_shapes() + return intermediate_shapes(self.to_core_tableau()) def pp(self): r""" @@ -802,10 +798,7 @@ def check(self): ValueError: The tableau is not semistandard! """ if not self.parent()._weight == WeakTableau_bounded.from_core_tableau(self._list,self.k).weight(): - w = WeakTableau_bounded.from_core_tableau(self._list,self.k).weight() - wp = self.parent()._weight - if not tuple([wp[i] for i in range(len(w))]) == w: - raise ValueError("The weight of the parent does not agree with the weight of the tableau!") + raise ValueError("The weight of the parent does not agree with the weight of the tableau!") t = SkewTableau(list(self)) if not t in SemistandardSkewTableaux(): raise ValueError("The tableau is not semistandard!") @@ -1532,10 +1525,7 @@ def check(self): if not t in SemistandardSkewTableaux(): raise ValueError("The tableaux is not semistandard!") if not self.parent()._weight == tuple(t.weight()): - w = tuple(t.weight()) - wp = self.parent()._weight - if not tuple([wp[i] for i in range(len(w))]) == w: - raise ValueError("The weight of the parent does not agree with the weight of the tableau!") + raise ValueError("The weight of the parent does not agree with the weight of the tableau!") outer = t.outer_shape() inner = t.inner_shape() if self.parent()._outer_shape != outer: @@ -1604,8 +1594,7 @@ def to_core_tableau(self): for j in range(len(l)): l_new += [l[j] + [i]*(p[j]-len(l[j]))] l = l_new - return WeakTableaux_core(self.k, self.shape_core(), self.weight())(l) - #return WeakTableau_core(l, self.k) + return WeakTableau_core(l, self.k) @classmethod def from_core_tableau(cls, t, k): @@ -2192,10 +2181,8 @@ def __iter__(self): sage: T.list() [[s0, s4, s3, s4*s2], [s0, s3, s4, s3*s2], [s3, s0, s4, s3*s2]] """ - for t in WeakTableaux_bounded(self.k, [self._outer_shape.to_bounded_partition(),self._inner_shape.to_bounded_partition()], self._weight): - yield t.to_core_tableau().to_factorized_permutation_tableau() - #for t in WeakTableaux_core(self.k, self.shape(), self._weight): - # yield WeakTableau_factorized_permutation.from_core_tableau(t, self.k) + for t in WeakTableaux_core(self.k, self.shape(), self._weight): + yield WeakTableau_factorized_permutation.from_core_tableau(t, self.k) Element = WeakTableau_factorized_permutation From a147b7fcd5edcd488828344bca1178edab390fcc Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Wed, 26 Feb 2014 14:54:10 +0100 Subject: [PATCH 147/163] remove duplicated changelog --- build/pkgs/gap/SPKG.txt | 142 ---------------------------------------- 1 file changed, 142 deletions(-) diff --git a/build/pkgs/gap/SPKG.txt b/build/pkgs/gap/SPKG.txt index d50dc1e5cd9..d32de4cf8c8 100644 --- a/build/pkgs/gap/SPKG.txt +++ b/build/pkgs/gap/SPKG.txt @@ -50,145 +50,3 @@ update GAP, please also update and use the spkg-src script. Since the (pre-)built HTML documentation is currently included, I've commented out some lines in that part of `spkg-install`. -leif -== Changelog == - -=== gap-4.6.4.p0 (Volker Braun, 3 June 2013) === - * #14682: Upgrade to version 4.6.4 - -=== gap-4.6.3.p0 (Jeroen Demeyer, Volker Braun, 25 April 2013) === - * #14039: Upgrade to version 4.6.3. - * Use standard spkg-install boilerplate. - * Remove all unneeded "cd" statements from spkg-install. - * Remove __GNU_MP_RELEASE hack. - * Removed siginterrupt.patch (included upstream) - -=== gap-4.5.7.p3 (Jean-Pierre Flori, 26 January 2013) === - * #13954: Let gap build on top of a shared version of MPIR. - * Cleanup old Cygwin fixes now unnecessary. - -=== gap-4.5.7.p2 (Jeroen Demeyer, 17 January 2013) === - * #13963: do not touch gap_stamp (which isn't used anyway). - * Use -O2 -g as default CFLAGS and never override user-set flags. - * Remove unsetting of CC and CXX which doesn't seem to be needed - anymore. - * Use autoconf tracing to determine the GAP version number. - -=== gap-4.5.7.p1 (Volker Braun, 20 December 2012) === - * #13211: Fix gap/latest symlink creation. - -=== gap-4.5.7.p0 (Jeroen Demeyer, 20 December 2012) === - * #13211: update to version 4.5.7. - * Add spkg-src script to download and clean up the src files. - * writeandcheck.patch: fix infinite loop in writeandcheck() when - writing an error message fails. - * cflags.patch: allow user-supplied CFLAGS to override - configure-guessed flags. - * siginterrupt.patch: make interrupt behaviour portable: an interrupt - while reading stdin shouldn't cause GAP to exit (it does cause an - error in the next command, which is a different bug). - -=== gap-4.5.6 (Volker Braun, 22 September 2012) === - * #13211: Update to latest upstream version - -=== gap-4.5.5 (Volker Braun, 26 August 2012) === - * Update to latest upstream version - * New (saner) filesystem layout, everything goes to - "$SAGE_LOCAL/gap/gap-x.y.z" with a "latest" symlink. - * Added spkg-check - -=== gap-4.4.12.p8 (Jean-Pierre Flori, Leif Leonhardy, 5 August 2012) === - * #13341: Only create symbolic link to gap.exe on Cygwin if needed. - -=== gap-4.4.12.p7 (Leif Leonhardy, March 22nd 2012) === - * #7041: Only unset `CC` and `CXX` if really necessary (i.e., if they - contain spaces, which is what currently would break the build). - * Clean up `spkg-install`. Some things seem still weird, see comments. - * Added "Special Update/Build Instructions" section above. - -=== gap-4.4.12.p6 (Jeroen Demeyer, 8 August 2011) === - * Trac #11661: Make all files world-readable - * Remove obsolete dist directory and spkg-debian script - -=== gap-4.4.12.p5 (Jason Grout, 22 Feb 2011) === - * #10825: Add SAGE_SPKG_INSTALL_DOCS support to build and install docs in - $SAGE_ROOT/local/share/doc/ - -=== gap-4.4.12.p4 (David Kirkby, 14th June 2010) === - * #9098 "gap buillds 32-bit on OpenSolaris when SAGE64=yes" - Change spkg-install to allow gap to build 64-bit on Solaris. - The changes are only for Solaris, since there are numerous - warnings that setting CC causes problems. Note, this will not - built 64-bit on OS X by setting the SAGE64 variable to "yes". - -=== gap-4.4.12.p3 (Willem Jan Palenstijn, 2010-4-28) === - * #8773: Fix some problems with strict aliasing (gcc 4.5) - * Don't pre-apply saveload.patch to src/ directory. - * Remove some files in src/tst which seemed to have been copied from src/ - -=== gap-4.4.12.p2 (Dima Pasechnik, 2010-4-27) === - * removed everything in src/bin/ (Windows/Cygwin-less related stuff, - i.e. not needed if full-blown Cygwin is used), - and GAP 4 PPC (a MacOS 9 executable) in src/ - -=== gap-4.4.12.p1 (Dima Pasechnik, 2010-1-25) === - * See ticket #8076 for full details. - * Added .hgignore. - * Applied Steve Linton's Itanium patch to GAP_ROOT/src/saveload.c - (not using the usual patches/* procedure, as this is - an upstream patch.) - * Removed a stray binary file "patch" at the top level. - * Replaced $LN, $MKDIR, etc as done in gap-4.4.10.p13 (see below) - -=== gap-4.4.12.p0 (David Joyner, 2009-6-17) === - * Upgraded to gap-4.4.12. Removed guava compilation. From the source - GAP tarball, removed tomlib, small, prim, trans. - -=== gap-4.4.10.p13 (David Kirkby, January 8th, 2010) === - * #7873 Remove references to $LN, $MKIDR and $RM and replace - with ln, mkdir and rm, as agreed at - http://groups.google.com/group/sage-devel/browse_thread/thread/bd7ae07a1157be -ad/970aa0dc8fa56ab7?lnk=raot - -=== gap-4.4.10.p12 (William Stein, June 2, 2009) === - * Turn optimization back off for itanium, using exactly the same code as from - before to do this. - -=== gap-4.4.10.p11 (Michael Abshoff, September 20th, 2008) === - * Delete all old GAP installs due to a downgrade from GAP 4.4.12 (#5697) - -=== gap-4.4.10.p10 (Michael Abshoff, September 20th, 2008) === - * unset CXX in spkg-install (work around for #4161) - -=== gap-4.4.10.p9 (William Stein, August 27th, 2008) === - * Apply all the itanium patches to the src/ directory. - These are from http://www.gap-system.org/Faq/Hardware-OS/hardware-os8.html - and will be in *all* future versions of Gap (i.e., they come - from upstream). They change about 10 files, so I didn't not - use our usual patches/* and copy protocol. - -=== gap-4.4.10.p8 (Michael Abshoff, June 16th, 2008) === - * unset CC in spkg-install (work around for #2575) - -=== gap-4.4.10.p6 (David Joyner, April 11th, 2008) === - * replace guava 3.4 by guava 3.4 with fixed Makefile.in - -=== gap-4.4.10.p5 (Michael Abshoff, April 1st, 2008) === - * Debianize GAP spkg (Tim Abbott, #2756) - -=== gap-4.4.10.p4 (Robert Miller, March 31st, 2008) === - * Leon's code is now fully compiled and copied over to $SAGE_LOCAL - -=== gap-4.4.10.p3 (David Joyner, March 30th, 2008) === - * replace guava 3.1 by guava 3.3 - -=== gap-4.4.10.p2 (Michael Abshoff, Jan. 31st, 2008) === - * remove src/pkg/guava3.1/src/leonconv (#2006) - -=== gap-4.4.10.p1 (Michael Abshoff, Jan. 22nd, 2008) === - * remove 1500 crap files from the spkg (part of #1883) - -=== gap-4.4.10.p0 === - -Upgraded to gap-4.4.10. Had to change files in the patches directory that -hard code gap-4.4.9. - From f8021680e367f7f5706ac723ce1d7432be7a6979 Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Wed, 26 Feb 2014 14:56:39 +0100 Subject: [PATCH 148/163] add SPARC alignment fix --- build/pkgs/gap/SPKG.txt | 7 ++++++ build/pkgs/gap/patches/sparc_segfault.patch | 25 +++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 build/pkgs/gap/patches/sparc_segfault.patch diff --git a/build/pkgs/gap/SPKG.txt b/build/pkgs/gap/SPKG.txt index d32de4cf8c8..c8197db6720 100644 --- a/build/pkgs/gap/SPKG.txt +++ b/build/pkgs/gap/SPKG.txt @@ -50,3 +50,10 @@ update GAP, please also update and use the spkg-src script. Since the (pre-)built HTML documentation is currently included, I've commented out some lines in that part of `spkg-install`. -leif +The following patches need to be applied: + + * writeandcheck.patch: fix infinite loop in writeandcheck() when + writing an error message fails. + + * sparc_segfault.patch: fix alignment issue on SPARC + diff --git a/build/pkgs/gap/patches/sparc_segfault.patch b/build/pkgs/gap/patches/sparc_segfault.patch new file mode 100644 index 00000000000..488652bfe77 --- /dev/null +++ b/build/pkgs/gap/patches/sparc_segfault.patch @@ -0,0 +1,25 @@ +Index: gap-4r7p3/src/pperm.c +=================================================================== +--- gap-4r7p3.orig/src/pperm.c 2014-02-24 20:25:12.000000000 +0000 ++++ gap-4r7p3/src/pperm.c 2014-02-24 20:26:00.000000000 +0000 +@@ -16,16 +16,16 @@ + #define MIN(a,b) (a Date: Wed, 26 Feb 2014 15:34:14 +0100 Subject: [PATCH 149/163] apply sparc patch also to libgap --- build/pkgs/gap/patches/sparc_segfault.patch | 2 +- build/pkgs/libgap/SPKG.txt | 44 +------------------ .../pkgs/libgap/patches/sparc_segfault.patch | 25 +++++++++++ build/pkgs/libgap/spkg-install | 14 +++++- 4 files changed, 41 insertions(+), 44 deletions(-) create mode 100644 build/pkgs/libgap/patches/sparc_segfault.patch diff --git a/build/pkgs/gap/patches/sparc_segfault.patch b/build/pkgs/gap/patches/sparc_segfault.patch index 488652bfe77..1511de7ad08 100644 --- a/build/pkgs/gap/patches/sparc_segfault.patch +++ b/build/pkgs/gap/patches/sparc_segfault.patch @@ -22,4 +22,4 @@ Index: gap-4r7p3/src/pperm.c +#define ADDR_PPERM4(f) ((UInt4*)(ADDR_OBJ(f))) #define IMG_PPERM4(f) (*((Obj*)(ADDR_PPERM4(f)+DEG_PPERM4(f)))) #define DOM_PPERM4(f) (*((Obj*)(ADDR_PPERM4(f)+DEG_PPERM4(f))+1)) - #define DEG_PPERM4(f) ((UInt)(SIZE_OBJ(f)-sizeof(UInt4)-2*sizeof(Obj))/sizeof(UInt4)) \ No newline at end of file + #define DEG_PPERM4(f) ((UInt)(SIZE_OBJ(f)-sizeof(UInt4)-2*sizeof(Obj))/sizeof(UInt4)) diff --git a/build/pkgs/libgap/SPKG.txt b/build/pkgs/libgap/SPKG.txt index 5e840492eeb..97bf50b5aac 100644 --- a/build/pkgs/libgap/SPKG.txt +++ b/build/pkgs/libgap/SPKG.txt @@ -40,46 +40,6 @@ though. This scrip parses the GAP sources, identifies global identifiers, and adds a libGAP_ prefix to them to avoid symbol namespace collisions in Sage. -== Changelog == +Patches: -=== libgap-4.6.5.p0 (Volker Braun, 5 October 2013) === - * Update to latest upstream - -=== libgap-4.6.4.p0 (Volker Braun, 3 June 2013) === - * Update to latest upstream - * Code cleanups following a code review by Fedora GAP packager Jerry - James, see https://bugzilla.redhat.com/show_bug.cgi?id=919703 - -=== libgap-4.6.3.p0 (Volker Braun, 25 April 2013) === - * Update to latest upstream - -=== libgap-4.6.2.p0 (Volker Braun, 9 March 2013) === - * Update to latest upstream - -=== libgap-4.5.7.p2 (Volker Braun, 28 Feb 2013) === - * Trac #14323: remove one more SIGCHLD handler - -=== libgap-4.5.7.p1 (Volker Braun, 30 Jan 2013) === - * See mercurial log - -=== libgap-4.6.2.p0 (Volker Braun, 22 March 2013) === - * Bump to latest upstream - -=== libgap-4.5.7.p1 (Volker Braun, 25 March 2013) === - * Removed last remaining SIGCHLD handler - -=== libgap-4.5.7.p1 (Volker Braun, 30 Jan 2013) === - * Cygwin fix - -=== libgap-4.5.7 (Volker Braun, 27 Dec 2012) === - * Update to latest upstream - * Fix Exec command - -=== libgap-4.5.6.p1 (Volker Braun, 22 Oct 2012) === - * Remove GAP signal handlers - -=== libgap-4.5.6 (Volker Braun, 10 Sept 2012) === - * Update to newest upsteram - -=== libgap-4.5.5 (Volker Braun, 2 Sept 2012) === - * Initial release + * sparc_segfault.patch: See the GAP spkg. diff --git a/build/pkgs/libgap/patches/sparc_segfault.patch b/build/pkgs/libgap/patches/sparc_segfault.patch new file mode 100644 index 00000000000..b71e7a51f04 --- /dev/null +++ b/build/pkgs/libgap/patches/sparc_segfault.patch @@ -0,0 +1,25 @@ +Index: gap-4r7p3/src/pperm.c +=================================================================== +--- gap-4r7p3.orig/src/pperm.c 2014-02-24 20:25:12.000000000 +0000 ++++ gap-4r7p3/src/pperm.c 2014-02-24 20:26:00.000000000 +0000 +@@ -16,16 +16,16 @@ + #define libGAP_MIN(a,b) (a&2 "Error applying '$patch'" + exit 1 + fi +done + +echo "Configuring libGAP..." ./configure --disable-static \ CFLAGS="$CFLAGS" CXXFLAGS="$CXXFLAGS" CPPFLAGS="$CPPFLAGS" \ --with-gap_system_arch="$GAParch_system" \ From 1dc5d9e1e633f7b689ac308c2e632e90d5020a95 Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Wed, 26 Feb 2014 17:31:14 +0100 Subject: [PATCH 150/163] fix trivial doctest failure --- src/sage/groups/finitely_presented.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/groups/finitely_presented.py b/src/sage/groups/finitely_presented.py index 133b170ab11..d85ff218721 100644 --- a/src/sage/groups/finitely_presented.py +++ b/src/sage/groups/finitely_presented.py @@ -564,7 +564,7 @@ def gap(self): sage: G=F/[a*a,b*b] sage: k=G.rewriting_system() sage: k.gap() - Knuth Bendix Rewriting System for Monoid( [ a, A, b, B ], ... ) with rules + Knuth Bendix Rewriting System for Monoid( [ a, A, b, B ] ) with rules [ [ a^2, ], [ a*A, ], [ A*a, ], [ b^2, ], [ b*B, ], [ B*b, ] ] From 623c5b6a5bd1217908c1a38f475a1457cdadf43f Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Wed, 26 Feb 2014 11:44:34 -0800 Subject: [PATCH 151/163] Reenable previously failing doctests for modular exponentiation of polynomials over finite field extensions. --- src/sage/rings/polynomial/polynomial_element.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index de0f7e3f2d1..aba003eddc6 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -1733,9 +1733,9 @@ cdef class Polynomial(CommutativeAlgebraElement): sage: R. = l[] sage: f = t^4 + (2*x - 1)*t^3 + (2*x + 1)*t^2 + 3 sage: h = t^4 - x*t^3 + (3*x + 1)*t^2 + 2*t + 2*x - 1 - sage: pow(f, 2, h) # not tested - see #15777 + sage: pow(f, 2, h) 3*t^3 + (2*x + 3)*t^2 + (2*x + 2)*t + 2*x + 2 - sage: pow(f, 10**7, h) # not tested - see #15777 + sage: pow(f, 10**7, h) 4*x*t^3 + 2*x*t^2 + 4*x*t + 4 """ if not PY_TYPE_CHECK_EXACT(right, Integer) or \ From c742335903c24c5021e9bd159169c6bb14906688 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Wed, 26 Feb 2014 12:16:34 -0800 Subject: [PATCH 152/163] Fix modular exponentiation of polynomials over finite field extensions. NTL does not accept a base of degree higher or equal to the modulus degree. Nor likes initializing pre conditioning objects from a degree one modulus. --- src/sage/libs/ntl/ntl_ZZ_pEX_linkage.pxi | 37 +++++++++++++++++++++--- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/src/sage/libs/ntl/ntl_ZZ_pEX_linkage.pxi b/src/sage/libs/ntl/ntl_ZZ_pEX_linkage.pxi index 0cc497647ae..38aeab7aa1e 100644 --- a/src/sage/libs/ntl/ntl_ZZ_pEX_linkage.pxi +++ b/src/sage/libs/ntl/ntl_ZZ_pEX_linkage.pxi @@ -254,7 +254,8 @@ cdef inline int celement_inv(ZZ_pEX_c* res, ZZ_pEX_c* a, cparent parent) except cdef inline int celement_pow(ZZ_pEX_c* res, ZZ_pEX_c* x, long e, ZZ_pEX_c *modulus, cparent parent) except -2: """ - EXAMPLE: + EXAMPLE:: + sage: K. = GF(next_prime(2**60)**3) sage: P. = PolynomialRing(K,implementation='NTL') sage: x^1000 @@ -266,10 +267,26 @@ cdef inline int celement_pow(ZZ_pEX_c* res, ZZ_pEX_c* x, long e, ZZ_pEX_c *modul sage: f = x+(a+1) sage: f**50 == sum(binomial(50,i)*(a+1)**i*x**(50-i) for i in range(51)) True + + TESTS: + + Check that :trac:`15777` is fixed:: + + sage: k. = GF(5**5) + sage: x = polygen(k) + sage: pow(x+1,100,x) + 1 + sage: pow(x+2,3,x) + 3 + sage: pow(x**3+1,2,x**2+2) + x + 3 + sage: pow(x**3+1,10**7,x**2+2) + x + 2 """ if parent != NULL: parent[0].restore() cdef ZZ_pEX_Modulus_c mod + cdef ZZ_pEX_c y if modulus == NULL: if ZZ_pEX_IsX(x[0]): ZZ_pEX_LeftShift(res[0], x[0], e - 1) @@ -278,10 +295,22 @@ cdef inline int celement_pow(ZZ_pEX_c* res, ZZ_pEX_c* x, long e, ZZ_pEX_c *modul ZZ_pEX_power(res[0], x[0], e) sig_off() else: + if ZZ_pEX_deg(modulus[0]) == 1: + ZZ_pEX_rem(y, x[0], modulus[0]) + sig_on() + ZZ_pEX_power(res[0], y, e) + sig_off() + return 0 ZZ_pEX_Modulus_build(mod, modulus[0]) - sig_on() - ZZ_pEX_PowerMod_pre(res[0], x[0], e, mod) - sig_off() + if ZZ_pEX_deg(x[0]) < ZZ_pEX_deg(modulus[0]): + sig_on() + ZZ_pEX_PowerMod_pre(res[0], x[0], e, mod) + sig_off() + else: + ZZ_pEX_rem_pre(y, x[0], mod) + sig_on() + ZZ_pEX_PowerMod_pre(res[0], y, e, mod) + sig_off() cdef inline int celement_gcd(ZZ_pEX_c* res, ZZ_pEX_c* a, ZZ_pEX_c *b, cparent parent) except -2: """ From f77c56404107e878fe3d45cd8269c7603e47286d Mon Sep 17 00:00:00 2001 From: Anne Schilling Date: Wed, 26 Feb 2014 16:57:57 -0800 Subject: [PATCH 153/163] added the affine factorization crystal to the documentation --- src/doc/en/reference/combinat/crystals.rst | 1 + .../combinat/crystals/affine_factorization.py | 46 ++++++++++--------- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/src/doc/en/reference/combinat/crystals.rst b/src/doc/en/reference/combinat/crystals.rst index b5c219cf189..1ae7b91befa 100644 --- a/src/doc/en/reference/combinat/crystals.rst +++ b/src/doc/en/reference/combinat/crystals.rst @@ -5,6 +5,7 @@ Crystals :maxdepth: 2 ../sage/combinat/crystals/affine + ../sage/combinat/crystals/affine_factorization ../sage/combinat/crystals/crystals ../sage/combinat/crystals/direct_sum ../sage/combinat/crystals/letters diff --git a/src/sage/combinat/crystals/affine_factorization.py b/src/sage/combinat/crystals/affine_factorization.py index b92f5ced53b..5a58e57914e 100644 --- a/src/sage/combinat/crystals/affine_factorization.py +++ b/src/sage/combinat/crystals/affine_factorization.py @@ -20,13 +20,16 @@ class AffineFactorizationCrystal(UniqueRepresentation, Parent): r""" This is an implementation of the crystal on affine factorizations with a cut-point, as introduced by Morse and Schilling, - ``Crystal operators and flag Gromov-Witten invariants". + "Crystal operators and flag Gromov-Witten invariants". INPUT: - ``w`` -- an element in an (affine) Weyl group or a skew shape of `k`-bounded partitions (if `k` was specified) + - ``n`` -- the number of factors in the factorization + - ``x`` -- (default: None) the cut point; if not specified it is determined as the minimal missing residue in ``w`` + - ``k`` -- (default: None) positive integer, specifies that ``w`` is `k`-bounded or a `k+1`-core when specified EXAMPLES:: @@ -38,20 +41,20 @@ class AffineFactorizationCrystal(UniqueRepresentation, Parent): Crystal on affine factorizations of type A3 associated to s2*s3*s2*s1 sage: B.list() [(1, s2, s3*s2*s1), - (1, s3*s2, s3*s1), - (1, s3*s2*s1, s3), - (s3, s2, s3*s1), - (s3, s2*s1, s3), - (s3*s2, s1, s3), - (s3*s2*s1, 1, s3), - (s3*s2*s1, s3, 1), - (s3*s2, 1, s3*s1), - (s3*s2, s3, s1), - (s3*s2, s3*s1, 1), - (s2, 1, s3*s2*s1), - (s2, s3, s2*s1), - (s2, s3*s2, s1), - (s2, s3*s2*s1, 1)] + (1, s3*s2, s3*s1), + (1, s3*s2*s1, s3), + (s3, s2, s3*s1), + (s3, s2*s1, s3), + (s3*s2, s1, s3), + (s3*s2*s1, 1, s3), + (s3*s2*s1, s3, 1), + (s3*s2, 1, s3*s1), + (s3*s2, s3, s1), + (s3*s2, s3*s1, 1), + (s2, 1, s3*s2*s1), + (s2, s3, s2*s1), + (s2, s3*s2, s1), + (s2, s3*s2*s1, 1)] We can also access the crystal by specifying a skew shape in terms of `k`-bounded partitions:: @@ -110,7 +113,7 @@ class AffineFactorizationCrystal(UniqueRepresentation, Parent): """ @staticmethod def __classcall_private__(cls, w, n, x = None, k = None): - """ + r""" Classcall to mend the input. TESTS:: @@ -136,7 +139,7 @@ def __classcall_private__(cls, w, n, x = None, k = None): return super(AffineFactorizationCrystal, cls).__classcall__(cls, w, n, x, k) def __init__(self, w, n, x = None, k = None): - """ + r""" EXAMPLES:: sage: from sage.combinat.crystals.affine_factorization import AffineFactorizationCrystal @@ -174,7 +177,7 @@ def __init__(self, w, n, x = None, k = None): self.x = x def _repr_(self): - """ + r""" EXAMPLES:: sage: from sage.combinat.crystals.affine_factorization import AffineFactorizationCrystal @@ -195,7 +198,7 @@ class Element(ElementWrapper): def e(self, i): r""" - Returns the action of `e_i` on ``self``. + Return the action of `e_i` on ``self``. EXAMPLES:: @@ -226,7 +229,7 @@ def e(self, i): def f(self, i): r""" - Returns the action of `f_i` on ``self``. + Return the action of `f_i` on ``self``. EXAMPLES:: @@ -295,7 +298,8 @@ def affine_factorizations(w, l): INPUT: - - ``w` -- an (affine) permutation or element of the (affine) Weyl group + - ``w`` -- an (affine) permutation or element of the (affine) Weyl group + - ``l`` -- nonegative integer EXAMPLES:: From 5fba647a7df8a0f02d5282daf191ddcc1f884caa Mon Sep 17 00:00:00 2001 From: Anne Schilling Date: Wed, 26 Feb 2014 18:49:02 -0800 Subject: [PATCH 154/163] reviewer changes with Travis --- .../combinat/crystals/affine_factorization.py | 72 ++++++++----------- 1 file changed, 31 insertions(+), 41 deletions(-) diff --git a/src/sage/combinat/crystals/affine_factorization.py b/src/sage/combinat/crystals/affine_factorization.py index 5a58e57914e..afc882a14c3 100644 --- a/src/sage/combinat/crystals/affine_factorization.py +++ b/src/sage/combinat/crystals/affine_factorization.py @@ -28,9 +28,9 @@ class AffineFactorizationCrystal(UniqueRepresentation, Parent): - ``n`` -- the number of factors in the factorization - - ``x`` -- (default: None) the cut point; if not specified it is determined as the minimal missing residue in ``w`` + - ``x`` -- (default: ``None``) the cut point; if not specified it is determined as the minimal missing residue in ``w`` - - ``k`` -- (default: None) positive integer, specifies that ``w`` is `k`-bounded or a `k+1`-core when specified + - ``k`` -- (default: ``None``) positive integer, specifies that ``w`` is `k`-bounded or a `k+1`-core when specified EXAMPLES:: @@ -84,32 +84,12 @@ class AffineFactorizationCrystal(UniqueRepresentation, Parent): sage: b.f(1) (1, s3*s2, s3*s1) - TESTS:: - - sage: TestSuite(B).run(verbose = True) - running ._test_an_element() . . . pass - running ._test_category() . . . pass - running ._test_elements() . . . - Running the test suite of self.an_element() - running ._test_category() . . . pass - running ._test_eq() . . . pass - running ._test_not_implemented_methods() . . . pass - running ._test_pickling() . . . pass - running ._test_stembridge_local_axioms() . . . pass - pass - running ._test_elements_eq_reflexive() . . . pass - running ._test_elements_eq_symmetric() . . . pass - running ._test_elements_eq_transitive() . . . pass - running ._test_elements_neq() . . . pass - running ._test_enumerated_set_contains() . . . pass - running ._test_enumerated_set_iter_cardinality() . . . pass - running ._test_enumerated_set_iter_list() . . . pass - running ._test_eq() . . . pass - running ._test_fast_iter() . . . pass - running ._test_not_implemented_methods() . . . pass - running ._test_pickling() . . . pass - running ._test_some_elements() . . . pass - running ._test_stembridge_local_axioms() . . . pass + The cut point `x` is not supposed to occur in the reduced words for `w`:: + + sage: B = AffineFactorizationCrystal([[3,2],[2]],4,x=0,k=3) + Traceback (most recent call last): + ... + ValueError: x cannot be in reduced word of s0*s3*s2 """ @staticmethod def __classcall_private__(cls, w, n, x = None, k = None): @@ -122,7 +102,7 @@ def __classcall_private__(cls, w, n, x = None, k = None): sage: A = AffineFactorizationCrystal([[3,1],[1]], 4, k=3); A Crystal on affine factorizations of type A4 associated to s3*s2*s1 sage: AC = AffineFactorizationCrystal([Core([4,1],4),Core([1],4)], 4, k=3) - sage: AC == A + sage: AC is A True """ if k is not None: @@ -157,6 +137,14 @@ def __init__(self, w, n, x = None, k = None): 3 sage: B.n 4 + + TESTS:: + + sage: from sage.combinat.crystals.affine_factorization import AffineFactorizationCrystal + sage: W = WeylGroup(['A',3,1], prefix='s') + sage: w = W.from_reduced_word([2,3,2,1]) + sage: B = AffineFactorizationCrystal(w,3) + sage: TestSuite(B).run() """ Parent.__init__(self, category = ClassicalCrystals()) self.n = n @@ -173,7 +161,7 @@ def __init__(self, w, n, x = None, k = None): else: x = 0 if x in set(w.reduced_word()): - raise ValueError, "x cannot be in reduced word of %s"%w + raise ValueError("x cannot be in reduced word of {}".format(w)) self.x = x def _repr_(self): @@ -189,7 +177,7 @@ def _repr_(self): sage: AffineFactorizationCrystal([[3,1],[1]], 4, k=3) Crystal on affine factorizations of type A4 associated to s3*s2*s1 """ - return "Crystal on affine factorizations of type A%s associated to %s"%(self.n, self.w) + return "Crystal on affine factorizations of type A{} associated to {}".format(self.n, self.w) # temporary workaround while an_element is overriden by Parent _an_element_ = EnumeratedSets.ParentMethods._an_element_ @@ -209,14 +197,15 @@ def e(self, i): sage: t.e(1) (1, 1, 1, s3*s2*s1) """ - assert i in self.index_set() + if i not in self.index_set(): + raise ValueError("i must be in the index set") + b = self.bracketing(i) + if not b[0]: + return None W = self.parent().w.parent() x = self.parent().x k = self.parent().k n = self.parent().n - b = self.bracketing(i) - if b[0] == []: - return None a = min(b[0]) left = [j for j in (self.value[n-i-1]).reduced_word() if j != (a+x)%(k+1)] right = [(j-x)%(k+1) for j in (self.value[n-i]).reduced_word()] @@ -242,14 +231,15 @@ def f(self, i): sage: t.f(1) (1, 1, s3*s2, s1) """ - assert i in self.index_set() + if i not in self.index_set(): + raise ValueError("i must be in the index set") + b = self.bracketing(i) + if not b[1]: + return None W = self.parent().w.parent() x = self.parent().x k = self.parent().k n = self.parent().n - b = self.bracketing(i) - if b[1] == []: - return None a = max(b[1]) right = [j for j in (self.value[n-i]).reduced_word() if j != (a+x)%(k+1)] left = [(j-x)%(k+1) for j in (self.value[n-i-1]).reduced_word()] @@ -281,11 +271,11 @@ def bracketing(self, i): right_n = [(j-x)%(k+1) for j in right] left_n = [(j-x)%(k+1) for j in left] left_unbracketed = [] - while left_n != []: + while left_n: m = max(left_n) left_n.remove(m) l = [j for j in right_n if j>m] - if l != []: + if l: right_n.remove(min(l)) else: left_unbracketed += [m] From f17605b514e9a545f9aa789f69a9b36c4b53465a Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Thu, 27 Feb 2014 13:50:55 +0100 Subject: [PATCH 155/163] udpate to GAP-4.7.4 --- build/pkgs/database_gap/checksums.ini | 6 +++--- build/pkgs/database_gap/package-version.txt | 2 +- build/pkgs/gap/checksums.ini | 6 +++--- build/pkgs/gap/package-version.txt | 2 +- build/pkgs/gap/spkg-src | 2 +- build/pkgs/gap_packages/checksums.ini | 6 +++--- build/pkgs/gap_packages/package-version.txt | 2 +- build/pkgs/libgap/checksums.ini | 6 +++--- build/pkgs/libgap/package-version.txt | 2 +- build/pkgs/libgap/spkg-install | 2 +- 10 files changed, 18 insertions(+), 18 deletions(-) diff --git a/build/pkgs/database_gap/checksums.ini b/build/pkgs/database_gap/checksums.ini index 7785f73940f..2ba4d51073d 100644 --- a/build/pkgs/database_gap/checksums.ini +++ b/build/pkgs/database_gap/checksums.ini @@ -1,4 +1,4 @@ tarball=database_gap-VERSION.tar.bz2 -sha1=0e2b4e42717f39f75d2a700b3b050fc2265a2d4a -md5=0ecb28c96493eeef6a1435a9e5cef66e -cksum=3670665484 +sha1=6e5f63df55881a509076c4ecbd02c7afc8f81ef9 +md5=6f9d4632f6d2f4a7000c22cff5d15406 +cksum=1275532986 diff --git a/build/pkgs/database_gap/package-version.txt b/build/pkgs/database_gap/package-version.txt index af9764a59e1..b48b2de9d96 100644 --- a/build/pkgs/database_gap/package-version.txt +++ b/build/pkgs/database_gap/package-version.txt @@ -1 +1 @@ -4.7.2 +4.7.4 diff --git a/build/pkgs/gap/checksums.ini b/build/pkgs/gap/checksums.ini index 8c5bcc2481a..5ba340483f8 100644 --- a/build/pkgs/gap/checksums.ini +++ b/build/pkgs/gap/checksums.ini @@ -1,4 +1,4 @@ tarball=gap-VERSION.tar.bz2 -sha1=1169b6edcff95a59a8ad37398a044d22d30ec641 -md5=573753d606e4d8b900f2387c377b3dcd -cksum=781240400 +sha1=e61699cedf56b3b1668dec7387437eeb08fba3e7 +md5=3d3c1a40185d05863afbfd59956eecd9 +cksum=2711033242 diff --git a/build/pkgs/gap/package-version.txt b/build/pkgs/gap/package-version.txt index af9764a59e1..b48b2de9d96 100644 --- a/build/pkgs/gap/package-version.txt +++ b/build/pkgs/gap/package-version.txt @@ -1 +1 @@ -4.7.2 +4.7.4 diff --git a/build/pkgs/gap/spkg-src b/build/pkgs/gap/spkg-src index c033c8d2c07..e1b24de92a7 100755 --- a/build/pkgs/gap/spkg-src +++ b/build/pkgs/gap/spkg-src @@ -59,4 +59,4 @@ autoconf --trace='AC_INIT:$2' src/cnf/configure.in > src/gap-version rm -rf autom4te.cache -# tar cjf gap-`cat src/gap-version`.tar.bz2 src/ && rm -rf src/ +tar cjf gap-`cat src/gap-version`.tar.bz2 src/ && rm -rf src/ diff --git a/build/pkgs/gap_packages/checksums.ini b/build/pkgs/gap_packages/checksums.ini index b623c0c4841..8b4c9b21681 100644 --- a/build/pkgs/gap_packages/checksums.ini +++ b/build/pkgs/gap_packages/checksums.ini @@ -1,4 +1,4 @@ tarball=gap_packages-VERSION.tar.bz2 -sha1=72be0c1a763bb7d0d6f7708f96796f2e40f23b63 -md5=dabef4d7f69069906134a1178ef5e000 -cksum=693425859 +sha1=8fbd475be3aec265e36a600fe9cf3b00bd131d88 +md5=8d3c0fa85af6528bf2b9faf491da4180 +cksum=1526641510 diff --git a/build/pkgs/gap_packages/package-version.txt b/build/pkgs/gap_packages/package-version.txt index af9764a59e1..b48b2de9d96 100644 --- a/build/pkgs/gap_packages/package-version.txt +++ b/build/pkgs/gap_packages/package-version.txt @@ -1 +1 @@ -4.7.2 +4.7.4 diff --git a/build/pkgs/libgap/checksums.ini b/build/pkgs/libgap/checksums.ini index 03a4468735e..563d74ebc49 100644 --- a/build/pkgs/libgap/checksums.ini +++ b/build/pkgs/libgap/checksums.ini @@ -1,4 +1,4 @@ tarball=libgap-VERSION.tar.gz -sha1=357d533ace5016d10d9635ff28e0abdba98b5c56 -md5=dff641319181e68cff5ffcbc03ea4b6b -cksum=3929362303 +sha1=8a642b7b8ba0e9f707b5dab89d435994257b9f43 +md5=b723a22c195d460c6bc130cc4d2c2d82 +cksum=128803677 diff --git a/build/pkgs/libgap/package-version.txt b/build/pkgs/libgap/package-version.txt index af9764a59e1..b48b2de9d96 100644 --- a/build/pkgs/libgap/package-version.txt +++ b/build/pkgs/libgap/package-version.txt @@ -1 +1 @@ -4.7.2 +4.7.4 diff --git a/build/pkgs/libgap/spkg-install b/build/pkgs/libgap/spkg-install index 8aa3838b45a..af1af256e99 100755 --- a/build/pkgs/libgap/spkg-install +++ b/build/pkgs/libgap/spkg-install @@ -34,7 +34,7 @@ cd src echo "Applying patches..." for patch in ../patches/*.patch; do [ -r "$patch" ] || continue # Skip non-existing or non-readable patches - patch --verbose -p1 <"$patch" + patch -p1 <"$patch" if [ $? -ne 0 ]; then echo >&2 "Error applying '$patch'" exit 1 From b7bd69c8ee394ecd55e427adb90c0397f04d4299 Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Fri, 28 Feb 2014 11:22:52 +0100 Subject: [PATCH 156/163] undefine FORTIFY_SOURCE --- build/pkgs/pkgconf/spkg-install | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/build/pkgs/pkgconf/spkg-install b/build/pkgs/pkgconf/spkg-install index 938e6d9022c..fd0050a9d0a 100755 --- a/build/pkgs/pkgconf/spkg-install +++ b/build/pkgs/pkgconf/spkg-install @@ -2,7 +2,12 @@ cd src -./configure --prefix="$SAGE_LOCAL" --libdir="$SAGE_LOCAL/lib" +# Workaround for bugs with -D_FORTIFY_SOURCE=2 on antiques +export CPPFLAGS='-U_FORTIFY_SOURCE' + +./configure \ + --prefix="$SAGE_LOCAL" \ + --libdir="$SAGE_LOCAL/lib" if [ $? -ne 0 ]; then echo >&2 "Error configuring pkgconf." exit 1 From 4ff9fbb80714fee974fcce6b6ed4469e125403c7 Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Fri, 28 Feb 2014 12:16:52 +0100 Subject: [PATCH 157/163] remove nose from dependencies --- build/pkgs/pkgconfig/SPKG.txt | 4 +++- build/pkgs/pkgconfig/patches/remove_nose.patch | 10 ++++++++++ build/pkgs/pkgconfig/spkg-install | 9 +++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 build/pkgs/pkgconfig/patches/remove_nose.patch diff --git a/build/pkgs/pkgconfig/SPKG.txt b/build/pkgs/pkgconfig/SPKG.txt index 3dae19b21b2..434c0d2b79f 100644 --- a/build/pkgs/pkgconfig/SPKG.txt +++ b/build/pkgs/pkgconfig/SPKG.txt @@ -23,4 +23,6 @@ https://github.com/matze/pkgconfig == Special Update/Build Instructions == -None, standard setup.py +Standard setup.py + +* remove_nose.patch: Remove the nose dependency (not actually used) diff --git a/build/pkgs/pkgconfig/patches/remove_nose.patch b/build/pkgs/pkgconfig/patches/remove_nose.patch new file mode 100644 index 00000000000..30e008f79b4 --- /dev/null +++ b/build/pkgs/pkgconfig/patches/remove_nose.patch @@ -0,0 +1,10 @@ +diff -ur old/setup.py src/setup.py +--- old/setup.py 2013-11-06 15:14:54.000000000 +0100 ++++ src/setup.py 2014-02-28 11:33:12.718096602 +0100 +@@ -12,6 +12,5 @@ + packages=['pkgconfig'], + description="Interface Python with pkg-config", + long_description=open('README.rst').read(), +- setup_requires=['nose>=1.0'], + test_suite='test', + ) diff --git a/build/pkgs/pkgconfig/spkg-install b/build/pkgs/pkgconfig/spkg-install index cd75613d25f..85f379bd0ad 100755 --- a/build/pkgs/pkgconfig/spkg-install +++ b/build/pkgs/pkgconfig/spkg-install @@ -2,6 +2,15 @@ cd src +for patch in ../patches/*.patch; do + [ -r "$patch" ] || continue # Skip non-existing or non-readable patches + patch -p1 <"$patch" + if [ $? -ne 0 ]; then + echo >&2 "Error applying '$patch'" + exit 1 + fi +done + python setup.py install if [ $? -ne 0 ]; then echo >&2 "Error installing pkgconfig." From 1a91835f99e01395b74226e185ed88f6cf26031a Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Fri, 28 Feb 2014 03:19:07 -0800 Subject: [PATCH 158/163] Slight modifications of gap related pkgs SPKG.txt files. * Remove now git recorded old changelog. * Put patches description into subsections. --- build/pkgs/database_gap/SPKG.txt | 31 -------------- build/pkgs/gap/SPKG.txt | 2 +- build/pkgs/gap_packages/SPKG.txt | 73 +------------------------------- build/pkgs/libgap/SPKG.txt | 2 +- 4 files changed, 3 insertions(+), 105 deletions(-) diff --git a/build/pkgs/database_gap/SPKG.txt b/build/pkgs/database_gap/SPKG.txt index 0b228e55048..39e1aa5c31b 100644 --- a/build/pkgs/database_gap/SPKG.txt +++ b/build/pkgs/database_gap/SPKG.txt @@ -31,34 +31,3 @@ Copy the following databases out the gap source tarball: * trans See also the spkg-src script. -== Changelog == - -=== gap_packages-4.6.5 (Volker Braun, 5 October 2013) === - * Update to latest upstream version - * Added spkg-src - * Moved to new git workflow. - -=== gap_packages-4.6.4 (Volker Braun, 3 June 2013) === - * Update to latest upstream version - -=== database_gap-4.6.3 (Volker Braun, 25 April 2013) === - * Update to latest upstream version - -=== database_gap-4.5.7 (Volker Braun, 20 December 2012) === - * Update to latest upstream version - -=== database_gap-4.5.6 (Volker Braun, 22 September 2012) === - * Update to latest upstream version - -=== database_gap-4.5.5 (Volker Braun, 26 August 2012) === - * Update to latest upstream version - -=== 4.4.12.p1 (John Palmieri, 20 March 2012) === - * cleaned up spkg-install, made it work following the deletion of the - "newest_version" script (trac #10492). - -=== 4.4.12.p0 (2010.03.17 Dmitrii Pasechnik) === - * fixed this file - -=== 4.4.12.p0 (2010.03.15 Dmitrii Pasechnik) === - * made spkg-install Solaris-compatible diff --git a/build/pkgs/gap/SPKG.txt b/build/pkgs/gap/SPKG.txt index c8197db6720..664b3fd6650 100644 --- a/build/pkgs/gap/SPKG.txt +++ b/build/pkgs/gap/SPKG.txt @@ -50,7 +50,7 @@ update GAP, please also update and use the spkg-src script. Since the (pre-)built HTML documentation is currently included, I've commented out some lines in that part of `spkg-install`. -leif -The following patches need to be applied: +=== Patches === * writeandcheck.patch: fix infinite loop in writeandcheck() when writing an error message fails. diff --git a/build/pkgs/gap_packages/SPKG.txt b/build/pkgs/gap_packages/SPKG.txt index 261b107aef8..546bc0b76da 100644 --- a/build/pkgs/gap_packages/SPKG.txt +++ b/build/pkgs/gap_packages/SPKG.txt @@ -28,78 +28,7 @@ The crystallographic group packages are untested/untestable. They rely on polymake and the dependency "cryst" is missing. This needs to be cleaned up. -== Changelog == - -=== gap_packages-4.6.5 (Volker Braun, 5 October 2013) === - * Deleted the braid gap package, its not in upstream and we have our - own braid implementation. - * Added spkg-src - * Moved to new git workflow. - -=== gap_packages-4.6.4.p1 (Volker Braun, 19 July 2013) === - * Trac #14909: Add polycyclic, Alnuth-3.0.0, autpgrp as new - dependencies. Removed reference to HAPprime which isn't included. - -=== gap_packages-4.6.4 (Volker Braun, 3 June 2013) === - * No changes to the packages we ship - -=== gap_packages-4.6.3 (Volker Braun, 25 April 2013) === - * Update to latest gap version: ctbllib, Hap1.10, laguna, sonata - -=== gap_packages-4.5.7 (Volker Braun, 20 December 2012) === - * Update to latest gap version, none of the contained packages changed - -=== gap_packages-4.5.6 (Volker Braun, 22 September 2012) === - * Update to latest upstream version - -=== gap_packages-4.5.5 (Volker Braun, 26 August 2012) === - * Update to latest upstream version - * Forked braid-1.2 to fix a function name clash - -=== gap_packages-4.4.12.p1 (Jeroen Demeyer, 27 March 2012) === - * Trac #12758: do not use "newest_version" in spkg-install. This is - needed since "newest_version" was deleted in #10492. - * Clean up spkg-install: use a for loop to copy packages. - -=== gap_packages-4.4.12.p0 (Dima Pasechnik, 17 March 2010) === - * fixed a GNU-ism in spkg-install, that made in break on Solaris 10 - * started proper version numbering. - -=== gap_packages-4.4.12_2 (Dima Pasechnik) === -bumped up design, toric and laguna packages to the latest stable revisions -stripped package directory names in src/, and appropriate places in -spkg-install, of package version numbers, to make it consistent, -and avoid changing spkg-install in the future unnecessarily. - -=== gap_packages-4.4.10_3 (Michael Abshoff) === - * fix "implausibly old time stamp 1969-12-31 16:00:00" - -=== gap_packages-4.4.10_2 === - -NOTES (Added by William Stein): - - grape -- it hardcodes cc as compiler, which of course doesn't work. -I've changed to hardcode gcc as compiler, which is more likely to work. - -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -Prepared by David Joyner (2008-24-07) - -This directory contains several "official" and "undeposited" -GAP packages available from -http://www.gap-system.org/Packages/packages.html. They are -all released under the GPL with the following exception: -(*) grape contains Brendon McKay's nauty program. - -To load a package, for example grape, into SAGE type - -sage: gap('LoadPackage("grape")') - -All these packages come with documentation in the -doc or htm subdirectory (e.g., for grape, it would be in -SAGEHOME/local/lib/gap-4.4.12/pkg/grape/htm). After loading all -the packages, you can type gap_reset_workspace() -so you don't have to reload them again. +== Notes == A brief description of each package follows: diff --git a/build/pkgs/libgap/SPKG.txt b/build/pkgs/libgap/SPKG.txt index 97bf50b5aac..28794b8aa95 100644 --- a/build/pkgs/libgap/SPKG.txt +++ b/build/pkgs/libgap/SPKG.txt @@ -40,6 +40,6 @@ though. This scrip parses the GAP sources, identifies global identifiers, and adds a libGAP_ prefix to them to avoid symbol namespace collisions in Sage. -Patches: +=== Patches === * sparc_segfault.patch: See the GAP spkg. From 0efa88589d7a37adda4a63a16d58d55647848a5d Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Fri, 28 Feb 2014 12:24:34 +0100 Subject: [PATCH 159/163] poison proxy environment variables --- src/bin/sage-spkg | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/bin/sage-spkg b/src/bin/sage-spkg index 9f20d312a70..1a2d014081f 100755 --- a/src/bin/sage-spkg +++ b/src/bin/sage-spkg @@ -664,6 +664,14 @@ echo "****************************************************" rm -f "$SAGE_SPKG_INST/$PKG_BASE-"* +################################################################## +# Poison the proxy variable to forbid downloads in spkg-install +################################################################## +export http_proxy=http://192.0.2.0:5187/ +export https_proxy=$http_proxy +export ftp_proxy=$http_proxy +export rsync_proxy=$http_proxy + ################################################################## # Actually install ################################################################## From 248179a4efad11c09d83625ea3a8820c3701f540 Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Fri, 28 Feb 2014 15:04:53 +0100 Subject: [PATCH 160/163] Do not hardcode the non-posix install program --- build/pkgs/pkgconf/SPKG.txt | 2 +- build/pkgs/pkgconf/patches/install.patch | 27 ++++++++++++++++++++++++ build/pkgs/pkgconf/spkg-install | 9 ++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 build/pkgs/pkgconf/patches/install.patch diff --git a/build/pkgs/pkgconf/SPKG.txt b/build/pkgs/pkgconf/SPKG.txt index c5b7ee75145..dd194b0214e 100644 --- a/build/pkgs/pkgconf/SPKG.txt +++ b/build/pkgs/pkgconf/SPKG.txt @@ -23,4 +23,4 @@ https://github.com/pkgconf/pkgconf == Special Update/Build Instructions == -None, standard autotools-based project. +* install.patch: Use install script from AC_PROG_INSTALL diff --git a/build/pkgs/pkgconf/patches/install.patch b/build/pkgs/pkgconf/patches/install.patch new file mode 100644 index 00000000000..b659812df29 --- /dev/null +++ b/build/pkgs/pkgconf/patches/install.patch @@ -0,0 +1,27 @@ +diff --git a/Makefile.in b/Makefile.in +index 7a1f42a..101044e 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -11,6 +11,7 @@ system_libdir = @SYSTEM_LIBDIR@ + pkgconfigdir = @PKGCONFIGDIR@ + + CC = @CC@ ++INSTALL = @INSTALL@ + PROG = pkgconf@EXEEXT@ + SRCS = main.c cache.c pkg.c bsdstubs.c getopt_long.c fragment.c argvsplit.c fileio.c tuple.c dependency.c queue.c + OBJS = ${SRCS:.c=.o} +@@ -30,11 +31,11 @@ clean: + + install: + mkdir -p $(DESTDIR)$(bindir) +- install -c -m755 $(PROG) $(DESTDIR)$(bindir)/$(PROG) ++ @INSTALL_PROGRAM@ $(PROG) $(DESTDIR)$(bindir)/$(PROG) + mkdir -p $(DESTDIR)$(datarootdir)/aclocal +- install -c -m644 $(srcdir)/pkg.m4 $(DESTDIR)$(datarootdir)/aclocal/pkg.m4 ++ @INSTALL_DATA@ $(srcdir)/pkg.m4 $(DESTDIR)$(datarootdir)/aclocal/pkg.m4 + mkdir -p $(DESTDIR)$(MANDIR) +- install -c -m644 $(srcdir)/pkgconf.1 $(DESTDIR)$(MANDIR)/pkgconf.1 ++ @INSTALL_DATA@ $(srcdir)/pkgconf.1 $(DESTDIR)$(MANDIR)/pkgconf.1 + + check: $(PROG) + $(SHELL) tests/run.sh ./$(PROG) diff --git a/build/pkgs/pkgconf/spkg-install b/build/pkgs/pkgconf/spkg-install index fd0050a9d0a..97db67359fa 100755 --- a/build/pkgs/pkgconf/spkg-install +++ b/build/pkgs/pkgconf/spkg-install @@ -2,6 +2,15 @@ cd src +for patch in ../patches/*.patch; do + [ -r "$patch" ] || continue # Skip non-existing or non-readable patches + patch -p1 <"$patch" + if [ $? -ne 0 ]; then + echo >&2 "Error applying '$patch'" + exit 1 + fi +done + # Workaround for bugs with -D_FORTIFY_SOURCE=2 on antiques export CPPFLAGS='-U_FORTIFY_SOURCE' From 9caae61b7b600ce4d836f4dea650d1fdc8c36a83 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Fri, 28 Feb 2014 06:24:11 -0800 Subject: [PATCH 161/163] Prevent python from using system hg and svn during its installation. --- build/pkgs/python/spkg-install | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build/pkgs/python/spkg-install b/build/pkgs/python/spkg-install index 43e27ec7a7c..a2a5995c934 100755 --- a/build/pkgs/python/spkg-install +++ b/build/pkgs/python/spkg-install @@ -16,6 +16,9 @@ fi unset PYTHONHOME unset PYTHONPATH +# Prevent use of the system hg and svn as it might make the installation fail +export HAS_HG=no +export SVNVERSION=no cd src From 80a1ca14672718d4e4a12a4d6c2fa36eb44610eb Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Fri, 28 Feb 2014 17:41:54 +0100 Subject: [PATCH 162/163] fix incorrect permissions for install-sh --- build/pkgs/pkgconf/spkg-install | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build/pkgs/pkgconf/spkg-install b/build/pkgs/pkgconf/spkg-install index 97db67359fa..6426feb067d 100755 --- a/build/pkgs/pkgconf/spkg-install +++ b/build/pkgs/pkgconf/spkg-install @@ -2,6 +2,9 @@ cd src +# workaround for incorrect permissions, see Trac #15742 +chmod 755 install-sh + for patch in ../patches/*.patch; do [ -r "$patch" ] || continue # Skip non-existing or non-readable patches patch -p1 <"$patch" From ccab9854bf85180a261d71a8adc103d4c1f26342 Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Mon, 3 Mar 2014 16:05:18 +0100 Subject: [PATCH 163/163] Updated Sage version to 6.2.beta3 --- VERSION.txt | 2 +- build/pkgs/configure/checksums.ini | 6 +++--- build/pkgs/configure/package-version.txt | 2 +- src/bin/sage-banner | 2 +- src/bin/sage-version.sh | 4 ++-- src/sage/version.py | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/VERSION.txt b/VERSION.txt index 386a587f11e..b4f13cd9653 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -Sage version 6.2.beta2, released 2014-02-15 +Sage version 6.2.beta3, released 2014-03-03 diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index 641d5ea226f..64a2323e71c 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,4 +1,4 @@ tarball=configure-VERSION.tar.gz -sha1=dc1ef3079014c19d7af48bf628a275b3dbcf2e11 -md5=1ab9d75a4babc66433730e4d95c24843 -cksum=4250141818 +sha1=777ec5d1185d5d1cd4a7b5fee72707a6b984eba1 +md5=24483846c41e48038714fac97981c25b +cksum=246370664 diff --git a/build/pkgs/configure/package-version.txt b/build/pkgs/configure/package-version.txt index 48082f72f08..8351c19397f 100644 --- a/build/pkgs/configure/package-version.txt +++ b/build/pkgs/configure/package-version.txt @@ -1 +1 @@ -12 +14 diff --git a/src/bin/sage-banner b/src/bin/sage-banner index 849195721a6..4f53510bbe1 100644 --- a/src/bin/sage-banner +++ b/src/bin/sage-banner @@ -1,5 +1,5 @@ ┌────────────────────────────────────────────────────────────────────┐ -│ Sage Version 6.2.beta2, Release Date: 2014-02-15 │ +│ Sage Version 6.2.beta3, Release Date: 2014-03-03 │ │ Type "notebook()" for the browser-based notebook interface. │ │ Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ diff --git a/src/bin/sage-version.sh b/src/bin/sage-version.sh index b87ea6672c6..4df6d92e18a 100644 --- a/src/bin/sage-version.sh +++ b/src/bin/sage-version.sh @@ -1,4 +1,4 @@ # Sage version information for shell scripts # This file is auto-generated by the sage-update-version script, do not edit! -SAGE_VERSION='6.2.beta2' -SAGE_RELEASE_DATE='2014-02-15' +SAGE_VERSION='6.2.beta3' +SAGE_RELEASE_DATE='2014-03-03' diff --git a/src/sage/version.py b/src/sage/version.py index 5fdba14fc04..212d6a0eebe 100644 --- a/src/sage/version.py +++ b/src/sage/version.py @@ -1,4 +1,4 @@ # Sage version information for Python scripts # This file is auto-generated by the sage-update-version script, do not edit! -version = '6.2.beta2' -date = '2014-02-15' +version = '6.2.beta3' +date = '2014-03-03'

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