diff --git a/Makefile b/Makefile index b99e775ed18..254c36cb359 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ logs: mkdir -p $@ build: logs configure - cd build && \ + +cd build && \ "../$(PIPE)" \ "env SAGE_PARALLEL_SPKG_BUILD='$(SAGE_PARALLEL_SPKG_BUILD)' ./install all 2>&1" \ "tee -a ../logs/install.log" diff --git a/README.txt b/README.txt index eb614bd8188..b4bbee9e734 100644 --- a/README.txt +++ b/README.txt @@ -75,12 +75,23 @@ Installation Guide: "Precise"), you need the dpkg-dev package. OS X: Xcode. Make sure you have installed the most recent version - of Xcode. For pre-Lion versions of OS X, you can download Xcode - from http://developer.apple.com/downloads/. For OS X Lion, you can - install it using the App Store. With Xcode 4.3 or later, you need - to install the "Command Line Tools": from the File menu, choose - "Preferences", then the "Downloads" tab, and then "Install" the - Command Line Tools. + of Xcode. With recent versions of OS X (OS X Lion or later), you + can install Xcode for free from the App Store. For pre-Lion + versions of OS X, you can download Xcode from + http://developer.apple.com/downloads/. + + With OS X, you also need to install the "command line tools". When + using OS X Mavericks, after installing Xcode, run this command from + a terminal window: + + xcode-select --install + + Then click "Install" in the pop-up window. + + When using OS X Mountain Lion or earlier, you need to install the + command line tools from Xcode: run Xcode; then from the File + menu, choose "Preferences", then the "Downloads" tab, and then + "Install" the Command Line Tools. Other platforms: See detailed instructions below. diff --git a/VERSION.txt b/VERSION.txt index bcf308fd083..0f3dc25e446 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -Sage version 6.1.rc0, released 2014-01-25 +Sage version 6.2.beta1, released 2014-02-07 diff --git a/build/deps b/build/deps index 0764bf72b02..b27ddb3ff9e 100644 --- a/build/deps +++ b/build/deps @@ -265,9 +265,6 @@ $(INST)/$(LINBOX): $(INST)/$(MPIR) $(INST)/$(NTL) $(INST)/$(GIVARO) \ $(INST)/$(IML): $(INST)/$(MPIR) $(INST)/$(GSL) $(INST)/$(ATLAS) +$(PIPE) "$(SAGE_SPKG) $(IML) 2>&1" "tee -a $(SAGE_LOGS)/$(IML).log" -$(INST)/$(ECLIB): $(INST)/$(MPIR) $(INST)/$(PARI) $(INST)/$(NTL) - +$(PIPE) "$(SAGE_SPKG) $(ECLIB) 2>&1" "tee -a $(SAGE_LOGS)/$(ECLIB).log" - $(INST)/$(GENUS2REDUCTION): $(INST)/$(PARI) +$(PIPE) "$(SAGE_SPKG) $(GENUS2REDUCTION) 2>&1" "tee -a $(SAGE_LOGS)/$(GENUS2REDUCTION).log" @@ -395,6 +392,9 @@ $(INST)/$(FLINTQS): $(INST)/$(MPIR) $(INST)/$(FLINT): $(INST)/$(MPIR) $(INST)/$(MPFR) $(INST)/$(NTL) +$(PIPE) "$(SAGE_SPKG) $(FLINT) 2>&1" "tee -a $(SAGE_LOGS)/$(FLINT).log" +$(INST)/$(ECLIB): $(INST)/$(PARI) $(INST)/$(NTL) $(INST)/$(FLINT) + +$(PIPE) "$(SAGE_SPKG) $(ECLIB) 2>&1" "tee -a $(SAGE_LOGS)/$(ECLIB).log" + $(INST)/$(M4RI): $(INST)/$(LIBPNG) +$(PIPE) "$(SAGE_SPKG) $(M4RI) 2>&1" "tee -a $(SAGE_LOGS)/$(M4RI).log" @@ -476,8 +476,6 @@ $(INST)/csage: $(INST)/$(SCONS) \ $(INST)/$(MPIR) \ $(INST)/$(NTL) \ $(INST)/$(PARI) \ - $(INST)/$(POLYBORI) \ - $(INST)/$(PYNAC) \ $(INST)/$(PYTHON) if [ -z "$$SAGE_INSTALL_FETCH_ONLY" ]; then \ cd $(SAGE_SRC) && source bin/sage-env && cd c_lib && \ diff --git a/build/install b/build/install index 7c4ac43169f..f0aba7e3ae3 100755 --- a/build/install +++ b/build/install @@ -310,9 +310,10 @@ fi # Create $SAGE_ROOT/build/Makefile starting from build/deps ############################################################################### -exec 3>Makefile +# Trac #15624: use file descriptor 5 since make uses 3 and 4 +exec 5>Makefile -cat >&3 <&5 <&3 "SHELL = `command -v bash`" -echo >&3 +echo >&5 "SHELL = `command -v bash`" +echo >&5 # If the user (or the Makefile) has set SAGE_PARALLEL_SPKG_BUILD=no, # then turn off parallel building: disable just building multiple # packages at the same time. Individual packages can still be built # in parallel by specifying '-j' in $MAKE. if [ "${SAGE_PARALLEL_SPKG_BUILD:-yes}" = no ]; then - echo ".NOTPARALLEL:" >&3 - echo "" >&3 + echo ".NOTPARALLEL:" >&5 + echo "" >&5 fi # Usage: newest_version $pkg @@ -349,7 +350,7 @@ newest_version() { fi } -cat >&3 <&5 <&3 -n 'TOOLCHAIN =' +echo >&5 -n 'TOOLCHAIN =' if [ "$SAGE_INSTALL_CCACHE" = yes ]; then - echo >&3 -n ' $(INST)/ccache' + echo >&5 -n ' $(INST)/ccache' fi if [ "$need_to_install_gcc" = yes ]; then - echo >&3 -n ' $(INST)/$(GCC)' + echo >&5 -n ' $(INST)/$(GCC)' # Use this option for the prereq configure script, such that it # will skip all compiler checks. export PREREQ_OPTIONS="--disable-compiler-checks $PREREQ_OPTIONS" fi -echo >&3 +echo >&5 -echo >&3 'SCRIPT_SOURCES = \' +echo >&5 'SCRIPT_SOURCES = \' for file in "$SAGE_SRC/bin/"*; do - echo >&3 " \$(SAGE_SRC)${file#$SAGE_SRC} \\" + echo >&5 " \$(SAGE_SRC)${file#$SAGE_SRC} \\" done -echo >&3 -echo >&3 'SCRIPTS = \' +echo >&5 +echo >&5 'SCRIPTS = \' for file in "$SAGE_SRC/bin/"*; do - echo >&3 " \$(SAGE_LOCAL)${file#$SAGE_SRC} \\" + echo >&5 " \$(SAGE_LOCAL)${file#$SAGE_SRC} \\" done -echo >&3 -echo >&3 'EXTCODE_SOURCES = \' +echo >&5 +echo >&5 'EXTCODE_SOURCES = \' for file in `find "$SAGE_SRC"/ext -type f`; do - echo >&3 " \$(SAGE_SRC)${file#$SAGE_SRC} \\" + echo >&5 " \$(SAGE_SRC)${file#$SAGE_SRC} \\" done -echo >&3 -echo >&3 'EXTCODE = \' +echo >&5 +echo >&5 'EXTCODE = \' for file in `find "$SAGE_SRC"/ext -type f`; do - echo >&3 " \$(SAGE_EXTCODE)${file#$SAGE_SRC/ext} \\" + echo >&5 " \$(SAGE_EXTCODE)${file#$SAGE_SRC/ext} \\" done -echo >&3 +echo >&5 -cat >&3 <&5 <&3 <&3 <&5 <&3 <&3 +cat "$SAGE_ROOT/build/deps" >&5 # Close the Makefile -exec 3>&- +exec 5>&- ############################################################################### # Skip the rest if nothing to do (i.e., to [re]build). diff --git a/build/pkgs/atlas/SPKG.txt b/build/pkgs/atlas/SPKG.txt index 5b5a7986c4b..86292be1f1f 100644 --- a/build/pkgs/atlas/SPKG.txt +++ b/build/pkgs/atlas/SPKG.txt @@ -24,8 +24,19 @@ Solaris, but should also work on OSX and Cygwin. * Python -== Build Instructions/Notes == +== Special Update/Build Instructions == + + * src/lapack-x.y.z.tgz: The netlib lapack tarball. If you update this, + make sure you also update the LAPACK_TARBALL variable in spkg-install. + * src/ATLAS-lib: We are using a dummy autotools/libtools project + to repack the static ATLAS libraries into shared libraries. + * src/ARCHS: We ship some archdef tarballs to speed ATLAS build. + * spkg-install: If you update atlas to a new version make sure that the + ATLAS_OSTYPE, ATLAS_MACHTYPE, and ATLAS_ISAEXT variables in + spkg-install remain in sync with atlas' CONFIG/include/atlconf.h + * The package is never installed on OS X, unless you set SAGE_ATLAS_ARCH. +=== Patches === * patches/archinfo_linux.c.patch: Fix Itanium2 support on modern RHEL 5 and SLES 10 systems. * patches/probe_comp.c.patch: work around -m64 issue on Itanium2 @@ -41,19 +52,8 @@ Solaris, but should also work on OSX and Cygwin. for details. * patches/glibc_scanf_workaround.patch: Workaround for the scanf bug in glibc-2.18 that breaks the atlas auto-tuning system. - * lapack-x.y.z.tgz: The netlib lapack tarball. If you update this, - make sure you also update the LAPACK_TARBALL variable in - spkg-install. - * If you update atlas to a new version make sure that the - ATLAS_OSTYPE, ATLAS_MACHTYPE, and ATLAS_ISAEXT variables in - spkg-install remain in sync with atlas' CONFIG/include/atlconf.h - * The package is never installed on Cygwin or OS X, unless you set - SAGE_ATLAS_ARCH. - -We are using a dummy autotools/libtools project (see -src/ATLAS-lib) to repack the static ATLAS libraries into shared -libraries. +=== Configuration === The package can be configured via three environment variables: * SAGE_ATLAS_LIB=path @@ -95,310 +95,3 @@ The package can be configured via three environment variables: * If SAGE_ATLAS_SAVE_ARCHDEF = is given, then a new archdef file is created and saved to the given path. -== ChangeLog == - -=== atlas-3.10.1.p7, lapack-3.4.2 (Jean-Pierre Flori, 25 November 2013) === - * Trac #14410: Let ATLAS build and install shared libraries on Cygwin. - * Bunch of modifications to the autotools project generating shared libraries - so that it does not invoke libtool on Cygwin. - * Fix a bug in spkg-install. - * Cleanup spkg-check. - -=== atlas-3.10.1.p6, lapack-3.4.2 (Volker Braun, 11 October 2013) === - * Trac #15270: Do not give up if the upstream shared library build - fails - * Solaris / ZFS fixes - -=== atlas-3.10.1.p5, lapack-3.4.2 (Volker Braun, 30 August 2013) === - * Trac #15045: Another workaround for shared library bug that does - not involve static libraries - -=== atlas-3.10.1.p4, lapack-3.4.2 (Volker Braun, 14 August 2013) === - * Trac #15045: Workaround for shared library bug, - non-deterministically affecting some old platforms - -=== atlas-3.10.1.p3, lapack-3.4.2 (Volker Braun, 6 July 2013) === - * Trac #14781: move untracked files to src/ in preparation for git - * Added spkg-src to populate the src/ directory - * Remove the archdef_dir variable, we already copy our own archdefs into src/ - * Trac #14754: Match other isa_ext level to existing archdefs too, if possible. - -=== atlas-3.10.1.p2, lapack-3.4.2 (Jeroen Demeyer, 18 June 2013) === - * Trac #14754: Do not use 3DNow in configure_base(). - * Use "None" instead of the empty tuple for isa_ext. - * Use $FC instead of sage_fortran in configuration.py. - * Apply patches at -p1 level like all other packages. - -=== atlas-3.10.1.p1, lapack-3.4.2 (Volker Braun, Jean-Pierre Flori, 7 June 2013) === - * Trac #14699: Install ATLAS header files - -=== atlas-3.10.1.p0, lapack-3.4.2 (Jean-Pierre Flori, 26 February 2013) === - * Trac #10508: Update ATLAS to version 3.10.1 and LAPACK to version 3.4.2. - * Removed patches integrated upstream. - * Add shell.patch to correctly build LAPACK on Solaris. - * Replace os.system() by subprocess.call() - -=== atlas-3.10.0.p1, lapack-3.4.1 (Volker Braun, September 20 2012) === - * Trac #10508: Fix for long file names. - * Disable tuning on Itanium, go straight to "fast". - -=== atlas-3.10.0.p0, lapack-3.4.1 (Jeroen Demeyer, 19 September 2012) === - * Trac #10508: re-run autotools in patches/ATLAS-lib to fix timestamps. - * Re-download sources to fix timestamps. - * Remove backup files (ending with ~). - * Uncompress lapack tarball, yielding a smaller spkg. - -=== atlas-3.10.0, lapack-3.4.1 (Volker Braun, July 11 2012) === - * Stable release - * Now OSX and Cygwin will attempt to build if SAGE_ATLAS_ARCH is set. - -=== atlas-3.9.85, lapack-3.4.1 (Volker Braun, July 9 2012) === - * Should be identical to the next stable release - -=== atlas-3.9.84, lapack-3.4.1 (Volker Braun, July 8 2012) === - * Update to the newest upstream version - * flush before os.system() - * completely new shared library build system - -=== atlas-3.9.80, lapack-3.4.1 (Volker Braun, June 23rd 2012) === - * Update to the newest upstream version - * remove obsoleted patches - -=== atlas-3.9.68, lapack-3.4.0 (Volker Braun, Jeroen Demeyer, March 6th 2012) === - * In src/CONFIG/src/Makefile, change "rm -f" to "rm -rf" in - the "clean" rule to support Xcode creating directories like - xspew.dSYM. - * update to latest upstream version - * Make atlas respect CC environment variable. - * Cygwin library name fix. - -=== atlas-3.9.32, lapack-3.3.0 (Volker Braun, December 5th 2010) === - * Introduce the SAGE_ATLAS_ARCH environment variable. - * Update to the developer release atlas-3.9.32 according to advice of - Clint Whaley (ATLAS developer). - * Now includes LAPACK source tarball. - -=== atlas-3.8.4.p1 (Jeroen Demeyer, 15 January 2012) === - * Trac #12312: Completely disable parallel make everywhere - -=== atlas-3.8.4 (Volker Braun, 15 June 2011) === - * Trac #10226: Rewrite spkg-install in Python - * Updated to new upstream stable version. - * Removed SpewMakeInc.c.patch as it is included in new upstream - version. - * Rediffed other patches. - * Cygwin library name fix. - -=== atlas-3.8.3.p18 (Mariah Lenox, 11 May 2011) === - * Make atlas respect CC environment variable. - -=== atlas-3.8.3.p17 (Volker Braun, November 5th 2010) === - * Rewrite the spkg-install script in pure python. Introduce the - SAGE_ATLAS_ARCH environment variable. - -=== atlas-3.8.3.p16 (John Palmieri, September 19th 2010) === - * Make spkg-check work when using SAGE_ATLAS_LIB: if SAGE_ATLAS_LIB - is set, skip the self-tests. - -=== atlas-3.8.3.p15 (David Kirkby, September 6th 2010) === - * Make SAGE_ATLAS_LIB use static libraries on all platforms, - as building two shared libraries often fails on Linux, and - messes things up on Solaris. The static library is less hassle - all around. Worth noting is that the ATLAS package only builds - the static library and Wolfram Research only ship the static - library with Mathematica, despite they usually use shared - libraries. To ensure full compatibility with a fresh build - of ATLAS, the symbolic links are created for the shared libraries too. - The links will fail to be created if the shared libraries do not exist, - but will not cause any extra problems. - * Update the list of dependencies to include Python and Lapack (see - spkg/deps) - * Note that the ATLAS build process could be made much quicker if its - depenancy on Python was removed. Since the amount of Python code is - very small compared to the bash code, this seems logical to do at - a later date. The Fortran package would need the same change - but again - the amount of Python in that is trivial. - * Add a note that make-correct-shared.sh is badly named, as it often fails. - * Remove the OS X specific code from make-correct-shared.sh, as ATLAS is - never installed on OS X - see the spkg-install-script. - -=== atlas-3.8.3.p14 (David Kirkby, August 10th 2010) === - * #9508 Fix multiple ATLAS build issues on Solaris 10 and OpenSolaris. - * Remove an inaccurate comment from spkg-install-script - about the number of shred libraries built. - * Build shared libraries libatlas.so libf77blas.so libcblas.so - on Solaris properly using the Sun linker. The library - liblapack.so is NOT built as it causes problems with R. - * Delete liblapack.so in make_correct_shared.sh on Solaris just - in case it is built by ATLAS, which does build some - libraries. (This is probably an unnecessary step, but - it's better to be safe than sorry). - * Correct linker options on 32-bit Solaris 10 or 32-bit - OpenSolaris builds on x86. These may not be optimal, but at - least they allow ATLAS to build. - * Make SPKG.txt have lines with less than 80 characters - * Fix a couple of spelling errors. - * Report whether the tests pass or fail in spkg-check. - * Report whether the timing data is collected correctly in spkg-check - -=== atlas-3.8.3.p13 (John Palmieri, June 27th, 2010) === - * #9356. Fix system_alias.py so that it works properly with Solaris: - when we build ATLAS on Solaris, we do not install liblapack.so -- - see make_correct_shared.sh. So we shouldn't test for its - existence when using SAGE_ATLAS_LIB, either. - -=== atlas-3.8.3.p12 (Jaap Spies, Februari 22th 2010) === - * #8039 For use with the Sun ld with SAGE64="yes" change ldflag - -melf_86_64 to -64 - * See also the remarks from David Kirkby on atlas-3.8.3.p5 - -=== atlas-3.8.3.p11 (Peter Jeremy, 2010-01-25)=== - * #7827: Fix atlas-3.8.3.p9 compilation on FreeBSD - * Minh Van Nguyen: patch spkg-install-script to copy - patches/SpewMakeInc.c over to src/CONFIG/src/SpewMakeInc.c - -=== atlas-3.8.3.p10 (David Kirkby, January 5th 2010) === - * replace bitwidth.py which uses 'ctypes' at that is broken - on many platforms. - -=== atlas-3.8.3.p7 (William Stein, Sept 21 2009) === - * Make this into a dummy package on Cygwin that requires lapack. - -=== atlas-3.8.3.p6 (David Kirkby, July 19th 2009) === - * Trac #6558 - This is an enhancement to trac #6276, which applies a Solaris patch - to only those based on the sun4v architecture, rather than all Solaris - machines. - * Finished off an unfinished sentance in a comment in spkg-install - -=== atlas-3.8.3.p5 (David Kirkby, June 24th 2009) === - * Made a backup of ATLAS-build/lib/Makefile to ATLAS-build/lib/Makefile.orig - * Alter the flags in ATLAS-build/lib/Makefile with those that will work if - the linker used is the Sun linker. The default Makefile makes use of the - GNU linker's flags, such as "-shared" which is not acceptable to the Sun - linker. - - The patch is only applied if the operating system is Solaris, and the - linker is not the GNU linker. The flags charged are: - -shared ==> -G - -soname ==> -h - --whole-archive ==> -z allextract - --no-whole-archive ==> -z defaultextract - - NOTES: - 1) Sun have a tool which accepts gcc flags, but calls the Sun compiler. - This patch might mess things up if that is used. Having never used the tool - it's impossible to be 100% sure of this. Anyway, that will be some time in - the future, so this patch can be removed. - - 2) The fact the linker flags are GNU specific has been reported to the ATLAS - maintainer, so they may fix this problem. In which case the patch could be - removed at a later date. - * Fixed a minor spelling mistake in this file - -=== atlas-3.8.3.p4 (David Kirkby, June 16th 2009) === - * Change GuessSmallNB() in src/tune/blas/gemm/mmsearch.c - as suggested by Clint Whaley to return 28 - on Solaris. This is ONLY A TEMPORARY FIX and once the real problem - in the function is sorted out, this fix will need to be removed. But - for now it permits ATLAS to build on a Sun T5240 with gcc-4.4.0. - -=== atlas-3.8.3.p3 (William Stein, June 2, 2009) === - * Fix so SAGE_FAT_BINARY *only* used on x86 boxes. - -=== atlas-3.8.3.p2 (William Stein, May 31, 2009) === - * Change SAGE_SIMD_MODE --> SAGE_FAT_BINARY - -=== atlas-3.8.3.p1 (Michael Abshoff, April 17th, 2009) === - * Introduce SAGE_SIMD_MODE. If set to SSE2 only use SSE1 and SSE2 - instructions (#5219) - * Detect Atom CPUs as Core2 (#5741) - * unbreak parallel make on system with "real" sh (#5742) - -=== atlas-3.8.3.p0 (William Stein, February 20, 2009) === - * implement up to 5 auto-restarts with random timeouts. - -=== atlas-3.8.3 (Michael Abshoff, February 20, 2009) === - * rebase against latest upstream (#5311) - * make ATLAS automatically restart build on tolerance error (#1641) - -=== atlas-3.8.2.p2 (Michael Abshoff, January 2nd, 2009) === - * Actually fix dynamic liblapack.so on Solaris as intended in atlas-3.8.2.p1 - * revert dumb mistake from atlas-3.8.2.p1 make_correct_shared.sh - -=== atlas-3.8.2.p1 (Michael Abshoff, January 2nd, 2009) === - * Do not create any dynamic liblapack.so on non-Linux since they break - numpy and scipy - -=== atlas-3.8.2.p0 (Michael Abshoff, January 2nd, 2009) === - * copy Make.top into the right directory - -=== atlas-3.8.2 (Michael Abshoff, January 1st, 2009) === - * update to latest upstream - * add cleaned up patches to repo - * clean up SPKG.txt some more - -=== atlas-3.8.1.p3 (Michael Abshoff, July 6th, 2008) === - * Really apply the ATLAS-3.8.1-ppc-g4-7447-detect-fix.patch - -=== atlas-3.8.1.p2 (Michael Abshoff, June 26th, 2008) === - * Complex GEMM sometimes accesses C when BETA=0 (#3290) - * Bad GEMM call causes performance drop for all architectures (#3380) - -=== atlas-3.8.1.p1 (Michael Abshoff, March 21st, 2008) === - * add Pentium D 64 bit tuning info (#2986) - -=== atlas-3.8.1.p0 (Michael Abshoff, March 19th, 2008) === - * update patch description - * Fix Itanium2 detection and work around "-m64" issue on RHEL 64 bit - -=== atlas-3.8 (Michael Abshoff, March 19th, 2008) === - * update to 3.8.1 release - * add tuning info for G4 on Linux - * add tuning and detection for Pentium D process (together with Burcin Erocal) - * clean up SPKG.txt - -=== atlas-3.8.p11 (Michael Abshoff, Feb. 2nd, 2008) === - * add pre-tuned information for Pentium M, Athlon MP - -=== atlas-3.8.p10 (Michael Abshoff, Jan. 26th, 2008) === - * exit spkg-check on Darwin (fixes #1934) - -=== atlas-3.8.p9 (Michael Abshoff, Jan. 22nd, 2008) === - * fix SAGE_ATLAS_LIB to point to the root of the ATLAS directory - * also link the headers which is the prime motivation for the change above - * Apply row-major GEMM major ATLAS errata (#1787) - -=== atlas-3.8.p8 (Josh Kantor, Jan. 19th, 2008) === - * Added optional environment variable SAGE_ATLAS_LIB. This should be a - directory that contains liblapack.so,libcblas.so, libf77blas.so, - libatlas.so. Instead of building atlas we make symbolic links to these - libraries in $SAGE_LOCAL/lib - -=== atlas-3.8.p6 (Josh Kantor, Dec. 15th, 2007) === - * check if ATLAS bailed out due to unprecise timings. This happens if the - system is too loaded. - -=== atlas-3.8.p5 (Josh Kantor, Dec. 14th, 2007) === - * introduce workaround for 32 bit userspace build on 64 bit CPUs - see #1497 - -=== atlas-3.8.p4 (Michael Abshoff, Dec. 13th, 2007) === - * disable parallel make - -=== atlas-3.8.p3 (Josh Kantor, Dec. 11th, 2007) === - * disable build on OSX for now - -=== atlas-3.8 (Josh Kantor, Nov. 28th, 2007) === - * updated to version 3.8 - * applied patch so that shared libraries are copied - * fortran wrapper uses sage_fortran - * ATLAS produces borked lapack.so which has missing symbols - * liblapack.so is around 100k while liblapack.a is 8 mb - * manually create a full liblapack.so - -=== atlas-3.7.38 (Michael Abshoff, Oct. 6th, 2007) === - * update to 3.7.38 - -=== atlas-3.7.37 (Michael Abshoff, Aug. 15th, 2007) === - * new upstream release (3.7.37), initial release - * {{{make check}}} added in spkg-check diff --git a/build/pkgs/atlas/checksums.ini b/build/pkgs/atlas/checksums.ini index e462d8fd985..d4f5ab69db9 100644 --- a/build/pkgs/atlas/checksums.ini +++ b/build/pkgs/atlas/checksums.ini @@ -1,4 +1,4 @@ tarball=atlas-VERSION.tar.bz2 -sha1=9084d7bb0580c54dd233f0b164f07f60117e029c -md5=cae064f152ab5faf0cc61bf2801463ad -cksum=4284029515 +sha1=d7a74adc654eaca6e05d0a90299fd271a5103c52 +md5=43a9a4324648ee3506d7982393b50f00 +cksum=3795128001 diff --git a/build/pkgs/atlas/package-version.txt b/build/pkgs/atlas/package-version.txt index ea4d24b7f41..dbe750311b5 100644 --- a/build/pkgs/atlas/package-version.txt +++ b/build/pkgs/atlas/package-version.txt @@ -1 +1 @@ -3.10.1.p7 +3.10.1.20140128 diff --git a/build/pkgs/atlas/spkg-install b/build/pkgs/atlas/spkg-install index 61bd7ab7212..138e663d168 100755 --- a/build/pkgs/atlas/spkg-install +++ b/build/pkgs/atlas/spkg-install @@ -179,8 +179,7 @@ for fname in glob.glob(os.path.join(PATCH_DIR,'*.patch')): assert_success(rc, bad='Applying '+fname+' failed.', good='Applied '+fname+'.') # add extra architectural defaults -# currently IA64Itan264 and x86SSE264SSE2 -cp('patches/ARCHS/*.tar.bz2', 'src/ATLAS/CONFIG/ARCHS') +cp('src/ARCHS/*.tar.bz2', 'src/ATLAS/CONFIG/ARCHS/') # hardcoded gcc in SpewMakeInc.c edit_in_place('src/ATLAS/CONFIG/src/SpewMakeInc.c') \ @@ -342,7 +341,8 @@ def configure_fast(): if conf['Intel?'] and conf['64bit?']: print('Fast configuration on Intel x86_64 compatible CPUs.') arch = 'P4E' - isa_ext = ('SSE3', 'SSE2', 'SSE1') + if not conf['CYGWIN?']: # cannot use assembly on Cygwin64 + isa_ext = ('SSE3', 'SSE2', 'SSE1') elif conf['Intel?'] and conf['32bit?']: print('Fast configuration on Intel i386 compatible CPUs.') arch = 'x86SSE2' @@ -368,7 +368,8 @@ def configure_base(): if conf['Intel?'] and conf['64bit?']: print('Generic configuration on Intel x86_64 compatible CPUs.') arch = 'x86SSE2' - isa_ext = ('SSE2', 'SSE1') + if not conf['CYGWIN?']: # cannot use assembly on Cygwin64 + isa_ext = ('SSE2', 'SSE1') elif conf['Intel?'] and conf['32bit?']: print('Generic configuration on Intel i386 compatible CPUs.') arch = 'x86x87' diff --git a/build/pkgs/atlas/spkg-src b/build/pkgs/atlas/spkg-src index 617c7a5cc42..2595f6a1d5a 100755 --- a/build/pkgs/atlas/spkg-src +++ b/build/pkgs/atlas/spkg-src @@ -5,7 +5,6 @@ if [ $# -ne 0 ]; then echo "Using tarballs from $UPSTREAM_SOURCE_DIRECTORY instead of downloading" fi - SPKG_ROOT=`pwd` set -e @@ -43,6 +42,15 @@ else fi gunzip $LAPACK +### Our archdefs ### + +if [ -z "$SAGE_ATLAS_ARCHDEFS_DIR" ]; then + echo "SAGE_ATLAS_ARCHDEFS_DIR should point to a directory containing the archedef tarballs." + exit 1 +fi + +mkdir ARCHS +cp -p "$SAGE_ATLAS_ARCHDEFS_DIR"/*.tar.bz2 ARCHS/ ### Our shared library hack ### diff --git a/build/pkgs/autotools/Makefile.build b/build/pkgs/autotools/Makefile.build new file mode 100644 index 00000000000..31087806b35 --- /dev/null +++ b/build/pkgs/autotools/Makefile.build @@ -0,0 +1,863 @@ +######################################################################## +# This file is automatically generated by ./spkg-write-makefile +######################################################################## + +all: autoconf-all automake-all libtool-all tools-all + +######################################################################## + +tools-all: $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/help2man + +$(SAGE_LOCAL)/bin/makeinfo: $(SRC)/texinfo-4.13 + if [ "$$UNAME" = CYGWIN ] ; then cp -p "$(SRC)/../install-info.exe.manifest" "$(SAGE_LOCAL)/bin" ; fi + cd $< && ./configure --prefix="$(SAGE_LOCAL)" && $(MAKE) && $(MAKE) install + +$(SAGE_LOCAL)/bin/m4: $(SRC)/m4-1.4.17 $(SAGE_LOCAL)/bin/makeinfo + cd $< && ./configure --prefix="$(SAGE_LOCAL)" && $(MAKE) && $(MAKE) install + +$(SAGE_LOCAL)/bin/help2man: $(SRC)/help2man-1.43.3 $(SAGE_LOCAL)/bin/makeinfo + cd $< && ./configure --prefix="$(SAGE_LOCAL)" && $(MAKE) && $(MAKE) install + +######################################################################## + +# Extract sources from git repository serially +autoconf-2.13.rc1/.tarball-version: + ( cd $(SRC)/autoconf && git archive --format=tar --prefix=autoconf-2.13.rc1/ autoconf-2-13-rc1 ) | tar xf - + echo 2.13.rc1 >autoconf-2.13.rc1/.tarball-version + +$(SAGE_LOCAL)/autoconf-2.13.rc1: autoconf-2.13.rc1/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo + export MAKE='$(MAKE) -j1' ; \ + cd autoconf-2.13.rc1 && touch autoupdate.sh && \ + ./configure --prefix="$(SAGE_LOCAL)/autoconf-2.13.rc1" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf autoconf-2.13.rc1/* + +# Extract sources from git repository serially +autoconf-2.57/.tarball-version: autoconf-2.13.rc1/.tarball-version + ( cd $(SRC)/autoconf && git archive --format=tar --prefix=autoconf-2.57/ AUTOCONF-2.57 ) | tar xf - + echo 2.57 >autoconf-2.57/.tarball-version + +$(SAGE_LOCAL)/autoconf-2.57: autoconf-2.57/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/bin/help2man + export MAKE='$(MAKE) -j1' ; \ + cd autoconf-2.57 && \ + ./configure --prefix="$(SAGE_LOCAL)/autoconf-2.57" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf autoconf-2.57/* + +# Extract sources from git repository serially +autoconf-2.58/.tarball-version: autoconf-2.57/.tarball-version + ( cd $(SRC)/autoconf && git archive --format=tar --prefix=autoconf-2.58/ AUTOCONF-2.58 ) | tar xf - + echo 2.58 >autoconf-2.58/.tarball-version + +$(SAGE_LOCAL)/autoconf-2.58: autoconf-2.58/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/bin/help2man + export MAKE='$(MAKE) -j1' ; \ + cd autoconf-2.58 && \ + ./configure --prefix="$(SAGE_LOCAL)/autoconf-2.58" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf autoconf-2.58/* + +# Extract sources from git repository serially +autoconf-2.59/.tarball-version: autoconf-2.58/.tarball-version + ( cd $(SRC)/autoconf && git archive --format=tar --prefix=autoconf-2.59/ AUTOCONF-2.59 ) | tar xf - + echo 2.59 >autoconf-2.59/.tarball-version + +$(SAGE_LOCAL)/autoconf-2.59: autoconf-2.59/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/bin/help2man + export MAKE='$(MAKE) -j1' ; \ + cd autoconf-2.59 && \ + ./configure --prefix="$(SAGE_LOCAL)/autoconf-2.59" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf autoconf-2.59/* + +# Extract sources from git repository serially +autoconf-2.60/.tarball-version: autoconf-2.59/.tarball-version + ( cd $(SRC)/autoconf && git archive --format=tar --prefix=autoconf-2.60/ AUTOCONF-2.60 ) | tar xf - + echo 2.60 >autoconf-2.60/.tarball-version + +$(SAGE_LOCAL)/autoconf-2.60: autoconf-2.60/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/bin/help2man + export MAKE='$(MAKE) -j1' ; \ + cd autoconf-2.60 && \ + ./configure --prefix="$(SAGE_LOCAL)/autoconf-2.60" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf autoconf-2.60/* + +# Extract sources from git repository serially +autoconf-2.61/.tarball-version: autoconf-2.60/.tarball-version + ( cd $(SRC)/autoconf && git archive --format=tar --prefix=autoconf-2.61/ AUTOCONF-2.61 ) | tar xf - + echo 2.61 >autoconf-2.61/.tarball-version + +$(SAGE_LOCAL)/autoconf-2.61: autoconf-2.61/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/bin/help2man + export MAKE='$(MAKE) -j1' ; \ + cd autoconf-2.61 && \ + ./configure --prefix="$(SAGE_LOCAL)/autoconf-2.61" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf autoconf-2.61/* + +# Extract sources from git repository serially +autoconf-2.62/.tarball-version: autoconf-2.61/.tarball-version + ( cd $(SRC)/autoconf && git archive --format=tar --prefix=autoconf-2.62/ v2.62 ) | tar xf - + echo 2.62 >autoconf-2.62/.tarball-version + +$(SAGE_LOCAL)/autoconf-2.62: autoconf-2.62/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/bin/help2man $(SAGE_LOCAL)/autoconf-2.60 $(SAGE_LOCAL)/automake-1.10 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.60 ; \ + export AUTOMAKE_VERSION=1.10 ; \ + cd autoconf-2.62 && autoreconf -i -I m4 && \ + ./configure --prefix="$(SAGE_LOCAL)/autoconf-2.62" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf autoconf-2.62/* + +# Extract sources from git repository serially +autoconf-2.63/.tarball-version: autoconf-2.62/.tarball-version + ( cd $(SRC)/autoconf && git archive --format=tar --prefix=autoconf-2.63/ v2.63 ) | tar xf - + echo 2.63 >autoconf-2.63/.tarball-version + +$(SAGE_LOCAL)/autoconf-2.63: autoconf-2.63/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/bin/help2man $(SAGE_LOCAL)/autoconf-2.60 $(SAGE_LOCAL)/automake-1.10 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.60 ; \ + export AUTOMAKE_VERSION=1.10 ; \ + cd autoconf-2.63 && autoreconf -i -I m4 && \ + ./configure --prefix="$(SAGE_LOCAL)/autoconf-2.63" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf autoconf-2.63/* + +# Extract sources from git repository serially +autoconf-2.64/.tarball-version: autoconf-2.63/.tarball-version + ( cd $(SRC)/autoconf && git archive --format=tar --prefix=autoconf-2.64/ v2.64 ) | tar xf - + echo 2.64 >autoconf-2.64/.tarball-version + +$(SAGE_LOCAL)/autoconf-2.64: autoconf-2.64/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/bin/help2man $(SAGE_LOCAL)/autoconf-2.60 $(SAGE_LOCAL)/automake-1.10 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.60 ; \ + export AUTOMAKE_VERSION=1.10 ; \ + cd autoconf-2.64 && autoreconf -i -I m4 && \ + ./configure --prefix="$(SAGE_LOCAL)/autoconf-2.64" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf autoconf-2.64/* + +# Extract sources from git repository serially +autoconf-2.65/.tarball-version: autoconf-2.64/.tarball-version + ( cd $(SRC)/autoconf && git archive --format=tar --prefix=autoconf-2.65/ v2.65 ) | tar xf - + echo 2.65 >autoconf-2.65/.tarball-version + +$(SAGE_LOCAL)/autoconf-2.65: autoconf-2.65/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/bin/help2man $(SAGE_LOCAL)/autoconf-2.60 $(SAGE_LOCAL)/automake-1.10 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.60 ; \ + export AUTOMAKE_VERSION=1.10 ; \ + cd autoconf-2.65 && autoreconf -i -I m4 && \ + ./configure --prefix="$(SAGE_LOCAL)/autoconf-2.65" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf autoconf-2.65/* + +# Extract sources from git repository serially +autoconf-2.66/.tarball-version: autoconf-2.65/.tarball-version + ( cd $(SRC)/autoconf && git archive --format=tar --prefix=autoconf-2.66/ v2.66 ) | tar xf - + echo 2.66 >autoconf-2.66/.tarball-version + +$(SAGE_LOCAL)/autoconf-2.66: autoconf-2.66/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/bin/help2man $(SAGE_LOCAL)/autoconf-2.62 $(SAGE_LOCAL)/automake-1.11 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.62 ; \ + export AUTOMAKE_VERSION=1.11 ; \ + cd autoconf-2.66 && autoreconf -i -I m4 && \ + ./configure --prefix="$(SAGE_LOCAL)/autoconf-2.66" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf autoconf-2.66/* + +# Extract sources from git repository serially +autoconf-2.67/.tarball-version: autoconf-2.66/.tarball-version + ( cd $(SRC)/autoconf && git archive --format=tar --prefix=autoconf-2.67/ v2.67 ) | tar xf - + echo 2.67 >autoconf-2.67/.tarball-version + +$(SAGE_LOCAL)/autoconf-2.67: autoconf-2.67/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/bin/help2man $(SAGE_LOCAL)/autoconf-2.62 $(SAGE_LOCAL)/automake-1.11 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.62 ; \ + export AUTOMAKE_VERSION=1.11 ; \ + cd autoconf-2.67 && autoreconf -i -I m4 && \ + ./configure --prefix="$(SAGE_LOCAL)/autoconf-2.67" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf autoconf-2.67/* + +# Extract sources from git repository serially +autoconf-2.68/.tarball-version: autoconf-2.67/.tarball-version + ( cd $(SRC)/autoconf && git archive --format=tar --prefix=autoconf-2.68/ v2.68 ) | tar xf - + echo 2.68 >autoconf-2.68/.tarball-version + +$(SAGE_LOCAL)/autoconf-2.68: autoconf-2.68/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/bin/help2man $(SAGE_LOCAL)/autoconf-2.62 $(SAGE_LOCAL)/automake-1.11 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.62 ; \ + export AUTOMAKE_VERSION=1.11 ; \ + cd autoconf-2.68 && autoreconf -i -I m4 && \ + ./configure --prefix="$(SAGE_LOCAL)/autoconf-2.68" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf autoconf-2.68/* + +# Extract sources from git repository serially +autoconf-2.69/.tarball-version: autoconf-2.68/.tarball-version + ( cd $(SRC)/autoconf && git archive --format=tar --prefix=autoconf-2.69/ v2.69 ) | tar xf - + echo 2.69 >autoconf-2.69/.tarball-version + +$(SAGE_LOCAL)/autoconf-2.69: autoconf-2.69/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/bin/help2man $(SAGE_LOCAL)/autoconf-2.62 $(SAGE_LOCAL)/automake-1.11 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.62 ; \ + export AUTOMAKE_VERSION=1.11 ; \ + cd autoconf-2.69 && autoreconf -i -I m4 && \ + ./configure --prefix="$(SAGE_LOCAL)/autoconf-2.69" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf autoconf-2.69/* + +autoconf-all: $(SAGE_LOCAL)/autoconf-2.13.rc1 $(SAGE_LOCAL)/autoconf-2.57 $(SAGE_LOCAL)/autoconf-2.58 $(SAGE_LOCAL)/autoconf-2.59 $(SAGE_LOCAL)/autoconf-2.60 $(SAGE_LOCAL)/autoconf-2.61 $(SAGE_LOCAL)/autoconf-2.62 $(SAGE_LOCAL)/autoconf-2.63 $(SAGE_LOCAL)/autoconf-2.64 $(SAGE_LOCAL)/autoconf-2.65 $(SAGE_LOCAL)/autoconf-2.66 $(SAGE_LOCAL)/autoconf-2.67 $(SAGE_LOCAL)/autoconf-2.68 $(SAGE_LOCAL)/autoconf-2.69 + +######################################################################## + +# Extract sources from git repository serially +automake-1.9/.tarball-version: autoconf-2.69/.tarball-version + ( cd $(SRC)/automake && git archive --format=tar --prefix=automake-1.9/ Release-1-9 ) | tar xf - + echo 1.9 >automake-1.9/.tarball-version + +$(SAGE_LOCAL)/automake-1.9: automake-1.9/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/autoconf-2.59 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.59 ; \ + cd automake-1.9 && \ + ./configure --prefix="$(SAGE_LOCAL)/automake-1.9" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf automake-1.9/* + +# Extract sources from git repository serially +automake-1.9.1/.tarball-version: automake-1.9/.tarball-version + ( cd $(SRC)/automake && git archive --format=tar --prefix=automake-1.9.1/ Release-1-9-1 ) | tar xf - + echo 1.9.1 >automake-1.9.1/.tarball-version + +$(SAGE_LOCAL)/automake-1.9.1: automake-1.9.1/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/autoconf-2.59 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.59 ; \ + cd automake-1.9.1 && \ + ./configure --prefix="$(SAGE_LOCAL)/automake-1.9.1" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf automake-1.9.1/* + +# Extract sources from git repository serially +automake-1.9.2/.tarball-version: automake-1.9.1/.tarball-version + ( cd $(SRC)/automake && git archive --format=tar --prefix=automake-1.9.2/ Release-1-9-2 ) | tar xf - + echo 1.9.2 >automake-1.9.2/.tarball-version + +$(SAGE_LOCAL)/automake-1.9.2: automake-1.9.2/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/autoconf-2.59 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.59 ; \ + cd automake-1.9.2 && \ + ./configure --prefix="$(SAGE_LOCAL)/automake-1.9.2" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf automake-1.9.2/* + +# Extract sources from git repository serially +automake-1.9.3/.tarball-version: automake-1.9.2/.tarball-version + ( cd $(SRC)/automake && git archive --format=tar --prefix=automake-1.9.3/ Release-1-9-3 ) | tar xf - + echo 1.9.3 >automake-1.9.3/.tarball-version + +$(SAGE_LOCAL)/automake-1.9.3: automake-1.9.3/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/autoconf-2.59 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.59 ; \ + cd automake-1.9.3 && \ + ./configure --prefix="$(SAGE_LOCAL)/automake-1.9.3" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf automake-1.9.3/* + +# Extract sources from git repository serially +automake-1.9.4/.tarball-version: automake-1.9.3/.tarball-version + ( cd $(SRC)/automake && git archive --format=tar --prefix=automake-1.9.4/ Release-1-9-4 ) | tar xf - + echo 1.9.4 >automake-1.9.4/.tarball-version + +$(SAGE_LOCAL)/automake-1.9.4: automake-1.9.4/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/autoconf-2.59 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.59 ; \ + cd automake-1.9.4 && \ + ./configure --prefix="$(SAGE_LOCAL)/automake-1.9.4" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf automake-1.9.4/* + +# Extract sources from git repository serially +automake-1.9.5/.tarball-version: automake-1.9.4/.tarball-version + ( cd $(SRC)/automake && git archive --format=tar --prefix=automake-1.9.5/ Release-1-9-5 ) | tar xf - + echo 1.9.5 >automake-1.9.5/.tarball-version + +$(SAGE_LOCAL)/automake-1.9.5: automake-1.9.5/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/autoconf-2.59 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.59 ; \ + cd automake-1.9.5 && \ + ./configure --prefix="$(SAGE_LOCAL)/automake-1.9.5" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf automake-1.9.5/* + +# Extract sources from git repository serially +automake-1.9.6/.tarball-version: automake-1.9.5/.tarball-version + ( cd $(SRC)/automake && git archive --format=tar --prefix=automake-1.9.6/ Release-1-9-6 ) | tar xf - + echo 1.9.6 >automake-1.9.6/.tarball-version + +$(SAGE_LOCAL)/automake-1.9.6: automake-1.9.6/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/autoconf-2.59 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.59 ; \ + cd automake-1.9.6 && \ + ./configure --prefix="$(SAGE_LOCAL)/automake-1.9.6" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf automake-1.9.6/* + +# Extract sources from git repository serially +automake-1.10/.tarball-version: automake-1.9.6/.tarball-version + ( cd $(SRC)/automake && git archive --format=tar --prefix=automake-1.10/ Release-1-10 ) | tar xf - + echo 1.10 >automake-1.10/.tarball-version + +$(SAGE_LOCAL)/automake-1.10: automake-1.10/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/autoconf-2.60 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.60 ; \ + cd automake-1.10 && \ + ./configure --prefix="$(SAGE_LOCAL)/automake-1.10" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf automake-1.10/* + +# Extract sources from git repository serially +automake-1.10.1/.tarball-version: automake-1.10/.tarball-version + ( cd $(SRC)/automake && git archive --format=tar --prefix=automake-1.10.1/ Release-1-10-1 ) | tar xf - + echo 1.10.1 >automake-1.10.1/.tarball-version + +$(SAGE_LOCAL)/automake-1.10.1: automake-1.10.1/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/autoconf-2.60 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.60 ; \ + cd automake-1.10.1 && \ + ./configure --prefix="$(SAGE_LOCAL)/automake-1.10.1" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf automake-1.10.1/* + +# Extract sources from git repository serially +automake-1.10.2/.tarball-version: automake-1.10.1/.tarball-version + ( cd $(SRC)/automake && git archive --format=tar --prefix=automake-1.10.2/ v1.10.2 ) | tar xf - + echo 1.10.2 >automake-1.10.2/.tarball-version + +$(SAGE_LOCAL)/automake-1.10.2: automake-1.10.2/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/autoconf-2.60 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.60 ; \ + cd automake-1.10.2 && \ + ./configure --prefix="$(SAGE_LOCAL)/automake-1.10.2" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf automake-1.10.2/* + +# Extract sources from git repository serially +automake-1.10.3/.tarball-version: automake-1.10.2/.tarball-version + ( cd $(SRC)/automake && git archive --format=tar --prefix=automake-1.10.3/ v1.10.3 ) | tar xf - + echo 1.10.3 >automake-1.10.3/.tarball-version + +$(SAGE_LOCAL)/automake-1.10.3: automake-1.10.3/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/autoconf-2.60 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.60 ; \ + cd automake-1.10.3 && \ + ./configure --prefix="$(SAGE_LOCAL)/automake-1.10.3" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf automake-1.10.3/* + +# Extract sources from git repository serially +automake-1.11/.tarball-version: automake-1.10.3/.tarball-version + ( cd $(SRC)/automake && git archive --format=tar --prefix=automake-1.11/ v1.11 ) | tar xf - + echo 1.11 >automake-1.11/.tarball-version + +$(SAGE_LOCAL)/automake-1.11: automake-1.11/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/bin/help2man $(SAGE_LOCAL)/autoconf-2.62 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.62 ; \ + cd automake-1.11 && \ + ./configure --prefix="$(SAGE_LOCAL)/automake-1.11" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf automake-1.11/* + +# Extract sources from git repository serially +automake-1.11.1/.tarball-version: automake-1.11/.tarball-version + ( cd $(SRC)/automake && git archive --format=tar --prefix=automake-1.11.1/ v1.11.1 ) | tar xf - + echo 1.11.1 >automake-1.11.1/.tarball-version + +$(SAGE_LOCAL)/automake-1.11.1: automake-1.11.1/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/bin/help2man $(SAGE_LOCAL)/autoconf-2.62 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.62 ; \ + cd automake-1.11.1 && \ + ./configure --prefix="$(SAGE_LOCAL)/automake-1.11.1" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf automake-1.11.1/* + +# Extract sources from git repository serially +automake-1.11.2/.tarball-version: automake-1.11.1/.tarball-version + ( cd $(SRC)/automake && git archive --format=tar --prefix=automake-1.11.2/ v1.11.2 ) | tar xf - + echo 1.11.2 >automake-1.11.2/.tarball-version + +$(SAGE_LOCAL)/automake-1.11.2: automake-1.11.2/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/bin/help2man $(SAGE_LOCAL)/autoconf-2.62 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.62 ; \ + cd automake-1.11.2 && \ + ./configure --prefix="$(SAGE_LOCAL)/automake-1.11.2" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf automake-1.11.2/* + +# Extract sources from git repository serially +automake-1.11.3/.tarball-version: automake-1.11.2/.tarball-version + ( cd $(SRC)/automake && git archive --format=tar --prefix=automake-1.11.3/ v1.11.3 ) | tar xf - + echo 1.11.3 >automake-1.11.3/.tarball-version + +$(SAGE_LOCAL)/automake-1.11.3: automake-1.11.3/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/bin/help2man $(SAGE_LOCAL)/autoconf-2.68 $(SAGE_LOCAL)/automake-1.10 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.68 ; \ + export AUTOMAKE_VERSION=1.10 ; \ + cd automake-1.11.3 && bash -c 'set -e; source bootstrap' && \ + ./configure --prefix="$(SAGE_LOCAL)/automake-1.11.3" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf automake-1.11.3/* + +# Extract sources from git repository serially +automake-1.11.4/.tarball-version: automake-1.11.3/.tarball-version + ( cd $(SRC)/automake && git archive --format=tar --prefix=automake-1.11.4/ v1.11.4 ) | tar xf - + echo 1.11.4 >automake-1.11.4/.tarball-version + +$(SAGE_LOCAL)/automake-1.11.4: automake-1.11.4/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/bin/help2man $(SAGE_LOCAL)/autoconf-2.68 $(SAGE_LOCAL)/automake-1.10 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.68 ; \ + export AUTOMAKE_VERSION=1.10 ; \ + cd automake-1.11.4 && bash -c 'set -e; source bootstrap' && \ + ./configure --prefix="$(SAGE_LOCAL)/automake-1.11.4" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf automake-1.11.4/* + +# Extract sources from git repository serially +automake-1.11.5/.tarball-version: automake-1.11.4/.tarball-version + ( cd $(SRC)/automake && git archive --format=tar --prefix=automake-1.11.5/ v1.11.5 ) | tar xf - + echo 1.11.5 >automake-1.11.5/.tarball-version + +$(SAGE_LOCAL)/automake-1.11.5: automake-1.11.5/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/bin/help2man $(SAGE_LOCAL)/autoconf-2.68 $(SAGE_LOCAL)/automake-1.10 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.68 ; \ + export AUTOMAKE_VERSION=1.10 ; \ + cd automake-1.11.5 && bash -c 'set -e; source bootstrap' && \ + ./configure --prefix="$(SAGE_LOCAL)/automake-1.11.5" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf automake-1.11.5/* + +# Extract sources from git repository serially +automake-1.11.6/.tarball-version: automake-1.11.5/.tarball-version + ( cd $(SRC)/automake && git archive --format=tar --prefix=automake-1.11.6/ v1.11.6 ) | tar xf - + echo 1.11.6 >automake-1.11.6/.tarball-version + +$(SAGE_LOCAL)/automake-1.11.6: automake-1.11.6/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/bin/help2man $(SAGE_LOCAL)/autoconf-2.68 $(SAGE_LOCAL)/automake-1.10 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.68 ; \ + export AUTOMAKE_VERSION=1.10 ; \ + cd automake-1.11.6 && bash -c 'set -e; source bootstrap' && \ + ./configure --prefix="$(SAGE_LOCAL)/automake-1.11.6" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf automake-1.11.6/* + +# Extract sources from git repository serially +automake-1.12/.tarball-version: automake-1.11.6/.tarball-version + ( cd $(SRC)/automake && git archive --format=tar --prefix=automake-1.12/ v1.12 ) | tar xf - + echo 1.12 >automake-1.12/.tarball-version + +$(SAGE_LOCAL)/automake-1.12: automake-1.12/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/autoconf-2.68 $(SAGE_LOCAL)/automake-1.10 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.68 ; \ + export AUTOMAKE_VERSION=1.10 ; \ + cd automake-1.12 && bash -c 'set -e; source bootstrap' && \ + ./configure --prefix="$(SAGE_LOCAL)/automake-1.12" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf automake-1.12/* + +# Extract sources from git repository serially +automake-1.12.1/.tarball-version: automake-1.12/.tarball-version + ( cd $(SRC)/automake && git archive --format=tar --prefix=automake-1.12.1/ v1.12.1 ) | tar xf - + echo 1.12.1 >automake-1.12.1/.tarball-version + +$(SAGE_LOCAL)/automake-1.12.1: automake-1.12.1/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/autoconf-2.69 $(SAGE_LOCAL)/automake-1.9.6 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.69 ; \ + export AUTOMAKE_VERSION=1.9.6 ; \ + cd automake-1.12.1 && bash -c 'set -e; source bootstrap.sh' && \ + ./configure --prefix="$(SAGE_LOCAL)/automake-1.12.1" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf automake-1.12.1/* + +# Extract sources from git repository serially +automake-1.12.2/.tarball-version: automake-1.12.1/.tarball-version + ( cd $(SRC)/automake && git archive --format=tar --prefix=automake-1.12.2/ v1.12.2 ) | tar xf - + echo 1.12.2 >automake-1.12.2/.tarball-version + +$(SAGE_LOCAL)/automake-1.12.2: automake-1.12.2/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/autoconf-2.69 $(SAGE_LOCAL)/automake-1.9.6 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.69 ; \ + export AUTOMAKE_VERSION=1.9.6 ; \ + cd automake-1.12.2 && bash -c 'set -e; source bootstrap.sh' && \ + ./configure --prefix="$(SAGE_LOCAL)/automake-1.12.2" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf automake-1.12.2/* + +# Extract sources from git repository serially +automake-1.12.3/.tarball-version: automake-1.12.2/.tarball-version + ( cd $(SRC)/automake && git archive --format=tar --prefix=automake-1.12.3/ v1.12.3 ) | tar xf - + echo 1.12.3 >automake-1.12.3/.tarball-version + +$(SAGE_LOCAL)/automake-1.12.3: automake-1.12.3/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/autoconf-2.69 $(SAGE_LOCAL)/automake-1.9.6 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.69 ; \ + export AUTOMAKE_VERSION=1.9.6 ; \ + cd automake-1.12.3 && bash -c 'set -e; source bootstrap.sh' && \ + ./configure --prefix="$(SAGE_LOCAL)/automake-1.12.3" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf automake-1.12.3/* + +# Extract sources from git repository serially +automake-1.12.4/.tarball-version: automake-1.12.3/.tarball-version + ( cd $(SRC)/automake && git archive --format=tar --prefix=automake-1.12.4/ v1.12.4 ) | tar xf - + echo 1.12.4 >automake-1.12.4/.tarball-version + +$(SAGE_LOCAL)/automake-1.12.4: automake-1.12.4/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/autoconf-2.69 $(SAGE_LOCAL)/automake-1.9.6 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.69 ; \ + export AUTOMAKE_VERSION=1.9.6 ; \ + cd automake-1.12.4 && bash -c 'set -e; source bootstrap.sh' && \ + ./configure --prefix="$(SAGE_LOCAL)/automake-1.12.4" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf automake-1.12.4/* + +# Extract sources from git repository serially +automake-1.12.5/.tarball-version: automake-1.12.4/.tarball-version + ( cd $(SRC)/automake && git archive --format=tar --prefix=automake-1.12.5/ v1.12.5 ) | tar xf - + echo 1.12.5 >automake-1.12.5/.tarball-version + +$(SAGE_LOCAL)/automake-1.12.5: automake-1.12.5/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/autoconf-2.69 $(SAGE_LOCAL)/automake-1.9.6 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.69 ; \ + export AUTOMAKE_VERSION=1.9.6 ; \ + cd automake-1.12.5 && bash -c 'set -e; source bootstrap.sh' && \ + ./configure --prefix="$(SAGE_LOCAL)/automake-1.12.5" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf automake-1.12.5/* + +# Extract sources from git repository serially +automake-1.12.6/.tarball-version: automake-1.12.5/.tarball-version + ( cd $(SRC)/automake && git archive --format=tar --prefix=automake-1.12.6/ v1.12.6 ) | tar xf - + echo 1.12.6 >automake-1.12.6/.tarball-version + +$(SAGE_LOCAL)/automake-1.12.6: automake-1.12.6/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/autoconf-2.69 $(SAGE_LOCAL)/automake-1.9.6 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.69 ; \ + export AUTOMAKE_VERSION=1.9.6 ; \ + cd automake-1.12.6 && bash -c 'set -e; source bootstrap.sh' && \ + ./configure --prefix="$(SAGE_LOCAL)/automake-1.12.6" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf automake-1.12.6/* + +# Extract sources from git repository serially +automake-1.13/.tarball-version: automake-1.12.6/.tarball-version + ( cd $(SRC)/automake && git archive --format=tar --prefix=automake-1.13/ v1.13 ) | tar xf - + echo 1.13 >automake-1.13/.tarball-version + +$(SAGE_LOCAL)/automake-1.13: automake-1.13/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/autoconf-2.69 $(SAGE_LOCAL)/automake-1.9.6 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.69 ; \ + export AUTOMAKE_VERSION=1.9.6 ; \ + cd automake-1.13 && bash -c 'set -e; source bootstrap.sh' && \ + ./configure --prefix="$(SAGE_LOCAL)/automake-1.13" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf automake-1.13/* + +# Extract sources from git repository serially +automake-1.13.1/.tarball-version: automake-1.13/.tarball-version + ( cd $(SRC)/automake && git archive --format=tar --prefix=automake-1.13.1/ v1.13.1 ) | tar xf - + echo 1.13.1 >automake-1.13.1/.tarball-version + +$(SAGE_LOCAL)/automake-1.13.1: automake-1.13.1/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/autoconf-2.69 $(SAGE_LOCAL)/automake-1.9.6 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.69 ; \ + export AUTOMAKE_VERSION=1.9.6 ; \ + cd automake-1.13.1 && bash -c 'set -e; source bootstrap.sh' && \ + ./configure --prefix="$(SAGE_LOCAL)/automake-1.13.1" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf automake-1.13.1/* + +# Extract sources from git repository serially +automake-1.13.2/.tarball-version: automake-1.13.1/.tarball-version + ( cd $(SRC)/automake && git archive --format=tar --prefix=automake-1.13.2/ v1.13.2 ) | tar xf - + echo 1.13.2 >automake-1.13.2/.tarball-version + +$(SAGE_LOCAL)/automake-1.13.2: automake-1.13.2/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/autoconf-2.69 $(SAGE_LOCAL)/automake-1.9.6 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.69 ; \ + export AUTOMAKE_VERSION=1.9.6 ; \ + cd automake-1.13.2 && bash -c 'set -e; source bootstrap.sh' && \ + ./configure --prefix="$(SAGE_LOCAL)/automake-1.13.2" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf automake-1.13.2/* + +# Extract sources from git repository serially +automake-1.13.3/.tarball-version: automake-1.13.2/.tarball-version + ( cd $(SRC)/automake && git archive --format=tar --prefix=automake-1.13.3/ v1.13.3 ) | tar xf - + echo 1.13.3 >automake-1.13.3/.tarball-version + +$(SAGE_LOCAL)/automake-1.13.3: automake-1.13.3/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/autoconf-2.69 $(SAGE_LOCAL)/automake-1.9.6 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.69 ; \ + export AUTOMAKE_VERSION=1.9.6 ; \ + cd automake-1.13.3 && bash -c 'set -e; source bootstrap.sh' && \ + ./configure --prefix="$(SAGE_LOCAL)/automake-1.13.3" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf automake-1.13.3/* + +# Extract sources from git repository serially +automake-1.13.4/.tarball-version: automake-1.13.3/.tarball-version + ( cd $(SRC)/automake && git archive --format=tar --prefix=automake-1.13.4/ v1.13.4 ) | tar xf - + echo 1.13.4 >automake-1.13.4/.tarball-version + +$(SAGE_LOCAL)/automake-1.13.4: automake-1.13.4/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/autoconf-2.69 $(SAGE_LOCAL)/automake-1.9.6 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.69 ; \ + export AUTOMAKE_VERSION=1.9.6 ; \ + cd automake-1.13.4 && bash -c 'set -e; source bootstrap.sh' && \ + ./configure --prefix="$(SAGE_LOCAL)/automake-1.13.4" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf automake-1.13.4/* + +# Extract sources from git repository serially +automake-1.14/.tarball-version: automake-1.13.4/.tarball-version + ( cd $(SRC)/automake && git archive --format=tar --prefix=automake-1.14/ v1.14 ) | tar xf - + echo 1.14 >automake-1.14/.tarball-version + +$(SAGE_LOCAL)/automake-1.14: automake-1.14/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/autoconf-2.69 $(SAGE_LOCAL)/automake-1.9.6 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.69 ; \ + export AUTOMAKE_VERSION=1.9.6 ; \ + cd automake-1.14 && bash -c 'set -e; source bootstrap.sh' && \ + ./configure --prefix="$(SAGE_LOCAL)/automake-1.14" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf automake-1.14/* + +# Extract sources from git repository serially +automake-1.14.1/.tarball-version: automake-1.14/.tarball-version + ( cd $(SRC)/automake && git archive --format=tar --prefix=automake-1.14.1/ v1.14.1 ) | tar xf - + echo 1.14.1 >automake-1.14.1/.tarball-version + +$(SAGE_LOCAL)/automake-1.14.1: automake-1.14.1/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/autoconf-2.69 $(SAGE_LOCAL)/automake-1.9.6 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.69 ; \ + export AUTOMAKE_VERSION=1.9.6 ; \ + cd automake-1.14.1 && bash -c 'set -e; source bootstrap.sh' && \ + ./configure --prefix="$(SAGE_LOCAL)/automake-1.14.1" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf automake-1.14.1/* + +automake-all: $(SAGE_LOCAL)/automake-1.9 $(SAGE_LOCAL)/automake-1.9.1 $(SAGE_LOCAL)/automake-1.9.2 $(SAGE_LOCAL)/automake-1.9.3 $(SAGE_LOCAL)/automake-1.9.4 $(SAGE_LOCAL)/automake-1.9.5 $(SAGE_LOCAL)/automake-1.9.6 $(SAGE_LOCAL)/automake-1.10 $(SAGE_LOCAL)/automake-1.10.1 $(SAGE_LOCAL)/automake-1.10.2 $(SAGE_LOCAL)/automake-1.10.3 $(SAGE_LOCAL)/automake-1.11 $(SAGE_LOCAL)/automake-1.11.1 $(SAGE_LOCAL)/automake-1.11.2 $(SAGE_LOCAL)/automake-1.11.3 $(SAGE_LOCAL)/automake-1.11.4 $(SAGE_LOCAL)/automake-1.11.5 $(SAGE_LOCAL)/automake-1.11.6 $(SAGE_LOCAL)/automake-1.12 $(SAGE_LOCAL)/automake-1.12.1 $(SAGE_LOCAL)/automake-1.12.2 $(SAGE_LOCAL)/automake-1.12.3 $(SAGE_LOCAL)/automake-1.12.4 $(SAGE_LOCAL)/automake-1.12.5 $(SAGE_LOCAL)/automake-1.12.6 $(SAGE_LOCAL)/automake-1.13 $(SAGE_LOCAL)/automake-1.13.1 $(SAGE_LOCAL)/automake-1.13.2 $(SAGE_LOCAL)/automake-1.13.3 $(SAGE_LOCAL)/automake-1.13.4 $(SAGE_LOCAL)/automake-1.14 $(SAGE_LOCAL)/automake-1.14.1 + +######################################################################## + +# Extract sources from git repository serially +libtool-1.5.20/.tarball-version: automake-1.14.1/.tarball-version + ( cd $(SRC)/libtool && git archive --format=tar --prefix=libtool-1.5.20/ release-1-5-20 ) | tar xf - + echo 1.5.20 >libtool-1.5.20/.tarball-version + +$(SAGE_LOCAL)/libtool-1.5.20: libtool-1.5.20/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/autoconf-2.59 $(SAGE_LOCAL)/automake-1.9.6 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.59 ; \ + export AUTOMAKE_VERSION=1.9.6 ; \ + cd libtool-1.5.20 && bash -c 'set -e; source bootstrap' && \ + ./configure --prefix="$(SAGE_LOCAL)/libtool-1.5.20" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf libtool-1.5.20/* + +# Extract sources from git repository serially +libtool-1.5.22/.tarball-version: libtool-1.5.20/.tarball-version + ( cd $(SRC)/libtool && git archive --format=tar --prefix=libtool-1.5.22/ release-1-5-22 ) | tar xf - + echo 1.5.22 >libtool-1.5.22/.tarball-version + +$(SAGE_LOCAL)/libtool-1.5.22: libtool-1.5.22/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/autoconf-2.59 $(SAGE_LOCAL)/automake-1.9.6 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.59 ; \ + export AUTOMAKE_VERSION=1.9.6 ; \ + cd libtool-1.5.22 && bash -c 'set -e; source bootstrap' && \ + ./configure --prefix="$(SAGE_LOCAL)/libtool-1.5.22" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf libtool-1.5.22/* + +# Extract sources from git repository serially +libtool-1.5.24/.tarball-version: libtool-1.5.22/.tarball-version + ( cd $(SRC)/libtool && git archive --format=tar --prefix=libtool-1.5.24/ release-1-5-24 ) | tar xf - + echo 1.5.24 >libtool-1.5.24/.tarball-version + +$(SAGE_LOCAL)/libtool-1.5.24: libtool-1.5.24/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/autoconf-2.59 $(SAGE_LOCAL)/automake-1.9.6 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.59 ; \ + export AUTOMAKE_VERSION=1.9.6 ; \ + cd libtool-1.5.24 && bash -c 'set -e; source bootstrap' && \ + ./configure --prefix="$(SAGE_LOCAL)/libtool-1.5.24" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf libtool-1.5.24/* + +# Extract sources from git repository serially +libtool-1.5.26/.tarball-version: libtool-1.5.24/.tarball-version + ( cd $(SRC)/libtool && git archive --format=tar --prefix=libtool-1.5.26/ release-1-5-26 ) | tar xf - + echo 1.5.26 >libtool-1.5.26/.tarball-version + +$(SAGE_LOCAL)/libtool-1.5.26: libtool-1.5.26/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/autoconf-2.59 $(SAGE_LOCAL)/automake-1.9.6 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.59 ; \ + export AUTOMAKE_VERSION=1.9.6 ; \ + cd libtool-1.5.26 && bash -c 'set -e; source bootstrap' && \ + ./configure --prefix="$(SAGE_LOCAL)/libtool-1.5.26" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf libtool-1.5.26/* + +# Extract sources from git repository serially +libtool-2.2.4/.tarball-version: libtool-1.5.26/.tarball-version + ( cd $(SRC)/libtool && git archive --format=tar --prefix=libtool-2.2.4/ v2.2.4 ) | tar xf - + echo 2.2.4 >libtool-2.2.4/.tarball-version + +$(SAGE_LOCAL)/libtool-2.2.4: libtool-2.2.4/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/autoconf-2.59 $(SAGE_LOCAL)/automake-1.9.6 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.59 ; \ + export AUTOMAKE_VERSION=1.9.6 ; \ + cd libtool-2.2.4 && bash -c 'set -e; source bootstrap' && \ + ./configure --prefix="$(SAGE_LOCAL)/libtool-2.2.4" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf libtool-2.2.4/* + +# Extract sources from git repository serially +libtool-2.2.6/.tarball-version: libtool-2.2.4/.tarball-version + ( cd $(SRC)/libtool && git archive --format=tar --prefix=libtool-2.2.6/ v2.2.6 ) | tar xf - + echo 2.2.6 >libtool-2.2.6/.tarball-version + +$(SAGE_LOCAL)/libtool-2.2.6: libtool-2.2.6/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/autoconf-2.60 $(SAGE_LOCAL)/automake-1.10.1 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.60 ; \ + export AUTOMAKE_VERSION=1.10.1 ; \ + cd libtool-2.2.6 && bash -c 'set -e; source bootstrap' && \ + ./configure --prefix="$(SAGE_LOCAL)/libtool-2.2.6" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf libtool-2.2.6/* + +# Extract sources from git repository serially +libtool-2.2.6b/.tarball-version: libtool-2.2.6/.tarball-version + ( cd $(SRC)/libtool && git archive --format=tar --prefix=libtool-2.2.6b/ v2.2.6b ) | tar xf - + echo 2.2.6b >libtool-2.2.6b/.tarball-version + +$(SAGE_LOCAL)/libtool-2.2.6b: libtool-2.2.6b/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/autoconf-2.60 $(SAGE_LOCAL)/automake-1.10.1 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.60 ; \ + export AUTOMAKE_VERSION=1.10.1 ; \ + cd libtool-2.2.6b && bash -c 'set -e; source bootstrap' && \ + ./configure --prefix="$(SAGE_LOCAL)/libtool-2.2.6b" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf libtool-2.2.6b/* + +# Extract sources from git repository serially +libtool-2.2.8/.tarball-version: libtool-2.2.6b/.tarball-version + ( cd $(SRC)/libtool && git archive --format=tar --prefix=libtool-2.2.8/ v2.2.8 ) | tar xf - + echo 2.2.8 >libtool-2.2.8/.tarball-version + +$(SAGE_LOCAL)/libtool-2.2.8: libtool-2.2.8/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/bin/help2man $(SAGE_LOCAL)/autoconf-2.62 $(SAGE_LOCAL)/automake-1.10.1 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.62 ; \ + export AUTOMAKE_VERSION=1.10.1 ; \ + cd libtool-2.2.8 && bash -c 'set -e; source bootstrap' && \ + ./configure --prefix="$(SAGE_LOCAL)/libtool-2.2.8" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf libtool-2.2.8/* + +# Extract sources from git repository serially +libtool-2.2.10/.tarball-version: libtool-2.2.8/.tarball-version + ( cd $(SRC)/libtool && git archive --format=tar --prefix=libtool-2.2.10/ v2.2.10 ) | tar xf - + echo 2.2.10 >libtool-2.2.10/.tarball-version + +$(SAGE_LOCAL)/libtool-2.2.10: libtool-2.2.10/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/bin/help2man $(SAGE_LOCAL)/autoconf-2.62 $(SAGE_LOCAL)/automake-1.10.1 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.62 ; \ + export AUTOMAKE_VERSION=1.10.1 ; \ + cd libtool-2.2.10 && bash -c 'set -e; source bootstrap' && \ + ./configure --prefix="$(SAGE_LOCAL)/libtool-2.2.10" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf libtool-2.2.10/* + +# Extract sources from git repository serially +libtool-2.4/.tarball-version: libtool-2.2.10/.tarball-version + ( cd $(SRC)/libtool && git archive --format=tar --prefix=libtool-2.4/ v2.4 ) | tar xf - + echo 2.4 >libtool-2.4/.tarball-version + +$(SAGE_LOCAL)/libtool-2.4: libtool-2.4/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/bin/help2man $(SAGE_LOCAL)/autoconf-2.62 $(SAGE_LOCAL)/automake-1.11.1 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.62 ; \ + export AUTOMAKE_VERSION=1.11.1 ; \ + cd libtool-2.4 && bash -c 'set -e; source bootstrap' && \ + ./configure --prefix="$(SAGE_LOCAL)/libtool-2.4" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf libtool-2.4/* + +# Extract sources from git repository serially +libtool-2.4.2/.tarball-version: libtool-2.4/.tarball-version + ( cd $(SRC)/libtool && git archive --format=tar --prefix=libtool-2.4.2/ v2.4.2 ) | tar xf - + echo 2.4.2 >libtool-2.4.2/.tarball-version + +$(SAGE_LOCAL)/libtool-2.4.2: libtool-2.4.2/.tarball-version $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/bin/help2man $(SAGE_LOCAL)/autoconf-2.62 $(SAGE_LOCAL)/automake-1.11.1 + export MAKE='$(MAKE) -j1' ; \ + export AUTOCONF_VERSION=2.62 ; \ + export AUTOMAKE_VERSION=1.11.1 ; \ + cd libtool-2.4.2 && bash -c 'set -e; source bootstrap' && \ + ./configure --prefix="$(SAGE_LOCAL)/libtool-2.4.2" && \ + $$MAKE && $$MAKE install + # Remove all files except for the .* files + [ "$$SAGE_KEEP_BUILT_SPKGS" = yes ] || rm -rf libtool-2.4.2/* + +libtool-all: $(SAGE_LOCAL)/libtool-1.5.20 $(SAGE_LOCAL)/libtool-1.5.22 $(SAGE_LOCAL)/libtool-1.5.24 $(SAGE_LOCAL)/libtool-1.5.26 $(SAGE_LOCAL)/libtool-2.2.4 $(SAGE_LOCAL)/libtool-2.2.6 $(SAGE_LOCAL)/libtool-2.2.6b $(SAGE_LOCAL)/libtool-2.2.8 $(SAGE_LOCAL)/libtool-2.2.10 $(SAGE_LOCAL)/libtool-2.4 $(SAGE_LOCAL)/libtool-2.4.2 + +######################################################################## + diff --git a/build/pkgs/autotools/SPKG.txt b/build/pkgs/autotools/SPKG.txt new file mode 100644 index 00000000000..b1fd17ed307 --- /dev/null +++ b/build/pkgs/autotools/SPKG.txt @@ -0,0 +1,69 @@ += autotools = + +== Description == + +This package contains a recent version of Texinfo, GNU m4, and help2man. +It contains the git repository of autoconf, automake and libtool. + +For the latter 3 packages (commonly referred to as "autotools"), +many different versions are installed, by checking out the versions +from the git repo and building/installing them separately. Since the +complete git repository is shipped in the spkg, this does not require +internet access. + +For Texinfo, m4 and help2man, just one version is installed. These are +prerequisites for autotools. Moreover, Texinfo is often needed for +bootstrapping packages. Even though m4 is already a prerequisite of +Sage, autoconf requires an up-to-date version of GNU m4. + +The package makes wrapper scripts in $SAGE_LOCAL/bin for the various +autotools, which call the "correct" version. This means that, if a file +"configure" already exists in the current directory, the same autoconf +version is run which created the original file. Otherwise, the latest +version is run. The goal of all this is to make it easier to patch +configure.ac or Makefile.am files inside a spkg. By using the same +version of autotools as originally used, the patch files should be +relatively small. The environment variables AUTOCONF_VERSION, +AUTOMAKE_VERSION and LIBTOOL_VERSION can be used to override the +chosen version. + +== License == + +GNU General Public License version 3 or later. + +== SPKG Maintainers == + +* Jeroen Demeyer + +== Upstream Contact == + +* http://www.gnu.org/software/texinfo/ +* http://www.gnu.org/software/m4/ +* http://www.gnu.org/software/help2man/ +* http://www.gnu.org/software/autoconf/ +* http://www.gnu.org/software/automake/ +* http://www.gnu.org/software/libtool/ + +== Dependencies == + +To install the package: +* Perl +* Git + +To update the package: +* Sage with autotools package installed +* Internet access + +== Special Update/Build Instructions == + +The file spkg-src can be used to automatically create the upstream +tarball from the git repositories. This obviously requires internet +access. + +The file version-list defines the list of versions installed by this +spkg. If you edit this, you must update Makefile.build using the +spkg-write-makefile script. After optionally updating the git repos +using spkg-src, you need to run + ./spkg-write-makefile >Makefile.build +This must be run in a Sage shell, with the the autotools spkg +installed. diff --git a/build/pkgs/autotools/autofoo b/build/pkgs/autotools/autofoo new file mode 100644 index 00000000000..485c4a02796 --- /dev/null +++ b/build/pkgs/autotools/autofoo @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +# Script to automatically call the "right" version of @AUTOFOO@ +# installed within Sage. We read the @AUTOFOO@ output file(s) to +# determine the version from that file. Otherwise, we simply run the +# latest version. In all cases, the version can be overridden by the +# @AUTOVAR@ environment variable. + +v="$@AUTOVAR@" + +if [ -z "$v" ]; then + for v_file in @AUTOFILES@; do + v=`exec 2>/dev/null; sed -n <$v_file \ + 's/^\(.*generated.*@AUTOFOO@\( *version\)*\|version=\)[ "]*\([0-9][-0-9a-z.]*\)/\3=/i; T; s/[.]*=.*//; p; q;'` + if [ -n "$v" ]; then break; fi + done +fi + +# Default version +if [ -z "$v" ]; then + v=@DEFAULT_VERSION@ +fi + +prog=`basename "$0"` +exec "$SAGE_LOCAL/@AUTOFOO@-$v/bin/$prog" "$@" diff --git a/build/pkgs/autotools/checksums.ini b/build/pkgs/autotools/checksums.ini new file mode 100644 index 00000000000..a367b91181d --- /dev/null +++ b/build/pkgs/autotools/checksums.ini @@ -0,0 +1,4 @@ +tarball=autotools-VERSION.tar.bz2 +sha1=671edb2a9bfe0f65803acc73e400497b4ee3fb21 +md5=c3838d86afb3505a5ae92a3342db424a +cksum=3255607767 diff --git a/build/pkgs/autotools/install-info.exe.manifest b/build/pkgs/autotools/install-info.exe.manifest new file mode 100755 index 00000000000..aaaa2c391f8 --- /dev/null +++ b/build/pkgs/autotools/install-info.exe.manifest @@ -0,0 +1,18 @@ + + + + + + + + + + + + + diff --git a/build/pkgs/autotools/latest_version b/build/pkgs/autotools/latest_version new file mode 100755 index 00000000000..5fd231a6b17 --- /dev/null +++ b/build/pkgs/autotools/latest_version @@ -0,0 +1,68 @@ +#!/usr/bin/env python +# +# Read a whitespace-separated list of version numbers on stdin +# and output the latest version. +# +# A version number is a list of numbers separated by dots, followed +# by an optional alphanumeric string (there may or may not be a dot +# before this string). The numbers must not have leading zeros. +# Typical examples: "5.4.3a" or "1.10.rc0" +# +# Any word in the input which does not start with a digit, is ignored. +# Any word which does start with a digit, but is not of the required +# form, is an error. Trailing alphanumeric strings are chopped off and +# ignored; they don't appear in the output. +# +# AUTHOR: Jeroen Demeyer (2012-10-01) +# + +# Make this script compatible with Python 3. +from __future__ import print_function + + +def version_to_tuple(v): + """ + Convert a version number like "5.4.3a" to a tuple (5,4,3). + """ + n = "" # Current number as string + t = [] # List of numbers + for c in v: + if c.isdigit(): + n += c + elif c == ".": + if len(n) == 0: + raise ValueError("Empty number in version string '{}'".format(v)) + if n[0] == '0' and len(n) >= 2: + raise ValueError("Leading zeros not allowed in version string '{}'".format(v)) + t.append(int(n)) + n = "" + elif c.isalpha(): + break + else: + raise ValueError("Illegal character '{}' in version string '{}'".format(c,v)) + if len(n) > 0: + t.append(int(n)) + return tuple(t) + +def tuple_to_version(t): + """ + Convert a tuple like (5,4,3) to a version number "5.4.3" + """ + return str.join(".", [str(x) for x in t]) + + +import sys +L = sys.stdin.read().split() + +debug = ' '.join(L) + +L = [version_to_tuple(s) for s in L if len(s) > 0 and s[0].isdigit()] +if len(L) == 0: + sys.exit(0) + +L = sorted(L, reverse=True) +ver = tuple_to_version(L[0]) +debug = debug + ' => ' + ver + +print(ver) +print(debug, file=sys.stderr) diff --git a/build/pkgs/autotools/package-version.txt b/build/pkgs/autotools/package-version.txt new file mode 100644 index 00000000000..ae02fcb2546 --- /dev/null +++ b/build/pkgs/autotools/package-version.txt @@ -0,0 +1,2 @@ +20140114 + diff --git a/build/pkgs/autotools/spkg-install b/build/pkgs/autotools/spkg-install new file mode 100755 index 00000000000..e91bddd2a4c --- /dev/null +++ b/build/pkgs/autotools/spkg-install @@ -0,0 +1,107 @@ +#!/usr/bin/env bash + +set -e + +if [ -z "$SAGE_LOCAL" ]; then + echo >&2 "SAGE_LOCAL undefined ... exiting" + echo >&2 "Maybe run 'sage --sh'?" + exit 1 +fi + +# Check that git is installed +if ! git --version &>/dev/null; then + echo >&2 "git is not installed, try running" + echo >&2 " sage -i git" + exit 3 +fi + +# Create an empty git repo here, otherwise the autotools installers +# get confused (they try to take version info from git if possible) +git init + + +SRC=`pwd`/src +BUILD=`pwd`/build + +######################################################################## +# Apply patch(es) +######################################################################## + +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 + +######################################################################## +# Remove old installed versions +######################################################################## + +cd "$SAGE_LOCAL" +rm -rf autoconf-* automake-* libtool-* +cd bin +rm -f m4 makeinfo help2man autoconf autoheader autom4te autoreconf \ + autoscan automake aclocal libtool libtoolize + +######################################################################## +# Install wrapper scripts in $SAGE_LOCAL/bin +######################################################################## + +# Determine the default versions of the various autotools, which is the +# last version in the list from version-list. +source "$SRC/../version-list" +for x in $autoconf_versions; do autoconf_latest=$x ; done +for x in $automake_versions; do automake_latest=$x ; done +for x in $libtool_versions; do libtool_latest=$x ; done + +# We install scripts for autoconf,... based on the generic "autofoo" script +cd "$SAGE_LOCAL/bin" +sed <"$SRC/../autofoo" >autoconf \ + "s/@AUTOFOO@/autoconf/; s/@AUTOFILES@/configure/; s/@AUTOVAR@/AUTOCONF_VERSION/; s/@DEFAULT_VERSION@/${autoconf_latest}/" +sed <"$SRC/../autofoo" >automake \ + "s/@AUTOFOO@/automake/; s/@AUTOFILES@/Makefile.in/; s/@AUTOVAR@/AUTOMAKE_VERSION/; s/@DEFAULT_VERSION@/${automake_latest}/" +sed <"$SRC/../autofoo" >libtool \ + "s/@AUTOFOO@/libtool/; s/@AUTOFILES@/ltmain.sh/; s/@AUTOVAR@/LIBTOOL_VERSION/; s/@DEFAULT_VERSION@/${libtool_latest}/" + +# Correct permissions +for prog in autoconf automake libtool; do + chmod 0755 $prog +done + +# Make symlinks +for prog in autoheader autom4te autoreconf autoscan; do + ln -s autoconf $prog +done +ln -s automake aclocal +ln -s libtool libtoolize + +# Make symlinks for some non-exact version matches +cd "$SAGE_LOCAL" +ln -s autoconf-2.13.rc1 autoconf-2.4 +ln -s autoconf-2.13.rc1 autoconf-2.13 +ln -s autoconf-2.60 autoconf-2.59a +ln -s autoconf-2.60 autoconf-2.59c +ln -s libtool-2.2.4 libtool-2.2.3a +ln -s libtool-2.2.8 libtool-2.2.7a + +######################################################################## +# Copy the Makefile and build everything +######################################################################## + +mkdir -p "$BUILD" +cd "$BUILD" +( + echo "SRC = $SRC" + echo "SAGE_LOCAL = $SAGE_LOCAL" + # Force the use of bash as shell (/bin/sh on OpenSolaris has + # problems with very long command lines used in some make rules). + echo "SHELL = `which bash`" + echo + cat "$SRC/../Makefile.build" +) >Makefile + +$MAKE diff --git a/build/pkgs/autotools/spkg-src b/build/pkgs/autotools/spkg-src new file mode 100755 index 00000000000..424668118c0 --- /dev/null +++ b/build/pkgs/autotools/spkg-src @@ -0,0 +1,38 @@ +#!/usr/bin/env bash + +set -e + +if [ -z "$SAGE_ROOT" ]; then + echo >&2 "SAGE_ROOT undefined ... exiting" + echo >&2 "Maybe run 'sage --sh'?" + exit 1 +fi + +cd "$SAGE_ROOT" + +TARGET=autotools-`cat build/pkgs/autotools/package-version.txt` + +rm -rf upstream/$TARGET +mkdir -p upstream/$TARGET +cd upstream/$TARGET + + +echo "Downloading m4 sources..." +sage-download-file http://ftp.gnu.org/gnu/m4/m4-1.4.17.tar.bz2 | tar xjf - + +echo "Downloading help2man sources..." +sage-download-file http://ftp.gnu.org/gnu/help2man/help2man-1.43.3.tar.gz | tar xzf - + +echo "Downloading texinfo sources..." +sage-download-file http://ftp.gnu.org/gnu/texinfo/texinfo-4.13.tar.gz | tar xzf - + +git clone --no-checkout git://git.sv.gnu.org/autoconf +git clone --no-checkout git://git.sv.gnu.org/automake +git clone --no-checkout git://git.sv.gnu.org/libtool + + +cd "$SAGE_ROOT/upstream" +tar cjf $TARGET.tar.bz2 $TARGET +rm -rf $TARGET + +echo "New autotools tarball is ready in $SAGE_ROOT/upstream/$TARGET.tar.bz2" diff --git a/build/pkgs/autotools/spkg-write-makefile b/build/pkgs/autotools/spkg-write-makefile new file mode 100755 index 00000000000..1d8542583e0 --- /dev/null +++ b/build/pkgs/autotools/spkg-write-makefile @@ -0,0 +1,185 @@ +#!/usr/bin/env bash +# +# Write a Makefile for the autotools spkg. This actually requires a +# Sage with autotools installed, so run this from within a Sage shell. +# This script also requires git. +# +# Typical usage: +# ./spkg-write-makefile >Makefile.build +# + +set -e + +if [ -z "$SAGE_ROOT" ]; then + echo >&2 "SAGE_ROOT undefined ... exiting" + echo >&2 "Maybe run 'sage --sh'?" + exit 1 +fi + +# Sanity check that AUTOCONF_VERSION and AUTOMAKE_VERSION works +if ! env "AUTOCONF_VERSION=2.62" autoconf --version | grep >/dev/null '2[.]62'; then + echo >&2 "The environment variable AUTOCONF_VERSION does not seem to work." + echo >&2 "Make sure you are running $0 within a Sage shell" + echo >&2 "with the autotools spkg installed." + exit 3 +fi +if ! env "AUTOMAKE_VERSION=1.9.6" aclocal --version | grep >/dev/null '1[.]9[.]6'; then + echo >&2 "The environment variable AUTOMAKE_VERSION does not seem to work." + echo >&2 "Make sure you are running $0 within a Sage shell" + echo >&2 "with the autotools spkg installed." + exit 3 +fi + +export PATH="$SAGE_ROOT/build/pkgs/autotools:$PATH" + + +# Read versions +source version-list + +# Extract upstream autotools tarball +cd "$SAGE_ROOT" +PKG=autotools-`cat build/pkgs/autotools/package-version.txt` +mkdir -p local/var/tmp/sage +cd "$SAGE_ROOT/local/var/tmp/sage" +tar xjf "$SAGE_ROOT/upstream/$PKG.tar.bz2" +cd $PKG + +cat <&2 "Processing $p-$v" + cd $p + + # Find out the correct tag for version $v + tag=`git tag -l | grep -i -x -e "v$v" -e "release-$v" -e "$p-$v" | head -1` + if [ -z "$tag" ]; then + echo >&2 "Cannot find tag for $p-$v" + exit 3 + fi + + # Checkout the version given by the tag (and remove all garbage) + git checkout -f $tag + git clean -f -d -x -q + + deps="\$(SAGE_LOCAL)/bin/m4 \$(SAGE_LOCAL)/bin/makeinfo" + ac_ver= + am_ver= + if cat configure.* | grep help2man >/dev/null; then + deps="$deps \$(SAGE_LOCAL)/bin/help2man" + fi + if [ -f configure.ac ]; then + # Minimum required version of Automake + if [ ! -f configure ]; then + # Run aclocal, such that AM_INIT_AUTOMAKE is available. + aclocal + # Require at least version 1.9.6, a reasonable default. + am_ver=`( echo 1.9.6; autoconf --trace='AM_INIT_AUTOMAKE:$1' configure.ac ) | latest_version` + # Run the *correct* version of aclocal, such that we do + # not introduce unneeded AC_PREREQ() definitions. + env "AUTOMAKE_VERSION=$am_ver" aclocal + fi + + # Minimum required version of Autoconf: always consider + # AC_PREREQ for Automake, even if "configure" exists. + if [ ! -f configure ] || [ $p = automake ]; then + # Require at least version 2.59, a reasonable default. + ac_ver=`( echo 2.59; autoconf --trace='AC_PREREQ:$1' configure.ac ) | latest_version` + fi + fi + if [ -n "$ac_ver" ]; then + deps="$deps \$(SAGE_LOCAL)/autoconf-$ac_ver" + fi + if [ -n "$am_ver" ]; then + deps="$deps \$(SAGE_LOCAL)/automake-$am_ver" + fi + + # Figure out how to bootstrap + if [ -f configure ]; then + bootstrap= + elif [ -f bootstrap.sh ]; then + bootstrap="bash -c 'set -e; source bootstrap.sh' && " + elif [ -f bootstrap ]; then + bootstrap="bash -c 'set -e; source bootstrap' && " + else + bootstrap="autoreconf -i -I m4 && " + fi + if [ -f autoheader.sh ]; then + # Work around Autoconf bootstrap bug + bootstrap="${bootstrap}touch autoupdate.sh && " + fi + + + # Write make rules + echo "# Extract sources from git repository serially" + echo "$p-$v/.tarball-version: $prevextract" + echo -e "\t( cd \$(SRC)/$p && git archive --format=tar --prefix=$p-$v/ $tag ) | tar xf -" + echo -e "\techo $v >$p-$v/.tarball-version" + echo + + echo "\$(SAGE_LOCAL)/$p-$v: $p-$v/.tarball-version $deps" + echo -e "\texport MAKE='\$(MAKE) -j1' ; \\\\" + [ -z "$ac_ver" ] || echo -e "\texport AUTOCONF_VERSION=$ac_ver ; \\\\" + [ -z "$am_ver" ] || echo -e "\texport AUTOMAKE_VERSION=$am_ver ; \\\\" +sed 's/^/\t/;' <Makefile.build +# +# The order of the versions is irrelevant, except that the last version +# is the one which will be used by default. +# + +autoconf_versions=" + 2.13.rc1 2.57 2.58 2.59 2.60 2.61 2.62 2.63 2.64 2.65 2.66 2.67 + 2.68 2.69" + +automake_versions=" + 1.9 1.9.1 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.10 1.10.1 1.10.2 1.10.3 + 1.11 1.11.1 1.11.2 1.11.3 1.11.4 1.11.5 1.11.6 1.12 1.12.1 1.12.2 + 1.12.3 1.12.4 1.12.5 1.12.6 1.13 1.13.1 1.13.2 1.13.3 1.13.4 + 1.14 1.14.1" + +libtool_versions=" + 1.5.20 1.5.22 1.5.24 1.5.26 + 2.2.4 2.2.6 2.2.6b 2.2.8 2.2.10 2.4 2.4.2" diff --git a/build/pkgs/cliquer/patches/cl_c.patch b/build/pkgs/cliquer/patches/cl_c.patch deleted file mode 100644 index a976397e17c..00000000000 --- a/build/pkgs/cliquer/patches/cl_c.patch +++ /dev/null @@ -1,138 +0,0 @@ ---- src.orig/cl.c 2010-01-22 02:49:27.000000000 -0500 -+++ src/cl.c 2013-07-15 00:24:12.313611644 -0400 -@@ -401,3 +401,135 @@ - return TRUE; - } - -+// As the global variables remain between two SAGE call, they -+// have to be reset each time -+void sage_reset_global_variables(){ -+ find_all=FALSE; -+ min_weight=0; -+ min_weight_set=FALSE; -+ max_weight=0; -+ max_weight_set=FALSE; -+ maximal=FALSE; -+ unweighted=FALSE; -+ number1=TRUE; -+ quiet=0; -+ only_weight=FALSE; -+ clique_count=0; -+ clique_list_size=0; -+} -+ -+ -+// The opt structure has to be initialised in each SAGE function -+clique_options * sage_init_clique_opt(){ -+ sage_reset_global_variables(); -+ clique_options *opts; -+ quiet++; -+ opts=malloc(sizeof(clique_options)); -+ if (quiet) -+ opts->time_function=NULL; -+ else -+ opts->time_function=clique_print_time; -+ opts->output=stderr; -+ opts->reorder_function=reorder; -+ opts->reorder_map=NULL; -+ // Without commenting these lines the sage_all_clique_max -+ // function does not work correctly -+ -+ /* -+ if (quiet) -+ opts->user_function=print_clique_func; -+ else -+ */ -+ opts->user_function=record_clique_func; -+ opts->user_data=NULL; -+ opts->clique_list=NULL; -+ opts->clique_list_length=0; -+ return opts; -+} -+ -+ -+// Computes a maximum clique of the graph g and return its size -+// The table list contains the ID of the vertices -+int sage_clique_max(graph_t *g,int **list){ -+ sage_reset_global_variables(); -+ quiet++; -+ find_all=FALSE; -+ maximal=TRUE; -+ number1=FALSE; -+ set_t s; -+ int i,l; -+ clique_options *opts = sage_init_clique_opt(); -+ s=clique_unweighted_find_single(g,min_weight, -+ max_weight,maximal, -+ opts); -+ free(opts); -+ -+ // Writing the answer into a int [] to be read by Sage -+ int size=set_size(s); -+ *list=malloc(sizeof(int)*size); -+ l=0; -+ for (i=0; i -+#include -+#include -+ -+#ifdef ENABLE_LONG_OPTIONS -+#include -+#endif -+ -+#include "cliquer.h" -+ -+ -+#define TRYFORHELP "Try `%s -h' for more information.\n",argv[0] -+ -+void printhelp(char *prog); -+void read_options(int argc, char **argv); -+void print_search(graph_t *g); -+boolean record_clique_func(set_t s,graph_t *g,clique_options *opts); -+boolean print_clique_func(set_t s,graph_t *g,clique_options *opts); -+void print_clique(set_t s,graph_t *g); -+ -+// As the global variables remain between two SAGE call, they -+// have to be reset each time -+void sage_reset_global_variables(); -+// The opt structure has to be initialised in each SAGE function -+clique_options * sage_init_clique_opt(); -+// Computes a maximum clique of the graph g and return its size -+// The table list contains the ID of the vertices -+int sage_clique_max(graph_t *g,int **list); -+int sage_all_clique_max(graph_t *g,int **list); -+int sage_clique_number(graph_t *g); -+ -+ diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index 94fe0c3f92d..6f3ab7ee9de 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,4 +1,4 @@ tarball=configure-VERSION.tar.gz -sha1=4bb4e11a71034632562c2463a869c6f7a7f7b2c7 -md5=289a27d614dfcbdfd87752282d30d738 -cksum=4063465730 +sha1=e0f0951560918d79141995852f276ac3e99a42f4 +md5=33b6cac80bafecc0ad880fd68cf258e6 +cksum=3483617699 diff --git a/build/pkgs/configure/package-version.txt b/build/pkgs/configure/package-version.txt index 7f8f011eb73..b4de3947675 100644 --- a/build/pkgs/configure/package-version.txt +++ b/build/pkgs/configure/package-version.txt @@ -1 +1 @@ -7 +11 diff --git a/build/pkgs/eclib/SPKG.txt b/build/pkgs/eclib/SPKG.txt index 80d2023f456..831b5747e57 100644 --- a/build/pkgs/eclib/SPKG.txt +++ b/build/pkgs/eclib/SPKG.txt @@ -6,6 +6,10 @@ John Cremona's programs for enumerating and computing with elliptic curves defined over the rational numbers. This is the culmination of over 25 years of hard work. +== License == + +eclib is licensed GPL v2+. + == Maintainers == * William Stein @@ -15,180 +19,13 @@ over 25 years of hard work. * Author: John Cremona * Email: john.cremona@gmail.com - * Website: https://code.google.com/p/eclib/ + * Website: https://github.com/JohnCremona/eclib == Dependencies == - * GMP / MPIR * PARI * NTL + * FLINT -== Changelog == - -=== eclib-20120830 (Jean-Pierre Flori, 5 September 2012) === - * #13325: Source code updated to version 2012-08-30. - * Now builds correctly on Cygwin. - -=== eclib-20120428 (John Cremona, 28 April 2012) === - * Source code update to revision 7fcd812213df (as at 25 April 2012), from - http://homepages.warwick.ac.uk/staff/J.E.Cremona/ftp/progs/eclib-2012-04-25.tar.gz - -=== eclib-20120421 (John Cremona, 21 April 2012) === - * Source code update to revision 0db48db1d463 (as at 21 April 2012), from - http://homepages.warwick.ac.uk/staff/J.E.Cremona/ftp/progs/eclib-2012-04-21.tar.gz - -=== eclib-20120419 (John Cremona, 19 April 2012) === - * Source code update to revision 91afac16a596 (as at 19 April 2012), from - http://homepages.warwick.ac.uk/staff/J.E.Cremona/ftp/progs/eclib-2012-04-19.tar.gz - -=== eclib-20120417.p2 (John Cremona, 18 April 2012) === - * Minor source code update to revision ed71f2904c55 (as at 18 April 2012), as at - http://homepages.warwick.ac.uk/staff/J.E.Cremona/ftp/progs/eclib-2012-04-18.tar.gz - -=== eclib-20120417.p1 (John Cremona, 18 April 2012) === - * Minor source code update to revision cf6aae3592bf (as at 17 April 2012), as at - http://homepages.warwick.ac.uk/staff/J.E.Cremona/ftp/progs/eclib-2012-04-17.tar.gz - -=== eclib-20120417.p0 (Leif Leonhardy, 17 April 2012) === - * #10993: Clean up `spkg-check` and `spkg-install`. - * Use `$MAKE` in `spkg-check` as well, add sanity check. - * Exit if `configure` failed. - * Support `SAGE64` and `SAGE_DEBUG`, enable optimization and debug symbols - by default. - * Redirect all warnings and error messages to `stderr`. - -=== eclib-20120417 (John Cremona, 17 April 2012) === - * Complete rewrite of build system using autotools and libtool - * Update source code to revision 042c47ea0bc4 (as at 17 April 2012), - unpacked from http://homepages.warwick.ac.uk/staff/J.E.Cremona/ftp/progs/eclib-2012-04-16.tar.gz - -=== eclib-20120115.p2 (John Cremona, 24 February 2012) === - * Small changes to top-level Makefile (remove "--as-needed" flag, see trac #10993) - * Update source code to revision 3e54531b1c27 (as at 24 February 2012) - -=== eclib-20120115.p1 (John Cremona, 1 February 2012) === - * Small changes to all Makefiles (see trac #10993) - * Update source code to revision c2266b8c6029 (as at 1 February 2012) - -=== eclib-20120115.p0 (John Cremona, 18 January 2012) === - * Small patch to spkg-install (adding PATH extension before calling - ldconfig) as suggested on review at trac #10993 - -=== eclib-20120115 (John Cremona, 15 January 2012) === - * Source code now at http://code.google.com/p/eclib/ - * Update source code to revision 2b04700f06ba (as at 15 January 2012) - * Add a line in spkg-install to run ldconfig - -=== eclib-20100711.p0 (Mariah Lenox and Leif Leonhardy, September 28th 2011) === - * #11354: Deleted the obsolete (Debian) dist/ directory. (May 2011) - * Comment by Leif: - Since (as release manager) I had to add this changelog entry, which was - missing, and fix the files' permissions anyway, I also did little "off-ticket" - clean-up (kind of "reviewer patch"): - - Use `cp -p` in all copy commands, since the current umask might break - permissions again. - - Check exit codes of `cp` (and `strip`) and all other important commands. - - Minor cosmetic clean-up, such as replacing `uname` by "$UNAME" and else-if - ladders by `elif`. - -=== eclib-20100711 (John Cremona, 11 July 2010) === - * Four changesets applied to source code, including - * Implementation of support for "minus space" modular symbols spaces - * Some improvements to sparse linear algebra (nothing dramatic) - -=== eclib-20080310.p10 (Mitesh Patel, 2nd March 2010) === - * Suppress writing 'PRIMES' on exit. See line 327 in - src/procs/marith.cc. - * Delete a file named '1' after 'make check'. - * To enable parallel builds, tweak Makefiles and remove #4228's work - around. - * Simplify g0n/Makefile to fix 'make check' on Solaris 10. - -=== eclib-20080310.p9 (John Cremona, 2nd February 2010) === - * Fix bug in second descent (R-solubility not tested) - * Enhance descent interface by providing separate rank_bound and - selmer_rank functions - -=== eclib-20080310.p8 (David Kirkby, 2nd January 2010) === - * Allow SAGE64 to work on all platforms, not just OS X. - -=== eclib-20080310.p7 (Michael Abshoff, October 12th, 2008) === - * Work around parallel make issue (#4228) - -=== eclib-20080310.p6 (John Cremona, September 24th, 2008) === - * Apply Arnaud Bergeron's patch to use ${MAKE} instead of make. - * Include ecnf in PROGS in src/g0n/Makefile - -=== eclib-20080310.p5 (John Cremona, July 6th, 2008) === - * Delete src/procs/ressol.c which was not used (and was labelled as having been borrowed from LiDIA) - -=== eclib-20080310.p4 (John Cremona, July 4th, 2008) === - * Delete some code that was never compiled but which was labelled as having been borrowed from LiDIA - -=== eclib-20080310.p3 (John Cremona) === - * minor bugfixes for gcc 4.2.3 - -=== eclib-20080310.p2 (Michael Abshoff) === - * add 64 bit OSX build support - -=== eclib-20080310.p1 (Michael Abshoff, April 1st, 2008) === - * minor eclib build system improvements (Tim Abbott, #2735) - * Fix Debian Sections (Tim Abbott, #2643) - * Copyright files for Debian packages (Tim Abbott, #2199) - -=== eclib-20080310.p0 (Michael Abshoff, March 19th, 2008) === - * fix directory name - * update SPKG.txt - * fix permissions - -=== eclib-20080310 (Tom Boothby, March 10th, 2008) === - * Applied patch from John Cremona to compute modular symbols of elliptic curves. - -=== eclib-20080127 (William Stein and John Cremona) === - * Fix osx build and check issues - -=== eclib-20071231.p0 (Michael Abshoff) === - - * added Cygwin support - * add spkg-check - * install headers into $SAGE_LOCAL/eclib - * delete $SAGE_LOCAL/include/cremona - * chown $SAGE_LOCAL/include/eclib and files underneath - -=== eclib-20071231 (John Cremona) === - - * renamed to eclib - * allows elliptic curves as input with rational (as opposed to just integer) coefficients. - -=== cremona-20071219.p1 (Michael Abshoff) === - - * patch to fix "Internal error: can't free this _ntl_gbigint" (John Cremona) - -=== cremona-20071219.p0 (John Cremona) === - - * fix main Makefile mismerge (Michael Abshoff) - * add missing export to g0n/Makefile (John Cremona) - * fix permission issue (Michael Abshoff) - -=== cremona-20071219 (John Cremona) === - - * update to latest source - * fix mwrank error on non-minimal curves (#1233) - -=== cremona-20071124.p4 (Michael Abshoff) === - - * apply John Cremoan's second patch for #1403 - * delete $SAGE_LOCAL/include/mwrank (#1410) - * strip the mwrank binaries and link dynamically (#1410) - * delete $SAGE_LOCAL/lib/libmwrank.[so|dylib] (#1410) - -=== cremona-20071124.p3 (Michael Abshoff) === - - * apply John Cremoan's patch for #1403 - * fix #1256, i.e. remove the now obsolete mwrank.spkg - -=== previous versions === - - * lost to history diff --git a/build/pkgs/eclib/checksums.ini b/build/pkgs/eclib/checksums.ini index c6bbeba031c..716f6204dc0 100644 --- a/build/pkgs/eclib/checksums.ini +++ b/build/pkgs/eclib/checksums.ini @@ -1,4 +1,4 @@ tarball=eclib-VERSION.tar.bz2 -sha1=e73c82c8bd75a9c1107c186a33181e71e7708994 -md5=0e56e0f6e3841bca412188a2559307c3 -cksum=1898809844 +sha1=1210d69f679f6d70c378cb78231980f28e18a0af +md5=87773eb30baaa7f413afa01a5c251265 +cksum=4230857238 diff --git a/build/pkgs/eclib/package-version.txt b/build/pkgs/eclib/package-version.txt index 9d4c9b86f9a..38d434f87e1 100644 --- a/build/pkgs/eclib/package-version.txt +++ b/build/pkgs/eclib/package-version.txt @@ -1 +1 @@ -20120830 +20140128 diff --git a/build/pkgs/eclib/spkg-install b/build/pkgs/eclib/spkg-install index 51a4177d2c0..af2a5278bb3 100755 --- a/build/pkgs/eclib/spkg-install +++ b/build/pkgs/eclib/spkg-install @@ -53,9 +53,9 @@ cd src/ echo echo "Now configuring eclib..." ./configure --prefix="$SAGE_LOCAL" \ - --with-gmp="$SAGE_LOCAL" \ --with-ntl="$SAGE_LOCAL" \ --with-pari="$SAGE_LOCAL" \ + --with-flint="$SAGE_LOCAL" \ --disable-allprogs if [ $? -ne 0 ]; then echo >&2 "Error configuring eclib." diff --git a/build/pkgs/flint/SPKG.txt b/build/pkgs/flint/SPKG.txt index 6dca0b97e36..fdf022b8791 100644 --- a/build/pkgs/flint/SPKG.txt +++ b/build/pkgs/flint/SPKG.txt @@ -26,224 +26,7 @@ FLINT is licensed GPL v2+. * MPFR * NTL -== Patches == - - * dylib.patch: patch configure so that the shared library is called - libflint.dylib on Darwin. - * cflags.patch: patch configure so that "-m64" (and other potentially - unwanted cflags) is not added on PowerPC G5. Also add -fno-common - on Darwin, which is needed for OS X 10.4 and doesn't hurt on other - systems. - -== Changelog == - -=== flint-2.3.p1 (Jean-Pierre Flori, 8 May 2013) === - * Trac #12173: add dylib.patch and cflags.patch - -=== flint-2.3 (Mike Hansen, Fredrik Johansson, Jean-Pierre Flori, May 2012-March 2013) === - * Trac #12173: Update FLINT to version 2.3. - * Removed obsolete patches. - * Cleanup spkg-install and spkg-check scripts. - * Removed Cygwin hack for libntl.a made useless by #9050. - * Removed now useless patch --binary flag on Cygwin. - * Only build shared library on Cygwin. - -=== flint-1.5.2.p3 (Timo Kluck, 7 March 2013) === - * #14241: Fix double // path separators in longlong.patch - -=== flint-1.5.2.p2 (Paul-Olivier Dehaye, 16 October 2012) === - * #9697: Remove the file 'src/zn_poly/demo/bernoulli/.DS_Store' - -=== flint-1.5.2.p1 (Jean-Pierre Flori, 3 August 2012) === - * #13330: Pass --binary flag to patch on Cygwin to deal with file terminators - mess. - -=== flint-1.5.2.p0 (Dima Pasechnik, March 24th 2012) === - * bumped up the version to reflect the fact that we patch the source - -=== flint-1.5.2 (Julien Puydt, William Stein, December 21st 2011) === - * #10328: enable ARM support; longlong.patch removes non-working - asm code for 32-bit ARM - -=== flint-1.5.0.p10 (Leif Leonhardy, October 11th 2011) === - * #9858: Add an upstream patch from FLINT 1.5.2 to make FLINT's test suite - build (when `SAGE_CHECK=yes`) with MPIR 1.3.x, 2.x (cf. #8664) and GMP 5.x. - The patch just substitutes deprecated random functions in one file - (`fmpz-test.c`) which have been removed from the mentioned GMP / MPIR - versions. - -=== flint-1.5.0.p9 (Karl-Dieter Crisman, Dima Pasechnik, 25 August 2011) === - * Fix DOS file endings introduced in p7 which made patch fail on some systems - -=== flint-1.5.0.p8 (Karl-Dieter Crisman, 12th July 2011) === - * Enable both libflint.dll and .so on Cygwin (see Trac 11547). - * Use 'cp' rather than '$CP' (affects only Cygwin). - * Remove '.svn' directories from upstream. - -=== flint-1.5.0.p7 (Jeroen Demeyer, 6 July 2011) === - * Trac #11246: remove check for gcc version since we require gcc >= 4.0.1 - for Sage anyway. - * Use `patch` instead of `cp` for patching the makefile - * Remove test_gcc_version.sh and the horrible makepatchfiles - * Check that `patch` succeeded in spkg-install, apply patches at -p1 level - * Remove obsolete dist/debian directory - -=== flint-1.5.0.p6 (Dima Pasechnik, 25th April 2011) === - * removed extraneous #include statements in ZmodF_mul.c, ZmodF_poly.c, and, mpn_extras.h, which - triggered a clash of typedef for ulong in sys/types.h and #define ulong in flint.h - on Cygwin (trac ticket 11246). - -=== flint-1.5.0.p5 (David Kirkby, 19th June 2010) === - * #9277 Add -m64 flag when building the Flint test suite - if SAGE64 is set to "yes". Otherwise it builds 32-bit - objects and so the test files are not built, but instead - generating the usual "WRONG ELF CLASS" error. - * Remove a couple of lines which call spkg-check from - spkg-install if SAGE_CHECK is set to "yes". Otherwise, - spkg-check gets called twice, which is a waste of time. - I'm afraid to say it was probably me that put those couple - of lines in a year or two ago, before I realised how - spkg-check was supposed to be called. - -=== flint-1.5.0.p4 (Jaap Spies, Feb 23th, 2010) === - * #8112 Pass CFLAG64 to FLINT_TUNE if set for a 64 bit build. - -=== flint-1.5.0.p3 (David Kirkby, January 2nd, 2010) === - * #7815 Changed makes and spkg-install so that the flag -m64 got - added with a 64-bit build. - -=== flint-1.5.0.p1 (William Stein, September 25th, 2009) === - * Included a cygwin fix that involves naming the library .dll instead of .so. - -=== flint-1.5.0.p0 (Mike Hansen, September 25th, 2009) === - * Updated to 1.5.0. - -=== flint-1.3.0p3 (Ondrej Certik, September 20th, 2009) === - * Move libntl.a out of the way temporarily on CYGWIN (this makes the package - built, because it will link to the .so lib instead) - -=== flint-1.3.0p2 (David Kirkby, June 30th, 2009) === - * Change '-a' to '-p' option spkg-install so flint installs - on Solaris too. The usual GNUism. Only one byte is changed! - -=== flint-1.3.0 (Nick Alexander, June 9th, 2009) === - * Update to latest upstream FLINT, 1.3.0. - -=== flint-1.3.0 (Nick Alexander, June 9th, 2009) === - * Update to latest upstream FLINT, 1.3.0. - -=== flint-1.2.5.p0 (Mike Hansen, June 4th, 2009) === - * Fix build issues found in #6209. - -=== flint-1.2.5 (Michael Abshoff, April 29th, 2009) === - * Update to latest upstream FLINT with reenabled znpoly 0.9. - -=== flint-1.2.4.p1 (William Stein, April 8th, 2009) === - * Disable znpoly. - -=== flint-1.2.4.p0 (Michael Abshoff, April 5th, 2009) === - * Build the OSX dylibs with CPP instead of CC - -=== flint-1.2.4 (Michael Abshoff, April 3rd, 2009) === - * Upgraded to newest stable version - * remove soname hack on Linux - * build all tests with CPP since otherwise linker failures due to the NTL interface happen on OSX - -=== flint-1.2.3 (Michael Abshoff, April 2nd, 2009) === - * Upgraded to newest stable version - -=== flint-1.2.2 (Burcin Erocal, March 31st, 2009) === - * Upgraded to newest stable version - -=== flint-1.2.1 (Burcin Erocal, March 15th, 2009) === - * Upgraded to newest stable version - * delay deleting library in local/lib until build is complete - * added zmod_mat-test and NTL-interface-test to spkg-check - * spkg-check now exits on error - * enabled tests - -=== flint-1.1.2 (William Stein, March 1st, 2009) === - * Upgraded to newest stable version - -=== flint-1.1.1 (William Stein, February 28th, 2009) === - * Upgraded to newest stable version - -=== flint-1.0.21.0 (Michael Abshoff, January 2nd, 2009) === - * do not run the test suite automatically - -=== flint-1.0.21 (Michael Abshoff, December 23rd, 2008) === - * Upgrade to latest upstream (#4879) - -=== flint-1.0.20 (Michael Abshoff, December 23rd, 2008) === - * Upgrade to latest upstream (#4861) - * clean up SPKG.txt - -=== flint-1.0.13.p0 (Michael Abshoff, August 18th, 2008) === - * Add 64 bit OSX support - -=== flint-1.0.13 (Michael Abshoff, July 21st, 2008) === - * Update FLINT to 1.0.13 release - -=== flint-1.011.p0 (William Stein, July 9th, 2008) === - * Fixed trac #3627: another FLINT BUG (in in ZmodF_poly_pointwise_mul): illegal instruction on modular/modsym/subspace.py on P4 3.4Ghz with 3.0.4.rc0 - -=== flint-1.011 (Michael Abshoff, July 9th, 2008) === - * update FLINT to 1.0.11 release (fixes a critical Itanium bug - thanks to Bill Hart) - * turn on spkg-check per default - * add additional tests to spkg-check as instructed by Bill Hart - -=== flint-1.010.p0 (Michael Abshoff, July 6th, 2008) === - * Only check major and minor gcc release number, not tiny (fixes #3528) - -=== flint-1.010 (William Stein and Craig Citro, June 30, 2008) === - * upgrade to version 1.0.10 - -=== flint-1.06.p3 (Michael Abshoff, April 1st, 2008) === - * import shared library versioning for flint (Tim Abbott, #3259) - * create proper link, fix bash shebang - * make sure $SAGE_LOCAL is defined (#633) - -=== flint-1.06.p2 (Michael Abshoff, April 1st, 2008) === - * Debian amd64 fixes for FLINT (Tim Abbott, #2762) - * Debian Copyright patch for FLINT (Tim Abbott, #2199) - -=== flint-1.06.p0 (Michael Abshoff, February 2nd, 2008) === - * disable mandatory check - -=== flint-1.06 (Michael Abshoff, January 19th, 2008) === - * update to FLINT 1.0.6 release - * turn make check on again per default - -=== flint-1.05.p0 (Michael Abshoff, January 17th, 2008) === - * disable mandatory check - -=== flint-1.05 (Michael Abshoff) === - * update to FLINT 1.05 - -2007-12-19 (Michael Abshoff): - + update to FLINT 1.03 - + reenable mandatory "make check" - -2007-12-16 (Michael Abshoff): - + disable mandatory "make check" - + remove -B flag in make check since it breaks make 2.79 and earlier - -2007-12-10 (Michael Abshoff): Update to FLINT 1.02 - -2007-12-08 (Michael Abshoff): Update to FLINT 1.01 - -2007-12-06 (Michael Abshoff): Update to FLINT 1.00 - -2007-11-25 (Michael Abshoff): add "flint_stack_release();" in fmpz_poly.c:1485 - to avoid a memory leak. Deteced and fixed by Bill Hart - -2007-11-24 (Michael Abshoff): upgraded to svn r1075 - -2007-10-02 (William Stein): upgraded to svn 1012 - -2007-10-02 (Robert Bradshaw): upgraded to svn r1068 - -Obtained from: - svn export https://flint.svn.sourceforge.net/svnroot/flint/trunk - +== Special Update/Build Instructions == +=== Patches === + * test_empty_string.patch: fix test for empty string in Makefile.in. diff --git a/build/pkgs/flint/checksums.ini b/build/pkgs/flint/checksums.ini index 825e0035e8a..ce64bd582cf 100644 --- a/build/pkgs/flint/checksums.ini +++ b/build/pkgs/flint/checksums.ini @@ -1,4 +1,4 @@ -tarball=flint-VERSION.tar.bz2 -sha1=03cb7f95b960cb64693d01a8c0b6243e64aca74c -md5=932e1c8790b3c761eb0bc058cfdcc50b -cksum=970975353 +tarball=flint-VERSION.tar.gz +sha1=b506c3870a3d976796ec0b6224659e9c82dcceae +md5=3b9bc754ef9e974ad4d0cf808d9809df +cksum=1290600232 diff --git a/build/pkgs/flint/package-version.txt b/build/pkgs/flint/package-version.txt index 3b116172a62..2cf43203234 100644 --- a/build/pkgs/flint/package-version.txt +++ b/build/pkgs/flint/package-version.txt @@ -1 +1 @@ -2.3.p1 +2.4.1.p0 diff --git a/build/pkgs/flint/patches/cflags.patch b/build/pkgs/flint/patches/cflags.patch deleted file mode 100644 index 55ce02a4df2..00000000000 --- a/build/pkgs/flint/patches/cflags.patch +++ /dev/null @@ -1,30 +0,0 @@ -diff -ru src/configure b/configure ---- src/configure 2012-11-09 21:42:47.000000000 +0100 -+++ b/configure 2013-05-08 12:12:08.233238871 +0200 -@@ -262,13 +262,7 @@ - #various tuning parameters - - if [ -z "$FLINT_TUNE" ]; then -- if [ "$KERNEL" = "Linux" -a "$ARCH" = "x86_64" ]; then -- FLINT_TUNE="-funroll-loops" -- elif [ "$KERNEL" = "Darwin" -a "$ARCH" = "ppc" ]; then -- FLINT_TUNE=" -funroll-loops" -- elif [ "`uname -p`" = "powerpc" ]; then -- FLINT_TUNE="-m64 -mcpu=970 -mtune=970 -mpowerpc64 -falign-loops=16 -falign-functions=16 -falign-labels=16 -falign-jumps=16" -- elif [ "$ARCH" = "ia64" ]; then -+ if [ "$ARCH" = "ia64" ]; then - # -funroll-loops crashes the build on itanium under GCC-4.2.1, as reported by - # Kate Minola. - FLINT_TUNE="" -@@ -325,6 +319,11 @@ - CFLAGS="-O2 -g -ansi -pedantic -Wall $POPCNT_FLAG $ABI_FLAG" - fi - -+# Old Darwin versions (OS X 10.4) require -fno-common -+if [ "$KERNEL" = Darwin ]; then -+ CFLAGS="-fno-common $CFLAGS" -+fi -+ - #add tuning parameters to CFLAGS - - CFLAGS="$CFLAGS $FLINT_TUNE" diff --git a/build/pkgs/flint/patches/dylib.patch b/build/pkgs/flint/patches/dylib.patch deleted file mode 100644 index b7be024bdbd..00000000000 --- a/build/pkgs/flint/patches/dylib.patch +++ /dev/null @@ -1,17 +0,0 @@ -diff -druN src.orig/configure src/configure ---- src.orig/configure 2012-11-09 21:42:47.000000000 +0100 -+++ src/configure 2013-03-06 18:21:03.644037750 +0100 -@@ -225,12 +225,7 @@ - if [ -z "$FLINT_LIB" ]; then - case $OS in - Darwin) -- case $MACHINE in -- *64) -- FLINT_LIB="libflint.dylib64";; -- *) -- FLINT_LIB="libflint.dylib";; -- esac;; -+ FLINT_LIB="libflint.dylib";; - CYGWIN | MINGW*) - FLINT_LIB="libflint.dll";; - *) diff --git a/build/pkgs/flint/patches/test_empty_string.patch b/build/pkgs/flint/patches/test_empty_string.patch new file mode 100644 index 00000000000..b4073926919 --- /dev/null +++ b/build/pkgs/flint/patches/test_empty_string.patch @@ -0,0 +1,19 @@ +commit 81c820b73dc0208f107629d7658f4f0642ca64e8 +Author: Jean-Pierre Flori +Date: Mon Feb 3 15:02:22 2014 +0100 + + Fix test for empty string in install target. + +diff --git a/Makefile.in b/Makefile.in +index 0fa717b..19caed2 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -178,7 +178,7 @@ install: library + cp libflint.a $(DESTDIR)$(PREFIX)/lib; \ + fi + cp $(HEADERS) $(DESTDIR)$(PREFIX)/include/flint +- $(AT)if [ ! -z $(EXT_HEADERS) ]; then \ ++ $(AT)if [ ! -z "$(EXT_HEADERS)" ]; then \ + cp $(EXT_HEADERS) $(DESTDIR)$(PREFIX)/include/flint; \ + fi + mkdir -p $(DESTDIR)$(FLINT_CPIMPORT_DIR) diff --git a/build/pkgs/gd/spkg-install b/build/pkgs/gd/spkg-install index 32821eff0d7..ea013d6c9e4 100755 --- a/build/pkgs/gd/spkg-install +++ b/build/pkgs/gd/spkg-install @@ -10,6 +10,11 @@ if [ $UNAME = "CYGWIN" ]; then cp patches/expr "$SAGE_LOCAL/bin" fi +if [ $UNAME = "Darwin" ]; then + # OSX does not have fontconfig, often causes problems with 3rd party distributions + LIBGD_CONFIGURE="--without-fontconfig $LIBGD_CONFIGURE" +fi + # Critical to get rid of old versions, since they will break the install, since # at some point one of the libraries accidently links against what's in SAGE_LOCAL, # instead of what is in the build directory! @@ -33,7 +38,7 @@ export CFLAGS # We explicitly disable X support, since (1) X is not a SAGE dependency, # and (2) the gd build fails on a lot of OS X PPC machines when X is enabled. -./configure --prefix="$SAGE_LOCAL" --libdir="$SAGE_LOCAL/lib" --without-jpeg --without-x --with-zlib="$SAGE_LOCAL" --with-freetype="$SAGE_LOCAL" --without-xpm +./configure --prefix="$SAGE_LOCAL" --libdir="$SAGE_LOCAL/lib" --without-jpeg --without-x --with-zlib="$SAGE_LOCAL" --with-freetype="$SAGE_LOCAL" --without-xpm $LIBGD_CONFIGURE if [ $? -ne 0 ]; then echo "Error configuring gd." diff --git a/build/pkgs/lcalc/SPKG.txt b/build/pkgs/lcalc/SPKG.txt index 8c70e383385..67f8dd89c73 100644 --- a/build/pkgs/lcalc/SPKG.txt +++ b/build/pkgs/lcalc/SPKG.txt @@ -81,162 +81,13 @@ http://code.google.com/p/l-calc/ to not redefine the double() cast, thats just fragile and will sooner or later again fail inside some system headers. * pari-2.4.4.patch: - (Patches src/src/Lcommandline.cc and src/src/Lcommandline_elliptic.cc) - Use allocatemem() instead of allocatemoremem() which the new PARI no - longer supports. Also replace lgeti() by (long)cgeti(). + Replace obsolete lgeti() by (long)cgeti(). + * init_stack.patch: + Replace obsolete allocatemoremem() by a direct call to the private + function pari_init_stack(). The public function allocatemem() prints + useless warnings and is by definition treated as an error. * time.h.patch: (Patches src/include/Lcommandline_numbertheory.h) Include also in Lcommandline_numbertheory.h (at least required on Cygwin, cf. #9845). This should get reported upstream. - -== Changelog == - -=== lcalc-1.23.p11 (Jean-Pierre Flori, 8 August 2012) === - * #13351: modify Makefile to define binaries and libraries extension - according to host system. As a side effect, this let - sage.libs.lcalc.lcal_Lfunction be imported on Cygwin. - -=== lcalc-1.23.p10 (Leif Leonhardy, March 17th 2012) === - * #12681: Fix hard-coded 'g++'. - The (patched) Makefile now uses $(CXX) (which *defaults* to 'g++') - for compiling and linking C++, $(CC) (which *defaults* to 'gcc') for - compiling C, although the latter is [currently] hardly used. - See also "Special Update/Build Instructions" above. (We could now also - set `INSTALL_DIR` and use 'make install'...) - -=== lcalc-1.23.p9 (Jeroen Demeyer, Leif Leonhardy, 6 October 2011) === - * Trac #11321: Add a patch for PARI-2.4.4 (use allocatemem() instead of - allocatemoremem()) - * Remove unused patch Lcommandline_elliptic.cc.cygwin.diff - * Use `patch` for patching instead of `cp`. - * Restore upstream sources (src/src/Makefile was edited) but remove - garbage files mentioned above. - * Remove date from spkg version string - * Various clean-up in spkg-install - -=== lcalc-20100428-1.23.p6 (Volker Braun, March 8, 2011) === - * upstream commented out lcalc_to_double(long double), but this is - now required with gcc-4.6. Comment back in! - -=== lcalc-20100428-1.23.p5 (Jeroen Demeyer, September 19, 2010) === - * Remove dist directory - * Put back SAGE_LOCAL sanity check in spkg-install - * Change "make" to "$MAKE" - -=== lcalc-20100428-1.23.p4 (Mike Hansen, William Stein, September 2, 2010) === - * Add time.h include to Lcommandline_numbertheory.h (this should get upstreamed) - -=== lcalc-20100428-1.23.p3 (Mike Hansen, August 21, 2010) === - * Update to work on Cygwin. - * #9775: lcalc should make a .dll file on Cygwin instead of .so file - -=== lcalc-20100428-1.23.p2 (John Cremona, August 13 2010 following Jeroen Demeyer, July 24, 2010) === - * Upgrade to PARI/GP 2.4.3 (#9343 and #9592). - * Removed some code from spkg-install made redundant when upgrading to 1.23 - in March 2010. - -=== lcalc-20100428-1.23.p1 (Rishikesh, 2nd Aug 2010) === - * Detect OS X 10.4 and copy to libLfunction.dylib instead of libLfunction.so - -=== lcalc-20100428-1.23.p0 (David Kirkby, 27th May 2010) === - * See: #9043 - lcalc failing to build on OpenSolaris x64. - * Force 64-bit build if SAGE64 is set to "yes" and not "yes" - and "1" as before, since an early part of Sage ensures SAGE64 - can only be "yes" or "no", so it is pointless to check for "1" too. - * Added a variable CXXFLAG64 to spkg-install, which defaults to - -m64, but can be set as an environment variable to whatever flag - is needed by the C++ compiler. - * Export CXXFLAG64 if SAGE64 is set to "yes". - * Added {$CXXFLAG64} to patches/Makefile.sage, so that the right flag - is added for a 64-bit build at the link phase. - * It should be noted the Makefile makes extensive use of $(FOOBAR), - but such variables only work internally to the Makefile. If they need - to be inported, then it needs to be ${FOOBAR}, and not $(FOOBAR). - * Removed these 4 files from the source, since they serve no useful - purpose (see note in Special Build Instructions). - ./src/src/.Makefile.old.swp - ./src/src/.Lcommandline.ggo.swp - ./src/include/.Lvalue.h.swp - ./src/include/.Lexplicit_formula.h.swp - -=== lcalc-20100428-1.23 (Rishikesh, 24th March 2010) === - * changed spkg-install to change location of header files (#4793) - * changed compile flags so that lcalc compiles on OSX (#4793) - -=== lcalc-20100428-1.23 (Rishikesh, 9th March 2010) === - * Changed makefile to compile on solaris (#5396) - * For lcalc wrapper, changed so that the library is copied(#5396) - * Replace the hard coded path to pari makefile to the $SAGE_LOCAL(#5396) - -=== lcalc-20080205.p3 (David kirkby, 15th September, 2009) === - * A general tidy-up/improvement in many ways, including: - * Force an exit on errors with 'set -e' - * Check for SAGE_LOCAL in a better way - * Build with debug flags as default, but allow them to be removed - * Add flags to generate all warnings messages on both Sun and GNU compilers. - This causes tons of warning messages from lcacl. - * Check that the C, C++ and Fortran compilers are not a mix of Sun and GNU - * Remove the flags which were sent directly to the assembler to - suppress warnings. The -W flag, which works on the GNU assembler, - is not portable and fails with Sun's assembler. - * All tests performed in what I believe is the safest and most - portable way, such as using || instead of -o in tests. - * Changed the Makefile to use CXXFLAGS rather than CFLAGS, as the - source is C++ not C, and the compiler used is the C++ compiler, - which will ignore CFLAGS. - * Added appropiate options to FCFLAGS. Not needed for 'lcalc', but I - hope to use this as a template for more widespread use in Sage. It - may however need more work, particularly in handling Fortran (There - may be specific issues when the Fortran compiler is f90.) - * Print variable names, to aid debugging. - * Allow debug information to be removed from file, if - SAGE_DEBUG is set to 'no', 'false' or '0' - By default, debugging information will be supplied. - -=== lcalc-20080205.p2 (Michael Abshoff, July 15th, 2008) === - * remove "-static-libgcc" from CFLAGS (fixes #3647) - -=== lcalc-20080205.p1 (Michael Abshoff, May 18th, 2008) === - * add 64 bit OSX build support - -=== lcalc-20080205.p0 (Michael Abshoff, April 19th, 2008) === - * Apply Tim Abbott's Debian build fix (#2967) - -=== lcalc-20080205 (Michael Abshoff, April 13th, 2008) === - * update to lcalc 1.11 (2008-Feb-05) - * Apply all three patches from patches directory - * fix gcc 4.3 build issues - * fix Solaris build - * do not strip the lcalc binary - -=== lcalc-20070105 === - * modified Lcommandline_elliptic.cc to work with Cygwin - by defining a certain macro. *** carry this change over when - updating the package *** and of course backport it upstream. - -* New version from Mike R. on 2006-12-05. - -* I replaced the included Makefile with my own, since I'm only interested - in building lcalc and not the library. Also, since I'm not doing - development on lcalc, the dependencies aren't needed in order - to minimize build time. - - -* 2006-09-15: Fix to spkg-install suggested by Kate Minola: -In lcalc-2006.03.05/spkg-install there is -: CFLAGS="$CFLAGS -O2 -g -Wa,-W -fno-exceptions -Wno-deprecated" -: -: cd src -: -: echo "Building Rubinstein's lcalc program using $CXX..." -: -: make lcalc -but since the environment variable CFLAGS is never exported, the subshell -entered with 'make lcalc' does not pick up the new CFLAGS. You need to -add - export CFLAGS -after the new definition of CLAGS. - -* Kate Minola: - Added -static-libgcc diff --git a/build/pkgs/lcalc/package-version.txt b/build/pkgs/lcalc/package-version.txt index c63180d97f2..a7292bf10d6 100644 --- a/build/pkgs/lcalc/package-version.txt +++ b/build/pkgs/lcalc/package-version.txt @@ -1 +1 @@ -1.23.p11 +1.23.p12 diff --git a/build/pkgs/lcalc/patches/init_stack.patch b/build/pkgs/lcalc/patches/init_stack.patch new file mode 100644 index 00000000000..e9e0237d7b8 --- /dev/null +++ b/build/pkgs/lcalc/patches/init_stack.patch @@ -0,0 +1,31 @@ +diff -ru src/include/Lcommandline.h b/include/Lcommandline.h +--- src/include/Lcommandline.h 2012-08-08 23:21:55.000000000 +0200 ++++ b/include/Lcommandline.h 2014-01-06 14:04:55.981027532 +0100 +@@ -40,12 +40,7 @@ + #include "Lcommandline_globals.h" //command line global variables + #ifdef INCLUDE_PARI + #include "pari.h" //for pari's elliptic curve functions +-#undef init //pari has a '#define init pari_init' which +- //causes trouble with the stream.h init. +- //pari also causes trouble with things like abs. +- //we place the pari include first since otherwise it +- //messes up. +- ++#include "paripriv.h" //for pari_init_stack() + #endif //ifdef INCLUDE_PARI + + +diff -ru src/src/Lcommandline.cc b/src/Lcommandline.cc +--- src/src/Lcommandline.cc 2012-08-08 23:21:56.000000000 +0200 ++++ b/src/Lcommandline.cc 2014-01-06 14:02:19.463388366 +0100 +@@ -473,7 +473,9 @@ + + #ifdef INCLUDE_PARI + if(do_elliptic_curve){ +- allocatemoremem((int) N_terms*16+1000000); //XXXXXXXXX this should depend on whether we're double or long double or mpfr double ++ // Reallocate PARI stack ++ pari_init_stack((size_t)N_terms*16 + 1000000, top-bot); //XXXXXXXXX this should depend on whether we're double or long double or mpfr double ++ + if (my_verbose>0) cout << "Will precompute " << N_terms << " elliptic L-function dirichlet coefficients..." << endl; + initialize_new_L(a1,a2,a3,a4,a6,N_terms); + } diff --git a/build/pkgs/lcalc/patches/pari-2.4.4.patch b/build/pkgs/lcalc/patches/pari-2.4.4.patch index 13ecf1baeaa..cee03519d63 100644 --- a/build/pkgs/lcalc/patches/pari-2.4.4.patch +++ b/build/pkgs/lcalc/patches/pari-2.4.4.patch @@ -1,33 +1,3 @@ ---- src/src/Lcommandline.cc 2010-01-31 16:16:45.000000000 +0100 -+++ src/src/Lcommandline.cc 2011-05-10 17:22:10.000000000 +0200 -@@ -31,6 +31,12 @@ - #include "Lcommandline.h" - #include "cmdline.h" - -+/* No-operation error recovery routine for PARI. This is needed for -+ * allocatemem(), which calls the error recovery routine (because -+ * allocatemem() destroys the PARI stack). -+ */ -+void pari_err_recover_nop(long errnum) {return;} -+ - int main (int argc, char *argv[]) - { - -@@ -473,7 +479,13 @@ - - #ifdef INCLUDE_PARI - if(do_elliptic_curve){ -- allocatemoremem((int) N_terms*16+1000000); //XXXXXXXXX this should depend on whether we're double or long double or mpfr double -+ /* allocatemem() calls the callback function cb_pari_err_recover(), -+ * which we temporarily change to do nothing. */ -+ void (*saved_err_recover)(long) = cb_pari_err_recover; -+ cb_pari_err_recover = pari_err_recover_nop; -+ allocatemem(N_terms*16 + 1000000); //XXXXXXXXX this should depend on whether we're double or long double or mpfr double -+ cb_pari_err_recover = saved_err_recover; -+ - if (my_verbose>0) cout << "Will precompute " << N_terms << " elliptic L-function dirichlet coefficients..." << endl; - initialize_new_L(a1,a2,a3,a4,a6,N_terms); - } --- src/src/Lcommandline_elliptic.cc 2010-01-31 16:16:45.000000000 +0100 +++ src/src/Lcommandline_elliptic.cc 2011-05-10 17:08:10.000000000 +0200 @@ -121,11 +121,11 @@ diff --git a/build/pkgs/mpc/SPKG.txt b/build/pkgs/mpc/SPKG.txt index 9c593bd41b7..34366cd7e34 100644 --- a/build/pkgs/mpc/SPKG.txt +++ b/build/pkgs/mpc/SPKG.txt @@ -33,40 +33,4 @@ The MPC team can be contact via the MPC mailing list: == Special Update/Build Instructions == -Patches: - * configure.patch: move AM_PROG_AR after MPC_GMP_CC_CFLAGS, see - https://gforge.inria.fr/tracker/?func=detail&group_id=131&aid=14669&atid=607 - (patch scheduled to be merged upstream in mpc-1.0.1) - -== Changelog == - -=== mpc-1.0.p0 (Jeroen Demeyer, 1 August 2012) === - * Trac #13290: add configure.patch (see above). - -=== mpc-1.0 (Jeroen Demeyer, 27 July 2012) === - * Trac #13290: upgrade to stable version 1.0. - * Remove no_fortify_source.patch (which is upstream now). - * Remove legacy "unset RM" command. - -=== mpc-1.0.0dev1126.p1 (Jeroen Demeyer, 23 March 2012) === - * Trac #12515: add no_fortify_source.patch to remove compiler option - "-D_FORTIFY_SOURCE=2". - -=== mpc-1.0.0dev1126 (Jeroen Demeyer, 22 February 2012) === - * Trac #12515: Upgrade to mpc-1.0.0, svn revision 1126 - * Unset CC and CFLAGS in spkg-install. - * Various fixes in spkg-install. - * Do not delete old libraries, see #12548. - -=== mpc-0.8.3-dev-svn793 (Yann Laigle-Chapuy, June 19th, 2010) === - * Upgrade to version 0.8.3-dev-svn793. This version of MPC includes a - faster mpc_pow_si. - -=== mpc-0.8.1 (Yann Laigle-Chapuy, January 2010) === - * Upgrade to version 0.8.1. - -=== mpc-0.6 (Philippe Theveny, August 2009) === - * Upgrade to version 0.6 (there was an optional spkg mpc-0.5.p0) - -=== mpc-0.5 (Philippe Theveny, October 18th, 2008) === - * initial release +None diff --git a/build/pkgs/mpc/checksums.ini b/build/pkgs/mpc/checksums.ini index 5aeaba2977f..c0800f351f1 100644 --- a/build/pkgs/mpc/checksums.ini +++ b/build/pkgs/mpc/checksums.ini @@ -1,4 +1,4 @@ -tarball=mpc-VERSION.tar.bz2 -sha1=057a2e3b938a980a3f7dc3cf7eb29d4a9b20e0ed -md5=b715eaed64cbab249a5bb0b30e1d8bad -cksum=3181545621 +tarball=mpc-VERSION.tar.gz +sha1=5072d82ab50ec36cc8c0e320b5c377adb48abe70 +md5=68fadff3358fb3e7976c7a398a0af4c3 +cksum=4238895906 diff --git a/build/pkgs/mpc/package-version.txt b/build/pkgs/mpc/package-version.txt index f9c24f5d4ec..6d7de6e6abe 100644 --- a/build/pkgs/mpc/package-version.txt +++ b/build/pkgs/mpc/package-version.txt @@ -1 +1 @@ -1.0.p0 +1.0.2 diff --git a/build/pkgs/mpc/patches/configure.patch b/build/pkgs/mpc/patches/configure.patch deleted file mode 100644 index fa90926eb25..00000000000 --- a/build/pkgs/mpc/patches/configure.patch +++ /dev/null @@ -1,1842 +0,0 @@ -diff -rud src/configure.ac b/configure.ac ---- src/configure.ac 2012-07-19 14:33:51.000000000 +0200 -+++ b/configure.ac 2012-08-01 15:34:32.000000000 +0200 -@@ -30,9 +30,6 @@ - USER_CC=$CC - USER_CFLAGS=$CFLAGS - --# automake 1.12 seems to require this, but automake 1.11 doesn't recognize it --m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) -- - AC_CANONICAL_HOST - AC_CONFIG_MACRO_DIR([m4]) - -@@ -111,6 +108,11 @@ - AC_PROG_CC - AC_LANG(C) - -+# Automake 1.12 seems to require this, but automake 1.11 doesn't recognize it. -+# Do not call AM_PROG_AR before MPC_GMP_CC_CFLAGS, since otherwise ac_cv_prog_CC -+# is already set and overrides our CC setting (which may come from gmp.h). -+m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) -+ - # Set up LibTool - LT_INIT - -diff -rud src/aclocal.m4 b/aclocal.m4 ---- src/aclocal.m4 2012-07-19 14:33:57.000000000 +0200 -+++ b/aclocal.m4 2012-08-01 15:56:44.000000000 +0200 -@@ -1,4 +1,4 @@ --# generated automatically by aclocal 1.11.5 -*- Autoconf -*- -+# generated automatically by aclocal 1.11.6 -*- Autoconf -*- - - # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, - # 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, -@@ -38,7 +38,7 @@ - [am__api_version='1.11' - dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to - dnl require some minimum version. Point them to the right macro. --m4_if([$1], [1.11.5], [], -+m4_if([$1], [1.11.6], [], - [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl - ]) - -@@ -54,7 +54,7 @@ - # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. - # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. - AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], --[AM_AUTOMAKE_VERSION([1.11.5])dnl -+[AM_AUTOMAKE_VERSION([1.11.6])dnl - m4_ifndef([AC_AUTOCONF_VERSION], - [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl - _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) -Only in b: autom4te.cache -diff -rud src/configure b/configure ---- src/configure 2012-07-19 14:33:58.000000000 +0200 -+++ b/configure 2012-08-01 15:56:46.000000000 +0200 -@@ -659,18 +659,8 @@ - LD - FGREP - LIBTOOL --SED --EGREP --GREP --VALGRIND --host_os --host_vendor --host_cpu --host --build_os --build_vendor --build_cpu --build -+ac_ct_AR -+AR - am__fastdepCC_FALSE - am__fastdepCC_TRUE - CCDEPMODE -@@ -688,8 +678,18 @@ - LDFLAGS - CFLAGS - CC --ac_ct_AR --AR -+SED -+EGREP -+GREP -+VALGRIND -+host_os -+host_vendor -+host_cpu -+host -+build_os -+build_vendor -+build_cpu -+build - MAINT - MAINTAINER_MODE_FALSE - MAINTAINER_MODE_TRUE -@@ -758,7 +758,6 @@ - ac_user_opts=' - enable_option_checking - enable_maintainer_mode --enable_dependency_tracking - with_mpfr_include - with_mpfr_lib - with_mpfr -@@ -767,6 +766,7 @@ - with_gmp - enable_logging - enable_valgrind_tests -+enable_dependency_tracking - enable_shared - enable_static - with_pic -@@ -1404,11 +1404,11 @@ - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --enable-maintainer-mode enable make rules and dependencies not useful - (and sometimes confusing) to the casual installer -- --disable-dependency-tracking speeds up one-time build -- --enable-dependency-tracking do not reject slow dependency extractors - --enable-logging enable logging of function calls to stderr (default - = no) - --enable-valgrind-tests run checks through valgrind (default = no) -+ --disable-dependency-tracking speeds up one-time build -+ --enable-dependency-tracking do not reject slow dependency extractors - --enable-shared[=PKGS] build shared libraries [default=yes] - --enable-static[=PKGS] build static libraries [default=yes] - --enable-fast-install[=PKGS] -@@ -2815,1149 +2815,6 @@ - USER_CC=$CC - USER_CFLAGS=$CFLAGS - --# automake 1.12 seems to require this, but automake 1.11 doesn't recognize it --DEPDIR="${am__leading_dot}deps" -- --ac_config_commands="$ac_config_commands depfiles" -- -- --am_make=${MAKE-make} --cat > confinc << 'END' --am__doit: -- @echo this is the am__doit target --.PHONY: am__doit --END --# If we don't find an include directive, just comment out the code. --{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 --$as_echo_n "checking for style of include used by $am_make... " >&6; } --am__include="#" --am__quote= --_am_result=none --# First try GNU make style include. --echo "include confinc" > confmf --# Ignore all kinds of additional output from `make'. --case `$am_make -s -f confmf 2> /dev/null` in #( --*the\ am__doit\ target*) -- am__include=include -- am__quote= -- _am_result=GNU -- ;; --esac --# Now try BSD make style include. --if test "$am__include" = "#"; then -- echo '.include "confinc"' > confmf -- case `$am_make -s -f confmf 2> /dev/null` in #( -- *the\ am__doit\ target*) -- am__include=.include -- am__quote="\"" -- _am_result=BSD -- ;; -- esac --fi -- -- --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 --$as_echo "$_am_result" >&6; } --rm -f confinc confmf -- --# Check whether --enable-dependency-tracking was given. --if test "${enable_dependency_tracking+set}" = set; then : -- enableval=$enable_dependency_tracking; --fi -- --if test "x$enable_dependency_tracking" != xno; then -- am_depcomp="$ac_aux_dir/depcomp" -- AMDEPBACKSLASH='\' -- am__nodep='_no' --fi -- if test "x$enable_dependency_tracking" != xno; then -- AMDEP_TRUE= -- AMDEP_FALSE='#' --else -- AMDEP_TRUE='#' -- AMDEP_FALSE= --fi -- -- --ac_ext=c --ac_cpp='$CPP $CPPFLAGS' --ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' --ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' --ac_compiler_gnu=$ac_cv_c_compiler_gnu --if test -n "$ac_tool_prefix"; then -- # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. --set dummy ${ac_tool_prefix}gcc; ac_word=$2 --{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 --$as_echo_n "checking for $ac_word... " >&6; } --if ${ac_cv_prog_CC+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- if test -n "$CC"; then -- ac_cv_prog_CC="$CC" # Let the user override the test. --else --as_save_IFS=$IFS; IFS=$PATH_SEPARATOR --for as_dir in $PATH --do -- IFS=$as_save_IFS -- test -z "$as_dir" && as_dir=. -- for ac_exec_ext in '' $ac_executable_extensions; do -- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then -- ac_cv_prog_CC="${ac_tool_prefix}gcc" -- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 -- break 2 -- fi --done -- done --IFS=$as_save_IFS -- --fi --fi --CC=$ac_cv_prog_CC --if test -n "$CC"; then -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 --$as_echo "$CC" >&6; } --else -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 --$as_echo "no" >&6; } --fi -- -- --fi --if test -z "$ac_cv_prog_CC"; then -- ac_ct_CC=$CC -- # Extract the first word of "gcc", so it can be a program name with args. --set dummy gcc; ac_word=$2 --{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 --$as_echo_n "checking for $ac_word... " >&6; } --if ${ac_cv_prog_ac_ct_CC+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- if test -n "$ac_ct_CC"; then -- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. --else --as_save_IFS=$IFS; IFS=$PATH_SEPARATOR --for as_dir in $PATH --do -- IFS=$as_save_IFS -- test -z "$as_dir" && as_dir=. -- for ac_exec_ext in '' $ac_executable_extensions; do -- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then -- ac_cv_prog_ac_ct_CC="gcc" -- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 -- break 2 -- fi --done -- done --IFS=$as_save_IFS -- --fi --fi --ac_ct_CC=$ac_cv_prog_ac_ct_CC --if test -n "$ac_ct_CC"; then -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 --$as_echo "$ac_ct_CC" >&6; } --else -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 --$as_echo "no" >&6; } --fi -- -- if test "x$ac_ct_CC" = x; then -- CC="" -- else -- case $cross_compiling:$ac_tool_warned in --yes:) --{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 --$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} --ac_tool_warned=yes ;; --esac -- CC=$ac_ct_CC -- fi --else -- CC="$ac_cv_prog_CC" --fi -- --if test -z "$CC"; then -- if test -n "$ac_tool_prefix"; then -- # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. --set dummy ${ac_tool_prefix}cc; ac_word=$2 --{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 --$as_echo_n "checking for $ac_word... " >&6; } --if ${ac_cv_prog_CC+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- if test -n "$CC"; then -- ac_cv_prog_CC="$CC" # Let the user override the test. --else --as_save_IFS=$IFS; IFS=$PATH_SEPARATOR --for as_dir in $PATH --do -- IFS=$as_save_IFS -- test -z "$as_dir" && as_dir=. -- for ac_exec_ext in '' $ac_executable_extensions; do -- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then -- ac_cv_prog_CC="${ac_tool_prefix}cc" -- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 -- break 2 -- fi --done -- done --IFS=$as_save_IFS -- --fi --fi --CC=$ac_cv_prog_CC --if test -n "$CC"; then -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 --$as_echo "$CC" >&6; } --else -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 --$as_echo "no" >&6; } --fi -- -- -- fi --fi --if test -z "$CC"; then -- # Extract the first word of "cc", so it can be a program name with args. --set dummy cc; ac_word=$2 --{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 --$as_echo_n "checking for $ac_word... " >&6; } --if ${ac_cv_prog_CC+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- if test -n "$CC"; then -- ac_cv_prog_CC="$CC" # Let the user override the test. --else -- ac_prog_rejected=no --as_save_IFS=$IFS; IFS=$PATH_SEPARATOR --for as_dir in $PATH --do -- IFS=$as_save_IFS -- test -z "$as_dir" && as_dir=. -- for ac_exec_ext in '' $ac_executable_extensions; do -- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then -- if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then -- ac_prog_rejected=yes -- continue -- fi -- ac_cv_prog_CC="cc" -- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 -- break 2 -- fi --done -- done --IFS=$as_save_IFS -- --if test $ac_prog_rejected = yes; then -- # We found a bogon in the path, so make sure we never use it. -- set dummy $ac_cv_prog_CC -- shift -- if test $# != 0; then -- # We chose a different compiler from the bogus one. -- # However, it has the same basename, so the bogon will be chosen -- # first if we set CC to just the basename; use the full file name. -- shift -- ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" -- fi --fi --fi --fi --CC=$ac_cv_prog_CC --if test -n "$CC"; then -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 --$as_echo "$CC" >&6; } --else -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 --$as_echo "no" >&6; } --fi -- -- --fi --if test -z "$CC"; then -- if test -n "$ac_tool_prefix"; then -- for ac_prog in cl.exe -- do -- # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. --set dummy $ac_tool_prefix$ac_prog; ac_word=$2 --{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 --$as_echo_n "checking for $ac_word... " >&6; } --if ${ac_cv_prog_CC+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- if test -n "$CC"; then -- ac_cv_prog_CC="$CC" # Let the user override the test. --else --as_save_IFS=$IFS; IFS=$PATH_SEPARATOR --for as_dir in $PATH --do -- IFS=$as_save_IFS -- test -z "$as_dir" && as_dir=. -- for ac_exec_ext in '' $ac_executable_extensions; do -- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then -- ac_cv_prog_CC="$ac_tool_prefix$ac_prog" -- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 -- break 2 -- fi --done -- done --IFS=$as_save_IFS -- --fi --fi --CC=$ac_cv_prog_CC --if test -n "$CC"; then -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 --$as_echo "$CC" >&6; } --else -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 --$as_echo "no" >&6; } --fi -- -- -- test -n "$CC" && break -- done --fi --if test -z "$CC"; then -- ac_ct_CC=$CC -- for ac_prog in cl.exe --do -- # Extract the first word of "$ac_prog", so it can be a program name with args. --set dummy $ac_prog; ac_word=$2 --{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 --$as_echo_n "checking for $ac_word... " >&6; } --if ${ac_cv_prog_ac_ct_CC+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- if test -n "$ac_ct_CC"; then -- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. --else --as_save_IFS=$IFS; IFS=$PATH_SEPARATOR --for as_dir in $PATH --do -- IFS=$as_save_IFS -- test -z "$as_dir" && as_dir=. -- for ac_exec_ext in '' $ac_executable_extensions; do -- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then -- ac_cv_prog_ac_ct_CC="$ac_prog" -- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 -- break 2 -- fi --done -- done --IFS=$as_save_IFS -- --fi --fi --ac_ct_CC=$ac_cv_prog_ac_ct_CC --if test -n "$ac_ct_CC"; then -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 --$as_echo "$ac_ct_CC" >&6; } --else -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 --$as_echo "no" >&6; } --fi -- -- -- test -n "$ac_ct_CC" && break --done -- -- if test "x$ac_ct_CC" = x; then -- CC="" -- else -- case $cross_compiling:$ac_tool_warned in --yes:) --{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 --$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} --ac_tool_warned=yes ;; --esac -- CC=$ac_ct_CC -- fi --fi -- --fi -- -- --test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 --$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} --as_fn_error $? "no acceptable C compiler found in \$PATH --See \`config.log' for more details" "$LINENO" 5; } -- --# Provide some information about the compiler. --$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 --set X $ac_compile --ac_compiler=$2 --for ac_option in --version -v -V -qversion; do -- { { ac_try="$ac_compiler $ac_option >&5" --case "(($ac_try" in -- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; -- *) ac_try_echo=$ac_try;; --esac --eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" --$as_echo "$ac_try_echo"; } >&5 -- (eval "$ac_compiler $ac_option >&5") 2>conftest.err -- ac_status=$? -- if test -s conftest.err; then -- sed '10a\ --... rest of stderr output deleted ... -- 10q' conftest.err >conftest.er1 -- cat conftest.er1 >&5 -- fi -- rm -f conftest.er1 conftest.err -- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -- test $ac_status = 0; } --done -- --cat confdefs.h - <<_ACEOF >conftest.$ac_ext --/* end confdefs.h. */ -- --int --main () --{ -- -- ; -- return 0; --} --_ACEOF --ac_clean_files_save=$ac_clean_files --ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" --# Try to create an executable without -o first, disregard a.out. --# It will help us diagnose broken compilers, and finding out an intuition --# of exeext. --{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 --$as_echo_n "checking whether the C compiler works... " >&6; } --ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` -- --# The possible output files: --ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" -- --ac_rmfiles= --for ac_file in $ac_files --do -- case $ac_file in -- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; -- * ) ac_rmfiles="$ac_rmfiles $ac_file";; -- esac --done --rm -f $ac_rmfiles -- --if { { ac_try="$ac_link_default" --case "(($ac_try" in -- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; -- *) ac_try_echo=$ac_try;; --esac --eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" --$as_echo "$ac_try_echo"; } >&5 -- (eval "$ac_link_default") 2>&5 -- ac_status=$? -- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -- test $ac_status = 0; }; then : -- # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. --# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' --# in a Makefile. We should not override ac_cv_exeext if it was cached, --# so that the user can short-circuit this test for compilers unknown to --# Autoconf. --for ac_file in $ac_files '' --do -- test -f "$ac_file" || continue -- case $ac_file in -- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) -- ;; -- [ab].out ) -- # We found the default executable, but exeext='' is most -- # certainly right. -- break;; -- *.* ) -- if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; -- then :; else -- ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` -- fi -- # We set ac_cv_exeext here because the later test for it is not -- # safe: cross compilers may not add the suffix if given an `-o' -- # argument, so we may need to know it at that point already. -- # Even if this section looks crufty: it has the advantage of -- # actually working. -- break;; -- * ) -- break;; -- esac --done --test "$ac_cv_exeext" = no && ac_cv_exeext= -- --else -- ac_file='' --fi --if test -z "$ac_file"; then : -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 --$as_echo "no" >&6; } --$as_echo "$as_me: failed program was:" >&5 --sed 's/^/| /' conftest.$ac_ext >&5 -- --{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 --$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} --as_fn_error 77 "C compiler cannot create executables --See \`config.log' for more details" "$LINENO" 5; } --else -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 --$as_echo "yes" >&6; } --fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 --$as_echo_n "checking for C compiler default output file name... " >&6; } --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 --$as_echo "$ac_file" >&6; } --ac_exeext=$ac_cv_exeext -- --rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out --ac_clean_files=$ac_clean_files_save --{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 --$as_echo_n "checking for suffix of executables... " >&6; } --if { { ac_try="$ac_link" --case "(($ac_try" in -- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; -- *) ac_try_echo=$ac_try;; --esac --eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" --$as_echo "$ac_try_echo"; } >&5 -- (eval "$ac_link") 2>&5 -- ac_status=$? -- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -- test $ac_status = 0; }; then : -- # If both `conftest.exe' and `conftest' are `present' (well, observable) --# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will --# work properly (i.e., refer to `conftest.exe'), while it won't with --# `rm'. --for ac_file in conftest.exe conftest conftest.*; do -- test -f "$ac_file" || continue -- case $ac_file in -- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; -- *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` -- break;; -- * ) break;; -- esac --done --else -- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 --$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} --as_fn_error $? "cannot compute suffix of executables: cannot compile and link --See \`config.log' for more details" "$LINENO" 5; } --fi --rm -f conftest conftest$ac_cv_exeext --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 --$as_echo "$ac_cv_exeext" >&6; } -- --rm -f conftest.$ac_ext --EXEEXT=$ac_cv_exeext --ac_exeext=$EXEEXT --cat confdefs.h - <<_ACEOF >conftest.$ac_ext --/* end confdefs.h. */ --#include --int --main () --{ --FILE *f = fopen ("conftest.out", "w"); -- return ferror (f) || fclose (f) != 0; -- -- ; -- return 0; --} --_ACEOF --ac_clean_files="$ac_clean_files conftest.out" --# Check that the compiler produces executables we can run. If not, either --# the compiler is broken, or we cross compile. --{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 --$as_echo_n "checking whether we are cross compiling... " >&6; } --if test "$cross_compiling" != yes; then -- { { ac_try="$ac_link" --case "(($ac_try" in -- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; -- *) ac_try_echo=$ac_try;; --esac --eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" --$as_echo "$ac_try_echo"; } >&5 -- (eval "$ac_link") 2>&5 -- ac_status=$? -- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -- test $ac_status = 0; } -- if { ac_try='./conftest$ac_cv_exeext' -- { { case "(($ac_try" in -- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; -- *) ac_try_echo=$ac_try;; --esac --eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" --$as_echo "$ac_try_echo"; } >&5 -- (eval "$ac_try") 2>&5 -- ac_status=$? -- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -- test $ac_status = 0; }; }; then -- cross_compiling=no -- else -- if test "$cross_compiling" = maybe; then -- cross_compiling=yes -- else -- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 --$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} --as_fn_error $? "cannot run C compiled programs. --If you meant to cross compile, use \`--host'. --See \`config.log' for more details" "$LINENO" 5; } -- fi -- fi --fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 --$as_echo "$cross_compiling" >&6; } -- --rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out --ac_clean_files=$ac_clean_files_save --{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 --$as_echo_n "checking for suffix of object files... " >&6; } --if ${ac_cv_objext+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- cat confdefs.h - <<_ACEOF >conftest.$ac_ext --/* end confdefs.h. */ -- --int --main () --{ -- -- ; -- return 0; --} --_ACEOF --rm -f conftest.o conftest.obj --if { { ac_try="$ac_compile" --case "(($ac_try" in -- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; -- *) ac_try_echo=$ac_try;; --esac --eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" --$as_echo "$ac_try_echo"; } >&5 -- (eval "$ac_compile") 2>&5 -- ac_status=$? -- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -- test $ac_status = 0; }; then : -- for ac_file in conftest.o conftest.obj conftest.*; do -- test -f "$ac_file" || continue; -- case $ac_file in -- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; -- *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` -- break;; -- esac --done --else -- $as_echo "$as_me: failed program was:" >&5 --sed 's/^/| /' conftest.$ac_ext >&5 -- --{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 --$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} --as_fn_error $? "cannot compute suffix of object files: cannot compile --See \`config.log' for more details" "$LINENO" 5; } --fi --rm -f conftest.$ac_cv_objext conftest.$ac_ext --fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 --$as_echo "$ac_cv_objext" >&6; } --OBJEXT=$ac_cv_objext --ac_objext=$OBJEXT --{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 --$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } --if ${ac_cv_c_compiler_gnu+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- cat confdefs.h - <<_ACEOF >conftest.$ac_ext --/* end confdefs.h. */ -- --int --main () --{ --#ifndef __GNUC__ -- choke me --#endif -- -- ; -- return 0; --} --_ACEOF --if ac_fn_c_try_compile "$LINENO"; then : -- ac_compiler_gnu=yes --else -- ac_compiler_gnu=no --fi --rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext --ac_cv_c_compiler_gnu=$ac_compiler_gnu -- --fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 --$as_echo "$ac_cv_c_compiler_gnu" >&6; } --if test $ac_compiler_gnu = yes; then -- GCC=yes --else -- GCC= --fi --ac_test_CFLAGS=${CFLAGS+set} --ac_save_CFLAGS=$CFLAGS --{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 --$as_echo_n "checking whether $CC accepts -g... " >&6; } --if ${ac_cv_prog_cc_g+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- ac_save_c_werror_flag=$ac_c_werror_flag -- ac_c_werror_flag=yes -- ac_cv_prog_cc_g=no -- CFLAGS="-g" -- cat confdefs.h - <<_ACEOF >conftest.$ac_ext --/* end confdefs.h. */ -- --int --main () --{ -- -- ; -- return 0; --} --_ACEOF --if ac_fn_c_try_compile "$LINENO"; then : -- ac_cv_prog_cc_g=yes --else -- CFLAGS="" -- cat confdefs.h - <<_ACEOF >conftest.$ac_ext --/* end confdefs.h. */ -- --int --main () --{ -- -- ; -- return 0; --} --_ACEOF --if ac_fn_c_try_compile "$LINENO"; then : -- --else -- ac_c_werror_flag=$ac_save_c_werror_flag -- CFLAGS="-g" -- cat confdefs.h - <<_ACEOF >conftest.$ac_ext --/* end confdefs.h. */ -- --int --main () --{ -- -- ; -- return 0; --} --_ACEOF --if ac_fn_c_try_compile "$LINENO"; then : -- ac_cv_prog_cc_g=yes --fi --rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext --fi --rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext --fi --rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -- ac_c_werror_flag=$ac_save_c_werror_flag --fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 --$as_echo "$ac_cv_prog_cc_g" >&6; } --if test "$ac_test_CFLAGS" = set; then -- CFLAGS=$ac_save_CFLAGS --elif test $ac_cv_prog_cc_g = yes; then -- if test "$GCC" = yes; then -- CFLAGS="-g -O2" -- else -- CFLAGS="-g" -- fi --else -- if test "$GCC" = yes; then -- CFLAGS="-O2" -- else -- CFLAGS= -- fi --fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 --$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } --if ${ac_cv_prog_cc_c89+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- ac_cv_prog_cc_c89=no --ac_save_CC=$CC --cat confdefs.h - <<_ACEOF >conftest.$ac_ext --/* end confdefs.h. */ --#include --#include --struct stat; --/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ --struct buf { int x; }; --FILE * (*rcsopen) (struct buf *, struct stat *, int); --static char *e (p, i) -- char **p; -- int i; --{ -- return p[i]; --} --static char *f (char * (*g) (char **, int), char **p, ...) --{ -- char *s; -- va_list v; -- va_start (v,p); -- s = g (p, va_arg (v,int)); -- va_end (v); -- return s; --} -- --/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has -- function prototypes and stuff, but not '\xHH' hex character constants. -- These don't provoke an error unfortunately, instead are silently treated -- as 'x'. The following induces an error, until -std is added to get -- proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an -- array size at least. It's necessary to write '\x00'==0 to get something -- that's true only with -std. */ --int osf4_cc_array ['\x00' == 0 ? 1 : -1]; -- --/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters -- inside strings and character constants. */ --#define FOO(x) 'x' --int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; -- --int test (int i, double x); --struct s1 {int (*f) (int a);}; --struct s2 {int (*f) (double a);}; --int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); --int argc; --char **argv; --int --main () --{ --return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; -- ; -- return 0; --} --_ACEOF --for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -- -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" --do -- CC="$ac_save_CC $ac_arg" -- if ac_fn_c_try_compile "$LINENO"; then : -- ac_cv_prog_cc_c89=$ac_arg --fi --rm -f core conftest.err conftest.$ac_objext -- test "x$ac_cv_prog_cc_c89" != "xno" && break --done --rm -f conftest.$ac_ext --CC=$ac_save_CC -- --fi --# AC_CACHE_VAL --case "x$ac_cv_prog_cc_c89" in -- x) -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 --$as_echo "none needed" >&6; } ;; -- xno) -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 --$as_echo "unsupported" >&6; } ;; -- *) -- CC="$CC $ac_cv_prog_cc_c89" -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 --$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; --esac --if test "x$ac_cv_prog_cc_c89" != xno; then : -- --fi -- --ac_ext=c --ac_cpp='$CPP $CPPFLAGS' --ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' --ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' --ac_compiler_gnu=$ac_cv_c_compiler_gnu -- --depcc="$CC" am_compiler_list= -- --{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 --$as_echo_n "checking dependency style of $depcc... " >&6; } --if ${am_cv_CC_dependencies_compiler_type+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then -- # We make a subdir and do the tests there. Otherwise we can end up -- # making bogus files that we don't know about and never remove. For -- # instance it was reported that on HP-UX the gcc test will end up -- # making a dummy file named `D' -- because `-MD' means `put the output -- # in D'. -- rm -rf conftest.dir -- mkdir conftest.dir -- # Copy depcomp to subdir because otherwise we won't find it if we're -- # using a relative directory. -- cp "$am_depcomp" conftest.dir -- cd conftest.dir -- # We will build objects and dependencies in a subdirectory because -- # it helps to detect inapplicable dependency modes. For instance -- # both Tru64's cc and ICC support -MD to output dependencies as a -- # side effect of compilation, but ICC will put the dependencies in -- # the current directory while Tru64 will put them in the object -- # directory. -- mkdir sub -- -- am_cv_CC_dependencies_compiler_type=none -- if test "$am_compiler_list" = ""; then -- am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` -- fi -- am__universal=false -- case " $depcc " in #( -- *\ -arch\ *\ -arch\ *) am__universal=true ;; -- esac -- -- for depmode in $am_compiler_list; do -- # Setup a source with many dependencies, because some compilers -- # like to wrap large dependency lists on column 80 (with \), and -- # we should not choose a depcomp mode which is confused by this. -- # -- # We need to recreate these files for each test, as the compiler may -- # overwrite some of them when testing with obscure command lines. -- # This happens at least with the AIX C compiler. -- : > sub/conftest.c -- for i in 1 2 3 4 5 6; do -- echo '#include "conftst'$i'.h"' >> sub/conftest.c -- # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with -- # Solaris 8's {/usr,}/bin/sh. -- touch sub/conftst$i.h -- done -- echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf -- -- # We check with `-c' and `-o' for the sake of the "dashmstdout" -- # mode. It turns out that the SunPro C++ compiler does not properly -- # handle `-M -o', and we need to detect this. Also, some Intel -- # versions had trouble with output in subdirs -- am__obj=sub/conftest.${OBJEXT-o} -- am__minus_obj="-o $am__obj" -- case $depmode in -- gcc) -- # This depmode causes a compiler race in universal mode. -- test "$am__universal" = false || continue -- ;; -- nosideeffect) -- # after this tag, mechanisms are not by side-effect, so they'll -- # only be used when explicitly requested -- if test "x$enable_dependency_tracking" = xyes; then -- continue -- else -- break -- fi -- ;; -- msvc7 | msvc7msys | msvisualcpp | msvcmsys) -- # This compiler won't grok `-c -o', but also, the minuso test has -- # not run yet. These depmodes are late enough in the game, and -- # so weak that their functioning should not be impacted. -- am__obj=conftest.${OBJEXT-o} -- am__minus_obj= -- ;; -- none) break ;; -- esac -- if depmode=$depmode \ -- source=sub/conftest.c object=$am__obj \ -- depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ -- $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ -- >/dev/null 2>conftest.err && -- grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && -- grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && -- grep $am__obj sub/conftest.Po > /dev/null 2>&1 && -- ${MAKE-make} -s -f confmf > /dev/null 2>&1; then -- # icc doesn't choke on unknown options, it will just issue warnings -- # or remarks (even with -Werror). So we grep stderr for any message -- # that says an option was ignored or not supported. -- # When given -MP, icc 7.0 and 7.1 complain thusly: -- # icc: Command line warning: ignoring option '-M'; no argument required -- # The diagnosis changed in icc 8.0: -- # icc: Command line remark: option '-MP' not supported -- if (grep 'ignoring option' conftest.err || -- grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else -- am_cv_CC_dependencies_compiler_type=$depmode -- break -- fi -- fi -- done -- -- cd .. -- rm -rf conftest.dir --else -- am_cv_CC_dependencies_compiler_type=none --fi -- --fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 --$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } --CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type -- -- if -- test "x$enable_dependency_tracking" != xno \ -- && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then -- am__fastdepCC_TRUE= -- am__fastdepCC_FALSE='#' --else -- am__fastdepCC_TRUE='#' -- am__fastdepCC_FALSE= --fi -- -- -- --if test -n "$ac_tool_prefix"; then -- for ac_prog in ar lib "link -lib" -- do -- # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. --set dummy $ac_tool_prefix$ac_prog; ac_word=$2 --{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 --$as_echo_n "checking for $ac_word... " >&6; } --if ${ac_cv_prog_AR+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- if test -n "$AR"; then -- ac_cv_prog_AR="$AR" # Let the user override the test. --else --as_save_IFS=$IFS; IFS=$PATH_SEPARATOR --for as_dir in $PATH --do -- IFS=$as_save_IFS -- test -z "$as_dir" && as_dir=. -- for ac_exec_ext in '' $ac_executable_extensions; do -- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then -- ac_cv_prog_AR="$ac_tool_prefix$ac_prog" -- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 -- break 2 -- fi --done -- done --IFS=$as_save_IFS -- --fi --fi --AR=$ac_cv_prog_AR --if test -n "$AR"; then -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 --$as_echo "$AR" >&6; } --else -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 --$as_echo "no" >&6; } --fi -- -- -- test -n "$AR" && break -- done --fi --if test -z "$AR"; then -- ac_ct_AR=$AR -- for ac_prog in ar lib "link -lib" --do -- # Extract the first word of "$ac_prog", so it can be a program name with args. --set dummy $ac_prog; ac_word=$2 --{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 --$as_echo_n "checking for $ac_word... " >&6; } --if ${ac_cv_prog_ac_ct_AR+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- if test -n "$ac_ct_AR"; then -- ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. --else --as_save_IFS=$IFS; IFS=$PATH_SEPARATOR --for as_dir in $PATH --do -- IFS=$as_save_IFS -- test -z "$as_dir" && as_dir=. -- for ac_exec_ext in '' $ac_executable_extensions; do -- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then -- ac_cv_prog_ac_ct_AR="$ac_prog" -- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 -- break 2 -- fi --done -- done --IFS=$as_save_IFS -- --fi --fi --ac_ct_AR=$ac_cv_prog_ac_ct_AR --if test -n "$ac_ct_AR"; then -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 --$as_echo "$ac_ct_AR" >&6; } --else -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 --$as_echo "no" >&6; } --fi -- -- -- test -n "$ac_ct_AR" && break --done -- -- if test "x$ac_ct_AR" = x; then -- AR="false" -- else -- case $cross_compiling:$ac_tool_warned in --yes:) --{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 --$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} --ac_tool_warned=yes ;; --esac -- AR=$ac_ct_AR -- fi --fi -- --: ${AR=ar} -- --{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5 --$as_echo_n "checking the archiver ($AR) interface... " >&6; } --if ${am_cv_ar_interface+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- am_cv_ar_interface=ar -- cat confdefs.h - <<_ACEOF >conftest.$ac_ext --/* end confdefs.h. */ --int some_variable = 0; --_ACEOF --if ac_fn_c_try_compile "$LINENO"; then : -- am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5' -- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 -- (eval $am_ar_try) 2>&5 -- ac_status=$? -- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -- test $ac_status = 0; } -- if test "$ac_status" -eq 0; then -- am_cv_ar_interface=ar -- else -- am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5' -- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 -- (eval $am_ar_try) 2>&5 -- ac_status=$? -- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -- test $ac_status = 0; } -- if test "$ac_status" -eq 0; then -- am_cv_ar_interface=lib -- else -- am_cv_ar_interface=unknown -- fi -- fi -- rm -f conftest.lib libconftest.a -- --fi --rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -- --fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5 --$as_echo "$am_cv_ar_interface" >&6; } -- --case $am_cv_ar_interface in --ar) -- ;; --lib) -- # Microsoft lib, so override with the ar-lib wrapper script. -- # FIXME: It is wrong to rewrite AR. -- # But if we don't then we get into trouble of one sort or another. -- # A longer-term fix would be to have automake use am__AR in this case, -- # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something -- # similar. -- AR="$am_aux_dir/ar-lib $AR" -- ;; --unknown) -- as_fn_error $? "could not determine $AR interface" "$LINENO" 5 -- ;; --esac -- -- - # Make sure we can run config.sub. - $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || - as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 -@@ -4770,6 +3627,256 @@ - test $ac_status = 0; } - done - -+cat confdefs.h - <<_ACEOF >conftest.$ac_ext -+/* end confdefs.h. */ -+ -+int -+main () -+{ -+ -+ ; -+ return 0; -+} -+_ACEOF -+ac_clean_files_save=$ac_clean_files -+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" -+# Try to create an executable without -o first, disregard a.out. -+# It will help us diagnose broken compilers, and finding out an intuition -+# of exeext. -+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 -+$as_echo_n "checking whether the C compiler works... " >&6; } -+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` -+ -+# The possible output files: -+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" -+ -+ac_rmfiles= -+for ac_file in $ac_files -+do -+ case $ac_file in -+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; -+ * ) ac_rmfiles="$ac_rmfiles $ac_file";; -+ esac -+done -+rm -f $ac_rmfiles -+ -+if { { ac_try="$ac_link_default" -+case "(($ac_try" in -+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; -+ *) ac_try_echo=$ac_try;; -+esac -+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -+$as_echo "$ac_try_echo"; } >&5 -+ (eval "$ac_link_default") 2>&5 -+ ac_status=$? -+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -+ test $ac_status = 0; }; then : -+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. -+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' -+# in a Makefile. We should not override ac_cv_exeext if it was cached, -+# so that the user can short-circuit this test for compilers unknown to -+# Autoconf. -+for ac_file in $ac_files '' -+do -+ test -f "$ac_file" || continue -+ case $ac_file in -+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) -+ ;; -+ [ab].out ) -+ # We found the default executable, but exeext='' is most -+ # certainly right. -+ break;; -+ *.* ) -+ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; -+ then :; else -+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` -+ fi -+ # We set ac_cv_exeext here because the later test for it is not -+ # safe: cross compilers may not add the suffix if given an `-o' -+ # argument, so we may need to know it at that point already. -+ # Even if this section looks crufty: it has the advantage of -+ # actually working. -+ break;; -+ * ) -+ break;; -+ esac -+done -+test "$ac_cv_exeext" = no && ac_cv_exeext= -+ -+else -+ ac_file='' -+fi -+if test -z "$ac_file"; then : -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -+$as_echo "no" >&6; } -+$as_echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -+as_fn_error 77 "C compiler cannot create executables -+See \`config.log' for more details" "$LINENO" 5; } -+else -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -+$as_echo "yes" >&6; } -+fi -+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 -+$as_echo_n "checking for C compiler default output file name... " >&6; } -+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 -+$as_echo "$ac_file" >&6; } -+ac_exeext=$ac_cv_exeext -+ -+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out -+ac_clean_files=$ac_clean_files_save -+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 -+$as_echo_n "checking for suffix of executables... " >&6; } -+if { { ac_try="$ac_link" -+case "(($ac_try" in -+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; -+ *) ac_try_echo=$ac_try;; -+esac -+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -+$as_echo "$ac_try_echo"; } >&5 -+ (eval "$ac_link") 2>&5 -+ ac_status=$? -+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -+ test $ac_status = 0; }; then : -+ # If both `conftest.exe' and `conftest' are `present' (well, observable) -+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will -+# work properly (i.e., refer to `conftest.exe'), while it won't with -+# `rm'. -+for ac_file in conftest.exe conftest conftest.*; do -+ test -f "$ac_file" || continue -+ case $ac_file in -+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; -+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` -+ break;; -+ * ) break;; -+ esac -+done -+else -+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -+as_fn_error $? "cannot compute suffix of executables: cannot compile and link -+See \`config.log' for more details" "$LINENO" 5; } -+fi -+rm -f conftest conftest$ac_cv_exeext -+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 -+$as_echo "$ac_cv_exeext" >&6; } -+ -+rm -f conftest.$ac_ext -+EXEEXT=$ac_cv_exeext -+ac_exeext=$EXEEXT -+cat confdefs.h - <<_ACEOF >conftest.$ac_ext -+/* end confdefs.h. */ -+#include -+int -+main () -+{ -+FILE *f = fopen ("conftest.out", "w"); -+ return ferror (f) || fclose (f) != 0; -+ -+ ; -+ return 0; -+} -+_ACEOF -+ac_clean_files="$ac_clean_files conftest.out" -+# Check that the compiler produces executables we can run. If not, either -+# the compiler is broken, or we cross compile. -+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 -+$as_echo_n "checking whether we are cross compiling... " >&6; } -+if test "$cross_compiling" != yes; then -+ { { ac_try="$ac_link" -+case "(($ac_try" in -+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; -+ *) ac_try_echo=$ac_try;; -+esac -+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -+$as_echo "$ac_try_echo"; } >&5 -+ (eval "$ac_link") 2>&5 -+ ac_status=$? -+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -+ test $ac_status = 0; } -+ if { ac_try='./conftest$ac_cv_exeext' -+ { { case "(($ac_try" in -+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; -+ *) ac_try_echo=$ac_try;; -+esac -+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -+$as_echo "$ac_try_echo"; } >&5 -+ (eval "$ac_try") 2>&5 -+ ac_status=$? -+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -+ test $ac_status = 0; }; }; then -+ cross_compiling=no -+ else -+ if test "$cross_compiling" = maybe; then -+ cross_compiling=yes -+ else -+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -+as_fn_error $? "cannot run C compiled programs. -+If you meant to cross compile, use \`--host'. -+See \`config.log' for more details" "$LINENO" 5; } -+ fi -+ fi -+fi -+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 -+$as_echo "$cross_compiling" >&6; } -+ -+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out -+ac_clean_files=$ac_clean_files_save -+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 -+$as_echo_n "checking for suffix of object files... " >&6; } -+if ${ac_cv_objext+:} false; then : -+ $as_echo_n "(cached) " >&6 -+else -+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext -+/* end confdefs.h. */ -+ -+int -+main () -+{ -+ -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.o conftest.obj -+if { { ac_try="$ac_compile" -+case "(($ac_try" in -+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; -+ *) ac_try_echo=$ac_try;; -+esac -+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -+$as_echo "$ac_try_echo"; } >&5 -+ (eval "$ac_compile") 2>&5 -+ ac_status=$? -+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -+ test $ac_status = 0; }; then : -+ for ac_file in conftest.o conftest.obj conftest.*; do -+ test -f "$ac_file" || continue; -+ case $ac_file in -+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; -+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` -+ break;; -+ esac -+done -+else -+ $as_echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -+as_fn_error $? "cannot compute suffix of object files: cannot compile -+See \`config.log' for more details" "$LINENO" 5; } -+fi -+rm -f conftest.$ac_cv_objext conftest.$ac_ext -+fi -+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 -+$as_echo "$ac_cv_objext" >&6; } -+OBJEXT=$ac_cv_objext -+ac_objext=$OBJEXT - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 - $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } - if ${ac_cv_c_compiler_gnu+:} false; then : -@@ -4980,6 +4087,69 @@ - ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' - ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' - ac_compiler_gnu=$ac_cv_c_compiler_gnu -+DEPDIR="${am__leading_dot}deps" -+ -+ac_config_commands="$ac_config_commands depfiles" -+ -+ -+am_make=${MAKE-make} -+cat > confinc << 'END' -+am__doit: -+ @echo this is the am__doit target -+.PHONY: am__doit -+END -+# If we don't find an include directive, just comment out the code. -+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 -+$as_echo_n "checking for style of include used by $am_make... " >&6; } -+am__include="#" -+am__quote= -+_am_result=none -+# First try GNU make style include. -+echo "include confinc" > confmf -+# Ignore all kinds of additional output from `make'. -+case `$am_make -s -f confmf 2> /dev/null` in #( -+*the\ am__doit\ target*) -+ am__include=include -+ am__quote= -+ _am_result=GNU -+ ;; -+esac -+# Now try BSD make style include. -+if test "$am__include" = "#"; then -+ echo '.include "confinc"' > confmf -+ case `$am_make -s -f confmf 2> /dev/null` in #( -+ *the\ am__doit\ target*) -+ am__include=.include -+ am__quote="\"" -+ _am_result=BSD -+ ;; -+ esac -+fi -+ -+ -+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 -+$as_echo "$_am_result" >&6; } -+rm -f confinc confmf -+ -+# Check whether --enable-dependency-tracking was given. -+if test "${enable_dependency_tracking+set}" = set; then : -+ enableval=$enable_dependency_tracking; -+fi -+ -+if test "x$enable_dependency_tracking" != xno; then -+ am_depcomp="$ac_aux_dir/depcomp" -+ AMDEPBACKSLASH='\' -+ am__nodep='_no' -+fi -+ if test "x$enable_dependency_tracking" != xno; then -+ AMDEP_TRUE= -+ AMDEP_FALSE='#' -+else -+ AMDEP_TRUE='#' -+ AMDEP_FALSE= -+fi -+ -+ - - depcc="$CC" am_compiler_list= - -@@ -5116,6 +4286,171 @@ - ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -+# Automake 1.12 seems to require this, but automake 1.11 doesn't recognize it. -+# Do not call AM_PROG_AR before MPC_GMP_CC_CFLAGS, since otherwise ac_cv_prog_CC -+# is already set and overrides our CC setting (which may come from gmp.h). -+ -+if test -n "$ac_tool_prefix"; then -+ for ac_prog in ar lib "link -lib" -+ do -+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -+set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -+$as_echo_n "checking for $ac_word... " >&6; } -+if ${ac_cv_prog_AR+:} false; then : -+ $as_echo_n "(cached) " >&6 -+else -+ if test -n "$AR"; then -+ ac_cv_prog_AR="$AR" # Let the user override the test. -+else -+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -+for as_dir in $PATH -+do -+ IFS=$as_save_IFS -+ test -z "$as_dir" && as_dir=. -+ for ac_exec_ext in '' $ac_executable_extensions; do -+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then -+ ac_cv_prog_AR="$ac_tool_prefix$ac_prog" -+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 -+ break 2 -+ fi -+done -+ done -+IFS=$as_save_IFS -+ -+fi -+fi -+AR=$ac_cv_prog_AR -+if test -n "$AR"; then -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 -+$as_echo "$AR" >&6; } -+else -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -+$as_echo "no" >&6; } -+fi -+ -+ -+ test -n "$AR" && break -+ done -+fi -+if test -z "$AR"; then -+ ac_ct_AR=$AR -+ for ac_prog in ar lib "link -lib" -+do -+ # Extract the first word of "$ac_prog", so it can be a program name with args. -+set dummy $ac_prog; ac_word=$2 -+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -+$as_echo_n "checking for $ac_word... " >&6; } -+if ${ac_cv_prog_ac_ct_AR+:} false; then : -+ $as_echo_n "(cached) " >&6 -+else -+ if test -n "$ac_ct_AR"; then -+ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. -+else -+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -+for as_dir in $PATH -+do -+ IFS=$as_save_IFS -+ test -z "$as_dir" && as_dir=. -+ for ac_exec_ext in '' $ac_executable_extensions; do -+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then -+ ac_cv_prog_ac_ct_AR="$ac_prog" -+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 -+ break 2 -+ fi -+done -+ done -+IFS=$as_save_IFS -+ -+fi -+fi -+ac_ct_AR=$ac_cv_prog_ac_ct_AR -+if test -n "$ac_ct_AR"; then -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 -+$as_echo "$ac_ct_AR" >&6; } -+else -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -+$as_echo "no" >&6; } -+fi -+ -+ -+ test -n "$ac_ct_AR" && break -+done -+ -+ if test "x$ac_ct_AR" = x; then -+ AR="false" -+ else -+ case $cross_compiling:$ac_tool_warned in -+yes:) -+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -+ac_tool_warned=yes ;; -+esac -+ AR=$ac_ct_AR -+ fi -+fi -+ -+: ${AR=ar} -+ -+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5 -+$as_echo_n "checking the archiver ($AR) interface... " >&6; } -+if ${am_cv_ar_interface+:} false; then : -+ $as_echo_n "(cached) " >&6 -+else -+ am_cv_ar_interface=ar -+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext -+/* end confdefs.h. */ -+int some_variable = 0; -+_ACEOF -+if ac_fn_c_try_compile "$LINENO"; then : -+ am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5' -+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 -+ (eval $am_ar_try) 2>&5 -+ ac_status=$? -+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -+ test $ac_status = 0; } -+ if test "$ac_status" -eq 0; then -+ am_cv_ar_interface=ar -+ else -+ am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5' -+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 -+ (eval $am_ar_try) 2>&5 -+ ac_status=$? -+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -+ test $ac_status = 0; } -+ if test "$ac_status" -eq 0; then -+ am_cv_ar_interface=lib -+ else -+ am_cv_ar_interface=unknown -+ fi -+ fi -+ rm -f conftest.lib libconftest.a -+ -+fi -+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -+ -+fi -+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5 -+$as_echo "$am_cv_ar_interface" >&6; } -+ -+case $am_cv_ar_interface in -+ar) -+ ;; -+lib) -+ # Microsoft lib, so override with the ar-lib wrapper script. -+ # FIXME: It is wrong to rewrite AR. -+ # But if we don't then we get into trouble of one sort or another. -+ # A longer-term fix would be to have automake use am__AR in this case, -+ # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something -+ # similar. -+ AR="$am_aux_dir/ar-lib $AR" -+ ;; -+unknown) -+ as_fn_error $? "could not determine $AR interface" "$LINENO" 5 -+ ;; -+esac -+ -+ - # Set up LibTool - case `pwd` in - *\ * | *\ *) -@@ -14665,7 +14000,7 @@ - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for current svn version" >&5 - $as_echo_n "checking for current svn version... " >&6; } -- SVNVERSION=1241M -+ SVNVERSION=exported - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SVNVERSION" >&5 - $as_echo "$SVNVERSION" >&6; } -@@ -14805,10 +14140,6 @@ - as_fn_error $? "conditional \"am__fastdepCC\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 - fi --if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then -- as_fn_error $? "conditional \"am__fastdepCC\" was never defined. --Usually this means the macro was only invoked conditionally." "$LINENO" 5 --fi - - : "${CONFIG_STATUS=./config.status}" - ac_write_fail=0 -diff -rud src/Makefile.in b/Makefile.in ---- src/Makefile.in 2012-07-19 14:33:58.000000000 +0200 -+++ b/Makefile.in 2012-08-01 15:56:48.000000000 +0200 -@@ -1,4 +1,4 @@ --# Makefile.in generated by automake 1.11.5 from Makefile.am. -+# Makefile.in generated by automake 1.11.6 from Makefile.am. - # @configure_input@ - - # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -@@ -634,7 +634,7 @@ - *.zip*) \ - unzip $(distdir).zip ;;\ - esac -- chmod -R a-w $(distdir); chmod a+w $(distdir) -+ chmod -R a-w $(distdir); chmod u+w $(distdir) - mkdir $(distdir)/_build - mkdir $(distdir)/_inst - chmod a-w $(distdir) -diff -rud src/doc/Makefile.in b/doc/Makefile.in ---- src/doc/Makefile.in 2012-07-19 14:33:58.000000000 +0200 -+++ b/doc/Makefile.in 2012-08-01 15:56:47.000000000 +0200 -@@ -1,4 +1,4 @@ --# Makefile.in generated by automake 1.11.5 from Makefile.am. -+# Makefile.in generated by automake 1.11.6 from Makefile.am. - # @configure_input@ - - # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -diff -rud src/src/Makefile.in b/src/Makefile.in ---- src/src/Makefile.in 2012-07-19 14:33:58.000000000 +0200 -+++ b/src/Makefile.in 2012-08-01 15:56:47.000000000 +0200 -@@ -1,4 +1,4 @@ --# Makefile.in generated by automake 1.11.5 from Makefile.am. -+# Makefile.in generated by automake 1.11.6 from Makefile.am. - # @configure_input@ - - # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -diff -rud src/tests/Makefile.in b/tests/Makefile.in ---- src/tests/Makefile.in 2012-07-19 14:33:58.000000000 +0200 -+++ b/tests/Makefile.in 2012-08-01 15:56:47.000000000 +0200 -@@ -1,4 +1,4 @@ --# Makefile.in generated by automake 1.11.5 from Makefile.am. -+# Makefile.in generated by automake 1.11.6 from Makefile.am. - # @configure_input@ - - # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, diff --git a/build/pkgs/ncurses/SPKG.txt b/build/pkgs/ncurses/SPKG.txt index 6b32d4ec530..ee995e9265b 100644 --- a/build/pkgs/ncurses/SPKG.txt +++ b/build/pkgs/ncurses/SPKG.txt @@ -44,22 +44,6 @@ None === Patches === - * osx_gcc_flags.patch: Pass -no-cpp-precomp to GCC on OS X. + * xopen_source.patch: remove harmful check from aclocal.m4 which may + reintroduce XOPEN_SOURCE on systems where it should not be used. - * SPARC_fix.patch: Don't mess with _XOPEN_SOURCE on Solaris. - - * xopen_source_extended.patch: Only define _XOPEN_SOURCE_EXTENDED for - C compiler. - - -== Changelog == - -=== ncurses-5.9.p2 (Jean-Pierre Flori, 4 November 2013) === - * #15268: Let ncurses build on Solaris. - * Build without ADA support. - -=== ncurses-5.9.p1 (Volker Braun, 22 Aug 2013) === - * Build narrow and wide versions (#15080) - -=== ncurses-5.9 (Volker Braun, 3 April 2013) === - * Initial version diff --git a/build/pkgs/ncurses/checksums.ini b/build/pkgs/ncurses/checksums.ini index da09375fc77..24699f0ab9f 100644 --- a/build/pkgs/ncurses/checksums.ini +++ b/build/pkgs/ncurses/checksums.ini @@ -1,4 +1,4 @@ tarball=ncurses-VERSION.tar.bz2 -sha1=56ca923ec9e9b99d3b7e88d79e443afa5ed5e4a3 -md5=b370caf5c80709215b3647f62845c3d8 -cksum=973191780 +sha1=c9e9e398a9bcfeb1cc005c4d3eac0998f3445ff2 +md5=b2996284ae18610aa2a4e5a968c5e1f3 +cksum=3072370532 diff --git a/build/pkgs/ncurses/package-version.txt b/build/pkgs/ncurses/package-version.txt index b86105c47bf..a2a77b0243f 100644 --- a/build/pkgs/ncurses/package-version.txt +++ b/build/pkgs/ncurses/package-version.txt @@ -1 +1 @@ -5.9.p2 +5.9.20131221 diff --git a/build/pkgs/ncurses/patches/SPARC_fix.patch b/build/pkgs/ncurses/patches/SPARC_fix.patch deleted file mode 100644 index 4774977bc67..00000000000 --- a/build/pkgs/ncurses/patches/SPARC_fix.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- src/configure 2011-04-01 00:35:51.000000000 +0100 -+++ new/configure 2013-08-14 18:46:20.686767274 +0100 -@@ -7096,7 +7096,7 @@ - # setting _XOPEN_SOURCE breaks Lynx on SCO Unix / OpenServer - ;; - solaris2.1[0-9]) #(vi -- cf_xopen_source="-D__EXTENSIONS__ -D_XOPEN_SOURCE=$cf_XOPEN_SOURCE" -+ cf_xopen_source="-D__EXTENSIONS__" - ;; - solaris2.[1-9]) #(vi - cf_xopen_source="-D__EXTENSIONS__" diff --git a/build/pkgs/ncurses/patches/osx_gcc_flags.patch b/build/pkgs/ncurses/patches/osx_gcc_flags.patch deleted file mode 100644 index fbdbf006550..00000000000 --- a/build/pkgs/ncurses/patches/osx_gcc_flags.patch +++ /dev/null @@ -1,47 +0,0 @@ -diff -u -r old/aclocal.m4 src/aclocal.m4 ---- old/aclocal.m4 2011-04-01 00:35:38.000000000 +0100 -+++ src/aclocal.m4 2013-04-05 21:00:44.179404568 +0100 -@@ -5088,7 +5088,6 @@ - chmod +x mk_shared_lib.sh - ;; - darwin*) #(vi -- EXTRA_CFLAGS="-no-cpp-precomp" - CC_SHARED_OPTS="-dynamic" - MK_SHARED_LIB='${CC} ${CFLAGS} -dynamiclib -install_name ${libdir}/`basename $[@]` -compatibility_version ${ABI_VERSION} -current_version ${ABI_VERSION} -o $[@]' - test "$cf_cv_shlib_version" = auto && cf_cv_shlib_version=abi -diff -u -r old/Ada95/aclocal.m4 src/Ada95/aclocal.m4 ---- old/Ada95/aclocal.m4 2011-04-01 00:32:36.000000000 +0100 -+++ src/Ada95/aclocal.m4 2013-04-05 21:02:04.550258173 +0100 -@@ -2935,7 +2935,6 @@ - chmod +x mk_shared_lib.sh - ;; - darwin*) #(vi -- EXTRA_CFLAGS="-no-cpp-precomp" - CC_SHARED_OPTS="-dynamic" - MK_SHARED_LIB='${CC} ${CFLAGS} -dynamiclib -install_name ${libdir}/`basename $[@]` -compatibility_version ${ABI_VERSION} -current_version ${ABI_VERSION} -o $[@]' - test "$cf_cv_shlib_version" = auto && cf_cv_shlib_version=abi -Only in src/Ada95: aclocal.m4~ -diff -u -r old/Ada95/configure src/Ada95/configure ---- old/Ada95/configure 2011-04-01 00:34:47.000000000 +0100 -+++ src/Ada95/configure 2013-04-05 21:01:57.871353745 +0100 -@@ -7460,7 +7460,6 @@ - chmod +x mk_shared_lib.sh - ;; - darwin*) #(vi -- EXTRA_CFLAGS="-no-cpp-precomp" - CC_SHARED_OPTS="-dynamic" - MK_SHARED_LIB='${CC} ${CFLAGS} -dynamiclib -install_name ${libdir}/`basename $@` -compatibility_version ${ABI_VERSION} -current_version ${ABI_VERSION} -o $@' - test "$cf_cv_shlib_version" = auto && cf_cv_shlib_version=abi -Only in src/Ada95: configure~ -diff -u -r old/configure src/configure ---- old/configure 2011-04-01 00:35:51.000000000 +0100 -+++ src/configure 2013-04-05 21:01:48.756484101 +0100 -@@ -5584,7 +5584,6 @@ - chmod +x mk_shared_lib.sh - ;; - darwin*) #(vi -- EXTRA_CFLAGS="-no-cpp-precomp" - CC_SHARED_OPTS="-dynamic" - MK_SHARED_LIB='${CC} ${CFLAGS} -dynamiclib -install_name ${libdir}/`basename $@` -compatibility_version ${ABI_VERSION} -current_version ${ABI_VERSION} -o $@' - test "$cf_cv_shlib_version" = auto && cf_cv_shlib_version=abi -Only in src: configure~ diff --git a/build/pkgs/ncurses/patches/xopen_source.patch b/build/pkgs/ncurses/patches/xopen_source.patch new file mode 100644 index 00000000000..cbb128b4bab --- /dev/null +++ b/build/pkgs/ncurses/patches/xopen_source.patch @@ -0,0 +1,313 @@ +diff -druN ncurses-5.9.20131221.orig/aclocal.m4 ncurses-5.9.20131221/aclocal.m4 +--- ncurses-5.9.20131221.orig/aclocal.m4 2013-11-23 10:20:50.000000000 -0800 ++++ ncurses-5.9.20131221/aclocal.m4 2014-02-07 06:00:43.277597929 -0800 +@@ -7198,32 +7198,3 @@ + CF_ADD_CFLAGS($cf_xopen_source) + fi + +-dnl In anything but the default case, we may have system-specific setting +-dnl which is still not guaranteed to provide all of the entrypoints that +-dnl _XOPEN_SOURCE would yield. +-if test -n "$cf_XOPEN_SOURCE" && test -z "$cf_cv_xopen_source" ; then +- AC_MSG_CHECKING(if _XOPEN_SOURCE really is set) +- AC_TRY_COMPILE([#include ],[ +-#ifndef _XOPEN_SOURCE +-make an error +-#endif], +- [cf_XOPEN_SOURCE_set=yes], +- [cf_XOPEN_SOURCE_set=no]) +- AC_MSG_RESULT($cf_XOPEN_SOURCE_set) +- if test $cf_XOPEN_SOURCE_set = yes +- then +- AC_TRY_COMPILE([#include ],[ +-#if (_XOPEN_SOURCE - 0) < $cf_XOPEN_SOURCE +-make an error +-#endif], +- [cf_XOPEN_SOURCE_set_ok=yes], +- [cf_XOPEN_SOURCE_set_ok=no]) +- if test $cf_XOPEN_SOURCE_set_ok = no +- then +- AC_MSG_WARN(_XOPEN_SOURCE is lower than requested) +- fi +- else +- CF_TRY_XOPEN_SOURCE +- fi +-fi +-]) +diff -druN ncurses-5.9.20131221.orig/configure ncurses-5.9.20131221/configure +--- ncurses-5.9.20131221.orig/configure 2013-12-14 16:44:11.000000000 -0800 ++++ ncurses-5.9.20131221/configure 2014-02-07 06:01:25.747602176 -0800 +@@ -8119,273 +8119,6 @@ + + fi + +-if test -n "$cf_XOPEN_SOURCE" && test -z "$cf_cv_xopen_source" ; then +- echo "$as_me:8123: checking if _XOPEN_SOURCE really is set" >&5 +-echo $ECHO_N "checking if _XOPEN_SOURCE really is set... $ECHO_C" >&6 +- cat >conftest.$ac_ext <<_ACEOF +-#line 8126 "configure" +-#include "confdefs.h" +-#include +-int +-main () +-{ +- +-#ifndef _XOPEN_SOURCE +-make an error +-#endif +- ; +- return 0; +-} +-_ACEOF +-rm -f conftest.$ac_objext +-if { (eval echo "$as_me:8141: \"$ac_compile\"") >&5 +- (eval $ac_compile) 2>&5 +- ac_status=$? +- echo "$as_me:8144: \$? = $ac_status" >&5 +- (exit $ac_status); } && +- { ac_try='test -s conftest.$ac_objext' +- { (eval echo "$as_me:8147: \"$ac_try\"") >&5 +- (eval $ac_try) 2>&5 +- ac_status=$? +- echo "$as_me:8150: \$? = $ac_status" >&5 +- (exit $ac_status); }; }; then +- cf_XOPEN_SOURCE_set=yes +-else +- echo "$as_me: failed program was:" >&5 +-cat conftest.$ac_ext >&5 +-cf_XOPEN_SOURCE_set=no +-fi +-rm -f conftest.$ac_objext conftest.$ac_ext +- echo "$as_me:8159: result: $cf_XOPEN_SOURCE_set" >&5 +-echo "${ECHO_T}$cf_XOPEN_SOURCE_set" >&6 +- if test $cf_XOPEN_SOURCE_set = yes +- then +- cat >conftest.$ac_ext <<_ACEOF +-#line 8164 "configure" +-#include "confdefs.h" +-#include +-int +-main () +-{ +- +-#if (_XOPEN_SOURCE - 0) < $cf_XOPEN_SOURCE +-make an error +-#endif +- ; +- return 0; +-} +-_ACEOF +-rm -f conftest.$ac_objext +-if { (eval echo "$as_me:8179: \"$ac_compile\"") >&5 +- (eval $ac_compile) 2>&5 +- ac_status=$? +- echo "$as_me:8182: \$? = $ac_status" >&5 +- (exit $ac_status); } && +- { ac_try='test -s conftest.$ac_objext' +- { (eval echo "$as_me:8185: \"$ac_try\"") >&5 +- (eval $ac_try) 2>&5 +- ac_status=$? +- echo "$as_me:8188: \$? = $ac_status" >&5 +- (exit $ac_status); }; }; then +- cf_XOPEN_SOURCE_set_ok=yes +-else +- echo "$as_me: failed program was:" >&5 +-cat conftest.$ac_ext >&5 +-cf_XOPEN_SOURCE_set_ok=no +-fi +-rm -f conftest.$ac_objext conftest.$ac_ext +- if test $cf_XOPEN_SOURCE_set_ok = no +- then +- { echo "$as_me:8199: WARNING: _XOPEN_SOURCE is lower than requested" >&5 +-echo "$as_me: WARNING: _XOPEN_SOURCE is lower than requested" >&2;} +- fi +- else +- +-echo "$as_me:8204: checking if we should define _XOPEN_SOURCE" >&5 +-echo $ECHO_N "checking if we should define _XOPEN_SOURCE... $ECHO_C" >&6 +-if test "${cf_cv_xopen_source+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 +-else +- +- cat >conftest.$ac_ext <<_ACEOF +-#line 8211 "configure" +-#include "confdefs.h" +- +-#include +-#include +-#include +- +-int +-main () +-{ +- +-#ifndef _XOPEN_SOURCE +-make an error +-#endif +- ; +- return 0; +-} +-_ACEOF +-rm -f conftest.$ac_objext +-if { (eval echo "$as_me:8230: \"$ac_compile\"") >&5 +- (eval $ac_compile) 2>&5 +- ac_status=$? +- echo "$as_me:8233: \$? = $ac_status" >&5 +- (exit $ac_status); } && +- { ac_try='test -s conftest.$ac_objext' +- { (eval echo "$as_me:8236: \"$ac_try\"") >&5 +- (eval $ac_try) 2>&5 +- ac_status=$? +- echo "$as_me:8239: \$? = $ac_status" >&5 +- (exit $ac_status); }; }; then +- cf_cv_xopen_source=no +-else +- echo "$as_me: failed program was:" >&5 +-cat conftest.$ac_ext >&5 +-cf_save="$CPPFLAGS" +- CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE=$cf_XOPEN_SOURCE" +- cat >conftest.$ac_ext <<_ACEOF +-#line 8248 "configure" +-#include "confdefs.h" +- +-#include +-#include +-#include +- +-int +-main () +-{ +- +-#ifdef _XOPEN_SOURCE +-make an error +-#endif +- ; +- return 0; +-} +-_ACEOF +-rm -f conftest.$ac_objext +-if { (eval echo "$as_me:8267: \"$ac_compile\"") >&5 +- (eval $ac_compile) 2>&5 +- ac_status=$? +- echo "$as_me:8270: \$? = $ac_status" >&5 +- (exit $ac_status); } && +- { ac_try='test -s conftest.$ac_objext' +- { (eval echo "$as_me:8273: \"$ac_try\"") >&5 +- (eval $ac_try) 2>&5 +- ac_status=$? +- echo "$as_me:8276: \$? = $ac_status" >&5 +- (exit $ac_status); }; }; then +- cf_cv_xopen_source=no +-else +- echo "$as_me: failed program was:" >&5 +-cat conftest.$ac_ext >&5 +-cf_cv_xopen_source=$cf_XOPEN_SOURCE +-fi +-rm -f conftest.$ac_objext conftest.$ac_ext +- CPPFLAGS="$cf_save" +- +-fi +-rm -f conftest.$ac_objext conftest.$ac_ext +- +-fi +-echo "$as_me:8291: result: $cf_cv_xopen_source" >&5 +-echo "${ECHO_T}$cf_cv_xopen_source" >&6 +- +-if test "$cf_cv_xopen_source" != no ; then +- +-CFLAGS=`echo "$CFLAGS" | \ +- sed -e 's/-[UD]'"_XOPEN_SOURCE"'\(=[^ ]*\)\?[ ]/ /g' \ +- -e 's/-[UD]'"_XOPEN_SOURCE"'\(=[^ ]*\)\?$//g'` +- +-CPPFLAGS=`echo "$CPPFLAGS" | \ +- sed -e 's/-[UD]'"_XOPEN_SOURCE"'\(=[^ ]*\)\?[ ]/ /g' \ +- -e 's/-[UD]'"_XOPEN_SOURCE"'\(=[^ ]*\)\?$//g'` +- +- cf_temp_xopen_source="-D_XOPEN_SOURCE=$cf_cv_xopen_source" +- +-cf_fix_cppflags=no +-cf_new_cflags= +-cf_new_cppflags= +-cf_new_extra_cppflags= +- +-for cf_add_cflags in $cf_temp_xopen_source +-do +-case $cf_fix_cppflags in +-no) +- case $cf_add_cflags in #(vi +- -undef|-nostdinc*|-I*|-D*|-U*|-E|-P|-C) #(vi +- case $cf_add_cflags in +- -D*) +- cf_tst_cflags=`echo ${cf_add_cflags} |sed -e 's/^-D[^=]*='\''\"[^"]*//'` +- +- test "${cf_add_cflags}" != "${cf_tst_cflags}" \ +- && test -z "${cf_tst_cflags}" \ +- && cf_fix_cppflags=yes +- +- if test $cf_fix_cppflags = yes ; then +- cf_new_extra_cppflags="$cf_new_extra_cppflags $cf_add_cflags" +- continue +- elif test "${cf_tst_cflags}" = "\"'" ; then +- cf_new_extra_cppflags="$cf_new_extra_cppflags $cf_add_cflags" +- continue +- fi +- ;; +- esac +- case "$CPPFLAGS" in +- *$cf_add_cflags) #(vi +- ;; +- *) #(vi +- case $cf_add_cflags in #(vi +- -D*) +- cf_tst_cppflags=`echo "x$cf_add_cflags" | sed -e 's/^...//' -e 's/=.*//'` +- +-CPPFLAGS=`echo "$CPPFLAGS" | \ +- sed -e 's/-[UD]'"$cf_tst_cppflags"'\(=[^ ]*\)\?[ ]/ /g' \ +- -e 's/-[UD]'"$cf_tst_cppflags"'\(=[^ ]*\)\?$//g'` +- +- ;; +- esac +- cf_new_cppflags="$cf_new_cppflags $cf_add_cflags" +- ;; +- esac +- ;; +- *) +- cf_new_cflags="$cf_new_cflags $cf_add_cflags" +- ;; +- esac +- ;; +-yes) +- cf_new_extra_cppflags="$cf_new_extra_cppflags $cf_add_cflags" +- +- cf_tst_cflags=`echo ${cf_add_cflags} |sed -e 's/^[^"]*"'\''//'` +- +- test "${cf_add_cflags}" != "${cf_tst_cflags}" \ +- && test -z "${cf_tst_cflags}" \ +- && cf_fix_cppflags=no +- ;; +-esac +-done +- +-if test -n "$cf_new_cflags" ; then +- +- CFLAGS="$CFLAGS $cf_new_cflags" +-fi +- +-if test -n "$cf_new_cppflags" ; then +- +- CPPFLAGS="$CPPFLAGS $cf_new_cppflags" +-fi +- +-if test -n "$cf_new_extra_cppflags" ; then +- +- EXTRA_CPPFLAGS="$cf_new_extra_cppflags $EXTRA_CPPFLAGS" +-fi +- +-fi +- +- fi +-fi +- + # Work around breakage on OS X + + echo "$as_me:8391: checking if SIGWINCH is defined" >&5 diff --git a/build/pkgs/ncurses/patches/xopen_source_extended.patch b/build/pkgs/ncurses/patches/xopen_source_extended.patch deleted file mode 100644 index 5d3109dd140..00000000000 --- a/build/pkgs/ncurses/patches/xopen_source_extended.patch +++ /dev/null @@ -1,21 +0,0 @@ -diff -druN src.orig/configure src/configure ---- src.orig/configure 2011-04-01 01:35:51.000000000 +0200 -+++ src/configure 2013-11-04 11:19:23.771479564 +0100 -@@ -7864,7 +7864,7 @@ - echo "${ECHO_T}$cf_result" >&6 - - if test "$cf_result" = yes ; then -- CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE_EXTENDED" -+ CFLAGS="$CFLAGS -D_XOPEN_SOURCE_EXTENDED" - elif test "x" != "x" ; then - echo "$as_me:7869: checking checking for compatible value versus " >&5 - echo $ECHO_N "checking checking for compatible value versus ... $ECHO_C" >&6 -@@ -7907,7 +7907,7 @@ - echo "${ECHO_T}$cf_result" >&6 - if test "$cf_result" = no ; then - # perhaps we can override it - try... -- CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE_EXTENDED=" -+ CFLAGS="$CFLAGS -D_XOPEN_SOURCE_EXTENDED=" - fi - fi - diff --git a/build/pkgs/pari/SPKG.txt b/build/pkgs/pari/SPKG.txt index 02e9dcc9462..df136592543 100644 --- a/build/pkgs/pari/SPKG.txt +++ b/build/pkgs/pari/SPKG.txt @@ -66,322 +66,3 @@ of doubt, have a look at the file spkg-src. directory. However, it should not be there in a final version. 4) cd ..; sage --spkg pari-version-name - -== Changelog == - -=== pari-2.5.5.p1 (Jeroen Demeyer, 12 November 2013) === - * Trac #15402: add patch q_eint1.patch - -=== pari-2.5.5.p0 (Jeroen Demeyer, 2 October 2013) === - * Trac #15250: upgrade to version 2.5.5. - -=== pari-2.5.4.p0 (Jeroen Demeyer, 13 May 2013) === - * Trac #14539: upgrade to version 2.5.4. - * Improve documentation of patches. - -=== pari-2.5.3.p3 (Jeroen Demeyer, 31 January 2013) === - * Trac #13054: polred.patch: fix polred() bug. - * Trac #6743: remove Cygwin-specific hacks from spkg-install. - -=== pari-2.5.3.p2 (Jeroen Demeyer, 7 January 2013) === - * Trac #13921: KERNELCFLAGS.patch: when SAGE_DEBUG=yes, compile mp.c - with -O1 (and without -funroll-loops) to avoid a segmentation fault - on some OS X systems. - * Rename PARI_EXTRA_OPTS to PARI_CONFIGURE (consistent with other - packages). - * Trac #13863: galoisanalysis_p4.patch: fix a segmentation fault - under Electric Fence. - -=== pari-2.5.3.p1 (Jeroen Demeyer, 3 January 2013) === - * Trac #13902: add a patch (backported from upstream PARI 2.6.0) - for integer determinants. - -=== pari-2.5.3.p0 (Jeroen Demeyer, 5 October 2012) === - * Trac #13534: upgrade to version 2.5.3 - * Remove upstreamed patch rootpol.patch - -=== pari-2.5.2.p2 (Jean-Pierre Flori, 30 September 2012) === - * Trac #13333: add upstream patch to copy libpari.dll.a on Cygwin. - -=== pari-2.5.2.p1 (Paul Zimmermann, 28 August 2012) === - * Trac #13314: add upstream patch rootpol.patch for rootpol(). - -=== pari-2.5.2.p0 (Jeroen Demeyer, 1 August 2012) === - * Trac #13320: upgrade to version 2.5.2 - * Rename spkg-make to spkg-src - * Remove various upstreamed patches: - - pari_1302.patch - - pari_1304.patch - - reorder_init_opts.patch - -=== pari-2.5.1.p3 (Jeroen Demeyer, 20 March 2012) === - * Trac #12638: add upstream patch pari_1304.patch for issquarefree(0), - see http://pari.math.u-bordeaux.fr/cgi-bin/bugreport.cgi?bug=1304 - -=== pari-2.5.1.p2 (Jeroen Demeyer, 13 March 2012) === - * Trac #12638: add upstream patch pari_1302.patch for ispower(), - see http://pari.math.u-bordeaux.fr/cgi-bin/bugreport.cgi?bug=1302 - * Apply all patches at -p1 level instead of -p0 (just like most other - Sage packages). - -=== pari-2.5.1.p1 (Jeroen Demeyer, 7 March 2012) === - * Trac #12638: add patch GCC_PR49330.patch to work around a bug - in gcc-4.6.3 on OS X 10.4 PPC. - -=== pari-2.5.1.p0 (Jeroen Demeyer, 11 February 2012) === - * Trac #12363: upgrade to PARI 2.5.1. - * Use git instead of svn in spkg-make to obtain the PARI sources. - * Remove upstreamed patch osx_13318_13330.patch. - -=== pari-2.5.0.p3 (Jeroen Demeyer, 20 December 2011) === - * Trac #12158: add reorder_init_opts.patch such that warnings - during pari_init_opts() do not cause segfaults. - -=== pari-2.5.0.p2 (Jeroen Demeyer, 26 July 2011) === - * Trac #11130: update to PARI stable version 2.5.0, which is - equal to svn version 13228. - * Moving to this upstream version fixes #10195, #10767, #11604. - * Remove all previous upstream patches. - * Add current working directory "." to default path in gprc.expect. - * Add patches osx_13318_13330.patch from upstream to fix linking on - Mac OS X. - -=== pari-2.4.3.alpha.p7 (Leif Leonhardy, July 16th, 2011) === - * Trac #11605: Fix typo in spkg-install and add `exit 1` (again) in - case the build fails. - * Quote some more variables and filenames in messages. - -=== pari-2.4.3.alpha.p6 (Dima Pasechnik, 22 April, 2011) === - * Trac #10240: made a proper check for libpari.dll on Cygwin. - -=== pari-2.4.3.alpha.p5 (Jeroen Demeyer, January 23th, 2011) === - * Avoid parallel "make install" because of race conditions. - * Remove Makefile_mv.patch because it doesn't actually fix the race - conditions in "make install". - -=== pari-2.4.3.alpha.p4 (Jeroen Demeyer, January 11th, 2011) === - * Trac #10430 (fixing also #9620, #10279, #10369, #10559) - * Use `patch` to apply patches (at -p0 level because this is how svn - gives the diffs). - * Apply patches for PARI bugs 1084, 1132, 1141, 1143, 1144. - * Move all comments about the patches to patches/README.txt - * Simplify the "install" part of spkg-install by doing "make install" - instead of copying everything by hand. This requires a small patch - to config/Makefile.SH (install_doc_no_make.patch) to ensure that - "make install-doc" does not build the documentation. - * Add patch Makefile_mv.patch to fix race condition in parallel make - install, see - http://pari.math.u-bordeaux.fr/cgi-bin/bugreport.cgi?bug=1148 - * Add patch perl_path.patch to change first line of all perl scripts - to "#!/usr/bin/env perl" (#10559). - * Add src/desc/pari.desc after config/get_MANIFEST in spkg-make to - remove build-time dependency on perl - -=== pari-2.4.3.alpha.p0 (Jeroen Demeyer, November 4th, 2010) === - * Update to PARI 2.4.3 (by using SVN revision 12623). Note that the - PARI developers consider version 2.4.3 to be an "alpha" version with - the idea that 2.4.4 might be a "beta" version and 2.5 will then be - the "stable" version. - * Removed patch for gphelp.in which is now upstream - * Removed patch for paripriv.h because of an upstream change removing - the need for the patch - * Rebased patch for config/get_fltk - -=== pari-2.4.3.svn-12577.p9 (Jeroen Demeyer, September 24th, 2010) === - * Add gprc.expect file to be installed in $SAGE_LOCAL/etc - * Remove $detex = 1; from gphelp.in patch - -=== pari-2.4.3.svn-12577.p7 (Jeroen Demeyer, September 17th, 2010) === - * Add -fno-common to DLCFLAGS on all Darwin systems instead of - PPC/PPC64 only. - * Add upstream fix for rnfequation(,,1) over Q - -=== pari-2.4.3.svn-12577.p6 (Jeroen Demeyer, September 11th, 2010) === - * Add upstream fix for config/get_dlcflags and remove the patch - * Add upstream fix for bnfinit() and the rnfkummer test - * Instead of patching Configure, force bash in spkg-install - -=== pari-2.4.3.svn-12577.p5 (Leif Leonhardy, Jeroen Demeyer, September 5th, 2010) === - * Added patches to: - - config/get_config_options: - * Make invalid arguments to "--graphic" a "Configure" error - (rather than potentially running into *compilation* errors - later). - - config/get_fltk: (see also/ported from #9722) - * Add libstdc++ to the libraries (to support Fedora 13 et al.). - * Also check the presence of the FLTK include directory to - prevent compilation errors on broken installations. - - config/get_X11: (see also/ported from #9722) - * Also search */lib64/* directories when doing a 64-bit build. - * Give more specific messages. - * Slightly extended existing patch to src/kernel/gmp/mp.c: - - Allow disabling PARI's use of "GMP internals" by preprocessor - directive (i.e. by adding "-DPARI_DONT_USE_GMP_INTERNALS" to - CFLAGS). Brief explanation added. - * spkg-install: - - Don't override user-specified CFLAGS (w.r.t. optimization, unless - SAGE_DEBUG=yes). - - Handle PARI_EXTRA_OPTS properly, and print informative messages - (regarding graphics support for plotting). - - Recognize SAGE_TUNE_PARI in addition to SAGE_TUNE_pari, and - add "--tune" to PARI_EXTRA_OPTS if self-tuning was requested. - - Clear/unset lots of (environment) variables used by PARI that might - unintentionally get their values from user settings. - - Quote *all* occurrences of SAGE_LOCAL (and some other expressions). - - Use $UNAME instead of `uname` everywhere, use "elif ...". - - *Always* use $MAKE (changed for "install-data"). - - Begin all error messages with "Error". - - Removed useless tests of $? at end. - - Some clean-up (typos, formatting); some comments, some messages added. - * spkg-check: - - Use $MAKE instead of "make". - - Don't override user-specified CFLAGS (w.r.t. optimization, unless - SAGE_DEBUG=yes). - - Begin error message with "Error". - - Some clean-up. - * Slight corrections to SPKG.txt. - * Updated patches/README.txt, some cosmetic changes. - * Remove patch for config/Makefile.SH and add upstream fix instead - in spkg-make. - * Add upstream fix for src/test/tune.c which should fix tuning. - * Add -O0 to CFLAGS in spkg-make to speed up compiling (the output of - the compiling is not used anyway). - -=== pari-2.4.3.svn-12577.p4 (Jeroen Demeyer, August 22, 2010) === - * Change "test -e" to "test -f" for Solaris. - * Configure using "#!/usr/bin/env bash" instead of "#!/bin/sh" - -=== pari-2.4.3.svn-12577.p3 (Jeroen Demeyer, August 21, 2010) === - * Cosmetic changes - -=== pari-2.4.3.svn-12577.p2 (Jeroen Demeyer, August 17, 2010) === - * Patch get_dlcflags on Darwin - -=== pari-2.4.3.svn-12577 (Jeroen Demeyer, August 5, 2010) === - -=== pari-2.4.3.svn-12546 (Jeroen Demeyer, July 25, 2010) === - * Removed the non-existent get_dlld patching. - * Cleaned up patches/README.txt - -=== pari-2.4.3.svn.p7 (Jeroen Demeyer, July 23, 2010) === - * pari 2.4.3 version svn 12543 - * Remove patches for get_cc, get_dlcflags, get_kernel, get_dlld - -=== pari-2.4.3.svn.p6 (Jeroen Demeyer, July 22, 2010) === - * pari 2.4.3 version svn 12541 - * Added spkg-make script to automate building of this spkg - * Changed patch logic in spkg-install - * Add patches for PARI bug 1079 - -=== pari-2.4.3.svn.p5 (John Cremona July 13, 2010) === - * pari 2.4.3 version svn 12541 - * adds spkg-check by David Kirkby - -=== pari-2.4.3.svn.p1, p2, p3, p4 (Robert Bradshaw and William Stein, -June 26, 2010; John Cremona July 13, 2010) === - * Major new version - * p4 contains pari 2.4.3 version svn 12534 - -=== pari-2.3.5.p1 (Mike Hansen, May 25th, 2010) === - * Do the same fix for Cygwin that we do on Solaris. - -=== pari-2.3.5.p0 (Georg S. Weber, May 2nd, 2010 === - * restore resp. correct the file patches/get_dlld - (there seems to have been a copy'n'paste issue w.r.t. pari-2.3.3.p8) - so that pari is buildable (again) as a dynamical library on Mac OS - (fixes trac ticket #8837, see there for more details) - -=== pari-2.3.5 (Mike Hansen, March 5th, 2010 === - * Update to PARI 2.3.5 - * Removed the alglin2.c patch since it was included upstream. - -=== pari-2.3.3.p8 (Jaap Spies, January 28th 2010) === - * Added 64 bit support for Open Solaris x64 - * This is trac http://trac.sagemath.org/sage_trac/ticket/8099 - -=== pari-2.3.3.p7 (David Kirkby, January 12th 2010) === - * #7901 Changes $MKDIR to 'mkdir' in the spkg-install file. - * #7738 Removed Michael Abshoff as a maintainer. - * Corrected the date on the previous entry - (it was - previously marked as 2009. - -=== pari-2.3.3.p6 (Mike Hansen, January 4th, 2010) === - * Fix on FreeBSD -- see #7825. - -=== pari-2.3.3.p5 (David Kirkby, October 14th, 2009) === - * Removed the use of $CP, since it has been agreed there is no - need for 'cp' to be specified as an environment variable - and to just use the normal CP command. Likewise for 'rm' - * Copied over a paripriv.h specific to Solaris, just as was done - on OS X. This is trac #6579 which allows 'modified sage library code' - to build on Solaris (SPARC) with no changes as long as the - Sun compiler suite can not be found in the path. If that can - be found, then the 'modified sage library code' will fail - for a different reason (see #6595) - -=== pari-2.3.3.p4 (???????????????????????????????????) === - -=== pari-2.3.3.p3 (???????????????????????????????????) === - -=== pari-2.3.3.p2 (Minh Van Nguyen, October 02nd, 2009) === - * Change optimization flag of src/config/get_cc from "-O3" to - "-O1". This fixes a build issue on 32-bit Fedora 11. See ticket #7092. - -=== pari-2.3.3.p1 (David Kirkby, June 30th, 2009) === - * Change code in spkg-install which was supposed to add -fPIC on - Solaris, to code that actually does add -fPIC on Solaris. - Prior to this, PARI built fine on a Sun Blade 2000 without - -fPIC, but failed on a Sun T5240 (hostname t2). I'm not - entirely sure whether this is actually need on Solaris x86 - or not - GCC manual says SPARC (no mention of Solaris x86) - but someone on comp.unxi.solaris reckons it should be on - Solaris x86 too. - - Hopefully this issue can be resolved by the PARI developers and - so the hack removed later. I'll report it to the PAPI developers. - - Thanks are due to Marc Glisse marc.glisse@gmail.com - whose reply to my query on comp.unix.solaris solved this. - - * Corrected a mis-spelling on my name written by someone else. - -=== pari-2.3.3.p0 (Michael Abshoff, Feb. 18th, 2008) === - * apply Karim's hnf patch - * add OSX 10.5 64 bit build support - -=== pari-2.3.3 (William Stein) === - * upgrade to the 2.3.3 release - -=== pari-2.3.2 === - -* 2007-10-31: (Carl Witty) - disable runpath altogether; we want Sage to be relocatable. - install gphelp, and required documentation source files. - -* 2007-09-09: (Michael Abshoff) - add -fPIC to DCLFLAGS on Linux PPC in src/config/get_dlcflags - -* 2007-03-04: included Pablo De Napoli (denapo@gmail.com)'s - improvement so PARI will build on systems with runpath support. - See sage/runpath.txt for details. - -* 2006-09-28: (William Stein and Justin Walker) - Modified PARI build scripts so that they build the - PARI *shared* library even under OS X, and on OS X intel - they build the x86/gmp kernel. - - -* I took the standard PARI tarball, but ran the script spkg-dist on it - to create this directory. This script does various things to some - of the PARI files to make them work better with SAGE, the most - important being to replace calls to exit() with calls to abort(). - -* Also, I placed a directory "sage" in this directory with some files - needed by spkg-install. - -* This changed removed -- 09/28/2006 -#* I changed a line of config/Makefile.SH to -# DLLDFLAGS = $DLLDFLAGS -mimpure-text - - -* Put the extra galois groups data files in the data/galdata subdirectory, diff --git a/build/pkgs/pari/package-version.txt b/build/pkgs/pari/package-version.txt index aa530b68344..fffdb6b0fe7 100644 --- a/build/pkgs/pari/package-version.txt +++ b/build/pkgs/pari/package-version.txt @@ -1 +1 @@ -2.5.5.p1 +2.5.5.p2 diff --git a/build/pkgs/pari/patches/README.txt b/build/pkgs/pari/patches/README.txt index 3315e98bb49..92ec68be9a9 100644 --- a/build/pkgs/pari/patches/README.txt +++ b/build/pkgs/pari/patches/README.txt @@ -69,3 +69,7 @@ C files: - 54eb37055167dbd8d4856b1bd698cf7018db561b and completely backport new algorithm for mpveceint1(). The prefix q_ in the patch filename is to ensure it comes after polred.patch. +* det_garbage.patch (Jeroen Demeyer, #15654): When computing a + determinant(), only collect garbage once per outer loop iteration. + Better increase PARI stack size instead of collecting garbage too + often. diff --git a/build/pkgs/pari/patches/det_garbage.patch b/build/pkgs/pari/patches/det_garbage.patch new file mode 100644 index 00000000000..76293f1a633 --- /dev/null +++ b/build/pkgs/pari/patches/det_garbage.patch @@ -0,0 +1,56 @@ +Binary files src/Olinux-x86_64/alglin1.o and b/Olinux-x86_64/alglin1.o differ +Only in src/Olinux-x86_64: libpari-gmp.so.2.5.5 +diff -ru src/src/basemath/alglin1.c b/src/basemath/alglin1.c +--- src/src/basemath/alglin1.c 2014-01-09 15:43:35.847263581 +0100 ++++ b/src/basemath/alglin1.c 2014-01-09 15:55:47.903649326 +0100 +@@ -2412,6 +2412,7 @@ + a = RgM_shallowcopy(a); + for (i=1; i1) pari_warn(warnmem,"det. col = %ld",i); + gerepileall(av,2, &a,&x); +@@ -2994,6 +2995,7 @@ + a = RgM_shallowcopy(a); + for (i=1; i nbco) return gerepilecopy(av, gcoeff(a,i,i)); + if (k != i) +@@ -3013,7 +3015,7 @@ + for (j=i+1; j<=nbco; j++) + { + gcoeff(a,j,k) = gsub(gcoeff(a,j,k), gmul(m,gcoeff(a,j,i))); +- if (low_stack(lim, stack_lim(av,1))) ++ if (low_stack(lim, stack_lim(av,1)) && (garbage++ == 0)) + { + if(DEBUGMEM>1) pari_warn(warnmem,"det. col = %ld",i); + gerepileall(av,2, &a,&x); +@@ -3063,6 +3065,7 @@ + { + GEN ci, ck, m; + int diveuc = (gequal1(pprec)==0); ++ int garbage = 0; /* Only gerepile() once per loop iteration */ + + p = gcoeff(a,i,i); + if (gequal0(p)) +@@ -3099,7 +3102,7 @@ + GEN p1 = gsub(gmul(p,gel(ck,j)), gmul(m,gel(ci,j))); + if (diveuc) p1 = mydiv(p1,pprec); + gel(ck,j) = gerepileupto(av2, p1); +- if (low_stack(lim,stack_lim(av,2))) ++ if (low_stack(lim,stack_lim(av,2)) && (garbage++ == 0)) + { + if(DEBUGMEM>1) pari_warn(warnmem,"det. col = %ld",i); + gerepileall(av,2, &a,&pprec); diff --git a/build/pkgs/pari/spkg-install b/build/pkgs/pari/spkg-install index 00586e2ba7d..fce58d3fb1a 100755 --- a/build/pkgs/pari/spkg-install +++ b/build/pkgs/pari/spkg-install @@ -33,8 +33,6 @@ set_environment() # This is needed or there are weird locale problems involving rpath # with building Sage: - LC_ALL=C - export LC_ALL LANG=C export LANG diff --git a/build/pkgs/ppl/SPKG.txt b/build/pkgs/ppl/SPKG.txt index 1421f76400a..b55d01b6854 100644 --- a/build/pkgs/ppl/SPKG.txt +++ b/build/pkgs/ppl/SPKG.txt @@ -42,8 +42,15 @@ Enea Zaffanella (University of Parma) == Special Update/Build Instructions == +=== Patches === + * None. + == Changelog == +=== ppl-1.1 (Jean-Pierre Flori, 25 December 2013) === + * #15589: Update to version 1.1. + * Reenable full testsuite by removing tests_Makefile.in.patch. + === ppl-1.1pre9.p0 (Jean-Pierre Flori, 6 August 2013) === * #15001: Update to prerelease 1.1pre9 version. * Let PPL build on Cygwin. @@ -77,4 +84,3 @@ Enea Zaffanella (University of Parma) === ppl-0.11 (Volker Braun, Sept 20, 2010) === * initial SPKG - diff --git a/build/pkgs/ppl/checksums.ini b/build/pkgs/ppl/checksums.ini index 0dbe88a9c9b..519204c0aa9 100644 --- a/build/pkgs/ppl/checksums.ini +++ b/build/pkgs/ppl/checksums.ini @@ -1,4 +1,4 @@ tarball=ppl-VERSION.tar.bz2 -sha1=ae611d7c5aed7f2936bea8490cf6e05b8bb4e727 -md5=8ebd818c18fc8c7fcae6b1d73dc3ae52 -cksum=1103974710 +sha1=f76fbc2d374170771fed030b79a5ffac08d907bf +md5=98be3e1a272bd5337fbadabb0d3f3d20 +cksum=3014134315 diff --git a/build/pkgs/ppl/package-version.txt b/build/pkgs/ppl/package-version.txt index e5c7acb1220..9459d4ba2a0 100644 --- a/build/pkgs/ppl/package-version.txt +++ b/build/pkgs/ppl/package-version.txt @@ -1 +1 @@ -1.1pre9.p0 +1.1 diff --git a/build/pkgs/ppl/patches/tests_Makefile.in.patch b/build/pkgs/ppl/patches/tests_Makefile.in.patch deleted file mode 100644 index 8b5c19f5670..00000000000 --- a/build/pkgs/ppl/patches/tests_Makefile.in.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- a/tests/Makefile.in 2012-06-28 12:50:42.000000000 +0200 -+++ b/tests/Makefile.in 2013-06-04 17:01:02.592394672 +0200 -@@ -388,10 +388,7 @@ - PIP_Problem \ - Powerset \ - Partially_Reduced_Product \ --Box \ - MIP_Problem \ --Octagonal_Shape \ --BD_Shape \ - Polyhedron \ - Grid \ - Watchdog diff --git a/build/pkgs/ppl/spkg-install b/build/pkgs/ppl/spkg-install index 02ef7edf76a..6498eb2ecfd 100755 --- a/build/pkgs/ppl/spkg-install +++ b/build/pkgs/ppl/spkg-install @@ -28,6 +28,7 @@ cd src # * break when setting MAKE="make -jN" # They cover code that is not exposed by the Cython wrapper for patch in ../patches/*.patch; do + [ -r "$patch" ] || continue patch -p1 <"$patch" if [ $? -ne 0 ]; then echo >&2 "Error applying '$patch'" diff --git a/build/pkgs/sagenb/checksums.ini b/build/pkgs/sagenb/checksums.ini index 77b2fc77f1a..ed1581bdd55 100644 --- a/build/pkgs/sagenb/checksums.ini +++ b/build/pkgs/sagenb/checksums.ini @@ -1,4 +1,4 @@ -tarball=sagenb-VERSION.tar.bz2 -sha1=646ed52c5f562518bd421489e1fffc69c65ece15 -md5=d285022fbcca9f31ac4730f77d8a12a7 -cksum=1454803706 +tarball=sagenb-VERSION.tar +sha1=89f92fa00102aa5c9080e0517c374fa6ebf11999 +md5=0504ae7be62b739f13cf80118983ab5e +cksum=1132378659 diff --git a/build/pkgs/sagenb/package-version.txt b/build/pkgs/sagenb/package-version.txt index 835aef1a8e0..34537b9d866 100644 --- a/build/pkgs/sagenb/package-version.txt +++ b/build/pkgs/sagenb/package-version.txt @@ -1 +1 @@ -0.10.7.2 +0.10.8.2 diff --git a/build/pkgs/singular/SPKG.txt b/build/pkgs/singular/SPKG.txt index e1194aa82b7..af447a80d1d 100644 --- a/build/pkgs/singular/SPKG.txt +++ b/build/pkgs/singular/SPKG.txt @@ -30,42 +30,21 @@ GNU patch, GMP/MPIR, NTL, Termcap, Readline and MPFR See spkg-src. == Patches == + * NTL6_compatibility.patch taken from commit + ddb348e97a991972e5dfee690a66663ba0418f40 + * factory_template_instantiation.patch taken from commit + 561842a06ad4b44f3b85b28ac35e7946eaba9a30 * assert.patch: logic seems to be broken on some platforms - * install_table.patch: install singular/table.h header file, needed - for the libsing GAP package. + * configure_comma.patch: remove a superfluous "," from configure. * Minor.h.patch: needs to have included on Cygwin - * NTL_negate.patch: change negate() to NTL::negate() to fix a conflict - with std::negate(). See - http://www.singular.uni-kl.de:8002/trac/ticket/437 - * singular_trac_439.patch: fix taken from upstream for - http://www.singular.uni-kl.de:8002/trac/ticket/439 - * singular_trac_440.patch: fix taken from upstream for - http://www.singular.uni-kl.de:8002/trac/ticket/440 - * singular_trac_441.patch: fix taken from upstream for - http://www.singular.uni-kl.de:8002/trac/ticket/441 - * singular_trac_443.patch: fix taken from upstream for - http://www.singular.uni-kl.de:8002/trac/ticket/443 - * sage_trac_12089.patch: fix (also reported upstream) from - https://github.com/alexanderdreyer/SingularSources/commit/7902222 * slibdir.patch: set default slibdir to ${datarootdir}/singular instead of ${prefix}/LIB, see #13344. - * singular_15435.patch: Backport of - http://www.singular.uni-kl.de:8002/trac/changeset/15435 - See also http://www.singular.uni-kl.de:8002/trac/ticket/463 - and http://trac.sagemath.org/sage_trac/ticket/13731. - * singular_part_of_changeset_baadc0f7.patch: Backport a small part - of https://github.com/Singular/Sources/commit/9ece45a2420dc43ff03a48c40423a3009c235fdd - that fixes one memory corruption (writing out of bound). - * cygwin-makefile.patch: simple fix for Cygwin, see - http://www.singular.uni-kl.de:8002/trac/ticket/476/ * sage_trac_14295.patch: Fix for GCC 4.7.x on Solaris; see http://trac.sagemath.org/sage_trac/ticket/14295 and the changelog entry for singular-3-1-5.p5 below. * osx_link.patch: #14415: Fixes linker problems on OS X PPC. * sanitize_gmp_header_hack.patch: Fix and simplify generation of `factory/cf_gmp.h` (cf. #14737). - * pullrequest215.patch: Backport of first 3 patches from - https://github.com/Singular/Sources/pull/215 Other notes * The option '--without-dynamic-kernel' is used on *all* @@ -93,6 +72,22 @@ Other notes == ChangeLog == +=== singular-3-1-6.p0 (Jeroen Demeyer, 26 August 2013) === + * Remove the following patches, which were fixed upstream: + - NTL_negate.patch + - install_table.patch + - pullrequest215.patch + - sage_trac_12089.patch + - singular_15435.patch + - singular_part_of_changeset_baadc0f7.patch + - singular_trac_439.patch + - singular_trac_440.patch + - singular_trac_441.patch + - singular_trac_443.patch + * Removed cygwin-makefile.patch, which is hopefully not needed anymore. + * Rebased some other patches. + * Add configure_comma.patch. + === singular-3-1-5.p9 (Paul Zimmermann, Jeroen Demeyer, 26 August 2013) === * #13770: Add upstream pull request 215 for multivariate factorisation. * spkg-install: split apply_patches step in 2 steps: choose_patches and diff --git a/build/pkgs/singular/checksums.ini b/build/pkgs/singular/checksums.ini index 0c6a42d90ba..0ec9fcd8086 100644 --- a/build/pkgs/singular/checksums.ini +++ b/build/pkgs/singular/checksums.ini @@ -1,4 +1,4 @@ tarball=singular-VERSION.tar.bz2 -sha1=b4834021a4b44f43806cca2561ec942dc2185c17 -md5=3b786f455fc9ffadf6b48f2318d29784 -cksum=3449175047 +sha1=aa94b574ca6632280a9fe58ad762eff9cd2d6912 +md5=84d77d4ab9d182bbadaf50243dc589ac +cksum=2601409183 diff --git a/build/pkgs/singular/package-version.txt b/build/pkgs/singular/package-version.txt index 8bbb0577c8d..a20f5edf470 100644 --- a/build/pkgs/singular/package-version.txt +++ b/build/pkgs/singular/package-version.txt @@ -1 +1 @@ -3.1.5.p9 +3.1.6.p0 diff --git a/build/pkgs/singular/patches/NTL6_compatibility.patch b/build/pkgs/singular/patches/NTL6_compatibility.patch new file mode 100644 index 00000000000..587a9dff1c3 --- /dev/null +++ b/build/pkgs/singular/patches/NTL6_compatibility.patch @@ -0,0 +1,42 @@ +ddb348e - update for NTL 6 (5 months ago)  +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; + template class Cache; + template class Cache; + ++#ifdef HAVE_NTL ++#include ++#if NTL_MAJOR_VERSION == 6 ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#ifdef NTL_CLIENT // in : using of name space NTL ++NTL_CLIENT ++#endif ++template class Vec; ++template class Vec; ++template class Mat; ++template class Mat; ++template class Mat; ++template class Vec >; ++template class Vec >; ++template class Vec >; ++template class Vec >; ++template class Vec >; ++template void swap(Vec&, Vec&); ++template long operator==(Vec const&, Vec const&); ++#endif ++ ++#endif diff --git a/build/pkgs/singular/patches/NTL_negate.patch b/build/pkgs/singular/patches/NTL_negate.patch deleted file mode 100644 index e0acb20d207..00000000000 --- a/build/pkgs/singular/patches/NTL_negate.patch +++ /dev/null @@ -1,18 +0,0 @@ -diff -ru src/factory/cf_chinese.cc b/factory/cf_chinese.cc ---- src/factory/cf_chinese.cc 2012-06-15 20:00:10.000000000 +0200 -+++ b/factory/cf_chinese.cc 2012-07-25 15:48:19.893359649 +0200 -@@ -211,12 +211,12 @@ - ZZ NTLc= convertFacCF2NTLZZ (c); - bool lessZero= (sign (NTLc) == -1); - if (lessZero) -- negate (NTLc, NTLc); -+ NTL::negate (NTLc, NTLc); - ZZ NTLnum, NTLden; - if (ReconstructRational (NTLnum, NTLden, NTLc, NTLq, bound, bound)) - { - if (lessZero) -- negate (NTLnum, NTLnum); -+ NTL::negate (NTLnum, NTLnum); - CanonicalForm num= convertNTLZZX2CF (to_ZZX (NTLnum), Variable (1)); - CanonicalForm den= convertNTLZZX2CF (to_ZZX (NTLden), Variable (1)); - On (SW_RATIONAL); diff --git a/build/pkgs/singular/patches/configure_comma.patch b/build/pkgs/singular/patches/configure_comma.patch new file mode 100644 index 00000000000..1d35eb94144 --- /dev/null +++ b/build/pkgs/singular/patches/configure_comma.patch @@ -0,0 +1,12 @@ +diff -ru a/configure b/configure +--- a/configure 2012-12-19 22:01:16.000000000 +0100 ++++ b/configure 2013-08-26 22:38:41.389607801 +0200 +@@ -2191,7 +2191,7 @@ + enableval="$enable_countedref" + : + fi +-, ++ + # Check whether --enable-Plural or --disable-Plural was given. + if test "${enable_Plural+set}" = set; then + enableval="$enable_Plural" diff --git a/build/pkgs/singular/patches/cygwin-makefile.patch b/build/pkgs/singular/patches/cygwin-makefile.patch deleted file mode 100644 index a5ee0248cb1..00000000000 --- a/build/pkgs/singular/patches/cygwin-makefile.patch +++ /dev/null @@ -1,15 +0,0 @@ -diff -druN src.orig/Singular/Makefile.in src/Singular/Makefile.in ---- src.orig/Singular/Makefile.in 2012-07-11 12:00:13.000000000 +0200 -+++ src/Singular/Makefile.in 2013-02-04 23:43:26.565194514 +0100 -@@ -121,9 +121,9 @@ - else - ## for cones & fans if under Win OS: - ## put "-lgfan -lcddgmp " before "-Xlinker" in definition of LIBS and LIBSG --LIBS = -lsingfac -lsingcf -lntl -static -lreadline -lhtmlhelp -Xlinker -Bdynamic -lgmp -lomalloc_ndebug -lncurses -+LIBS = @NEED_LIBS@ - ## -lpython_module -lpython2.4 /usr/local/lib/libboost_python-gcc-d-1_32.dll --LIBSG = -lsingfac -lsingcf -lntl -static -lreadline -lhtmlhelp -Xlinker -Bdynamic -lgmp -lncurses -+LIBSG = @NEED_LIBSG@ - ## with cdd and gfan: LIBSG = -lsingfac -lsingcf -lntl -static -lreadline -lhtmlhelp -lgfan -lcddgmp -Xlinker -Bdynamic -lgmp -lncurses - endif - MP_LIBS = @MP_LIBS@ diff --git a/build/pkgs/singular/patches/factory_template_instantiation.patch b/build/pkgs/singular/patches/factory_template_instantiation.patch new file mode 100644 index 00000000000..c0e41109cd8 --- /dev/null +++ b/build/pkgs/singular/patches/factory_template_instantiation.patch @@ -0,0 +1,25 @@ +561842a - fix: template instantiation in libfac (4 weeks ago)  +diff --git a/libfac/factor/tmpl_inst.cc b/libfac/factor/tmpl_inst.cc +index bda287a..2f5ba49 100644 +--- a/libfac/factor/tmpl_inst.cc ++++ b/libfac/factor/tmpl_inst.cc +@@ -3,7 +3,7 @@ + //////////////////////////////////////////////////////////// + + +-//#include ++#include + //#include + #include + #include +@@ -75,8 +75,8 @@ template OSTREAM & operator << ( OSTREAM &, const List & ); + template OSTREAM & operator << ( OSTREAM &, const Array & ); + #endif + +-template class Array; +-template class Array; ++//template class Array; ++//template class Array; + //template class Array; + + // for database diff --git a/build/pkgs/singular/patches/install_table.patch b/build/pkgs/singular/patches/install_table.patch deleted file mode 100644 index c21888ba9b7..00000000000 --- a/build/pkgs/singular/patches/install_table.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- src/Singular/Makefile.in 2012-07-11 11:00:13.000000000 +0100 -+++ src/Singular/Makefile.in 2012-08-27 16:22:26.013159361 +0100 -@@ -599,7 +599,7 @@ - ${INSTALL_PROGRAM} $$file ${libdir}; \ - done - ${INSTALL_PROGRAM} libsingular.h ${includedir} -- for file in subexpr.h tok.h grammar.h ipid.h lists.h ipshell.h attrib.h; do \ -+ for file in subexpr.h tok.h grammar.h ipid.h lists.h ipshell.h attrib.h table.h; do \ - sed -e "s:${includedir}/singular/$$file ;\ - done diff --git a/build/pkgs/singular/patches/pullrequest215.patch b/build/pkgs/singular/patches/pullrequest215.patch deleted file mode 100644 index c26c8795111..00000000000 --- a/build/pkgs/singular/patches/pullrequest215.patch +++ /dev/null @@ -1,230 +0,0 @@ -diff -ru latest/factory/facFqBivar.cc b/factory/facFqBivar.cc ---- latest/factory/facFqBivar.cc 2012-07-12 16:24:57.000000000 +0200 -+++ b/factory/facFqBivar.cc 2013-08-26 14:09:25.479601121 +0200 -@@ -403,7 +403,9 @@ - delete [] v; - if (recombination) - { -- appendTestMapDown (result, buf (y - eval, y), info, source, -+ buf= buf (y-eval,y); -+ buf /= Lc (buf); -+ appendTestMapDown (result, buf, info, source, - dest); - F= 1; - return result; -@@ -430,7 +432,9 @@ - delete [] v; - if (recombination) - { -- appendTestMapDown (result, buf (y - eval, y), info, source, dest); -+ buf= buf (y-eval,y); -+ buf /= Lc (buf); -+ appendTestMapDown (result, buf, info, source, dest); - F= 1; - return result; - } -@@ -1616,6 +1620,8 @@ - buf= mod (buf, yToL); - buf /= content (buf, x); - buf2= buf (y-evaluation, y); -+ buf2 /= Lc (buf2); -+ buf2 /= Lc (buf2); - if (!k && beta == x) - { - if (degree (buf2, alpha) < 1) -@@ -1738,6 +1744,8 @@ - { - tmp1= tmp1 (y - evaluation, y); - tmp2= tmp2 (y - evaluation, y); -+ tmp1 /= Lc (tmp1); -+ tmp2 /= Lc (tmp2); - if (!k && beta == x && degree (tmp2, alpha) < 1 && - degree (tmp1, alpha) < 1) - { -@@ -1792,6 +1800,8 @@ - buf= mod (buf, yToL); - buf /= content (buf, x); - buf2= buf (y - evaluation, y); -+ buf2 /= Lc (buf2); -+ buf2 /= Lc (buf2); - if (!k && beta == x) - { - if (degree (buf2, alpha) < 1) -@@ -2650,9 +2660,12 @@ - if (isIrreducible) - { - delete [] bounds; -- CanonicalForm G= F; -+ Variable y= Variable (2); -+ CanonicalForm tmp= F (y - evaluation, y); -+ CFList source, dest; -+ tmp= mapDown (tmp, info, source, dest); - F= 1; -- return CFList (G); -+ return CFList (tmp); - } - - CFArray * A= new CFArray [factors.length()]; -@@ -4327,11 +4340,11 @@ - else - { - i= 1; -- while ((degree (F,y)/4)*i + 4 <= smallFactorDeg) -+ while ((degree (F,y)/4+1)*i + 4 <= smallFactorDeg) - i++; - while (i < 5) - { -- dummy= tmin (degree (F,y)+1, (degree (F,y)/4)*i+4); -+ dummy= tmin (degree (F,y)+1, (degree (F,y)/4+1)*i+4); - if (l < dummy) - { - factors.insert (LCF); -@@ -4471,11 +4484,11 @@ - else - { - i= 1; -- while ((degree (F,y)/4)*i + 4 <= smallFactorDeg) -+ while ((degree (F,y)/4+1)*i + 4 <= smallFactorDeg) - i++; - while (i < 5) - { -- dummy= tmin (degree (F,y)+1, (degree (F,y)/4)*i+4); -+ dummy= tmin (degree (F,y)+1, (degree (F,y)/4+1)*i+4); - if (l < dummy) - { - factors.insert (LCF); -@@ -4619,11 +4632,11 @@ - else - { - i= 1; -- while ((degree (F,y)/4)*i + 4 <= smallFactorDeg) -+ while (((degree (F,y)/4)*i+1) + 4 <= smallFactorDeg) - i++; - while (i < 5) - { -- dummy= tmin (degree (F,y)+1, (degree (F,y)/4)*i+4); -+ dummy= tmin (degree (F,y)+1, ((degree (F,y)/4)+1)*i+4); - if (l < dummy) - { - factors.insert (LCF); -@@ -5020,12 +5033,12 @@ - CanonicalForm bufF= F; - int factorsFound= 0; - if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp)) -- reconstructionTry (result, bufF, bufUniFactors, degree (F) + 1 + degree -- (LCF), factorsFound, factorsFoundIndex, NTLN, false -+ reconstructionTry (result, bufF, bufUniFactors, degree (F) + 1, -+ factorsFound, factorsFoundIndex, NTLN, false - ); - else -- reconstructionTry (result, bufF, bufUniFactors, degree (F) + 1 + degree -- (LCF), factorsFound, factorsFoundIndex, NTLNe, false -+ reconstructionTry (result, bufF, bufUniFactors, degree (F) + 1, -+ factorsFound, factorsFoundIndex, NTLNe, false - ); - if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp)) - { -@@ -5336,7 +5349,7 @@ - if (minBound > 16 || result.length() == 0) - { - result= Union (result, smallFactors); -- CanonicalForm MODl= power (y, degree (F) + 1 + degree (LC (F, 1))); -+ CanonicalForm MODl= power (y, degree (F) + 1); - delete [] bounds; - return Union (result, factorRecombination (bufUniFactors, F, MODl, degs, 1, - bufUniFactors.length()/2 -@@ -5585,7 +5598,7 @@ - delete [] bounds; - return Union (smallFactors, extFactorRecombination - (bufUniFactors, F, -- power (y, degree (F) + 1 + degree (LCF)),info, -+ power (y, degree (F) + 1),info, - degs, evaluation, 1, bufUniFactors.length()/2 - ) - ); -@@ -5638,8 +5651,8 @@ - CanonicalForm bufF= F; - int factorsFound= 0; - -- extReconstructionTry (result, bufF, bufUniFactors, degree (F) + 1 + degree -- (LCF), factorsFound, factorsFoundIndex, NTLN, false, -+ extReconstructionTry (result, bufF, bufUniFactors, degree (F) + 1, -+ factorsFound, factorsFoundIndex, NTLN, false, - info, evaluation - ); - -@@ -5767,7 +5780,10 @@ - result= Union (result, smallFactors); - if (degs.getLength() == 1 || bufUniFactors.length() == 1) - { -- result.append (bufF); -+ CFList source, dest; -+ CanonicalForm tmp= bufF (y - evaluation, y); -+ tmp= mapDown (tmp, info, source, dest); -+ result.append (tmp); - return result; - } - return Union (result, extHenselLiftAndLatticeRecombi (bufF, bufUniFactors, -@@ -5834,7 +5850,7 @@ - if (minBound > 16 || result.length() == 0) - { - result= Union (result, smallFactors); -- CanonicalForm MODl= power (y, degree (F) + 1 + degree (LC (F, 1))); -+ CanonicalForm MODl= power (y, degree (F) + 1); - delete [] bounds; - return Union (result, extFactorRecombination (bufUniFactors, F, MODl, info, - degs, evaluation, 1, -@@ -6116,7 +6132,7 @@ - return factors; - } - -- if (i == 0) -+ if (i == 0 && !extension) - { - if (subCheck1 > 0) - { -diff -ru latest/factory/facFqBivarUtil.cc b/factory/facFqBivarUtil.cc ---- latest/factory/facFqBivarUtil.cc 2012-07-12 16:24:57.000000000 +0200 -+++ b/factory/facFqBivarUtil.cc 2013-08-26 14:09:38.979597772 +0200 -@@ -494,16 +494,21 @@ - //middle product style computation of [G*oldQ]^{l}_{oldL} - CanonicalForm G3= div (G, xToOldL); - CanonicalForm Up= mulMod2 (G3, oldQ, xToLOldL); -- CanonicalForm xToOldL2= power (x, oldL/2); -+ CanonicalForm xToOldL2= power (x, (oldL+1)/2); - CanonicalForm G2= mod (G, xToOldL); - CanonicalForm G1= div (G2, xToOldL2); - CanonicalForm G0= mod (G2, xToOldL2); - CanonicalForm oldQ1= div (oldQ, xToOldL2); - CanonicalForm oldQ0= mod (oldQ, xToOldL2); -- CanonicalForm Mid= mulMod2 (G1, oldQ1, xToLOldL); -+ CanonicalForm Mid; -+ if (oldL % 2 == 1) -+ Mid= mulMod2 (G1, oldQ1*x, xToLOldL); -+ else -+ Mid= mulMod2 (G1, oldQ1, xToLOldL); - //computation of Low might be faster using a real middle product? - CanonicalForm Low= mulMod2 (G0, oldQ1, xToOldL)+mulMod2 (G1, oldQ0, xToOldL); -- Low= div (Low, xToOldL2); -+ Low= div (Low, power (x, oldL/2)); -+ Low= mod (Low, xToLOldL); - Up += Mid + Low; - bufF= div (F, xToOldL); - bufF -= Up; -diff -ru latest/factory/facMul.cc b/factory/facMul.cc ---- latest/factory/facMul.cc 2012-07-12 16:24:57.000000000 +0200 -+++ b/factory/facMul.cc 2013-08-26 14:09:38.979597772 +0200 -@@ -2720,13 +2720,6 @@ - divrem (A, B, Q, R); - return; - } -- if (!(B.level() == 1 && B.isUnivariate()) && -- (A.level() == 1 && A.isUnivariate())) -- { -- Q= 0; -- R= A; -- return; -- } - - Variable x= Variable (1); - int degB= degree (B, x); diff --git a/build/pkgs/singular/patches/sage_trac_12089.patch b/build/pkgs/singular/patches/sage_trac_12089.patch deleted file mode 100644 index 8843df59bfd..00000000000 --- a/build/pkgs/singular/patches/sage_trac_12089.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 7902222c6e73d452b3d75576bd9bc0140f5e827a Mon Sep 17 00:00:00 2001 -From: Alexander Dreyer -Date: Sat, 4 Aug 2012 21:53:32 +0200 -Subject: [PATCH] fix: apply LDFLAGS fixes from svn#13210/git#b1dfafe to cygwin-specific flags (Sage's trac #12089; reported by Jean-Pierre Flori) - ---- - Singular/Makefile.in | 6 +++--- - 1 files changed, 3 insertions(+), 3 deletions(-) - -diff --git a/Singular/Makefile.in b/Singular/Makefile.in -index c4a6e78..b907085 100644 ---- a/Singular/Makefile.in -+++ b/Singular/Makefile.in -@@ -90,9 +90,9 @@ LDFLAGSG = -L@prefix@/kernel -L../kernel -lkernel_g @LD_DYN_FLAGS1@ @LDFLAGS@ - LDFLAGSP = -L@prefix@/kernel -L../kernel -lkernel_p @LD_DYN_FLAGS1@ @LDFLAGS@ - else - ## -L/usr/local/lib -L@prefix@/modules/python --> PySingular --LDFLAGS = -L@prefix@/kernel -L/bin -lkernel @LDFLAGS@ -L/usr/local/lib -L../modules/python --LDFLAGSG = -L@prefix@/kernel -L/bin -lkernel_g @LDFLAGS@ --LDFLAGSP = -L@prefix@/kernel -L/bin -lkernel_p @LDFLAGS@ -+LDFLAGS = -L@prefix@/kernel -L../kernel -L/bin -lkernel @LDFLAGS@ -L/usr/local/lib -L../modules/python -+LDFLAGSG = -L@prefix@/kernel -L../kernel -L/bin -lkernel_g @LDFLAGS@ -+LDFLAGSP = -L@prefix@/kernel -L../kernel -L/bin -lkernel_p @LDFLAGS@ - endif - LD_DYN_FLAGS1 = @LD_DYN_FLAGS1@ - LD_DYN_FLAGS2 = @LD_DYN_FLAGS2@ --- -1.6.0.2 - diff --git a/build/pkgs/singular/patches/sage_trac_14295.patch b/build/pkgs/singular/patches/sage_trac_14295.patch index f0d75c1fd7b..528142beb3b 100644 --- a/build/pkgs/singular/patches/sage_trac_14295.patch +++ b/build/pkgs/singular/patches/sage_trac_14295.patch @@ -1,29 +1,38 @@ ---- src/kernel/bigintmat.cc 2012-06-20 17:00:07.000000000 +0200 -+++ src/kernel/bigintmat.cc 2013-03-18 16:18:26.281905612 +0100 -@@ -344,7 +344,7 @@ +--- a/kernel/bigintmat.cc 2012-12-19 22:01:16.000000000 +0100 ++++ b/kernel/bigintmat.cc 2013-08-26 22:21:06.839607851 +0200 +@@ -341,7 +341,7 @@ + if (nl > colwid[cj]) + { + StringSetS(""); +- int ci = floor(i/col); ++ int ci = floor((double)i/col); + StringAppend("[%d,%d]", ci+1, cj+1); + char *tmp = StringAppendS(""); + char * ph = omStrDup(tmp); +@@ -420,7 +420,7 @@ int index = cols*i+j; if ((a[index] > sndlong) && (a[index] < l)) { -- int min = floor(log10(cols))+floor(log10(rows))+5; -+ int min = floor(log10((double)cols))+floor(log10((double)rows))+5; +- int min = (int)(floor(log10(cols))+floor(log10(rows)))+5; ++ int min = (int)(floor(log10((double)cols))+floor(log10((double)rows)))+5; if ((a[index] < min) && (min < l)) sndlong = min; else -@@ -353,7 +353,7 @@ +@@ -429,7 +429,7 @@ } if (sndlong == 0) { -- int min = floor(log10(cols))+floor(log10(rows))+5; -+ int min = floor(log10((double)cols))+floor(log10((double)rows))+5; +- int min = (int)(floor(log10(cols))+floor(log10(rows)))+5; ++ int min = (int)(floor(log10((double)cols))+floor(log10((double)rows)))+5; if (min < l) sndlong = min; else -@@ -424,7 +424,7 @@ +@@ -501,7 +501,7 @@ if (nl > colwid[cj]) { StringSetS(""); - int ci = floor(i/col); -+ int ci = floor((double)(i/col)); // actually the same as ci = i/col ++ int ci = floor((double)i/col); // actually the same as ci = i/col StringAppend("[%d,%d]", ci+1, cj+1); char *tmp = StringAppendS(""); char * ph = omStrDup(tmp); diff --git a/build/pkgs/singular/patches/singular_15435.patch b/build/pkgs/singular/patches/singular_15435.patch deleted file mode 100644 index caa6a26bb83..00000000000 --- a/build/pkgs/singular/patches/singular_15435.patch +++ /dev/null @@ -1,166 +0,0 @@ -# HG changeset patch -# User Simon King -# Date 1354202248 -3600 -# Node ID ace49ff24a907b119b4aa274ab81a5abc8313825 -# Parent 0c697481fdf85d159764fb303a89cd34607c21b5 -imported patch singular_15435.patch - -diff --git a/kernel/gring.cc b/kernel/gring.cc ---- a/kernel/gring.cc -+++ b/kernel/gring.cc -@@ -35,9 +35,6 @@ - #include - #include - --// dirty tricks: --#include -- - #include - #include - #include -@@ -458,8 +455,6 @@ - return( gnc_p_Mult_mm_Common(p_Copy(p,r), m, 0, r) ); - } - -- -- - poly gnc_mm_Mult_nn(int *F0, int *G0, const ring r) - /* destroys nothing, no coeffs and exps */ - { -@@ -467,7 +462,6 @@ - int i,j; - int iF,jG,iG; - int rN=r->N; -- int ExpSize=(((rN+1)*sizeof(int)+sizeof(long)-1)/sizeof(long))*sizeof(long); - - int *F=(int *)omAlloc0((rN+1)*sizeof(int)); - int *G=(int *)omAlloc0((rN+1)*sizeof(int)); -@@ -476,7 +470,7 @@ - // pExpVectorCopy(F,F0); - memcpy(G, G0,(rN+1)*sizeof(int)); - // pExpVectorCopy(G,G0); -- F[0]=0; /* important for p_MemAdd */ -+ F[0]=0; - G[0]=0; - - iF=rN; -@@ -500,10 +494,9 @@ - if (iF<=jG) - /* i.e. no mixed exp_num , MERGE case */ - { -- p_MemAdd_LengthGeneral(F, G, ExpSize/sizeof(long)); -+ { for(int ii=rN;ii>0;ii--) F[ii]+=G[ii]; } - p_SetExpV(out,F,r); - p_Setm(out,r); -- // omFreeSize((ADDRESS)F,ExpSize); - freeT(F,rN); - freeT(G,rN); - return(out); -@@ -562,11 +555,10 @@ - } - cff=totcff; - } -- p_MemAdd_LengthGeneral(F, G, ExpSize/sizeof(long)); -+ { for(int ii=rN;ii>0;ii--) F[ii]+=G[ii]; } - p_SetExpV(out,F,r); - p_Setm(out,r); - p_SetCoeff(out,cff,r); -- // p_MemAdd_NegWeightAdjust(p, r); ??? do we need this? - freeT(F,rN); - freeT(G,rN); - return(out); -diff --git a/kernel/ring.cc b/kernel/ring.cc ---- a/kernel/ring.cc -+++ b/kernel/ring.cc -@@ -1898,7 +1898,7 @@ - return TRUE; - } - --rOrderType_t rGetOrderType(ring r) -+rOrderType_t rGetOrderType(const ring r) - { - // check for simple ordering - if (rHasSimpleOrder(r)) -@@ -2016,7 +2016,7 @@ - } - } - --BOOLEAN rHasSimpleOrderAA(ring r) -+BOOLEAN rHasSimpleOrderAA(const ring r) - { - if (r->order[0] == ringorder_unspec) return TRUE; - int blocks = rBlocks(r) - 1; -@@ -2047,7 +2047,7 @@ - } - - // return TRUE if p_SetComp requires p_Setm --BOOLEAN rOrd_SetCompRequiresSetm(ring r) -+BOOLEAN rOrd_SetCompRequiresSetm(const ring r) - { - if (r->typ != NULL) - { -@@ -2061,15 +2061,28 @@ - return FALSE; - } - -+BOOLEAN rHasModuleOrder(const ring r) -+{ -+ int i=0; -+ loop -+ { -+ if ((r->order[i]==ringorder_c) -+ || (r->order[i]==ringorder_C)) -+ return TRUE; -+ if (r->order[i]==0) return FALSE; -+ i++; -+ } -+ return FALSE; /*never reached */ -+} - // return TRUE if p->exp[r->pOrdIndex] holds total degree of p */ --BOOLEAN rOrd_is_Totaldegree_Ordering(ring r) -+BOOLEAN rOrd_is_Totaldegree_Ordering(const ring r) - { - // Hmm.... what about Syz orderings? - return (rVar(r) > 1 && - ((rHasSimpleOrder(r) && - (rOrder_is_DegOrdering((rRingOrder_t)r->order[0]) || - rOrder_is_DegOrdering(( rRingOrder_t)r->order[1]))) || -- (rHasSimpleOrderAA(r) && -+ (rHasSimpleOrderAA(r) && rHasModuleOrder(r) && - (rOrder_is_DegOrdering((rRingOrder_t)r->order[1]) || - rOrder_is_DegOrdering((rRingOrder_t)r->order[2]))))); - } -@@ -2084,7 +2097,7 @@ - rOrder_is_WeightedOrdering(( rRingOrder_t)r->order[1]))); - } - --BOOLEAN rIsPolyVar(int v, ring r) -+BOOLEAN rIsPolyVar(int v, const ring r) - { - int i=0; - while(r->order[i]!=0) -diff --git a/kernel/ring.h b/kernel/ring.h ---- a/kernel/ring.h -+++ b/kernel/ring.h -@@ -408,16 +408,16 @@ - //{ return (r->OrdSgn==-1); } - #define rHasLocalOrMixedOrdering(R) ((R)->OrdSgn==-1) - #define rHasLocalOrMixedOrdering_currRing() (pOrdSgn==-1) --BOOLEAN rOrd_is_Totaldegree_Ordering(ring r =currRing); -+BOOLEAN rOrd_is_Totaldegree_Ordering(const ring r =currRing); - - /// return TRUE if p_SetComp requires p_Setm --BOOLEAN rOrd_SetCompRequiresSetm(ring r); --rOrderType_t rGetOrderType(ring r); -+BOOLEAN rOrd_SetCompRequiresSetm(const ring r); -+rOrderType_t rGetOrderType(const ring r); - - /// returns TRUE if var(i) belongs to p-block --BOOLEAN rIsPolyVar(int i, ring r = currRing); -+BOOLEAN rIsPolyVar(int i, const ring r = currRing); - --static inline BOOLEAN rOrd_is_Comp_dp(ring r) -+static inline BOOLEAN rOrd_is_Comp_dp(const ring r) - { - return ((r->order[0] == ringorder_c || r->order[0] == ringorder_C) && - r->order[1] == ringorder_dp && diff --git a/build/pkgs/singular/patches/singular_part_of_changeset_baadc0f7.patch b/build/pkgs/singular/patches/singular_part_of_changeset_baadc0f7.patch deleted file mode 100644 index e02508d7a60..00000000000 --- a/build/pkgs/singular/patches/singular_part_of_changeset_baadc0f7.patch +++ /dev/null @@ -1,19 +0,0 @@ -# HG changeset patch -# User Simon King -# Date 1354202289 -3600 -# Node ID 88cfad9e089148694276da1d8a605bf4ee015054 -# Parent ace49ff24a907b119b4aa274ab81a5abc8313825 -See Sage ticket #13731, Singular ticket 463: Fix out-of-bound error in facFactorize.cc - -diff --git a/factory/facFactorize.cc b/factory/facFactorize.cc ---- a/factory/facFactorize.cc -+++ b/factory/facFactorize.cc -@@ -705,7 +705,7 @@ - - evaluationWRTDifferentSecondVars (bufAeval2, bufEvaluation, A); - -- for (int j= 0; j < A.level() - 1; j++) -+ for (int j= 0; j < A.level() - 2; j++) - { - if (!bufAeval2[j].isEmpty()) - counter++; diff --git a/build/pkgs/singular/patches/singular_trac_439.patch b/build/pkgs/singular/patches/singular_trac_439.patch deleted file mode 100644 index da18b56579a..00000000000 --- a/build/pkgs/singular/patches/singular_trac_439.patch +++ /dev/null @@ -1,41 +0,0 @@ -commit 53f79f794aabd5451e090764871dde7c6020d5fa -Author: Martin Lee -Date: Mon Jul 30 11:20:00 2012 +0200 - - fix: tr 439 - -diff --git a/factory/facBivar.h b/factory/facBivar.h -index cabdff8..2d8531e 100644 ---- a/factory/facBivar.h -+++ b/factory/facBivar.h -@@ -183,7 +183,7 @@ ratBiFactorize (const CanonicalForm & G, ///< [in] a bivariate poly - { - for (CFFListIterator i= result; i.hasItem(); i++) - { -- LcF /= bCommonDen (i.getItem().factor()); -+ LcF /= power (bCommonDen (i.getItem().factor()), i.getItem().exp()); - i.getItem()= CFFactor (i.getItem().factor()* - bCommonDen(i.getItem().factor()), i.getItem().exp()); - } -@@ -215,7 +215,7 @@ ratBiFactorize (const CanonicalForm & G, ///< [in] a bivariate poly - { - for (CFFListIterator i= result; i.hasItem(); i++) - { -- LcF /= bCommonDen (i.getItem().factor()); -+ LcF /= power (bCommonDen (i.getItem().factor()), i.getItem().exp()); - i.getItem()= CFFactor (i.getItem().factor()* - bCommonDen(i.getItem().factor()), i.getItem().exp()); - } -diff --git a/factory/facFactorize.h b/factory/facFactorize.h -index 5ccfe16..95bfa66 100644 ---- a/factory/facFactorize.h -+++ b/factory/facFactorize.h -@@ -136,7 +136,7 @@ ratFactorize (const CanonicalForm& G, ///<[in] a multivariate poly - { - for (CFFListIterator i= result; i.hasItem(); i++) - { -- LcF /= bCommonDen (i.getItem().factor()); -+ LcF /= power (bCommonDen (i.getItem().factor()), i.getItem().exp()); - i.getItem()= CFFactor (i.getItem().factor()* - bCommonDen(i.getItem().factor()), i.getItem().exp()); - } diff --git a/build/pkgs/singular/patches/singular_trac_440.patch b/build/pkgs/singular/patches/singular_trac_440.patch deleted file mode 100644 index d439d9d0ee3..00000000000 --- a/build/pkgs/singular/patches/singular_trac_440.patch +++ /dev/null @@ -1,64 +0,0 @@ -commit a315346ac7424b4a5427320fad1f4eb47dbb22ed -Author: Martin Lee -Date: Mon Jul 30 11:40:42 2012 +0200 - - fix: tr 440 - -diff --git a/factory/facFqBivar.cc b/factory/facFqBivar.cc -index 79b968b..f526883 100644 ---- a/factory/facFqBivar.cc -+++ b/factory/facFqBivar.cc -@@ -5928,7 +5928,7 @@ biFactorize (const CanonicalForm& F, const ExtensionInfo& info) - - //check trivial case - if (degree (A) == 1 || degree (A, 1) == 1 || -- (size (A) == 2 && gcd (degree (A), degree (A,1)).isOne())) -+ (size (A) == 2 && igcd (degree (A), degree (A,1))==1)) - { - factors.append (A); - -commit e5e9d9dc87093af880507e242a15709368fdcf28 -Author: Martin Lee -Date: Mon Jul 30 11:40:04 2012 +0200 - - chg: new command igcd to compute integer gcd - -diff --git a/factory/cf_util.cc b/factory/cf_util.cc -index 02ecb42..91c3303 100644 ---- a/factory/cf_util.cc -+++ b/factory/cf_util.cc -@@ -46,6 +46,22 @@ int ilog2 (int a) - return n; - } - -+int igcd( int a, int b ) -+{ -+ if ( a < 0 ) a = -a; -+ if ( b < 0 ) b = -b; -+ -+ int c; -+ -+ while ( b != 0 ) -+ { -+ c = a % b; -+ a = b; -+ b = c; -+ } -+ return a; -+} -+ - #include - #include - -diff --git a/factory/cf_util.h b/factory/cf_util.h -index 17baf35..e7309b0 100644 ---- a/factory/cf_util.h -+++ b/factory/cf_util.h -@@ -13,6 +13,7 @@ - - int ipower ( int b, int n ); - int ilog2 (int a); -+int igcd (int a, int b); - - /*BEGINPUBLIC*/ - void factoryError_intern(const char *s); diff --git a/build/pkgs/singular/patches/singular_trac_441.patch b/build/pkgs/singular/patches/singular_trac_441.patch deleted file mode 100644 index 3d17177c63c..00000000000 --- a/build/pkgs/singular/patches/singular_trac_441.patch +++ /dev/null @@ -1,21 +0,0 @@ -commit 0246ba4f2c356ac24a96ef92762abf72bf775fdd -Author: Martin Lee -Date: Thu Aug 2 10:49:05 2012 +0200 - - fix: tr 441 - -diff --git a/factory/facFqBivar.cc b/factory/facFqBivar.cc -index f526883..6fad188 100644 ---- a/factory/facFqBivar.cc -+++ b/factory/facFqBivar.cc -@@ -6102,9 +6102,7 @@ biFactorize (const CanonicalForm& F, const ExtensionInfo& info) - if (extension) - { - CFList source, dest; -- ExtensionInfo info2= ExtensionInfo (beta, alpha, delta, gamma, k, -- info.getGFName(), info.isInExtension()); -- appendMapDown (factors, A, info2, source, dest); -+ appendMapDown (factors, A, info, source, dest); - } - else - factors.append (A); diff --git a/build/pkgs/singular/patches/singular_trac_443.patch b/build/pkgs/singular/patches/singular_trac_443.patch deleted file mode 100644 index 95f6ded36a1..00000000000 --- a/build/pkgs/singular/patches/singular_trac_443.patch +++ /dev/null @@ -1,249 +0,0 @@ -diff -ru src/Singular/configure b/Singular/configure ---- src/Singular/configure 2012-07-11 12:00:13.000000000 +0200 -+++ b/Singular/configure 2012-08-10 15:33:02.283359555 +0200 -@@ -742,12 +742,8 @@ - LIBS - CPPFLAGS - CPP --CPPFLAGS - CXX - CXXFLAGS --LDFLAGS --LIBS --CPPFLAGS - CCC - CXXCPP' - -@@ -5413,9 +5409,9 @@ - fi - - fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for in -lnsl" >&5 --$as_echo_n "checking for in -lnsl... " >&6; } --if ${ac_cv_lib_nsl_+:} false; then : -+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5 -+$as_echo_n "checking for gethostbyname in -lnsl... " >&6; } -+if ${ac_cv_lib_nsl_gethostbyname+:} false; then : - $as_echo_n "(cached) " >&6 - else - ac_check_lib_save_LIBS=$LIBS -@@ -5429,27 +5425,27 @@ - #ifdef __cplusplus - extern "C" - #endif --char (); -+char gethostbyname (); - int - main () - { --return (); -+return gethostbyname (); - ; - return 0; - } - _ACEOF - if ac_fn_c_try_link "$LINENO"; then : -- ac_cv_lib_nsl_=yes -+ ac_cv_lib_nsl_gethostbyname=yes - else -- ac_cv_lib_nsl_=no -+ ac_cv_lib_nsl_gethostbyname=no - fi - rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LIBS=$ac_check_lib_save_LIBS - fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_" >&5 --$as_echo "$ac_cv_lib_nsl_" >&6; } --if test "x$ac_cv_lib_nsl_" = xyes; then : -+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5 -+$as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; } -+if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then : - cat >>confdefs.h <<_ACEOF - #define HAVE_LIBNSL 1 - _ACEOF -@@ -5458,9 +5454,9 @@ - - fi - --{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for in -lsocket" >&5 --$as_echo_n "checking for in -lsocket... " >&6; } --if ${ac_cv_lib_socket_+:} false; then : -+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for accept in -lsocket" >&5 -+$as_echo_n "checking for accept in -lsocket... " >&6; } -+if ${ac_cv_lib_socket_accept+:} false; then : - $as_echo_n "(cached) " >&6 - else - ac_check_lib_save_LIBS=$LIBS -@@ -5474,27 +5470,27 @@ - #ifdef __cplusplus - extern "C" - #endif --char (); -+char accept (); - int - main () - { --return (); -+return accept (); - ; - return 0; - } - _ACEOF - if ac_fn_c_try_link "$LINENO"; then : -- ac_cv_lib_socket_=yes -+ ac_cv_lib_socket_accept=yes - else -- ac_cv_lib_socket_=no -+ ac_cv_lib_socket_accept=no - fi - rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LIBS=$ac_check_lib_save_LIBS - fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_" >&5 --$as_echo "$ac_cv_lib_socket_" >&6; } --if test "x$ac_cv_lib_socket_" = xyes; then : -+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_accept" >&5 -+$as_echo "$ac_cv_lib_socket_accept" >&6; } -+if test "x$ac_cv_lib_socket_accept" = xyes; then : - cat >>confdefs.h <<_ACEOF - #define HAVE_LIBSOCKET 1 - _ACEOF -@@ -5503,6 +5499,52 @@ - - fi - -+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sem_open in -lrt" >&5 -+$as_echo_n "checking for sem_open in -lrt... " >&6; } -+if ${ac_cv_lib_rt_sem_open+:} false; then : -+ $as_echo_n "(cached) " >&6 -+else -+ ac_check_lib_save_LIBS=$LIBS -+LIBS="-lrt $LIBS" -+cat confdefs.h - <<_ACEOF >conftest.$ac_ext -+/* end confdefs.h. */ -+ -+/* Override any GCC internal prototype to avoid an error. -+ Use char because int might match the return type of a GCC -+ builtin and then its argument prototype would still apply. */ -+#ifdef __cplusplus -+extern "C" -+#endif -+char sem_open (); -+int -+main () -+{ -+return sem_open (); -+ ; -+ return 0; -+} -+_ACEOF -+if ac_fn_c_try_link "$LINENO"; then : -+ ac_cv_lib_rt_sem_open=yes -+else -+ ac_cv_lib_rt_sem_open=no -+fi -+rm -f core conftest.err conftest.$ac_objext \ -+ conftest$ac_exeext conftest.$ac_ext -+LIBS=$ac_check_lib_save_LIBS -+fi -+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_sem_open" >&5 -+$as_echo "$ac_cv_lib_rt_sem_open" >&6; } -+if test "x$ac_cv_lib_rt_sem_open" = xyes; then : -+ cat >>confdefs.h <<_ACEOF -+#define HAVE_LIBRT 1 -+_ACEOF -+ -+ LIBS="-lrt $LIBS" -+ -+fi -+ -+ - SAVE_LIBS=${LIBS} - LIBS= - -@@ -8978,55 +9020,6 @@ - $as_echo "no" >&6; } - fi - --{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for in -lrt" >&5 --$as_echo_n "checking for in -lrt... " >&6; } --if ${ac_cv_lib_rt_+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- ac_check_lib_save_LIBS=$LIBS --LIBS="-lrt $LIBS" --cat confdefs.h - <<_ACEOF >conftest.$ac_ext --/* end confdefs.h. */ -- --/* Override any GCC internal prototype to avoid an error. -- Use char because int might match the return type of a GCC -- builtin and then its argument prototype would still apply. */ --#ifdef __cplusplus --extern "C" --#endif --char (); --int --main () --{ --return (); -- ; -- return 0; --} --_ACEOF --if ac_fn_c_try_link "$LINENO"; then : -- ac_cv_lib_rt_=yes --else -- ac_cv_lib_rt_=no --fi --rm -f core conftest.err conftest.$ac_objext \ -- conftest$ac_exeext conftest.$ac_ext --LIBS=$ac_check_lib_save_LIBS --fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_" >&5 --$as_echo "$ac_cv_lib_rt_" >&6; } --if test "x$ac_cv_lib_rt_" = xyes; then : -- cat >>confdefs.h <<_ACEOF --#define HAVE_LIBRT 1 --_ACEOF -- -- LIBS="-lrt $LIBS" -- --fi -- --if test "$ac_cv_lib_rt" = yes; then -- NEED_LIBS="${NEED_LIBS} -lrt" --fi -- - NEED_LIBSG="${NEED_LIBS} -lpthread" - - if test "$ac_cv_sizeof_voidp" != 4; then -diff -ru src/Singular/configure.in b/Singular/configure.in ---- src/Singular/configure.in 2012-07-11 12:00:13.000000000 +0200 -+++ b/Singular/configure.in 2012-08-10 15:32:54.943358842 +0200 -@@ -799,8 +799,10 @@ - if test "$ac_cv_singuname" != ix86-Win; then - AC_CHECK_LIB(m, atof) - fi --AC_CHECK_LIB(nsl) --AC_CHECK_LIB(socket) -+AC_CHECK_LIB(nsl,gethostbyname) -+AC_CHECK_LIB(socket,accept) -+AC_CHECK_LIB(rt,sem_open) -+ - SAVE_LIBS=${LIBS} - LIBS= - -@@ -1438,11 +1440,6 @@ - AC_MSG_RESULT(no) - fi - --AC_CHECK_LIB(rt) --if test "$ac_cv_lib_rt" = yes; then -- NEED_LIBS="${NEED_LIBS} -lrt" --fi -- - NEED_LIBSG="${NEED_LIBS} -lpthread" - - if test "$ac_cv_sizeof_voidp" != 4; then diff --git a/build/pkgs/singular/patches/slibdir.patch b/build/pkgs/singular/patches/slibdir.patch index 58d867be102..7b1575ca725 100644 --- a/build/pkgs/singular/patches/slibdir.patch +++ b/build/pkgs/singular/patches/slibdir.patch @@ -1,14 +1,7 @@ -commit d753563ff6bb8ea992999f83db9f454da873d4ba -Author: Jeroen Demeyer -Date: Mon Aug 6 11:50:31 2012 +0200 - - Change default slibdir to ${datarootdir}/singular - -diff --git a/IntegerProgramming/Makefile.in b/IntegerProgramming/Makefile.in -index 50de520..88238a6 100644 ---- a/IntegerProgramming/Makefile.in -+++ b/IntegerProgramming/Makefile.in -@@ -5,7 +5,7 @@ SINGUNAME = @SINGUNAME@ +diff -ru a/IntegerProgramming/Makefile.in b/IntegerProgramming/Makefile.in +--- a/IntegerProgramming/Makefile.in 2012-12-19 22:01:16.000000000 +0100 ++++ b/IntegerProgramming/Makefile.in 2013-08-26 22:44:59.909607832 +0200 +@@ -5,7 +5,7 @@ ## bindir = @bindir@ prefix = @prefix@ @@ -17,11 +10,10 @@ index 50de520..88238a6 100644 install_bindir = ${install_prefix}/${SINGUNAME} libdir = @libdir@ -diff --git a/Singular/Makefile.in b/Singular/Makefile.in -index c4a6e78..e077cd3 100644 ---- a/Singular/Makefile.in -+++ b/Singular/Makefile.in -@@ -47,7 +47,7 @@ libdir = @libdir@ +diff -ru a/Singular/Makefile.in b/Singular/Makefile.in +--- a/Singular/Makefile.in 2012-12-19 22:01:16.000000000 +0100 ++++ b/Singular/Makefile.in 2013-08-26 22:44:59.909607832 +0200 +@@ -48,7 +48,7 @@ bindir = @bindir@ # includes are taken from here includedir = @includedir@ @@ -29,4 +21,5 @@ index c4a6e78..e077cd3 100644 +slibdir = @datarootdir@/singular install_bindir = ${install_prefix}/${SINGUNAME} install_slibdir = ${install_prefix}/LIB - + ifeq (${PYOBJECT_MODULE},) +Only in b/Singular: Makefile.in.orig diff --git a/build/pkgs/singular/spkg-install b/build/pkgs/singular/spkg-install index 5eec77c8599..3caa3829f88 100755 --- a/build/pkgs/singular/spkg-install +++ b/build/pkgs/singular/spkg-install @@ -14,9 +14,6 @@ if [ "$SAGE_LOCAL" = "" ]; then exit 1 fi -# singular's build system uses the output of grep -unset GREP_OPTIONS - # disable the dynamic kernel, except on Linux if [ "$UNAME" != "Linux" ]; then SINGULAR_CONFIGURE="--without-dynamic-kernel $SINGULAR_CONFIGURE" @@ -221,6 +218,10 @@ build_libsingular() echo >&2 "Unable to build and install libsingular." return 1 fi + + # singular does not install this header + cp Singular/sing_dbm.h $SAGE_LOCAL/include/singular/ + export CFLAGS="$OLD_CFLAGS" export CXXFLAGS="$OLD_CXXFLAGS" } diff --git a/build/pkgs/singular/spkg-src b/build/pkgs/singular/spkg-src index 0e28039138a..7235ed3e0a4 100755 --- a/build/pkgs/singular/spkg-src +++ b/build/pkgs/singular/spkg-src @@ -1,6 +1,6 @@ #!/usr/bin/env bash -VERSION="3-1-5" +VERSION="3-1-6" if [ $# -ne 0 ]; then diff --git a/build/pkgs/tachyon/SPKG.txt b/build/pkgs/tachyon/SPKG.txt index 6da10569896..38aaa5c3df9 100644 --- a/build/pkgs/tachyon/SPKG.txt +++ b/build/pkgs/tachyon/SPKG.txt @@ -69,75 +69,3 @@ This spkg depends on: * TODO: [Optionally] also install some of the documentation. * TODO: I doubt the CFLAGS set for AIX and HP-UX won't get overridden by the created Makefile, but that's a minor issue. -leif - - -== Changelog == - -=== tachyon-0.98.9.p5 (William Stein and Leif Leonhardy, August 19th 2011) === - * #11706: Make package build on 64-bit PPC Linux, too (by using the `linux-ppc` - `make` target, which works for ppc64 as well). - * Check exit codes of `cp`, especially in the last case where the built - Tachyon executable gets installed. Also use `cp -p` (and `-f`) there, to - avoid permission issues in multi-user environments. - * Quote all instances of `$UNAME`. - * Copy / install `tachyon.exe` (instead of `tachyon`) on Cygwin. - * Make `spkg-install` executable. - * Fix all file permissions (see Special Update/Build Instructions). - * Fix mark-up of headings of changelog entries. - * Minor cosmetic clean-up. - -=== tachyon-0.98.9.p4 (Karl-Dieter Crisman, June 22, 2011) === - * #11504: Made package build on Cygwin (again) - -=== tachyon-0.98.9.p3 (Julien Puydt, March 12, 2011) === - * #10820: Made package compile on ARM - -=== tachyon-0.98.9.p2 (Volker Braun, January 24, 2011) === - * #10681: Remove "CC=cc" for the maxosx (32-bit) make target - -=== tachyon-0.98.9.p1 (Willem Jan Palenstijn, January 12, 2011) === - * #10609: Fix filename extension detection - -=== tachyon-0.98.9 (Marshall Hampton, David Kirkby, Volker Braun, Leif Leonhardy, January 11, 2011) === - * #5281: upgrade to 0.98.9 form 0.98.beta. - * Also cleaned up SPKG.txt and spkg-install. - * Deleted scenes folder and msvc folders to save space. - * #9997 Add targets for AIX and HP-UX for a generic compiler - such as gcc into patches/Make-arch. These 4 targets are: - aix-generic, aix-generic-thr, hpux-generic and hpux-generic-thr - * Call the targets aix-generic-thr and hpux-generic-thr from - spkg-install on AIX and HP-UX repectively. - -=== tachyon-0.98beta.p12 (Mariah Lenox, 11 Jan 2011) === - * not officially released - * #9378: changed Make-arch so that neither CC, AR, nor RANLIB are - overridden on GNU compiler targets. - -=== tachyon-0.98beta.p11 (David Kirkby, May 23rd 2010) === - * #9024: tachyon is buiding 32-bit on OpenSolaris x64 even when SAGE64 is set to "yes" - -=== tachyon-0.98beta.p10 (Mike Hansen, November 6th, 2009) === - * Fixed tachyon on Cygwin (#7335) - -=== tachyon-0.98beta.p9 (Mike Hansen, June 19th, 2009) === - * Applied Peter Jeremy's fix at #5875. - -=== tachyon-0.98beta.p8 (Michael Abshoff, February 15th, 2009) === - * changed Make-config to link against libpng12 - -=== tachyon-0.98beta.p7 (Michael Abshoff, January 20th, 2009) === - * Add 64 bit OSX support - -=== tachyon-0.98beta.p6 (Andrzej Giniewicz, August 2nd, 2008) === - * Workaround segfault on new GCC versions (#3710) - -=== tachyon-0.98beta.p5 (Michael Abshoff, April 1st, 2008) === - * Debian amd64 fixes (Tim Abbott, #2761) - -=== tachyon-0.98beta.p4 (Tim Abbott, Jan. 15th, 2008) === - * Debianize spkg (Tim Abbott) - * add .hgignore, update SPKG.txt (Michael Abshoff) - -=== tachyon-0.98beta.p3 === - * Changes lost to history - diff --git a/build/pkgs/tachyon/spkg-install b/build/pkgs/tachyon/spkg-install index 1305dff2ab5..2a3b6b71094 100755 --- a/build/pkgs/tachyon/spkg-install +++ b/build/pkgs/tachyon/spkg-install @@ -81,7 +81,7 @@ if [ "$UNAME" = "Linux" ]; then $MAKE linux-64-thr;; ppc|powerpc|ppc64|powerpc64) $MAKE linux-ppc;; - armv7l) + armv6l|armv7l) sed "s/-m32//g" ../../patches/Make-arch > Make-arch $MAKE linux-thr;; *) # e.g. SPARC diff --git a/src/bin/sage-banner b/src/bin/sage-banner index fa48a1fff1b..1130cabd6b6 100644 --- a/src/bin/sage-banner +++ b/src/bin/sage-banner @@ -1,5 +1,5 @@ ┌────────────────────────────────────────────────────────────────────┐ -│ Sage Version 6.1.rc0, Release Date: 2014-01-25 │ +│ Sage Version 6.2.beta1, Release Date: 2014-02-07 │ │ Type "notebook()" for the browser-based notebook interface. │ │ Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ diff --git a/src/bin/sage-spkg b/src/bin/sage-spkg index 82d71abc69c..13adc925da2 100755 --- a/src/bin/sage-spkg +++ b/src/bin/sage-spkg @@ -54,6 +54,8 @@ # http://www.gnu.org/licenses/ #***************************************************************************** +# Avoid surprises with character ranges [a-z] in regular expressions +export LC_ALL=C # error_msg(header, command) # This is for printing an error message if something went wrong. diff --git a/src/bin/sage-version.sh b/src/bin/sage-version.sh index 0423698a2f9..d818fa4bfed 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.1.rc0' -SAGE_RELEASE_DATE='2014-01-25' +SAGE_VERSION='6.2.beta1' +SAGE_RELEASE_DATE='2014-02-07' diff --git a/src/c_lib/SConstruct b/src/c_lib/SConstruct index 1813de8b344..2c3c06e7816 100644 --- a/src/c_lib/SConstruct +++ b/src/c_lib/SConstruct @@ -132,9 +132,9 @@ cFiles = Split( "convert.c interrupt.c memory.c mpn_pylong.c mpz_pylong.c") Split( "mpz_longlong.c stdsage.c gmp_globals.c" ) cppFiles = Split( "ZZ_pylong.cpp ntl_wrap.cpp" ) srcFiles = cFiles + cppFiles -incFiles = Split( "ccobject.h convert.h ginac_wrap.h gmp_globals.h" ) + \ +incFiles = Split( "ccobject.h convert.h gmp_globals.h" ) + \ Split( "interrupt.h memory.h mpn_pylong.h mpz_longlong.h" ) + \ - Split( "mpz_pylong.h ntl_wrap.h pb_wrap.h stdsage.h ZZ_pylong.h" ) + Split( "mpz_pylong.h ntl_wrap.h stdsage.h ZZ_pylong.h" ) lib = env.SharedLibrary( "csage", [ "src/" + x for x in srcFiles ], LIBS=['ntl', 'pari', 'gmp', 'python$PYV'], diff --git a/src/doc/common/build_options.py b/src/doc/common/build_options.py index 7b0cf5f74a9..da287915c83 100644 --- a/src/doc/common/build_options.py +++ b/src/doc/common/build_options.py @@ -25,3 +25,4 @@ from sage.interfaces.gap import set_gap_memory_pool_size set_gap_memory_pool_size(0) # will be rounded up to 1M +INCREMENTAL_BUILD = os.path.exists(os.path.join(SAGE_DOC, 'output')) diff --git a/src/doc/common/builder.py b/src/doc/common/builder.py index f7218cb7844..d5322afac63 100644 --- a/src/doc/common/builder.py +++ b/src/doc/common/builder.py @@ -84,7 +84,7 @@ def f(self, *args, **kwds): except Exception: import traceback logger.error(traceback.format_exc()) - + raise # Print message about location of output: # - by default if html output @@ -278,9 +278,20 @@ def _wrapper(self, name, *args, **kwds): L = [(doc, name, kwds) + args for doc in others] # map_async handles KeyboardInterrupt correctly. Plain map and # apply_async does not, so don't use it. - pool.map_async(build_other_doc, L, 1).get(99999) - pool.close() - pool.join() + x = pool.map_async(build_other_doc, L, 1) + try: + x.get(99999) + pool.close() + pool.join() + except Exception: + pool.terminate() + logger.error('Error building the documentation.') + if INCREMENTAL_BUILD: + logger.error(''' +Note: incremental documentation builds sometimes cause spurious +error messages. To be certain that these are real errors, run +"make doc-clean" first and try again.''') + raise logger.warning("Elapsed time: %.1f seconds."%(time.time()-start)) logger.warning("Done building the documentation!") @@ -469,9 +480,20 @@ def _wrapper(self, format, *args, **kwds): pool = Pool(NUM_THREADS, maxtasksperchild=1) L = [(doc, lang, format, kwds) + args for doc in self.get_all_documents(refdir)] # (See comment in AllBuilder._wrapper about using map instead of apply.) - pool.map_async(build_ref_doc, L, 1).get(99999) - pool.close() - pool.join() + x = pool.map_async(build_ref_doc, L, 1) + try: + x.get(99999) + pool.close() + pool.join() + except Exception: + pool.terminate() + logger.error('Error building the documentation.') + if INCREMENTAL_BUILD: + logger.error(''' +Note: incremental documentation builds sometimes cause spurious +error messages. To be certain that these are real errors, run +"make doc-clean" first and try again.''') + raise # The html refman must be build at the end to ensure correct # merging of indexes and inventories. # Sphinx is run here in the current process (not in a diff --git a/src/doc/common/custom-sphinx-build.py b/src/doc/common/custom-sphinx-build.py index e8c1cd984cc..2a1f50cd34b 100644 --- a/src/doc/common/custom-sphinx-build.py +++ b/src/doc/common/custom-sphinx-build.py @@ -46,6 +46,18 @@ def term_width_line(text): replacements += ([re.compile('build succeeded, [0-9]+ warning[s]?.'), 'build succeeded.'], ) +# warnings: regular expressions (or strings) indicating a problem with +# docbuilding. Raise an exception if any of these occur. + +warnings = (re.compile('Segmentation fault'), + re.compile('SEVERE'), + re.compile('ERROR'), + re.compile('^make.*Error'), + re.compile('Exception occurred'), + re.compile('Sphinx error')) + +if 'pdf' not in sys.argv: + warnings += (re.compile('WARNING'),) class SageSphinxLogger(object): """ @@ -74,6 +86,13 @@ def _filter_out(self, line): return True return False + def _warnings(self, line): + global warnings + for regex in warnings: + if regex.search(line) is not None: + return True + return False + def _log_line(self, line): if self._filter_out(line): return @@ -85,6 +104,8 @@ def _log_line(self, line): line = self.ansi_color.sub('', line) self._stream.write(line) self._stream.flush() + if self._warnings(line): + raise OSError(line) _line_buffer = '' @@ -142,6 +163,8 @@ def flush(self): def write(self, str): try: self._write(str) + except OSError: + raise except StandardError: import traceback traceback.print_exc(file=self._stream) diff --git a/src/doc/en/bordeaux_2008/elliptic_curves.rst b/src/doc/en/bordeaux_2008/elliptic_curves.rst index 8176059a745..eec9bb6715f 100644 --- a/src/doc/en/bordeaux_2008/elliptic_curves.rst +++ b/src/doc/en/bordeaux_2008/elliptic_curves.rst @@ -369,7 +369,6 @@ where :math:`E` is still the rank :math:`2` curve 389a. :: sage: L.zeros(10) - *** Warning: new stack size = ... [0.000000000, 0.000000000, 2.87609907, 4.41689608, 5.79340263, 6.98596665, 7.47490750, 8.63320525, 9.63307880, 10.3514333] diff --git a/src/doc/en/reference/coercion/index.rst b/src/doc/en/reference/coercion/index.rst index 933098a1af0..59c80fb772e 100644 --- a/src/doc/en/reference/coercion/index.rst +++ b/src/doc/en/reference/coercion/index.rst @@ -222,11 +222,11 @@ be obtained and queried. sage: cm.explain(ZZ['x','y'], QQ['x']) Coercion on left operand via - Call morphism: + Conversion map: From: Multivariate Polynomial Ring in x, y over Integer Ring To: Multivariate Polynomial Ring in x, y over Rational Field Coercion on right operand via - Call morphism: + Conversion map: From: Univariate Polynomial Ring in x over Rational Field To: Multivariate Polynomial Ring in x, y over Rational Field Arithmetic performed after coercions. diff --git a/src/doc/en/reference/libs/index.rst b/src/doc/en/reference/libs/index.rst index 7081b20cb55..729fe5e97f1 100644 --- a/src/doc/en/reference/libs/index.rst +++ b/src/doc/en/reference/libs/index.rst @@ -27,6 +27,7 @@ to be aware of the modules described in this chapter. sage/libs/gap/element sage/libs/flint/fmpz_poly sage/libs/libecm + sage/libs/lcalc/lcalc_Lfunction sage/libs/lrcalc/lrcalc sage/libs/ntl/all sage/libs/mwrank/all diff --git a/src/doc/en/thematic_tutorials/coercion_and_categories.rst b/src/doc/en/thematic_tutorials/coercion_and_categories.rst index 1a31e7a1224..6b5a02d0652 100644 --- a/src/doc/en/thematic_tutorials/coercion_and_categories.rst +++ b/src/doc/en/thematic_tutorials/coercion_and_categories.rst @@ -751,7 +751,7 @@ thus have:: sage: P1.has_coerce_map_from(P2) True sage: P1.coerce_map_from(P2) - Call morphism: + Conversion map: From: Multivariate Polynomial Ring in w, v over Integer Ring To: Multivariate Polynomial Ring in v, w over Rational Field @@ -759,7 +759,7 @@ While there is a conversion from `P_1` to `P_2` (namely restricted to polynomials with integral coefficients), this conversion is not a coercion:: sage: P2.convert_map_from(P1) - Call morphism: + Conversion map: From: Multivariate Polynomial Ring in v, w over Rational Field To: Multivariate Polynomial Ring in w, v over Integer Ring sage: P2.has_coerce_map_from(P1) diff --git a/src/doc/en/thematic_tutorials/tutorial-objects-and-classes.rst b/src/doc/en/thematic_tutorials/tutorial-objects-and-classes.rst index 47d2a45191c..300a92bb813 100644 --- a/src/doc/en/thematic_tutorials/tutorial-objects-and-classes.rst +++ b/src/doc/en/thematic_tutorials/tutorial-objects-and-classes.rst @@ -297,11 +297,12 @@ Some particular actions modify the data structure of ``el``:: sage: e.__dict__ dict_proxy({'__module__': 'sage.categories.euclidean_domains', - '_reduction': (, (Category of - euclidean domains, 'element_class')), '__doc__': None, + '__doc__': None, '_reduction': (, (Category + of euclidean domains, 'element_class')), 'gcd': + , '_sage_src_lines_': }) sage: e.__dict__.keys() - ['__module__', '_reduction', '__doc__', '_sage_src_lines_'] + ['__module__', '__doc__', '_reduction', 'gcd', '_sage_src_lines_'] sage: id4 = SymmetricGroup(4).one() sage: type(id4) diff --git a/src/doc/fr/tutorial/sagetex.rst b/src/doc/fr/tutorial/sagetex.rst index 49f35ff3a26..4e9ca8ab78b 100644 --- a/src/doc/fr/tutorial/sagetex.rst +++ b/src/doc/fr/tutorial/sagetex.rst @@ -1,3 +1,5 @@ +.. _sec-sagetex: + **************** Utiliser SageTeX **************** diff --git a/src/doc/fr/tutorial/tour_rings.rst b/src/doc/fr/tutorial/tour_rings.rst index 7a165bf38bf..535f1da6f75 100644 --- a/src/doc/fr/tutorial/tour_rings.rst +++ b/src/doc/fr/tutorial/tour_rings.rst @@ -1,3 +1,5 @@ +.. _section-rings: + *************** Anneaux de base *************** diff --git a/src/module_list.py b/src/module_list.py index d6a3bd5553e..26520f83ae9 100755 --- a/src/module_list.py +++ b/src/module_list.py @@ -369,10 +369,9 @@ def uname_specific(name, value, alternative): libraries = ['gmp']), Extension('sage.graphs.cliquer', - sources = ['sage/graphs/cliquer.pyx'], + sources = ['sage/graphs/cliquer.pyx', 'sage/graphs/cliquer/cl.c'], libraries = ['cliquer']), - Extension('sage.graphs.graph_decompositions.vertex_separation', sources = ['sage/graphs/graph_decompositions/vertex_separation.pyx']), diff --git a/src/sage/algebras/group_algebra.py b/src/sage/algebras/group_algebra.py index caca0de3d44..5195f6b71a9 100644 --- a/src/sage/algebras/group_algebra.py +++ b/src/sage/algebras/group_algebra.py @@ -222,7 +222,7 @@ def _an_element_impl(self): (self.base_ring().random_element(), self.group().random_element()), (self.base_ring().random_element(), self.group().random_element()), ])) - except StandardError: # base ring or group might not implement .random_element() + except Exception: # base ring or group might not implement .random_element() return self(self._formal_sum_module([ (self.base_ring().an_element(), self.group().an_element()) ])) def __call__(self, x, check=True): diff --git a/src/sage/algebras/hall_algebra.py b/src/sage/algebras/hall_algebra.py index f987f9322d0..847bf416c7f 100644 --- a/src/sage/algebras/hall_algebra.py +++ b/src/sage/algebras/hall_algebra.py @@ -228,7 +228,7 @@ def __init__(self, base_ring, q, prefix='H'): hopf_structure = False else: hopf_structure = True - except StandardError: + except Exception: hopf_structure = False if hopf_structure: category = HopfAlgebrasWithBasis(base_ring) @@ -549,7 +549,7 @@ def __init__(self, base_ring, q, prefix='I'): hopf_structure = False else: hopf_structure = True - except StandardError: + except Exception: hopf_structure = False if hopf_structure: category = HopfAlgebrasWithBasis(base_ring) diff --git a/src/sage/algebras/iwahori_hecke_algebra.py b/src/sage/algebras/iwahori_hecke_algebra.py index ac7f3494a8b..9c48845e95d 100644 --- a/src/sage/algebras/iwahori_hecke_algebra.py +++ b/src/sage/algebras/iwahori_hecke_algebra.py @@ -1270,7 +1270,7 @@ def inverse_generator(self, i): # avoids accidental coercion into a field of fractions. i1 = normalized_laurent_polynomial(A._base, A._q1.__pow__(-1)) i2 = normalized_laurent_polynomial(A._base, A._q2.__pow__(-1)) - except StandardError: + except Exception: raise ValueError("%s and %s must be invertible."%(A._q1, A._q2)) return (-i1*i2)*self.algebra_generator(i)+(i1+i2) diff --git a/src/sage/all.py b/src/sage/all.py index bc18bb5a626..5c46bfc19bd 100644 --- a/src/sage/all.py +++ b/src/sage/all.py @@ -210,7 +210,7 @@ #try: # import resource # unix only... # resource.setrlimit(resource.RLIMIT_AS, (-1,-1)) -#except StandardError: +#except Exception: # pass # very useful 2-letter shortcuts diff --git a/src/sage/categories/crystals.py b/src/sage/categories/crystals.py index 5367ba52083..d44a0daf353 100644 --- a/src/sage/categories/crystals.py +++ b/src/sage/categories/crystals.py @@ -441,12 +441,12 @@ def morphism(b): # - images contains all known morphism(x) # - known contains all elements x for which we know morphism(x) # - todo contains all elements x for which we haven't propagated to each child - while todo <> set( [] ): + while todo != set( [] ): x = todo.pop() for i in index_set: eix = getattr(x, f_string)([i for k in range(similarity_factor_domain[i])]) eigx = getattr(morphism[x], f_string)([automorphism(i) for k in range(similarity_factor[i])]) - if bool(eix is None) <> bool(eigx is None): + if bool(eix is None) != bool(eigx is None): # This is not a crystal morphism! raise ValueError, "This is not a morphism!" #, print("x="x,"g(x)="g(x),"i="i) if (eix is not None) and (eix not in known): diff --git a/src/sage/categories/euclidean_domains.py b/src/sage/categories/euclidean_domains.py index 25c9870659c..77f572b76f8 100644 --- a/src/sage/categories/euclidean_domains.py +++ b/src/sage/categories/euclidean_domains.py @@ -12,6 +12,7 @@ from sage.categories.category_singleton import Category_singleton from sage.categories.principal_ideal_domains import PrincipalIdealDomains from sage.misc.cachefunc import cached_method +from sage.structure.element import coerce_binop class EuclideanDomains(Category_singleton): """ @@ -54,4 +55,34 @@ def is_euclidean_domain(self): return True class ElementMethods: - pass + @coerce_binop + def gcd(self, other): + """ + Return the greatest common divisor of this element and ``other``. + + INPUT: + + - ``other`` -- an element in the same ring as ``self`` + + ALGORITHM: + + Algorithm 3.2.1 in [Coh1996]_. + + REFERENCES: + + .. [Coh1996] Henri Cohen. *A Course in Computational Algebraic + Number Theory*. Springer, 1996. + + EXAMPLES:: + + sage: EuclideanDomains().ElementMethods().gcd(6,4) + 2 + """ + A = self + B = other + while not B.is_zero(): + Q, R = A.quo_rem(B) + A = B + B = R + return A + diff --git a/src/sage/categories/examples/finite_enumerated_sets.py b/src/sage/categories/examples/finite_enumerated_sets.py index f6463aa835b..2f2b368abcd 100644 --- a/src/sage/categories/examples/finite_enumerated_sets.py +++ b/src/sage/categories/examples/finite_enumerated_sets.py @@ -195,5 +195,5 @@ def __contains__(self, x): """ try: return self.lift(x) in self.ambient() - except StandardError: + except Exception: return False diff --git a/src/sage/categories/facade_sets.py b/src/sage/categories/facade_sets.py index c2bbed0d499..647cbf34ec2 100644 --- a/src/sage/categories/facade_sets.py +++ b/src/sage/categories/facade_sets.py @@ -206,7 +206,7 @@ def _element_constructor_(self, element): for parent in self.facade_for(): try: return parent(element) - except StandardError: + except Exception: pass raise ValueError, "Can't coerce `%s` in any parent `%s` is a facade for"%(element, self) diff --git a/src/sage/categories/fields.py b/src/sage/categories/fields.py index 52398f5089a..e1547f6a724 100644 --- a/src/sage/categories/fields.py +++ b/src/sage/categories/fields.py @@ -6,6 +6,7 @@ # William Stein # 2008 Teresa Gomez-Diaz (CNRS) # 2008-2009 Nicolas M. Thiery +# 2012 Julian Rueth # # Distributed under the terms of the GNU General Public License (GPL) # http://www.gnu.org/licenses/ @@ -20,6 +21,7 @@ from sage.misc.cachefunc import cached_method from sage.misc.lazy_attribute import lazy_class_attribute import sage.rings.ring +from sage.structure.element import coerce_binop class Fields(Category_singleton): """ @@ -104,7 +106,7 @@ def __contains__(self, x): """ try: return self._contains_helper(x) or sage.rings.ring._is_Field(x) - except StandardError: + except Exception: return False @lazy_class_attribute @@ -397,3 +399,42 @@ def lcm(self,other): if self==0 or other==0: return P.zero() return P.one() + + @coerce_binop + def xgcd(self, other): + """ + Compute the extended gcd of ``self`` and ``other``. + + INPUT: + + - ``other`` -- an element with the same parent as ``self`` + + OUTPUT: + + A tuple ``(r, s, t)`` of elements in the parent of ``self`` such + that ``r = s * self + t * other``. Since the computations are done + over a field, ``r`` is zero if ``self`` and ``other`` are zero, + and one otherwise. + + AUTHORS: + + - Julian Rueth (2012-10-19): moved here from + :class:`sage.structure.element.FieldElement` + + EXAMPLES:: + + sage: (1/2).xgcd(2) + (1, 2, 0) + sage: (0/2).xgcd(2) + (1, 0, 1/2) + sage: (0/2).xgcd(0) + (0, 0, 0) + """ + R = self.parent() + if not self.is_zero(): + return (R.one(), ~self, R.zero()) + if not other.is_zero(): + return (R.one(), R.zero(), ~other) + # else both are 0 + return (R.zero(), R.zero(), R.zero()) + diff --git a/src/sage/categories/functor.pyx b/src/sage/categories/functor.pyx index 8ce2813d74a..512b67997a1 100644 --- a/src/sage/categories/functor.pyx +++ b/src/sage/categories/functor.pyx @@ -253,7 +253,7 @@ cdef class Functor(SageObject): """ try: return self(f.domain()).hom(f, self(f.codomain())) - except StandardError: + except Exception: raise TypeError, 'unable to transform %s into a morphism in %s'%(f,self.codomain()) def _coerce_into_domain(self, x): diff --git a/src/sage/categories/morphism.pyx b/src/sage/categories/morphism.pyx index 47aa1881265..8ed524af2a6 100644 --- a/src/sage/categories/morphism.pyx +++ b/src/sage/categories/morphism.pyx @@ -389,7 +389,7 @@ cdef class SetMorphism(Morphism): """ try: return self._function(x, *args, **kwds) - except StandardError: + except Exception: raise TypeError, "Underlying map %s does not accept additional arguments"%type(self._function) cdef _extra_slots(self, _slots): diff --git a/src/sage/categories/quotient_fields.py b/src/sage/categories/quotient_fields.py index 06c72dd8431..f58a35ac5c9 100644 --- a/src/sage/categories/quotient_fields.py +++ b/src/sage/categories/quotient_fields.py @@ -266,6 +266,48 @@ def partial_fraction_decomposition(self): sage: sum(parts) == q True + We can decompose over a given algebraic extension:: + + sage: R. = QQ[sqrt(2)][] + sage: r = 1/(x^4+1) + sage: r.partial_fraction_decomposition() + (0, + [(-1/4*sqrt2*x + 1/2)/(x^2 - sqrt2*x + 1), + (1/4*sqrt2*x + 1/2)/(x^2 + sqrt2*x + 1)]) + + sage: R. = QQ[I][] # of QQ[sqrt(-1)] + sage: r = 1/(x^4+1) + sage: r.partial_fraction_decomposition() + (0, [(-1/2*I)/(x^2 - I), 1/2*I/(x^2 + I)]) + + We can also ask Sage to find the least extension where the + denominator factors in linear terms:: + + sage: R. = QQ[] + sage: r = 1/(x^4+2) + sage: N = r.denominator().splitting_field('a') + sage: N + Number Field in a with defining polynomial x^8 - 8*x^6 + 28*x^4 + 16*x^2 + 36 + sage: R1.=N[] + sage: r1 = 1/(x1^4+2) + sage: r1.partial_fraction_decomposition() + (0, + [(-1/224*a^6 + 13/448*a^4 - 5/56*a^2 - 25/224)/(x1 - 1/28*a^6 + 13/56*a^4 - 5/7*a^2 - 25/28), + (1/224*a^6 - 13/448*a^4 + 5/56*a^2 + 25/224)/(x1 + 1/28*a^6 - 13/56*a^4 + 5/7*a^2 + 25/28), + (-5/1344*a^7 + 43/1344*a^5 - 85/672*a^3 - 31/672*a)/(x1 - 5/168*a^7 + 43/168*a^5 - 85/84*a^3 - 31/84*a), + (5/1344*a^7 - 43/1344*a^5 + 85/672*a^3 + 31/672*a)/(x1 + 5/168*a^7 - 43/168*a^5 + 85/84*a^3 + 31/84*a)]) + + Or we may work directly over an algebraically closed field:: + + sage: R. = QQbar[] + sage: r = 1/(x^4+1) + sage: r.partial_fraction_decomposition() + (0, + [(-0.1767766952966369? - 0.1767766952966369?*I)/(x - 0.7071067811865475? - 0.7071067811865475?*I), + (-0.1767766952966369? + 0.1767766952966369?*I)/(x - 0.7071067811865475? + 0.7071067811865475?*I), + (0.1767766952966369? - 0.1767766952966369?*I)/(x + 0.7071067811865475? - 0.7071067811865475?*I), + (0.1767766952966369? + 0.1767766952966369?*I)/(x + 0.7071067811865475? + 0.7071067811865475?*I)]) + We do the best we can over inexact fields:: sage: R. = RealField(20)[] diff --git a/src/sage/coding/binary_code.pyx b/src/sage/coding/binary_code.pyx index a5eab65e6d3..5286fb30be5 100644 --- a/src/sage/coding/binary_code.pyx +++ b/src/sage/coding/binary_code.pyx @@ -1526,7 +1526,7 @@ cdef class PartitionStack: self.nrows = arg1 self.nwords = 1 << self.nrows self.ncols = arg2 - except StandardError: + except Exception: other = arg1 self.nrows = other.nrows self.nwords = other.nwords diff --git a/src/sage/coding/code_constructions.py b/src/sage/coding/code_constructions.py index bc004135dd5..892c7344500 100644 --- a/src/sage/coding/code_constructions.py +++ b/src/sage/coding/code_constructions.py @@ -221,13 +221,13 @@ def cyclotomic_cosets(q, n, t = None): the cosets are in ZZ/nZZ and 2 = 0 in ZZ/2ZZ. """ from sage.misc.misc import srange - if not(t==None) and type(t)<>Integer: + if t is not None and not isinstance(t, Integer): raise TypeError, "Optional input %s must None or an integer."%t if q<2 or n<2: raise TypeError, "Inputs %s and %s must be > 1."%(q,n) - if GCD(q,n) <> 1: + if GCD(q,n) != 1: raise TypeError, "Inputs %s and %s must be relative prime."%(q,n) - if t<>None and type(t)==Integer: + if t is not None and isinstance(t, Integer): S = Set([t*q**i%n for i in srange(n)]) L = list(S) L.sort() @@ -302,7 +302,7 @@ def is_a_splitting(S1,S2,n): This is a special case of Theorem 6.4.3 in [HP]_. """ - if Set(S1).union(Set(S2)) <> Set(range(1,n)): + if Set(S1).union(Set(S2)) != Set(range(1,n)): raise TypeError, "Lists must partition [1,2,...,n-1]." if n<3: raise TypeError, "Input %s must be > 2."%n diff --git a/src/sage/coding/linear_code.py b/src/sage/coding/linear_code.py index e762b669cce..09990c5d356 100644 --- a/src/sage/coding/linear_code.py +++ b/src/sage/coding/linear_code.py @@ -2919,9 +2919,9 @@ def standard_form(self): for i in range(1,k+1): r = M.rows()[i-1] j = r.nonzero_positions()[0] - if (j < d and i <> j+1): + if j < d and i != j+1: perm = perm *G([(i,j+1)]) - if perm <> G([()]): + if perm != G([()]): for i in range(k): r = M.rows()[i] A.append(perm_action(perm,r)) diff --git a/src/sage/combinat/abstract_tree.py b/src/sage/combinat/abstract_tree.py index 411fd7b834a..8badc3bdce3 100644 --- a/src/sage/combinat/abstract_tree.py +++ b/src/sage/combinat/abstract_tree.py @@ -44,10 +44,10 @@ **Canonical labellings** -Equality between instances of classes extending both of :class:`AbstractTree` +Equality between instances of classes extending both :class:`AbstractTree` and ``A`` is entirely defined by the equality defined on the elements of -``A``. A canonical labelling of such a tree however, should be such that two -trees ``a`` and ``b`` satisfying ``a == b`` should have the same canonical +``A``. A canonical labelling of such a tree, however, should be such that +two trees ``a`` and ``b`` satisfying ``a == b`` have the same canonical labellings. On the other hand, the canonical labellings of trees ``a`` and ``b`` satisfying ``a != b`` are expected to be different. @@ -67,17 +67,18 @@ from sage.rings.integer import Integer from sage.misc.misc_c import prod + # Unfortunately Cython forbids multiple inheritance. Therefore, we do not -# inherits from SageObject to be able to inherits from Element or a subclass +# inherit from SageObject to be able to inherit from Element or a subclass # of it later. class AbstractTree(object): """ - Abstract Tree + Abstract Tree. There is no data structure defined here, as this class is meant to be extended, not instantiated. - .. rubric:: How should this class be extended ? + .. rubric:: How should this class be extended? A class extending :class:`AbstractTree ` should respect several @@ -90,7 +91,7 @@ class AbstractTree(object): ` method should return the same value for trees that are considered equal (see the "canonical labellings" section in the documentation of the - :class:`AbstractTree ` module). + :class:`AbstractTree ` class). * For a tree ``T`` the call ``T.parent().labelled_trees()`` should return a parent for labelled trees of the same kind: for example, @@ -106,12 +107,641 @@ class AbstractTree(object): sage: TestSuite(OrderedTree()).run() sage: TestSuite(BinaryTree()).run() """ + def pre_order_traversal_iter(self): + r""" + The depth-first pre-order traversal iterator. + + This method iters each node following the depth-first pre-order + traversal algorithm (recursive implementation). The algorithm + is:: + + yield the root (in the case of binary trees, if it is not + a leaf); + then explore each subtree (by the algorithm) from the + leftmost one to the rightmost one. + + EXAMPLES: + + For example, on the following binary tree `b`:: + + | ___3____ | + | / \ | + | 1 _7_ | + | \ / \ | + | 2 5 8 | + | / \ | + | 4 6 | + + (only the nodes shown), the depth-first pre-order traversal + algorithm explores `b` in the following order of nodes: + `3,1,2,7,5,4,6,8`. + + Another example:: + + | __1____ | + | / / / | + | 2 6 8_ | + | | | / / | + | 3_ 7 9 10 | + | / / | + | 4 5 | + + The algorithm explores this labelled tree in the following + order: `1,2,3,4,5,6,7,8,9,10`. + + TESTS:: + + sage: b = BinaryTree([[None,[]],[[[],[]],[]]]).canonical_labelling() + sage: ascii_art([b]) + [ ___3____ ] + [ / \ ] + [ 1 _7_ ] + [ \ / \ ] + [ 2 5 8 ] + [ / \ ] + [ 4 6 ] + sage: [n.label() for n in b.pre_order_traversal_iter()] + [3, 1, 2, 7, 5, 4, 6, 8] + + sage: t = OrderedTree([[[[],[]]],[[]],[[],[]]]).canonical_labelling() + sage: ascii_art([t]) + [ __1____ ] + [ / / / ] + [ 2 6 8_ ] + [ | | / / ] + [ 3_ 7 9 10 ] + [ / / ] + [ 4 5 ] + sage: [n.label() for n in t.pre_order_traversal_iter()] + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + + sage: [n for n in BinaryTree(None).pre_order_traversal_iter()] + [] + + The following test checks that things do not go wrong if some among + the descendants of the tree are equal or even identical:: + + sage: u = BinaryTree(None) + sage: v = BinaryTree([u, u]) + sage: w = BinaryTree([v, v]) + sage: t = BinaryTree([w, w]) + sage: t.node_number() + 7 + sage: l = [1 for i in t.pre_order_traversal_iter()] + sage: len(l) + 7 + """ + if self.is_empty(): + return + yield self + # TODO:: PYTHON 3 + # import itertools + # yield from itertools.chain(map( + # lambda c: c.pre_order_traversal_iter(), + # self + # )) + for children in self: + for node in children.pre_order_traversal_iter(): + yield node + + def iterative_pre_order_traversal(self, action=None): + r""" + Run the depth-first pre-order traversal algorithm (iterative + implementation) and subject every node encountered + to some procedure ``action``. The algorithm is:: + + manipulate the root with function `action` (in the case + of a binary tree, only if the root is not a leaf); + then explore each subtree (by the algorithm) from the + leftmost one to the rightmost one. + + INPUT: + + - ``action`` -- (optional) a function which takes a node as + input, and does something during the exploration + + OUTPUT: + + ``None``. (This is *not* an iterator.) + + .. SEEALSO:: + + - :meth:`~sage.combinat.abstract_tree.AbstractTree.pre_order_traversal_iter()` + - :meth:`~sage.combinat.abstract_tree.AbstractTree.pre_order_traversal()` + + TESTS:: + + sage: l = [] + sage: b = BinaryTree([[None,[]],[[[],[]],[]]]).canonical_labelling() + sage: b + 3[1[., 2[., .]], 7[5[4[., .], 6[., .]], 8[., .]]] + sage: b.iterative_pre_order_traversal(lambda node: l.append(node.label())) + sage: l + [3, 1, 2, 7, 5, 4, 6, 8] + + sage: t = OrderedTree([[[[],[]]],[[]],[[],[]]]).canonical_labelling() + sage: t + 1[2[3[4[], 5[]]], 6[7[]], 8[9[], 10[]]] + sage: l = [] + sage: t.iterative_pre_order_traversal(lambda node: l.append(node.label())) + sage: l + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + sage: l = [] + + sage: BinaryTree().canonical_labelling().\ + ....: pre_order_traversal(lambda node: l.append(node.label())) + sage: l + [] + sage: OrderedTree([]).canonical_labelling().\ + ....: iterative_pre_order_traversal(lambda node: l.append(node.label())) + sage: l + [1] + + The following test checks that things do not go wrong if some among + the descendants of the tree are equal or even identical:: + + sage: u = BinaryTree(None) + sage: v = BinaryTree([u, u]) + sage: w = BinaryTree([v, v]) + sage: t = BinaryTree([w, w]) + sage: t.node_number() + 7 + sage: l = [] + sage: t.iterative_pre_order_traversal(lambda node: l.append(1)) + sage: len(l) + 7 + """ + if self.is_empty(): + return + if action is None: + action = lambda x: None + stack = [] + stack.append(self) + while len(stack) > 0: + node = stack.pop() + action(node) + for i in range(len(node)): + subtree = node[-i - 1] + if not subtree.is_empty(): + stack.append(subtree) + + def pre_order_traversal(self, action=None): + r""" + Run the depth-first pre-order traversal algorithm (recursive + implementation) and subject every node encountered + to some procedure ``action``. The algorithm is:: + + manipulate the root with function `action` (in the case + of a binary tree, only if the root is not a leaf); + then explore each subtree (by the algorithm) from the + leftmost one to the rightmost one. + + INPUT: + + - ``action`` -- (optional) a function which takes a node as + input, and does something during the exploration + + OUTPUT: + + ``None``. (This is *not* an iterator.) + + EXAMPLES: + + For example, on the following binary tree `b`:: + + | ___3____ | + | / \ | + | 1 _7_ | + | \ / \ | + | 2 5 8 | + | / \ | + | 4 6 | + + the depth-first pre-order traversal algorithm explores `b` in the + following order of nodes: `3,1,2,7,5,4,6,8`. + + Another example:: + + | __1____ | + | / / / | + | 2 6 8_ | + | | | / / | + | 3_ 7 9 10 | + | / / | + | 4 5 | + + The algorithm explores this tree in the following order: + `1,2,3,4,5,6,7,8,9,10`. + + .. SEEALSO:: + + - :meth:`~sage.combinat.abstract_tree.AbstractTree.pre_order_traversal_iter()` + - :meth:`~sage.combinat.abstract_tree.AbstractTree.iterative_pre_order_traversal()` + + TESTS:: + + sage: l = [] + sage: b = BinaryTree([[None,[]],[[[],[]],[]]]).canonical_labelling() + sage: b + 3[1[., 2[., .]], 7[5[4[., .], 6[., .]], 8[., .]]] + sage: b.pre_order_traversal(lambda node: l.append(node.label())) + sage: l + [3, 1, 2, 7, 5, 4, 6, 8] + sage: li = [] + sage: b.iterative_pre_order_traversal(lambda node: li.append(node.label())) + sage: l == li + True + + sage: t = OrderedTree([[[[],[]]],[[]],[[],[]]]).canonical_labelling() + sage: t + 1[2[3[4[], 5[]]], 6[7[]], 8[9[], 10[]]] + sage: l = [] + sage: t.pre_order_traversal(lambda node: l.append(node.label())) + sage: l + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + sage: li = [] + sage: t.iterative_pre_order_traversal(lambda node: li.append(node.label())) + sage: l == li + True + + sage: l = [] + sage: BinaryTree().canonical_labelling().\ + ....: pre_order_traversal(lambda node: l.append(node.label())) + sage: l + [] + sage: OrderedTree([]).canonical_labelling().\ + ....: pre_order_traversal(lambda node: l.append(node.label())) + sage: l + [1] + + The following test checks that things do not go wrong if some among + the descendants of the tree are equal or even identical:: + + sage: u = BinaryTree(None) + sage: v = BinaryTree([u, u]) + sage: w = BinaryTree([v, v]) + sage: t = BinaryTree([w, w]) + sage: t.node_number() + 7 + sage: l = [] + sage: t.pre_order_traversal(lambda node: l.append(1)) + sage: len(l) + 7 + """ + if action is None: + action = lambda x: None + for node in self.pre_order_traversal_iter(): + action(node) + + def post_order_traversal_iter(self): + r""" + The depth-first post-order traversal iterator. + + This method iters each node following the depth-first post-order + traversal algorithm (recursive implementation). The algorithm + is:: + + explore each subtree (by the algorithm) from the + leftmost one to the rightmost one; + then yield the root (in the case of binary trees, only if + it is not a leaf). + + EXAMPLES: + + For example on the following binary tree `b`:: + + | ___3____ | + | / \ | + | 1 _7_ | + | \ / \ | + | 2 5 8 | + | / \ | + | 4 6 | + + (only the nodes are shown), the depth-first post-order traversal + algorithm explores `b` in the following order of nodes: + `2,1,4,6,5,8,7,3`. + + For another example, consider the labelled tree:: + + | __1____ | + | / / / | + | 2 6 8_ | + | | | / / | + | 3_ 7 9 10 | + | / / | + | 4 5 | + + The algorithm explores this tree in the following order: + `4,5,3,2,7,6,9,10,8,1`. + + TESTS:: + + sage: b = BinaryTree([[None,[]],[[[],[]],[]]]).canonical_labelling() + sage: ascii_art([b]) + [ ___3____ ] + [ / \ ] + [ 1 _7_ ] + [ \ / \ ] + [ 2 5 8 ] + [ / \ ] + [ 4 6 ] + sage: [node.label() for node in b.post_order_traversal_iter()] + [2, 1, 4, 6, 5, 8, 7, 3] + + sage: t = OrderedTree([[[[],[]]],[[]],[[],[]]]).canonical_labelling() + sage: ascii_art([t]) + [ __1____ ] + [ / / / ] + [ 2 6 8_ ] + [ | | / / ] + [ 3_ 7 9 10 ] + [ / / ] + [ 4 5 ] + sage: [node.label() for node in t.post_order_traversal_iter()] + [4, 5, 3, 2, 7, 6, 9, 10, 8, 1] + + sage: [node.label() for node in BinaryTree().canonical_labelling().\ + ....: post_order_traversal_iter()] + [] + sage: [node.label() for node in OrderedTree([]).\ + ....: canonical_labelling().post_order_traversal_iter()] + [1] + + The following test checks that things do not go wrong if some among + the descendants of the tree are equal or even identical:: + + sage: u = BinaryTree(None) + sage: v = BinaryTree([u, u]) + sage: w = BinaryTree([v, v]) + sage: t = BinaryTree([w, w]) + sage: t.node_number() + 7 + sage: l = [1 for i in t.post_order_traversal_iter()] + sage: len(l) + 7 + """ + if self.is_empty(): + return + # TODO:: PYTHON 3 + # import itertools + # yield from itertools.chain(map( + # lambda c: c.post_order_traversal_iter(), + # self + # )) + for children in self: + for node in children.post_order_traversal_iter(): + yield node + yield self + + def post_order_traversal(self, action=None): + r""" + Run the depth-first post-order traversal algorithm (recursive + implementation) and subject every node encountered + to some procedure ``action``. The algorithm is:: + + explore each subtree (by the algorithm) from the + leftmost one to the rightmost one; + then manipulate the root with function `action` (in the + case of a binary tree, only if the root is not a leaf). + + INPUT: + + - ``action`` -- (optional) a function which takes a node as + input, and does something during the exploration + + OUTPUT: + + ``None``. (This is *not* an iterator.) + + .. SEEALSO:: + + - :meth:`~sage.combinat.abstract_tree.AbstractTree.post_order_traversal_iter()` + - :meth:`~sage.combinat.abstract_tree.AbstractTree.iterative_post_order_traversal()` + + TESTS:: + + sage: l = [] + sage: b = BinaryTree([[None,[]],[[[],[]],[]]]).canonical_labelling() + sage: b + 3[1[., 2[., .]], 7[5[4[., .], 6[., .]], 8[., .]]] + sage: b.post_order_traversal(lambda node: l.append(node.label())) + sage: l + [2, 1, 4, 6, 5, 8, 7, 3] + + sage: t = OrderedTree([[[[],[]]],[[]],[[],[]]]).\ + ....: canonical_labelling(); t + 1[2[3[4[], 5[]]], 6[7[]], 8[9[], 10[]]] + sage: l = [] + sage: t.post_order_traversal(lambda node: l.append(node.label())) + sage: l + [4, 5, 3, 2, 7, 6, 9, 10, 8, 1] + + sage: l = [] + sage: BinaryTree().canonical_labelling().\ + ....: post_order_traversal(lambda node: l.append(node.label())) + sage: l + [] + sage: OrderedTree([]).canonical_labelling().\ + ....: post_order_traversal(lambda node: l.append(node.label())) + sage: l + [1] + + The following test checks that things do not go wrong if some among + the descendants of the tree are equal or even identical:: + + sage: u = BinaryTree(None) + sage: v = BinaryTree([u, u]) + sage: w = BinaryTree([v, v]) + sage: t = BinaryTree([w, w]) + sage: t.node_number() + 7 + sage: l = [] + sage: t.post_order_traversal(lambda node: l.append(1)) + sage: len(l) + 7 + """ + if action is None: + action = lambda x: None + for node in self.post_order_traversal_iter(): + action(node) + + def iterative_post_order_traversal(self, action=None): + r""" + Run the depth-first post-order traversal algorithm (iterative + implementation) and subject every node encountered + to some procedure ``action``. The algorithm is:: + + explore each subtree (by the algorithm) from the + leftmost one to the rightmost one; + then manipulate the root with function `action` (in the + case of a binary tree, only if the root is not a leaf). + + INPUT: + + - ``action`` -- (optional) a function which takes a node as + input, and does something during the exploration + + OUTPUT: + + ``None``. (This is *not* an iterator.) + + .. SEEALSO:: + + - :meth:`~sage.combinat.abstract_tree.AbstractTree.post_order_traversal_iter()` + + TESTS:: + + sage: l = [] + sage: b = BinaryTree([[None,[]],[[[],[]],[]]]).canonical_labelling() + sage: b + 3[1[., 2[., .]], 7[5[4[., .], 6[., .]], 8[., .]]] + sage: b.iterative_post_order_traversal(lambda node: l.append(node.label())) + sage: l + [2, 1, 4, 6, 5, 8, 7, 3] + + sage: t = OrderedTree([[[[],[]]],[[]],[[],[]]]).canonical_labelling() + sage: t + 1[2[3[4[], 5[]]], 6[7[]], 8[9[], 10[]]] + sage: l = [] + sage: t.iterative_post_order_traversal(lambda node: l.append(node.label())) + sage: l + [4, 5, 3, 2, 7, 6, 9, 10, 8, 1] + + sage: l = [] + sage: BinaryTree().canonical_labelling().\ + ....: iterative_post_order_traversal( + ....: lambda node: l.append(node.label())) + sage: l + [] + sage: OrderedTree([]).canonical_labelling().\ + ....: iterative_post_order_traversal( + ....: lambda node: l.append(node.label())) + sage: l + [1] + + The following test checks that things do not go wrong if some among + the descendants of the tree are equal or even identical:: + + sage: u = BinaryTree(None) + sage: v = BinaryTree([u, u]) + sage: w = BinaryTree([v, v]) + sage: t = BinaryTree([w, w]) + sage: t.node_number() + 7 + sage: l = [] + sage: t.iterative_post_order_traversal(lambda node: l.append(1)) + sage: len(l) + 7 + """ + if self.is_empty(): + return + if action is None: + action = lambda x: None + stack = [self] + while len(stack) > 0: + node = stack[-1] + if node != None: + # A "None" on the stack means that the node right before + # it on the stack has already been "exploded" into + # subtrees, and should not be exploded again, but instead + # should be manipulated and removed from the stack. + stack.append(None) + for i in range(len(node)): + subtree = node[-i - 1] + if not subtree.is_empty(): + stack.append(subtree) + else: + stack.pop() + node = stack.pop() + action(node) + + def breadth_first_order_traversal(self, action=None): + r""" + Run the breadth-first post-order traversal algorithm + and subject every node encountered to some procedure + ``action``. The algorithm is:: + + queue <- [ root ]; + while the queue is not empty: + node <- pop( queue ); + manipulate the node; + prepend to the queue the list of all subtrees of + the node (from the rightmost to the leftmost). + + INPUT: + + - ``action`` -- (optional) a function which takes a node as + input, and does something during the exploration + + OUTPUT: + + ``None``. (This is *not* an iterator.) + + EXAMPLES: + + For example, on the following binary tree `b`:: + + | ___3____ | + | / \ | + | 1 _7_ | + | \ / \ | + | 2 5 8 | + | / \ | + | 4 6 | + + the breadth-first order traversal algorithm explores `b` in the + following order of nodes: `3,1,7,2,5,8,4,6`. + + TESTS:: + + sage: b = BinaryTree([[None,[]],[[[],[]],[]]]).canonical_labelling() + sage: l = [] + sage: b.breadth_first_order_traversal(lambda node: l.append(node.label())) + sage: l + [3, 1, 7, 2, 5, 8, 4, 6] + + sage: t = OrderedTree([[[[],[]]],[[]],[[],[]]]).canonical_labelling() + sage: t + 1[2[3[4[], 5[]]], 6[7[]], 8[9[], 10[]]] + sage: l = [] + sage: t.breadth_first_order_traversal(lambda node: l.append(node.label())) + sage: l + [1, 2, 6, 8, 3, 7, 9, 10, 4, 5] + + sage: l = [] + sage: BinaryTree().canonical_labelling().\ + ....: breadth_first_order_traversal( + ....: lambda node: l.append(node.label())) + sage: l + [] + sage: OrderedTree([]).canonical_labelling().\ + ....: breadth_first_order_traversal( + ....: lambda node: l.append(node.label())) + sage: l + [1] + """ + if self.is_empty(): + return + if action is None: + action = lambda x: None + queue = [] + queue.append(self) + while len(queue) > 0: + node = queue.pop() + action(node) + for subtree in node: + if not subtree.is_empty(): + queue.insert(0, subtree) def subtrees(self): """ - Returns a generator for all subtrees of ``self`` + Return a generator for all nonempty subtrees of ``self``. - The number of subtrees of a tree is its number of elements. + The number of nonempty subtrees of a tree is its number of + nodes. (The word "nonempty" makes a difference only in the + case of binary trees. For ordered trees, for example, all + trees are nonempty.) EXAMPLES:: @@ -120,9 +750,16 @@ def subtrees(self): sage: list(OrderedTree([[],[[]]]).subtrees()) [[[], [[]]], [], [[]], []] + sage: list(OrderedTree([[],[[]]]).canonical_labelling().subtrees()) + [1[2[], 3[4[]]], 2[], 3[4[]], 4[]] + sage: list(BinaryTree([[],[[],[]]]).subtrees()) [[[., .], [[., .], [., .]]], [., .], [[., .], [., .]], [., .], [., .]] + sage: v = BinaryTree([[],[]]) + sage: list(v.canonical_labelling().subtrees()) + [2[1[., .], 3[., .]], 1[., .], 3[., .]] + TESTS:: sage: t = OrderedTree([[], [[], [[], []], [[], []]], [[], []]]) @@ -134,23 +771,21 @@ def subtrees(self): sage: bt.node_number() == len(list(bt.subtrees())) True """ - if not self.is_empty(): - yield self - for i in self: - for t in i.subtrees(): - yield t + return self.pre_order_traversal_iter() def paths(self): """ - Returns a generator for all paths to nodes of ``self`` + Return a generator for all paths to nodes of ``self``. OUTPUT: This method returns a list of sequences of integers. Each of these - sequences represents a path from the root node to another one : `(1, 3, - 2, 5, 3)` represents the node obtained by chosing the 1st children of - the root node (in the ordering returned by ``iter``), then the 3rd of - its children, then the 2nd of this element, etc. + sequences represents a path from the root node to some node. For + instance, `(1, 3, 2, 5, 0, 3)` represents the node obtained by + choosing the 1st child of the root node (in the ordering returned + by ``iter``), then the 3rd child of its child, then the 2nd child + of the latter, etc. (where the labelling of the children is + zero-based). The root element is represented by the empty tuple ``()``. @@ -183,7 +818,7 @@ def paths(self): def node_number(self): """ - The number of nodes of ``self`` + The number of nodes of ``self``. EXAMPLES:: @@ -198,7 +833,7 @@ def node_number(self): sage: OrderedTree([[], [[], [[], []], [[], []]], [[], []]]).node_number() 13 - EXAMPLE:: + EXAMPLES:: sage: BinaryTree(None).node_number() 0 @@ -216,7 +851,7 @@ def node_number(self): def depth(self): """ - The depth of ``self`` + The depth of ``self``. EXAMPLES:: @@ -354,7 +989,7 @@ def _ascii_art_(self): def canonical_labelling(self,shift=1): """ - Returns a labelled version of ``self`` + Returns a labelled version of ``self``. The actual canonical labelling is currently unspecified. However, it is guaranteed to have labels in `1...n` where `n` is the number of @@ -431,7 +1066,7 @@ def to_hexacode(self): def tree_factorial(self): """ - Returns the tree-factorial of ``self`` + Return the tree-factorial of ``self``. Definition: @@ -456,134 +1091,420 @@ def tree_factorial(self): nb = self.node_number() if nb <= 1: return 1 - else: - return nb*prod(s.tree_factorial() for s in self) - - latex_unit_length = "4mm" - latex_node_diameter = "0.5" - latex_root_diameter = "0.7" + return nb * prod(s.tree_factorial() for s in self) def _latex_(self): - """ - Returns a LaTeX version of ``self`` - - EXAMPLES:: - - sage: print(OrderedTree([[],[]])._latex_()) - \vcenter{\hbox{{\setlength\unitlength{4mm} - \begin{picture}(4,3) - \put(1,1){\circle*{0.5}} - \put(2,2){\circle*{0.5}} - \put(3,1){\circle*{0.5}} - \put(2,2){\line(-1,-1){1}} - \put(2,2){\line(1,-1){1}} - \put(2,2){\circle*{0.7}} - \end{picture}}}} + r""" + Generate `\LaTeX` output which can be easily modified. TESTS:: - sage: OrderedTree([])._latex_() - '\\vcenter{\\hbox{{\\setlength\\unitlength{4mm}\n\\begin{picture}(2,2)\n\\put(1,1){\\circle*{0.5}}\n\\put(1,1){\\circle*{0.7}}\n\\end{picture}}}}' - sage: OrderedTree([[]])._latex_() - '\\vcenter{\\hbox{{\\setlength\\unitlength{4mm}\n\\begin{picture}(2,3)\n\\put(1,1){\\circle*{0.5}}\n\\put(1,2){\\circle*{0.5}}\n\\put(1,2){\\line(0,-1){1}}\n\\put(1,2){\\circle*{0.7}}\n\\end{picture}}}}' - sage: OrderedTree([[], [[], [[], []], [[], []]], [[], []]])._latex_() - '\\vcenter{\\hbox{{\\setlength\\unitlength{4mm}\n\\begin{picture}(12,5)\n\\put(1,3){\\circle*{0.5}}\n\\put(2,2){\\circle*{0.5}}\n\\put(3,1){\\circle*{0.5}}\n\\put(4,2){\\circle*{0.5}}\n\\put(5,1){\\circle*{0.5}}\n\\put(4,2){\\line(-1,-1){1}}\n\\put(4,2){\\line(1,-1){1}}\n\\put(4,3){\\circle*{0.5}}\n\\put(6,1){\\circle*{0.5}}\n\\put(7,2){\\circle*{0.5}}\n\\put(8,1){\\circle*{0.5}}\n\\put(7,2){\\line(-1,-1){1}}\n\\put(7,2){\\line(1,-1){1}}\n\\put(4,3){\\line(-2,-1){2}}\n\\put(4,3){\\line(0,-1){1}}\n\\put(4,3){\\line(3,-1){3}}\n\\put(4,4){\\circle*{0.5}}\n\\put(9,2){\\circle*{0.5}}\n\\put(10,3){\\circle*{0.5}}\n\\put(11,2){\\circle*{0.5}}\n\\put(10,3){\\line(-1,-1){1}}\n\\put(10,3){\\line(1,-1){1}}\n\\put(4,4){\\line(-3,-1){3}}\n\\put(4,4){\\line(0,-1){1}}\n\\put(4,4){\\line(6,-1){6}}\n\\put(4,4){\\circle*{0.7}}\n\\end{picture}}}}' + sage: latex(BinaryTree([[[],[]],[[],None]])) + { \newcommand{\nodea}{\node[draw,circle] (a) {$$} + ;}\newcommand{\nodeb}{\node[draw,circle] (b) {$$} + ;}\newcommand{\nodec}{\node[draw,circle] (c) {$$} + ;}\newcommand{\noded}{\node[draw,circle] (d) {$$} + ;}\newcommand{\nodee}{\node[draw,circle] (e) {$$} + ;}\newcommand{\nodef}{\node[draw,circle] (f) {$$} + ;}\begin{tikzpicture}[auto] + \matrix[column sep=.3cm, row sep=.3cm,ampersand replacement=\&]{ + \& \& \& \nodea \& \& \& \\ + \& \nodeb \& \& \& \& \nodee \& \\ + \nodec \& \& \noded \& \& \nodef \& \& \\ + }; + + \path[ultra thick, red] (b) edge (c) edge (d) + (e) edge (f) + (a) edge (b) edge (e); + \end{tikzpicture}} """ + ############################################################################### + # # use to load tikz in the preamble (one for *view* and one for *notebook*) from sage.misc.latex import latex - drawing = [""] # allows modification of in rec... - x = [1] # allows modification of x[0] in rec... - max_label_width = [0] # allows modification of x[0] in rec... - maxy = self.depth() - - def rec(t, y): - """ - Draw the subtree t on the drawing, below y (included) and to - the right of x[0] (included). Update x[0]. Returns the horizontal - position of the root - """ - if t.node_number() == 0 : return -1 - n = len(t) - posChild = [rec(t[i], y+1) for i in range(n // 2)] - i = n // 2 - if n % 2 == 1: - xc = rec(t[i], y+1) - posChild.append(xc) - i += 1 - else: - xc = x[0] - x[0] +=1 - drawing[0] = drawing[0] + "\\put(%s,%s){\\circle*{%s}}\n"%( - xc, maxy-y, self.latex_node_diameter) - try: - lbl = t.label() - except AttributeError: - pass + latex.add_package_to_preamble_if_available("tikz") + latex.add_to_mathjax_avoid_list("tikz") + ############################################################################### + # latex environnement : TikZ + begin_env = "\\begin{tikzpicture}[auto]\n" + end_env = "\\end{tikzpicture}" + # it uses matrix trick to place each node + matrix_begin = "\\matrix[column sep=.3cm, row sep=.3cm,ampersand replacement=\&]{\n" + matrix_end = "\\\\\n};\n" + # a basic path to each edges + path_begin = "\\path[ultra thick, red] " + path_end = ";\n" + # to make a pretty output, it creates one LaTeX command for + # each node + cmd = "\\node" + new_cmd1 = "\\newcommand{" + cmd + new_cmd2 = "}{\\node[draw,circle] (" + new_cmd3 = ") {$" + new_cmd4 = "$}\n;}" + # some variables to simplify code + sep = "\\&" + space = " "*9 + sepspace = sep + space + spacesep = space + sep + node_to_str = lambda node: " " + node + " " * (len(space) - 1 - len(node)) + # # TODO:: modify how to create nodes --> new_cmd : \\node[...] in create_node + num = [0] + + def resolve(self): + nodes = []; matrix = []; edges = [] + + def create_node(self): + r""" + create a name (infixe reading) + -> ex: b + create a new command: + -> ex: \newcommand{\nodeb}{\node[draw,circle] (b) {$$}; + return the name and the command to build: + . the matrix + . and the edges + """ + name = reduce( + lambda x, y: x + y, + map( + lambda x: chr(ord(x) + 49), + list(str(num[0]))), + "") + node = cmd + name + nodes.append((name, + (str(self.label()) if hasattr(self, "label") else "")) + ) + num[0] += 1 + return node, name + + def empty_tree(): + r""" + TESTS:: + + sage: t = BinaryTree() + sage: print latex(t) + { \begin{tikzpicture}[auto] + \matrix[column sep=.3cm, row sep=.3cm,ampersand replacement=\&]{ + \\ + }; + \end{tikzpicture}} + """ + matrix.append(space) + + def one_node_tree(self): + r""" + TESTS:: + + sage: t = BinaryTree([]); print latex(t) + { \newcommand{\nodea}{\node[draw,circle] (a) {$$} + ;}\begin{tikzpicture}[auto] + \matrix[column sep=.3cm, row sep=.3cm,ampersand replacement=\&]{ + \nodea \\ + }; + \end{tikzpicture}} + sage: t = OrderedTree([]); print latex(t) + { \newcommand{\nodea}{\node[draw,circle] (a) {$$} + ;}\begin{tikzpicture}[auto] + \matrix[column sep=.3cm, row sep=.3cm,ampersand replacement=\&]{ + \nodea \\ + }; + \end{tikzpicture}} + """ + node, _ = create_node(self) + matrix.append(node_to_str(node)) + + def concat_matrix(mat, mat2): + lmat = len(mat); lmat2 = len(mat2) + for i in range(max(lmat, lmat2)): + # mat[i] --> n & n & ... + # mat2[i] -> n' & n' & ... + # ==> n & n & ... & n' & n' & ... + try: + mat[i] += sep + mat2[i] + except: + if i >= lmat: + if i != 0: + # mat[i] does not exist but + # mat[0] has k "&" + # mat2[i] -> n' & n' & ... + # ==> (_ &)*k+1 n' & n' & ... + nb_of_and = mat[0].count(sep) - mat2[0].count(sep) + mat.append(spacesep * (nb_of_and) + mat2[i]) + else: + # mat is empty + # mat2[i] -> n' & n' & ... + # ==> mat2 + mat.extend(mat2) + return + else: + # mat[i] -> n & n & ... + # mat2[i] does not exist but mat2[0] exists + # # and has k "&" + # NOTE:: i != 0 because that is a no-empty subtree. + # ==> n & n & ... (& _)*k+1 + nb_of_and = mat2[0].count(sep) + mat[i] += sepspace * (nb_of_and + 1) + + def tmp(subtree, edge, nodes, edges, matrix): + if not subtree.is_empty(): + # # create representation of the subtree + nodes_st, matrix_st, edges_st = resolve(subtree) + # # add its nodes to the "global" nodes set + nodes.extend(nodes_st) + # # create a new edge between the root and the subtree + edge.append(nodes_st[0][0]) + # # add the subtree edges to the "global" edges set + edges.extend(edges_st) + # # build a new matrix by concatenation + concat_matrix(matrix, matrix_st) + else: + concat_matrix(matrix, [space]) + + def pair_nodes_tree(self, nodes, edges, matrix): + r""" + TESTS:: + + sage: t = OrderedTree([[[],[]],[[],[]]]).\ + ....: canonical_labelling(); print latex(t) + { \newcommand{\nodea}{\node[draw,circle] (a) {$1$} + ;}\newcommand{\nodeb}{\node[draw,circle] (b) {$2$} + ;}\newcommand{\nodec}{\node[draw,circle] (c) {$3$} + ;}\newcommand{\noded}{\node[draw,circle] (d) {$4$} + ;}\newcommand{\nodee}{\node[draw,circle] (e) {$5$} + ;}\newcommand{\nodef}{\node[draw,circle] (f) {$6$} + ;}\newcommand{\nodeg}{\node[draw,circle] (g) {$7$} + ;}\begin{tikzpicture}[auto] + \matrix[column sep=.3cm, row sep=.3cm,ampersand replacement=\&]{ + \& \& \& \nodea \& \& \& \\ + \& \nodeb \& \& \& \& \nodee \& \\ + \nodec \& \& \noded \& \& \nodef \& \& \nodeg \\ + }; + + \path[ultra thick, red] (b) edge (c) edge (d) + (e) edge (f) edge (g) + (a) edge (b) edge (e); + \end{tikzpicture}} + sage: t = BinaryTree([[],[[],[]]]); print latex(t) + { \newcommand{\nodea}{\node[draw,circle] (a) {$$} + ;}\newcommand{\nodeb}{\node[draw,circle] (b) {$$} + ;}\newcommand{\nodec}{\node[draw,circle] (c) {$$} + ;}\newcommand{\noded}{\node[draw,circle] (d) {$$} + ;}\newcommand{\nodee}{\node[draw,circle] (e) {$$} + ;}\begin{tikzpicture}[auto] + \matrix[column sep=.3cm, row sep=.3cm,ampersand replacement=\&]{ + \& \nodea \& \& \& \\ + \nodeb \& \& \& \nodec \& \\ + \& \& \noded \& \& \nodee \\ + }; + + \path[ultra thick, red] (c) edge (d) edge (e) + (a) edge (b) edge (c); + \end{tikzpicture}} + """ + # build all subtree matrices. + node, name = create_node(self) + edge = [name] + split = int(len(self) / 2) + # the left part + for i in range(split): + tmp(self[i], edge, nodes, edges, matrix) + # # prepare the root line + nb_of_and = matrix[0].count(sep) + # the middle + for i in range(len(matrix)): + matrix[i] += sepspace + # the right part + for i in range(split, len(self)): + tmp(self[i], edge, nodes, edges, matrix) + + # # create the root line + root_line = (spacesep * (nb_of_and + 1) + node_to_str(node) + + sepspace * (matrix[0].count(sep) - nb_of_and - 1)) + matrix.insert(0, root_line) + # add edges from the root + edges.append(edge) + + def odd_nodes_tree(self, nodes, edges, matrix): + r""" + TESTS:: + + sage: t = OrderedTree([[]]).canonical_labelling() + sage: print latex(t) + { \newcommand{\nodea}{\node[draw,circle] (a) {$1$} + ;}\newcommand{\nodeb}{\node[draw,circle] (b) {$2$} + ;}\begin{tikzpicture}[auto] + \matrix[column sep=.3cm, row sep=.3cm,ampersand replacement=\&]{ + \nodea \\ + \nodeb \\ + }; + + \path[ultra thick, red] (a) edge (b); + \end{tikzpicture}} + sage: t = OrderedTree([[[],[]]]).canonical_labelling(); print latex(t) + { \newcommand{\nodea}{\node[draw,circle] (a) {$1$} + ;}\newcommand{\nodeb}{\node[draw,circle] (b) {$2$} + ;}\newcommand{\nodec}{\node[draw,circle] (c) {$3$} + ;}\newcommand{\noded}{\node[draw,circle] (d) {$4$} + ;}\begin{tikzpicture}[auto] + \matrix[column sep=.3cm, row sep=.3cm,ampersand replacement=\&]{ + \& \nodea \& \\ + \& \nodeb \& \\ + \nodec \& \& \noded \\ + }; + + \path[ultra thick, red] (b) edge (c) edge (d) + (a) edge (b); + \end{tikzpicture}} + sage: t = OrderedTree([[[],[],[]]]).canonical_labelling(); print latex(t) + { \newcommand{\nodea}{\node[draw,circle] (a) {$1$} + ;}\newcommand{\nodeb}{\node[draw,circle] (b) {$2$} + ;}\newcommand{\nodec}{\node[draw,circle] (c) {$3$} + ;}\newcommand{\noded}{\node[draw,circle] (d) {$4$} + ;}\newcommand{\nodee}{\node[draw,circle] (e) {$5$} + ;}\begin{tikzpicture}[auto] + \matrix[column sep=.3cm, row sep=.3cm,ampersand replacement=\&]{ + \& \nodea \& \\ + \& \nodeb \& \\ + \nodec \& \noded \& \nodee \\ + }; + + \path[ultra thick, red] (b) edge (c) edge (d) edge (e) + (a) edge (b); + \end{tikzpicture}} + sage: t = OrderedTree([[[],[],[]],[],[]]).canonical_labelling(); print latex(t) + { \newcommand{\nodea}{\node[draw,circle] (a) {$1$} + ;}\newcommand{\nodeb}{\node[draw,circle] (b) {$2$} + ;}\newcommand{\nodec}{\node[draw,circle] (c) {$3$} + ;}\newcommand{\noded}{\node[draw,circle] (d) {$4$} + ;}\newcommand{\nodee}{\node[draw,circle] (e) {$5$} + ;}\newcommand{\nodef}{\node[draw,circle] (f) {$6$} + ;}\newcommand{\nodeg}{\node[draw,circle] (g) {$7$} + ;}\begin{tikzpicture}[auto] + \matrix[column sep=.3cm, row sep=.3cm,ampersand replacement=\&]{ + \& \& \& \nodea \& \\ + \& \nodeb \& \& \nodef \& \nodeg \\ + \nodec \& \noded \& \nodee \& \& \\ + }; + + \path[ultra thick, red] (b) edge (c) edge (d) edge (e) + (a) edge (b) edge (f) edge (g); + \end{tikzpicture}} + """ + # build all subtree matrices. + node, name = create_node(self) + edge = [name] + split = int(len(self) / 2) + # the left part + for i in range(split): + tmp(self[i], edge, nodes, edges, matrix) + # # prepare the root line + if len(matrix) != 0: + nb_of_and = matrix[0].count(sep) + sizetmp = len(matrix[0]) + else: + nb_of_and = 0 + sizetmp = 0 + # the middle + tmp(self[split], edge, nodes, edges, matrix) + nb_of_and += matrix[0][sizetmp:].split("node")[0].count(sep) + + # the right part + for i in range(split + 1, len(self)): + tmp(self[i], edge, nodes, edges, matrix) + + # # create the root line + root_line = (spacesep * (nb_of_and) + node_to_str(node) + + sepspace * (matrix[0].count(sep) - nb_of_and)) + matrix.insert(0, root_line) + # add edges from the root + edges.append(edge) + if self.is_empty(): + empty_tree() + elif len(self) == 0 or all(subtree.is_empty() + for subtree in self): + one_node_tree(self) + elif len(self) % 2 == 0: + pair_nodes_tree(self, nodes, edges, matrix) else: - max_label_width[0] = 1 # TODO find a better heuristic - drawing[0] = drawing[0] + "\\put(%s,%s){$\scriptstyle %s$}"%( - xc+0.3, maxy-y-0.3, latex(lbl)) - posChild += [rec(t[j], y+1) for j in range(i, n)] - for i in range(n): - if posChild[i] != -1: - drawing[0] = (drawing[0] + - "\\put(%s,%s){\\line(%s,-1){%s}}\n"%( - xc, maxy-y, posChild[i]-xc, - max(abs(posChild[i]-xc), 1))) - return xc - - res = rec(self, 0) - drawing[0] = drawing[0] + "\\put(%s,%s){\\circle*{%s}}\n"%( - res, maxy, self.latex_root_diameter) - return "\\vcenter{\hbox{{\setlength\unitlength{%s}\n\\begin{picture}(%s,%s)\n%s\\end{picture}}}}"%( - self.latex_unit_length, - x[0] + max_label_width[0], - maxy + 1, - drawing[0]) + odd_nodes_tree(self, nodes, edges, matrix) + return nodes, matrix, edges + + nodes, matrix, edges = resolve(self) + + def make_cmd(nodes): + cmds = [] + for name, label in nodes: + cmds.append(new_cmd1 + name + new_cmd2 + + name + new_cmd3 + + label + new_cmd4) + return cmds + + def make_edges(edges): + all_paths = [] + for edge in edges: + path = "(" + edge[0] + ")" + for i in range(1, len(edge)): + path += " edge (%s)" % edge[i] + all_paths.append(path) + return all_paths + return ("{ " + + "".join(make_cmd(nodes)) + + begin_env + + (matrix_begin + + "\\\\ \n".join(matrix) + + matrix_end + + ("\n" + + path_begin + + "\n\t".join(make_edges(edges)) + + path_end if len(edges) > 0 else "") + if len(matrix) > 0 else "") + + end_env + + "}") + class AbstractClonableTree(AbstractTree): """ - Abstract Clonable Tree + Abstract Clonable Tree. An abstract class for trees with clone protocol (see :mod:`~sage.structure.list_clone`). It is expected that classes extending this one may also inherit from classes like :class:`ClonableArray` or - :class:`~sage.structure.list_clone.ClonableList` depending wether one + :class:`~sage.structure.list_clone.ClonableList` depending whether one wants to build trees where adding a child is allowed. .. NOTE:: Due to the limitation of Cython inheritance, one cannot inherit here from :class:`~sage.structure.list_clone.ClonableElement`, because - it would prevent us to inherit later from + it would prevent us from later inheriting from :class:`~sage.structure.list_clone.ClonableArray` or :class:`~sage.structure.list_clone.ClonableList`. .. rubric:: How should this class be extended ? - A class extending :class:`AbstractTree - ` should the following - assumptions: + A class extending :class:`AbstractClonableTree + ` should satisfy the + following assumptions: - * An instantiable class extending :class:`AbstractTree - ` should also extend the - :class:`ClonableElement ` - class or one of its subclass generally at least :class:`ClonableArray + * An instantiable class extending :class:`AbstractClonableTree + ` should also extend + the :class:`ClonableElement ` + class or one of its subclasses generally, at least :class:`ClonableArray `. - * To respect the Clone protocol, the :meth:`AbstractClonableTree.check` method should be overridden by the new class. + + See also the assumptions in :class:`AbstractTree`. """ def check(self): """ - Check that ``self`` is a correct tree + Check that ``self`` is a correct tree. This method does nothing. It is implemented here because many - extensions of :class:`AbstractTree - ` also extend + extensions of :class:`AbstractClonableTree + ` also extend :class:`sage.structure.list_clone.ClonableElement`, which requires it. - It should be overriden in subclass in order to check that the - invariant of the kind of tree holds (eg: two children for binary - trees). + It should be overridden in subclasses in order to check that the + characterizing property of the respective kind of tree holds (eg: two + children for binary trees). EXAMPLES:: @@ -625,7 +1546,7 @@ def __setitem__(self, idx, value): sage: x = OrderedTree([[],[[]]]) sage: with x.clone() as x: - ... x[0] = OrderedTree([[]]) + ....: x[0] = OrderedTree([[]]) sage: x [[[]], [[]]] @@ -633,13 +1554,13 @@ def __setitem__(self, idx, value): sage: y = OrderedTree(x) sage: with x.clone() as x: - ... x[0,0] = OrderedTree([[]]) + ....: x[0,0] = OrderedTree([[]]) sage: x [[[[]]], [[]]] sage: y [[[]], [[]]] sage: with y.clone() as y: - ... y[(0,)] = OrderedTree([]) + ....: y[(0,)] = OrderedTree([]) sage: y [[], [[]]] @@ -648,7 +1569,7 @@ def __setitem__(self, idx, value): sage: bt = BinaryTree([[],[[],[]]]); bt [[., .], [[., .], [., .]]] sage: with bt.clone() as bt1: - ... bt1[0,0] = BinaryTree([[[], []], None]) + ....: bt1[0,0] = BinaryTree([[[], []], None]) sage: bt1 [[[[[., .], [., .]], .], .], [[., .], [., .]]] @@ -656,14 +1577,14 @@ def __setitem__(self, idx, value): sage: x = OrderedTree([]) sage: with x.clone() as x: - ... x[0] = OrderedTree([[]]) + ....: x[0] = OrderedTree([[]]) Traceback (most recent call last): - ... + ....: IndexError: list assignment index out of range - sage: x = OrderedTree([]); x = OrderedTree([x,x]);x = OrderedTree([x,x]); x = OrderedTree([x,x]) + sage: x = OrderedTree([]); x = OrderedTree([x,x]); x = OrderedTree([x,x]); x = OrderedTree([x,x]) sage: with x.clone() as x: - ... x[0,0] = OrderedTree() + ....: x[0,0] = OrderedTree() sage: x [[[], [[], []]], [[[], []], [[], []]]] """ @@ -680,7 +1601,7 @@ def __setitem_rec__(self, idx, i, value): sage: x = OrderedTree([[[], []],[[]]]) sage: with x.clone() as x: - ... x[0,1] = OrderedTree([[[]]]) # indirect doctest + ....: x[0,1] = OrderedTree([[[]]]) # indirect doctest sage: x [[[], [[[]]]], [[]]] """ @@ -693,9 +1614,16 @@ def __setitem_rec__(self, idx, i, value): def __getitem__(self, idx): """ + Return the ``idx``-th child of ``self`` (which is a subtree) if + ``idx`` is an integer, or the ``idx[n-1]``-th child of the + ``idx[n-2]``-th child of the ... of the ``idx[0]``-th child of + ``self`` if ``idx`` is a list (or iterable) of length `n`. + + The indexing of the children is zero-based. + INPUT: - - ``idx`` -- a valid path in ``self`` identifying a node + - ``idx`` -- an integer, or a valid path in ``self`` identifying a node .. NOTE:: @@ -717,6 +1645,22 @@ def __getitem__(self, idx): Traceback (most recent call last): ... IndexError: list index out of range + + sage: u = BinaryTree(None) + sage: v = BinaryTree([u, u]) + sage: w = BinaryTree([u, v]) + sage: t = BinaryTree([v, w]) + sage: z = BinaryTree([w, t]) + sage: z[0,1] + [., .] + sage: z[0,0] + . + sage: z[1] + [[., .], [., [., .]]] + sage: z[1,1] + [., [., .]] + sage: z[1][1,1] + [., .] """ if isinstance(idx, slice): return ClonableArray.__getitem__(self, idx) @@ -734,10 +1678,10 @@ def __getitem__(self, idx): class AbstractLabelledTree(AbstractTree): """ - Abstract Labelled Tree + Abstract Labelled Tree. - Typically a class for labelled tree is contructed by inheriting from a - class for unlabelled trees and :class:`AbstractLabelledTree` + Typically a class for labelled trees is contructed by inheriting from + a class for unlabelled trees and :class:`AbstractLabelledTree`. .. rubric:: How should this class be extended ? @@ -746,7 +1690,8 @@ class for unlabelled trees and :class:`AbstractLabelledTree` following assumptions: * For a labelled tree ``T`` the call ``T.parent().unlabelled_trees()`` - should return a parent for labelled trees of the same kind: for example, + should return a parent for unlabelled trees of the same kind: for + example, - if ``T`` is a binary labelled tree, ``T.parent()`` is ``LabelledBinaryTrees()`` and ``T.parent().unlabelled_trees()`` is @@ -757,9 +1702,11 @@ class for unlabelled trees and :class:`AbstractLabelledTree` ``OrderedTrees()`` * In the same vein, the class of ``T`` should contain an attribute - ``_Unlabelled`` which should be the class for the corresponding + ``_UnLabelled`` which should be the class for the corresponding unlabelled trees. + See also the assumptions in :class:`AbstractTree`. + .. SEEALSO:: :class:`AbstractTree` """ def __init__(self, parent, children, label = None, check = True): @@ -808,7 +1755,7 @@ def _repr_(self): def label(self, path=None): """ - Returns the label of ``self`` + Return the label of ``self``. INPUT: @@ -842,7 +1789,7 @@ def label(self, path=None): def labels(self): """ - Returns the list of labels of ``self`` + Return the list of labels of ``self``. EXAMPLES:: @@ -859,7 +1806,11 @@ def labels(self): def leaf_labels(self): """ - Returns the list of labels of the leaves of ``self`` + Return the list of labels of the leaves of ``self``. + + In case of a labelled binary tree, these "leaves" are not actually + the leaves of the binary trees, but the nodes whose both children + are leaves! EXAMPLES:: @@ -1029,7 +1980,7 @@ def set_root_label(self, label): ... ValueError: object is immutable; please change a copy instead. sage: with t.clone() as t: - ... t.set_root_label(3) + ....: t.set_root_label(3) sage: t.label() 3 sage: t @@ -1043,7 +1994,7 @@ def set_root_label(self, label): ... ValueError: object is immutable; please change a copy instead. sage: with bt.clone() as bt: - ... bt.set_root_label(3) + ....: bt.set_root_label(3) sage: bt.label() 3 sage: bt @@ -1052,14 +2003,14 @@ def set_root_label(self, label): TESTS:: sage: with t.clone() as t: - ... t[0] = LabelledOrderedTree(t[0], label = 4) + ....: t[0] = LabelledOrderedTree(t[0], label = 4) sage: t 3[4[], None[None[], None[]]] sage: with t.clone() as t: - ... t[1,0] = LabelledOrderedTree(t[1,0], label = 42) + ....: t[1,0] = LabelledOrderedTree(t[1,0], label = 42) sage: t 3[4[], None[42[], None[]]] - """ + """ self._require_mutable() self._label = label @@ -1090,11 +2041,11 @@ def set_label(self, path, label): ... ValueError: object is immutable; please change a copy instead. sage: with t.clone() as t: - ... t.set_label((0,), 4) + ....: t.set_label((0,), 4) sage: t None[4[], None[None[], None[]]] sage: with t.clone() as t: - ... t.set_label((1,0), label = 42) + ....: t.set_label((1,0), label = 42) sage: t None[4[], None[42[], None[]]] diff --git a/src/sage/combinat/binary_tree.py b/src/sage/combinat/binary_tree.py index 4c1a5ad9333..1bc05e0a0f5 100644 --- a/src/sage/combinat/binary_tree.py +++ b/src/sage/combinat/binary_tree.py @@ -1,16 +1,34 @@ +# -*- coding: utf-8 -*- """ -Binary trees +Binary Trees. -This module deals with binary trees as mathematical (in particular immmutable) +This module deals with binary trees as mathematical (in particular immutable) objects. -.. NOTE :: If you need the data-structure for example to represent sets or hash - tables with AVL trees, you should have a look at - :mod:`sage.misc.sagex_ds`. +.. NOTE:: -**AUTHORS:** + If you need the data-structure for example to represent sets or hash + tables with AVL trees, you should have a look at :mod:`sage.misc.sagex_ds`. + +AUTHORS: - Florent Hivert (2010-2011): initial implementation. + +REFERENCES: + +.. [LodayRonco] Jean-Louis Loday and Maria O. Ronco. + *Hopf algebra of the planar binary trees*, + Advances in Mathematics, volume 139, issue 2, + 10 November 1998, pp. 293-309. + http://www.sciencedirect.com/science/article/pii/S0001870898917595 + +.. [HNT05] Florent Hivert, Jean-Christophe Novelli, and Jean-Yves Thibon. + *The algebra of binary search trees*, + :arxiv:`math/0401089v2`. + +.. [CP12] Gregory Chatel, Viviane Pons. + *Counting smaller trees in the Tamari order*, + :arxiv:`1212.0751v1`. """ #***************************************************************************** # Copyright (C) 2010 Florent Hivert , @@ -31,23 +49,28 @@ class BinaryTree(AbstractClonableTree, ClonableArray): """ - The class of binary trees + Binary trees. + + Binary trees here mean ordered (a.k.a. plane) finite binary + trees, where "ordered" means that the children of each node are + ordered. - Binary trees here mean ordered (a.k.a. plane) binary trees, - meaning that the children of each node are ordered. + Binary trees contain nodes and leaves, where each node has two + children while each leaf has no children. The number of leaves + of a binary tree always equals the number of nodes plus `1`. INPUT: - ``children`` -- ``None`` (default) or a list, tuple or iterable of - length 2 of binary trees or convertible objects. This corresponds to - the standard recursive definition of a binary tree as either a leaf - or a pair of binary trees. Syntactic sugar allows leaving out all - but the outermost calls of the ``BinaryTree()`` constructor, so that, - e. g., ``BinaryTree([BinaryTree(None),BinaryTree(None)])`` can be - simplified to ``BinaryTree([None,None])``. It is also allowed to + length `2` of binary trees or convertible objects. This corresponds + to the standard recursive definition of a binary tree as either a + leaf or a pair of binary trees. Syntactic sugar allows leaving out + all but the outermost calls of the ``BinaryTree()`` constructor, so + that, e. g., ``BinaryTree([BinaryTree(None),BinaryTree(None)])`` can + be shortened to ``BinaryTree([None,None])``. It is also allowed to abbreviate ``[None, None]`` by ``[]``. - - ``check`` -- (default to ``True``) whether check for binary should be + - ``check`` -- (default: ``True``) whether check for binary should be performed or not. EXAMPLES:: @@ -66,6 +89,8 @@ class BinaryTree(AbstractClonableTree, ClonableArray): [[., .], .] sage: BinaryTree("[[], .]") [[., .], .] + sage: BinaryTree([None, BinaryTree([None, None])]) + [., [., .]] sage: BinaryTree([[], None, []]) Traceback (most recent call last): @@ -77,7 +102,7 @@ class BinaryTree(AbstractClonableTree, ClonableArray): sage: t1 = BinaryTree([[None, [[],[[], None]]],[[],[]]]) sage: t2 = BinaryTree([[[],[]],[]]) sage: with t1.clone() as t1c: - ... t1c[1,1,1] = t2 + ....: t1c[1,1,1] = t2 sage: t1 == t1c False """ @@ -87,7 +112,7 @@ class BinaryTree(AbstractClonableTree, ClonableArray): def __classcall_private__(cls, *args, **opts): """ Ensure that binary trees created by the enumerated sets and directly - are the same and that they are instances of :class:`BinaryTree` + are the same and that they are instances of :class:`BinaryTree`. TESTS:: @@ -117,7 +142,7 @@ def __classcall_private__(cls, *args, **opts): @lazy_class_attribute def _auto_parent(cls): """ - The automatic parent of the element of this class + The automatic parent of the elements of this class. When calling the constructor of an element of this class, one needs a parent. This class attribute specifies which parent is used. @@ -128,7 +153,7 @@ def _auto_parent(cls): Binary trees sage: BinaryTree([None, None]).parent() Binary trees - """ + """ return BinaryTrees_all() def __init__(self, parent, children = None, check = True): @@ -164,7 +189,7 @@ def __init__(self, parent, children = None, check = True): def check(self): """ - Checks that ``self`` is a binary tree + Check that ``self`` is a binary tree. EXAMPLES:: @@ -400,7 +425,11 @@ def _ascii_art_( self ): def is_empty(self): """ - Return whether ``self`` is empty. + Return whether ``self`` is empty. + + The notion of emptiness employed here is the one which defines + a binary tree to be empty if its root is a leaf. There is + precisely one empty binary tree. EXAMPLES:: @@ -413,39 +442,110 @@ def is_empty(self): """ return not self - def graph(self): + def graph(self, with_leaves=True): """ - Convert ``self`` to a digraph + Convert ``self`` to a digraph. By default, this graph contains + both nodes and leaves, hence is never empty. To obtain a graph + which contains only the nodes, the ``with_leaves`` optional + keyword variable has to be set to ``False``. - EXAMPLE:: + INPUT: + + - ``with_leaves`` -- (default: ``True``) a Boolean, determining + whether the resulting graph will be formed from the leaves + and the nodes of ``self`` (if ``True``), or only from the + nodes of ``self`` (if ``False``) + + EXAMPLES:: sage: t1 = BinaryTree([[], None]) sage: t1.graph() Digraph on 5 vertices + sage: t1.graph(with_leaves=False) + Digraph on 2 vertices sage: t1 = BinaryTree([[], [[], None]]) sage: t1.graph() Digraph on 9 vertices sage: t1.graph().edges() [(0, 1, None), (0, 4, None), (1, 2, None), (1, 3, None), (4, 5, None), (4, 8, None), (5, 6, None), (5, 7, None)] + sage: t1.graph(with_leaves=False) + Digraph on 4 vertices + sage: t1.graph(with_leaves=False).edges() + [(0, 1, None), (0, 2, None), (2, 3, None)] + + sage: t1 = BinaryTree() + sage: t1.graph() + Digraph on 1 vertex + sage: t1.graph(with_leaves=False) + Digraph on 0 vertices + + sage: BinaryTree([]).graph() + Digraph on 3 vertices + sage: BinaryTree([]).graph(with_leaves=False) + Digraph on 1 vertex + + sage: t1 = BinaryTree([[], [[], []]]) + sage: t1.graph(with_leaves=False) + Digraph on 5 vertices + sage: t1.graph(with_leaves=False).edges() + [(0, 1, None), (0, 2, None), (2, 3, None), (2, 4, None)] """ from sage.graphs.graph import DiGraph - res = DiGraph() - def rec(tr, idx): - if not tr: - return - else: - nbl = 2*tr[0].node_number() + 1 - res.add_edges([[idx,idx+1], [idx,idx+1+nbl]]) - rec(tr[0], idx + 1) - rec(tr[1], idx + nbl + 1) - rec(self, 0) - return res - def canonical_labelling(self,shift=1): - """ + if with_leaves: # We want leaves and nodes. + + # Special treatment for the case when self is empty. + # In this case, rec(self, 0) would give a false result. + if not self: + return DiGraph({0: []}) + + res = DiGraph() + # The edge set of res will be built up step by step using the + # following function: + def rec(tr, idx): + if not tr: # tr is a leaf. + return + else: # tr is a node. + nbl = 2 * tr[0].node_number() + 1 + res.add_edges([[idx, idx + 1], [idx, idx + 1 + nbl]]) + rec(tr[0], idx + 1) + rec(tr[1], idx + nbl + 1) + rec(self, 0) + return res + + else: # We want only the nodes. + + # Special treatment for the case when self has only 1 node. + # In this case, the general DiGraph construction would + # falsely yield an empty graph (since it adds nodes only + # implicitly by adding edges). + if self.node_number() == 1: + return DiGraph({0: []}) + + res = DiGraph() + # The edge set of res will be built up step by step using the + # following function: + def rec(tr, idx): + if not tr: # tr is a leaf. + return + else: # tr is a node. + nbl = tr[0].node_number() + if nbl > 0: + res.add_edge([idx, idx + 1]) + rec(tr[0], idx + 1) + if tr[1].node_number() > 0: + res.add_edge([idx, idx + nbl + 1]) + rec(tr[1], idx + nbl + 1) + rec(self, 0) + return res + + def canonical_labelling(self, shift=1): + r""" Return a labelled version of ``self``. + The canonical labelling of a binary tree is a certain labelling of the + nodes (not the leaves) of the tree. The actual canonical labelling is currently unspecified. However, it is guaranteed to have labels in `1...n` where `n` is the number of nodes of the tree. Moreover, two (unlabelled) trees compare as equal if @@ -469,18 +569,36 @@ def canonical_labelling(self,shift=1): else: return LTR(None) - def show(self): + def show(self, with_leaves=False): """ + Show the binary tree ``show``, with or without leaves depending + on the Boolean keyword variable ``with_leaves``. + + .. WARNING:: + + Left and right children might get interchanged in + the actual picture. Moreover, for a labelled binary + tree, the labels shown in the picture are not (in + general) the ones given by the labelling! + + Use :meth:`_latex_`, ``view``, + :meth:`_ascii_art_` or ``pretty_print`` for more + faithful representations of the data of the tree. + TESTS:: sage: t1 = BinaryTree([[], [[], None]]) sage: t1.show() """ - self.graph().show(layout='tree', tree_root=0, tree_orientation="down") + try: + self.graph(with_leaves=with_leaves).show(layout='tree', tree_root=0, tree_orientation="down") + except RuntimeError: + # This is for the border case BinaryTree().show(). + self.graph(with_leaves=with_leaves).show() def make_node(self, child_list = [None, None]): """ - Modify ``self`` so that it becomes a node with children ``childlist`` + Modify ``self`` so that it becomes a node with children ``child_list``. INPUT: @@ -489,6 +607,7 @@ def make_node(self, child_list = [None, None]): .. NOTE:: ``self`` must be in a mutable state. .. SEEALSO:: + :meth:`make_leaf ` EXAMPLES:: @@ -499,18 +618,18 @@ def make_node(self, child_list = [None, None]): ... ValueError: object is immutable; please change a copy instead. sage: with t.clone() as t1: - ... t1.make_node([None, None]) + ....: t1.make_node([None, None]) sage: t, t1 (., [., .]) sage: with t.clone() as t: - ... t.make_node([BinaryTree(), BinaryTree(), BinaryTree([])]) + ....: t.make_node([BinaryTree(), BinaryTree(), BinaryTree([])]) Traceback (most recent call last): ... ValueError: the list must have length 2 sage: with t1.clone() as t2: - ... t2.make_node([t1, t1]) + ....: t2.make_node([t1, t1]) sage: with t2.clone() as t3: - ... t3.make_node([t1, t2]) + ....: t3.make_node([t1, t2]) sage: t1, t2, t3 ([., .], [[., .], [., .]], [[., .], [[., .], [., .]]]) """ @@ -522,11 +641,12 @@ def make_node(self, child_list = [None, None]): def make_leaf(self): """ - Modify ``self`` so that it became a leaf + Modify ``self`` so that it becomes a leaf (i. e., an empty tree). .. NOTE:: ``self`` must be in a mutable state. .. SEEALSO:: + :meth:`make_node ` EXAMPLES:: @@ -537,7 +657,7 @@ def make_leaf(self): ... ValueError: object is immutable; please change a copy instead. sage: with t.clone() as t1: - ... t1.make_leaf() + ....: t1.make_leaf() sage: t, t1 ([., .], .) """ @@ -574,7 +694,7 @@ def _to_dyck_word_rec(self, usemap="1L0R"): def to_dyck_word_tamari(self): r""" Return the Dyck word associated with ``self`` in consistency with - the Tamari order on dyck words and binary trees. + the Tamari order on Dyck words and binary trees. The bijection is defined recursively as follows: @@ -594,25 +714,24 @@ def to_dyck_word_tamari(self): sage: BinaryTree([[[], [[], None]], [[], []]]).to_dyck_word_tamari() [1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0] """ - from sage.combinat.dyck_word import DyckWord return self.to_dyck_word("L1R0") @combinatorial_map(name="to Dyck paths: up step, left tree, down step, right tree") def to_dyck_word(self, usemap="1L0R"): r""" + Return the Dyck word associated with ``self`` using the given map. + INPUT: - ``usemap`` -- a string, either ``1L0R``, ``1R0L``, ``L1R0``, ``R1L0`` - Return the Dyck word associated with ``self`` using the given map. - The bijection is defined recursively as follows: - a leaf is associated to the empty Dyck Word - a tree with children `l,r` is associated with the Dyck word described by ``usemap`` where `L` and `R` are respectively the - Dyck words associated with the `l` and `r`. + Dyck words associated with the trees `l` and `r`. EXAMPLES:: @@ -717,7 +836,7 @@ def to_ordered_tree_left_branch(self): @combinatorial_map(name="To ordered tree, right child = right brother") def to_ordered_tree_right_branch(self): r""" - Return an ordered tree of size n+1 by the following recursive rule: + Return an ordered tree of size `n+1` by the following recursive rule: - if `x` is the right child of `y`, `x` becomes the right brother of `y` @@ -773,7 +892,7 @@ def to_312_avoiding_permutation(self): Return a 312-avoiding permutation corresponding to the binary tree. The linear extensions of a binary tree form an interval of the weak - order called the sylester class of the tree. This permutation is + order called the sylvester class of the tree. This permutation is the minimal element of this sylvester class. EXAMPLES:: @@ -798,10 +917,11 @@ def to_312_avoiding_permutation(self): return Permutation(self._postfix_word()) @combinatorial_map(name="To complete tree") - def as_ordered_tree(self,with_leaves=True): + def as_ordered_tree(self, with_leaves=True): r""" Return the same tree seen as an ordered tree. By default, leaves - are transformed into actual nodes. + are transformed into actual nodes, but this can be avoided by + setting the optional variable ``with_leaves`` to ``False``. EXAMPLES:: @@ -821,6 +941,8 @@ def as_ordered_tree(self,with_leaves=True): if with_leaves: children = [child.as_ordered_tree(with_leaves) for child in self] else: + if not self: + raise ValueError("The empty binary tree cannot be made into an ordered tree with with_leaves = False") children = [child.as_ordered_tree(with_leaves) for child in self if not child.is_empty()] if self in LabelledBinaryTrees(): from sage.combinat.ordered_tree import LabelledOrderedTree @@ -830,11 +952,19 @@ def as_ordered_tree(self,with_leaves=True): return OrderedTree(children) @combinatorial_map(name="To graph") - def to_undirected_graph(self, with_leaves = False): + def to_undirected_graph(self, with_leaves=False): r""" Return the undirected graph obtained from the tree nodes and edges. - Leafs are ignored by default but can set ``with_leaves`` to ``True`` - to obtain the graph of the complete tree. + + Leaves are ignored by default, but one can set ``with_leaves`` to + ``True`` to obtain the graph of the complete tree. + + INPUT: + + - ``with_leaves`` -- (default: ``False``) a Boolean, determining + whether the resulting graph will be formed from the leaves + and the nodes of ``self`` (if ``True``), or only from the + nodes of ``self`` (if ``False``) EXAMPLES:: @@ -844,6 +974,12 @@ def to_undirected_graph(self, with_leaves = False): sage: bt.to_undirected_graph(with_leaves=True) Graph on 3 vertices + sage: bt = BinaryTree() + sage: bt.to_undirected_graph() + Graph on 0 vertices + sage: bt.to_undirected_graph(with_leaves=True) + Graph on 1 vertex + If the tree is labelled, we use its labelling to label the graph. Otherwise, we use the graph canonical labelling which means that two different trees can have the same graph. @@ -862,25 +998,33 @@ def to_undirected_graph(self, with_leaves = False): sage: BinaryTree([[],[]]).to_undirected_graph() == BinaryTree([[[],None],None]).to_undirected_graph() True """ + if (not with_leaves) and (not self): + # this case needs extra care :( + from sage.graphs.graph import Graph + return Graph([]) return self.as_ordered_tree(with_leaves).to_undirected_graph() @combinatorial_map(name="To poset") - def to_poset(self, with_leaves = False, root_to_leaf=False): + def to_poset(self, with_leaves=False, root_to_leaf=False): r""" - Return the poset obtained by interpreting the tree as a hasse + Return the poset obtained by interpreting the tree as a Hasse diagram. The default orientation is from leaves to root but you can pass ``root_to_leaf=True`` to obtain the inverse orientation. - Leafs are ignored by default but can set ``with_leaves`` to ``True`` - to obtain the poset of the complete tree. + Leaves are ignored by default, but one can set ``with_leaves`` to + ``True`` to obtain the poset of the complete tree. INPUT: - - ``with_leaves`` -- boolean, true if leaves should be added to the poset - - ``root_to_leaf`` -- boolean, true if the poset orientation should - be from root to leaves. It is false by default. + - ``with_leaves`` -- (default: ``False``) a Boolean, determining + whether the resulting poset will be formed from the leaves + and the nodes of ``self`` (if ``True``), or only from the + nodes of ``self`` (if ``False``) + - ``root_to_leaf`` -- (default: ``False``) a Boolean, + determining whether the poset orientation should be from root + to leaves (if ``True``) or from leaves to root (if ``False``). EXAMPLES:: @@ -903,7 +1047,19 @@ def to_poset(self, with_leaves = False, root_to_leaf=False): 2[1[., .], 3[., 4[., .]]] sage: bt.to_poset().cover_relations() [[4, 3], [3, 2], [1, 2]] + + Let us check that the empty binary tree is correctly handled:: + + sage: bt = BinaryTree() + sage: bt.to_poset() + Finite poset containing 0 elements + sage: bt.to_poset(with_leaves=True) + Finite poset containing 1 elements """ + if (not with_leaves) and (not self): + # this case needs extra care :( + from sage.combinat.posets.posets import Poset + return Poset({}) return self.as_ordered_tree(with_leaves).to_poset(root_to_leaf) @combinatorial_map(name="To 132 avoiding permutation") @@ -912,7 +1068,7 @@ def to_132_avoiding_permutation(self): Return a 132-avoiding permutation corresponding to the binary tree. The linear extensions of a binary tree form an interval of the weak - order called the sylester class of the tree. This permutation is + order called the sylvester class of the tree. This permutation is the maximal element of this sylvester class. EXAMPLES:: @@ -1003,9 +1159,9 @@ def left_border_symmetry(self): def canopee(self): """ - Return the canopee of ``self`` + Return the canopee of ``self``. - The *canopee* of a non empty binary tree `T` with `n` internal nodes is + The *canopee* of a non-empty binary tree `T` with `n` internal nodes is the list `l` of `0` and `1` of length `n-1` obtained by going along the leaves of `T` from left to right except the two extremal ones, writing `0` if the leaf is a right leaf and `1` if the leaf is a left leaf. @@ -1025,12 +1181,12 @@ def canopee(self): The number of pairs `(t_1, t_2)` of binary trees of size `n` such that the canopee of `t_1` is the complementary of the canopee of `t_2` is - also the number of Baxter permutations (see [DG]_, see + also the number of Baxter permutations (see [DG94]_, see also :oeis:`A001181`). We check this in small cases:: sage: [len([(u,v) for u in BinaryTrees(n) for v in BinaryTrees(n) - ... if map(lambda x:1-x, u.canopee()) == v.canopee()]) - ... for n in range(1, 5)] + ....: if map(lambda x:1-x, u.canopee()) == v.canopee()]) + ....: for n in range(1, 5)] [1, 2, 6, 22] Here is a less trivial implementation of this:: @@ -1038,10 +1194,10 @@ def canopee(self): sage: from sage.sets.finite_set_map_cy import fibers sage: from sage.misc.all import attrcall sage: def baxter(n): - ... f = fibers(lambda t: tuple(t.canopee()), - ... BinaryTrees(n)) - ... return sum(len(f[i])*len(f[tuple(1-x for x in i)]) - ... for i in f) + ....: f = fibers(lambda t: tuple(t.canopee()), + ....: BinaryTrees(n)) + ....: return sum(len(f[i])*len(f[tuple(1-x for x in i)]) + ....: for i in f) sage: [baxter(n) for n in range(1, 7)] [1, 2, 6, 22, 92, 422] @@ -1054,9 +1210,9 @@ def canopee(self): REFERENCES: - .. [DG] S. Dulucq and O, Guibert. Mots de piles, tableaux - standards et permutations de Baxter, proceedings of - Formal Power Series and Algebraic Combinatorics, 1994. + .. [DG94] S. Dulucq and O. Guibert. Mots de piles, tableaux + standards et permutations de Baxter, proceedings of + Formal Power Series and Algebraic Combinatorics, 1994. """ if not self: raise ValueError("canopee is only defined for non empty binary trees") @@ -1070,7 +1226,1264 @@ def add_leaf_rec(tr): add_leaf_rec(self) return res[1:-1] + def in_order_traversal_iter(self): + """ + The depth-first infix-order traversal iterator for the binary + tree ``self``. + + This method iters each vertex (node and leaf alike) of the given + binary tree following the depth-first infix order traversal + algorithm. + + The *depth-first infix order traversal algorithm* iterates + through a binary tree as follows:: + + iterate through the left subtree (by the depth-first infix + order traversal algorithm); + yield the root; + iterate through the right subtree (by the depth-first infix + order traversal algorithm). + + For example on the following binary tree `T`, where we denote + leaves by `a, b, c, \ldots` and nodes by `1, 2, 3, \ldots`:: + + | ____3____ | + | / \ | + | 1 __7__ | + | / \ / \ | + | a 2 _5_ 8 | + | / \ / \ / \ | + | b c 4 6 h i | + | / \ / \ | + | d e f g | + + the depth-first infix-order traversal algorithm iterates through + the vertices of `T` in the following order: + `a,1,b,2,c,3,d,4,e,5,f,6,g,7,h,8,i`. + + See :meth:`in_order_traversal` for a version of this algorithm + which not only iterates through, but actually does something at + the vertices of tree. + + TESTS:: + + sage: b = BinaryTree([[],[[],[]]]); ascii_art([b]) + [ _o_ ] + [ / \ ] + [ o o ] + [ / \ ] + [ o o ] + sage: ascii_art(list(b.in_order_traversal_iter())) + [ ] + [ , o, , _o_ o o o ] + [ / \ / \ ] + [ o o o o ] + [ / \ ] + [ o o, , , , , , , ] + sage: ascii_art(filter(lambda node: node.label() is not None, + ....: b.canonical_labelling().in_order_traversal_iter())) + [ ] + [ 1, _2_ 3 4 5 ] + [ / \ / \ ] + [ 1 4 3 5 ] + [ / \ ] + [ 3 5, , , ] + + sage: list(BinaryTree(None).in_order_traversal_iter()) + [.] + """ + if self.is_empty(): + yield self + return + # TODO:: PYTHON 3 + # yield from self[0].in_order_traversal_iter() + for left_subtree in self[0].in_order_traversal_iter(): + yield left_subtree + yield self + # TODO:: PYTHON 3 + # yield from self[1].in_order_traversal_iter() + for right_subtree in self[1].in_order_traversal_iter(): + yield right_subtree + + def in_order_traversal(self, node_action=None, leaf_action=None): + r""" + Explore the binary tree ``self`` using the depth-first infix-order + traversal algorithm, executing the ``node_action`` function + whenever traversing a node and executing the ``leaf_action`` + function whenever traversing a leaf. + + In more detail, what this method does to a tree `T` is the + following:: + + if the root of `T` is a node: + apply in_order_traversal to the left subtree of `T` + (with the same node_action and leaf_action); + apply node_action to the root of `T`; + apply in_order_traversal to the right subtree of `T` + (with the same node_action and leaf_action); + else: + apply leaf_action to the root of `T`. + + For example on the following binary tree `T`, where we denote + leaves by `a, b, c, \ldots` and nodes by `1, 2, 3, \ldots`:: + + | ____3____ | + | / \ | + | 1 __7__ | + | / \ / \ | + | a 2 _5_ 8 | + | / \ / \ / \ | + | b c 4 6 h i | + | / \ / \ | + | d e f g | + + this method first applies ``leaf_action`` to `a`, then applies + ``node_action`` to `1`, then ``leaf_action`` to `b`, then + ``node_action`` to `2`, etc., with the vertices being traversed + in the order `a,1,b,2,c,3,d,4,e,5,f,6,g,7,h,8,i`. + + See :meth:`in_order_traversal_iter` for a version of this + algorithm which only iterates through the vertices rather than + applying any function to them. + + INPUT: + + - ``node_action`` -- (optional) a function which takes a node in input + and does something during the exploration + - ``leaf_action`` -- (optional) a function which takes a leaf in input + and does something during the exploration + + TESTS:: + + sage: nb_leaf = 0 + sage: def l_action(_): + ....: global nb_leaf + ....: nb_leaf += 1 + sage: nb_node = 0 + sage: def n_action(_): + ....: global nb_node + ....: nb_node += 1 + + sage: BinaryTree().in_order_traversal(n_action, l_action) + sage: nb_leaf, nb_node + (1, 0) + + sage: nb_leaf, nb_node = 0, 0 + sage: b = BinaryTree([[],[[],[]]]); b + [[., .], [[., .], [., .]]] + sage: b.in_order_traversal(n_action, l_action) + sage: nb_leaf, nb_node + (6, 5) + sage: nb_leaf, nb_node = 0, 0 + sage: b = b.canonical_labelling() + sage: b.in_order_traversal(n_action, l_action) + sage: nb_leaf, nb_node + (6, 5) + sage: l = [] + sage: b.in_order_traversal(lambda node: l.append( node.label() )) + sage: l + [1, 2, 3, 4, 5] + + sage: leaf = 'a' + sage: l = [] + sage: def l_action(_): + ....: global leaf, l + ....: l.append(leaf) + ....: leaf = chr( ord(leaf)+1 ) + sage: n_action = lambda node: l.append( node.label() ) + sage: b = BinaryTree([[None,[]],[[[],[]],[]]]).\ + ....: canonical_labelling() + sage: b.in_order_traversal(n_action, l_action) + sage: l + ['a', 1, 'b', 2, 'c', 3, 'd', 4, 'e', 5, 'f', 6, 'g', 7, 'h', 8, + 'i'] + """ + if leaf_action is None: + leaf_action = lambda x: None + if node_action is None: + node_action = lambda x: None + + for node in self.in_order_traversal_iter(): + if node.is_empty(): + leaf_action(node) + else: + node_action(node) + + def tamari_greater(self): + r""" + The list of all trees greater or equal to ``self`` in the Tamari + order. + + This is the order filter of the Tamari order generated by ``self``. + + The Tamari order on binary trees of size `n` is the partial order + on the set of all binary trees of size `n` generated by the + following requirement: If a binary tree `T'` is obtained by + right rotation (see :meth:`right_rotate`) from a binary tree `T`, + then `T < T'`. + This not only is a well-defined partial order, but actually is + a lattice structure on the set of binary trees of size `n`, and + is a quotient of the weak order on the `n`-th symmetric group. + See [CP12]_. + + .. SEEALSO:: + + :meth:`tamari_smaller` + + EXAMPLES: + + For example, the tree:: + + | __o__ | + | / \ | + | o o | + | / \ / | + | o o o | + + has these trees greater or equal to it:: + + |o , o , o , o , o , o ,| + | \ \ \ \ \ \ | + | o o o o _o_ __o__ | + | \ \ \ \ / \ / \ | + | o o o _o_ o o o o | + | \ \ / \ / \ \ \ \ / | + | o o o o o o o o o o | + | \ \ \ / | + | o o o o | + | \ / | + | o o | + + | o , o , _o_ , _o__ , __o__ , ___o___ ,| + | / \ / \ / \ / \ / \ / \ | + | o o o o o o o _o_ o o o o | + | \ \ / \ / \ \ \ \ / | + | o o o o o o o o o o | + | \ \ \ / \ \ | + | o o o o o o | + | \ / | + | o o | + + | _o_ , __o__ | + | / \ / \ | + | o o o o| + | / \ \ / \ / | + | o o o o o o | + + TESTS:: + + sage: B = BinaryTree + sage: b = B([None, B([None, B([None, B([])])])]);b + [., [., [., [., .]]]] + sage: b.tamari_greater() + [[., [., [., [., .]]]]] + sage: b = B([B([B([B([]), None]), None]), None]);b + [[[[., .], .], .], .] + sage: b.tamari_greater() + [[., [., [., [., .]]]], [., [., [[., .], .]]], + [., [[., .], [., .]]], [., [[., [., .]], .]], + [., [[[., .], .], .]], [[., .], [., [., .]]], + [[., .], [[., .], .]], [[., [., .]], [., .]], + [[., [., [., .]]], .], [[., [[., .], .]], .], + [[[., .], .], [., .]], [[[., .], [., .]], .], + [[[., [., .]], .], .], [[[[., .], .], .], .]] + """ + from sage.combinat.tools import transitive_ideal + return transitive_ideal(lambda x: x.tamari_succ(), self) + + def tamari_pred(self): + r""" + Compute the list of predecessors of ``self`` in the Tamari poset. + + This list is computed by performing all left rotates possible on + its nodes. + + EXAMPLES: + + For this tree:: + + | __o__ | + | / \ | + | o o | + | / \ / | + | o o o | + + the list is:: + + | o , _o_ | + | / / \ | + | _o_ o o | + | / \ / / | + | o o o o | + | / \ / | + | o o o | + + TESTS:: + + sage: B = BinaryTree + sage: b = B([B([B([B([]), None]), None]), None]);b + [[[[., .], .], .], .] + sage: b.tamari_pred() + [] + sage: b = B([None, B([None, B([None, B([])])])]);b + [., [., [., [., .]]]] + sage: b.tamari_pred() + [[[., .], [., [., .]]], [., [[., .], [., .]]], [., [., [[., .], .]]]] + """ + res = [] + if self.is_empty(): + return [] + if not self[1].is_empty(): + res.append(self.left_rotate()) + B = self.parent()._element_constructor_ + return (res + + [B([g, self[1]]) for g in self[0].tamari_pred()] + + [B([self[0], d]) for d in self[1].tamari_pred()]) + + def tamari_smaller(self): + r""" + The list of all trees smaller or equal to ``self`` in the Tamari + order. + + This is the order ideal of the Tamari order generated by ``self``. + + The Tamari order on binary trees of size `n` is the partial order + on the set of all binary trees of size `n` generated by the + following requirement: If a binary tree `T'` is obtained by + right rotation (see :meth:`right_rotate`) from a binary tree `T`, + then `T < T'`. + This not only is a well-defined partial order, but actually is + a lattice structure on the set of binary trees of size `n`, and + is a quotient of the weak order on the `n`-th symmetric group. + See [CP12]_. + + .. SEEALSO:: + + :meth:`tamari_greater` + + EXAMPLES: + + The tree:: + + | __o__ | + | / \ | + | o o | + | / \ / | + | o o o | + + has these trees smaller or equal to it:: + + | __o__ , _o_ , o , o, o, o | + | / \ / \ / / / / | + | o o o o _o_ o o o | + | / \ / / / / \ / \ / / | + |o o o o o o o o o o o | + | / / \ / / / | + | o o o o o o | + | / / \ / | + | o o o o | + | / | + | o | + + TESTS:: + + sage: B = BinaryTree + sage: b = B([None, B([None, B([None, B([])])])]);b + [., [., [., [., .]]]] + sage: b.tamari_smaller() + [[., [., [., [., .]]]], [., [., [[., .], .]]], + [., [[., .], [., .]]], [., [[., [., .]], .]], + [., [[[., .], .], .]], [[., .], [., [., .]]], + [[., .], [[., .], .]], [[., [., .]], [., .]], + [[., [., [., .]]], .], [[., [[., .], .]], .], + [[[., .], .], [., .]], [[[., .], [., .]], .], + [[[., [., .]], .], .], [[[[., .], .], .], .]] + sage: b = B([B([B([B([]), None]), None]), None]);b + [[[[., .], .], .], .] + sage: b.tamari_smaller() + [[[[[., .], .], .], .]] + """ + from sage.combinat.tools import transitive_ideal + return transitive_ideal(lambda x: x.tamari_pred(), self) + + def tamari_succ(self): + r""" + Compute the list of successors of ``self`` in the Tamari poset. + + This is the list of all trees obtained by a right rotate of + one of its nodes. + + EXAMPLES: + + The list of successors of:: + + | __o__ | + | / \ | + | o o | + | / \ / | + | o o o | + + is:: + + | _o__ , ___o___ , _o_ | + | / \ / \ / \ | + | o _o_ o o o o | + | / \ \ / / \ \ | + | o o o o o o o | + | / \ | + | o o | + + TESTS:: + + sage: B = BinaryTree + sage: b = B([B([B([B([]), None]), None]), None]);b + [[[[., .], .], .], .] + sage: b.tamari_succ() + [[[[., .], .], [., .]], [[[., .], [., .]], .], [[[., [., .]], .], .]] + + sage: b = B([]) + sage: b.tamari_succ() + [] + + sage: b = B([[],[]]) + sage: b.tamari_succ() + [[., [., [., .]]]] + """ + res = [] + if self.is_empty(): + return [] + B = self.parent()._element_constructor_ + if not self[0].is_empty(): + res.append(self.right_rotate()) + return (res + + [B([g, self[1]]) for g in self[0].tamari_succ()] + + [B([self[0], d]) for d in self[1].tamari_succ()]) + + def q_hook_length_fraction(self, q=None, q_factor=False): + r""" + Compute the ``q``-hook length fraction of the binary tree ``self``, + with an additional "q-factor" if desired. + + If `T` is a (plane) binary tree and `q` is a polynomial + indeterminate over some ring, then the `q`-hook length fraction + `h_{q} (T)` of `T` is defined by + + .. MATH:: + + h_{q} (T) + = \frac{[\lvert T \rvert]_q!}{\prod_{t \in T} + [\lvert T_t \rvert]_q}, + + where the product ranges over all nodes `t` of `T`, where `T_t` + denotes the subtree of `T` consisting of `t` and its all + descendants, and where for every tree `S`, we denote by + `\lvert S \rvert` the number of nodes of `S`. While this + definition only shows that `h_{q} (T)` is a rational function + in `T`, it is in fact easy to show that `h_{q} (T)` is + actually a polynomial in `T`, and thus makes sense when any + element of a commutative ring is substituted for `q`. + This can also be explicitly seen from the following recursive + formula for `h_{q} (T)`: + + .. MATH:: + + h_{q} (T) + = \binom{ \lvert T \rvert - 1 }{ \lvert T_1 \rvert }_q + h_{q} (T_1) h_{q} (T_2), + + where `T` is any nonempty binary tree, and `T_1` and `T_2` are + the two child trees of the root of `T`, and where + `\binom{a}{b}_q` denotes a `q`-binomial coefficient. + + A variation of the `q`-hook length fraction is the following + "`q`-hook length fraction with `q`-factor": + + .. MATH:: + + f_{q} (T) + = h_{q} (T) \cdot + \prod_{t \in T} q^{\lvert T_{\mathrm{right}(t)} \rvert}, + + where for every node `t`, we denote by `\mathrm{right}(t)` the + right child of `t`. + This `f_{q} (T)` differs from `h_{q} (T)` only in a + multiplicative factor, which is a power of `q`. + + When `q = 1`, both `f_{q} (T)` and `h_{q} (T)` equal the number + of permutations whose binary search tree (see [HNT05]_ for the + definition) is `T` (after dropping the labels). For example, + there are `20` permutations which give a binary tree of the + following shape:: + + | __o__ | + | / \ | + | o o | + | / \ / | + | o o o | + + by the binary search insertion algorithm, in accordance with + the fact that this tree satisfies `f_{1} (T) = 20`. + + When `q` is considered as a polynomial indeterminate, + `f_{q} (T)` is the generating function for all permutations + whose binary search tree is `T` (after dropping the labels) + with respect to the number of inversions (i. e., the Coxeter + length) of the permutations. + + Objects similar to `h_{q} (T)` also make sense for general + ordered forests (rather than just binary trees), see e. g. + [BW88]_, Theorem 9.1. + + INPUT: + + - ``q`` -- a ring element which is to be substituted as `q` + into the `q`-hook length fraction (by default, this is + set to be the indeterminate `q` in the polynomial ring + `\ZZ[q]`) + + - ``q_factor`` -- a Boolean (default: ``False``) which + determines whether to compute `h_{q} (T)` or to + compute `f_{q} (T)` (namely, `h_{q} (T)` is obtained when + ``q_factor == False``, and `f_{q} (T)` is obtained when + ``q_factor == True``) + + REFERENCES: + + .. [BW88] Anders Bjoerner, Michelle L. Wachs, + *Generalized quotients in Coxeter groups*. + Transactions of the American Mathematical Society, + vol. 308, no. 1, July 1988. + http://www.ams.org/journals/tran/1988-308-01/S0002-9947-1988-0946427-X/S0002-9947-1988-0946427-X.pdf + + EXAMPLES: + + Let us start with a simple example. Actually, let us start + with the easiest possible example -- the binary tree with + only one vertex (which is a leaf):: + + sage: b = BinaryTree() + sage: b.q_hook_length_fraction() + 1 + sage: b.q_hook_length_fraction(q_factor=True) + 1 + + Nothing different for a tree with one node and two leaves:: + + sage: b = BinaryTree([]); b + [., .] + sage: b.q_hook_length_fraction() + 1 + sage: b.q_hook_length_fraction(q_factor=True) + 1 + + Let us get to a more interesting tree:: + + sage: b = BinaryTree([[[],[]],[[],None]]); b + [[[., .], [., .]], [[., .], .]] + sage: b.q_hook_length_fraction()(q=1) + 20 + sage: b.q_hook_length_fraction() + q^7 + 2*q^6 + 3*q^5 + 4*q^4 + 4*q^3 + 3*q^2 + 2*q + 1 + sage: b.q_hook_length_fraction(q_factor=True) + q^10 + 2*q^9 + 3*q^8 + 4*q^7 + 4*q^6 + 3*q^5 + 2*q^4 + q^3 + sage: b.q_hook_length_fraction(q=2) + 465 + sage: b.q_hook_length_fraction(q=2, q_factor=True) + 3720 + sage: q = PolynomialRing(ZZ, 'q').gen() + sage: b.q_hook_length_fraction(q=q**2) + q^14 + 2*q^12 + 3*q^10 + 4*q^8 + 4*q^6 + 3*q^4 + 2*q^2 + 1 + + Let us check the fact that `f_{q} (T)` is the generating function + for all permutations whose binary search tree is `T` (after + dropping the labels) with respect to the number of inversions of + the permutations:: + + sage: def q_hook_length_fraction_2(T): + ....: P = PolynomialRing(ZZ, 'q') + ....: q = P.gen() + ....: res = P.zero() + ....: for w in T.sylvester_class(): + ....: res += q ** Permutation(w).length() + ....: return res + sage: def test_genfun(i): + ....: return all( q_hook_length_fraction_2(T) + ....: == T.q_hook_length_fraction(q_factor=True) + ....: for T in BinaryTrees(i) ) + sage: test_genfun(4) + True + """ + from sage.combinat.q_analogues import q_binomial + + if q is None: + from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing + from sage.rings.integer_ring import ZZ + basering = PolynomialRing(ZZ, 'q') + q = basering.gen() + else: + basering = q.base_ring() + + if q_factor: + def product_of_subtrees(b): + if b.is_empty(): + return basering.one() + b0 = b[0] + b1 = b[1] + return q_binomial(b.node_number() - 1, b0.node_number(), q=q) * \ + product_of_subtrees(b0) * product_of_subtrees(b1) * \ + q ** (b1.node_number()) + else: + def product_of_subtrees(b): + if b.is_empty(): + return basering.one() + b0 = b[0] + b1 = b[1] + return q_binomial(b.node_number() - 1, b0.node_number(), q=q) * \ + product_of_subtrees(b0) * product_of_subtrees(b1) + + return product_of_subtrees(self) + + @combinatorial_map(name="Right rotate") + def right_rotate(self): + r""" + Return the result of right rotation applied to the binary + tree ``self``. + + Right rotation on binary trees is defined as follows: + Let `T` be a binary tree such that the left child of the + root of `T` is a node. Let `C` be the right + child of the root of `T`, and let `A` and `B` be the + left and right children of the left child of the root + of `T`. (Keep in mind that nodes of trees are identified + with the subtrees consisting of their descendants.) + Then, the right rotation of `T` is the binary tree in + which the left child of the root is `A`, whereas + the right child of the root is a node whose left and right + children are `B` and `C`. In pictures:: + + | * * | + | / \ / \ | + | * C -right-rotate-> A * | + | / \ / \ | + | A B B C | + + where asterisks signify a single node each (but `A`, `B` + and `C` might be empty). + + For example, :: + + | o _o_ | + | / / \ | + | o -right-rotate-> o o | + | / \ / | + | o o o | + + | __o__ _o__ | + | / \ / \ | + | o o -right-rotate-> o _o_ | + | / \ / / \ | + | o o o o o | + | / \ \ | + | o o o | + + Right rotation is the inverse operation to left rotation + (:meth:`left_rotate`). + + The right rotation operation introduced here is the one defined + in Definition 2.1 of [CP12]_. + + .. SEEALSO:: + + :meth:`left_rotate` + EXAMPLES:: + + sage: b = BinaryTree([[[],[]], None]); ascii_art([b]) + [ o ] + [ / ] + [ o ] + [ / \ ] + [ o o ] + sage: ascii_art([b.right_rotate()]) + [ _o_ ] + [ / \ ] + [ o o ] + [ / ] + [ o ] + sage: b = BinaryTree([[[[],None],[None,[]]], []]); ascii_art([b]) + [ __o__ ] + [ / \ ] + [ o o ] + [ / \ ] + [ o o ] + [ / \ ] + [ o o ] + sage: ascii_art([b.right_rotate()]) + [ _o__ ] + [ / \ ] + [ o _o_ ] + [ / / \ ] + [ o o o ] + [ \ ] + [ o ] + """ + B = self.parent()._element_constructor_ + return B([self[0][0], B([self[0][1], self[1]])]) + + @combinatorial_map(name="Left rotate") + def left_rotate(self): + r""" + Return the result of left rotation applied to the binary + tree ``self``. + + Left rotation on binary trees is defined as follows: + Let `T` be a binary tree such that the right child of the + root of `T` is a node. Let `A` be the left + child of the root of `T`, and let `B` and `C` be the + left and right children of the right child of the root + of `T`. (Keep in mind that nodes of trees are identified + with the subtrees consisting of their descendants.) + Then, the left rotation of `T` is the binary tree in + which the right child of the root is `C`, whereas + the left child of the root is a node whose left and right + children are `A` and `B`. In pictures:: + + | * * | + | / \ / \ | + | A * -left-rotate-> * C | + | / \ / \ | + | B C A B | + + where asterisks signify a single node each (but `A`, `B` + and `C` might be empty). + + For example, :: + + | _o_ o | + | / \ / | + | o o -left-rotate-> o | + | / / \ | + | o o o | + + | __o__ o | + | / \ / | + | o o -left-rotate-> o | + | / \ / | + | o o o | + | / \ / \ | + | o o o o | + | / \ | + | o o | + + Left rotation is the inverse operation to right rotation + (:meth:`right_rotate`). + + .. SEEALSO:: + + :meth:`right_rotate` + + EXAMPLES:: + + sage: b = BinaryTree([[],[[],None]]); ascii_art([b]) + [ _o_ ] + [ / \ ] + [ o o ] + [ / ] + [ o ] + sage: ascii_art([b.left_rotate()]) + [ o ] + [ / ] + [ o ] + [ / \ ] + [ o o ] + sage: b.left_rotate().right_rotate() == b + True + """ + B = self.parent()._element_constructor_ + return B([B([self[0], self[1][0]]), self[1][1]]) + + @combinatorial_map(name="Over operation on Binary Trees") + def over(self, bt): + r""" + Return ``self`` over ``bt``, where "over" is the ``over`` + (`/`) operation. + + If `T` and `T'` are two binary trees, then `T` over `T'` + (written `T / T'`) is defined as the tree obtained by grafting + `T'` on the rightmost leaf of `T`. More precisely, `T / T'` is + defined by identifying the root of the `T'` with the rightmost + leaf of `T`. See section 4.5 of [HNT05]_. + + If `T` is empty, then `T / T' = T'`. + + The definition of this "over" operation goes back to + Loday-Ronco [LodRon0102066]_ (Definition 2.2), but it is + denoted by `\backslash` and called the "under" operation there. + In fact, trees in sage have their root at the top, contrary to + the trees in [LodRon0102066]_ which are growing upwards. For + this reason, the names of the over and under operations are + swapped, in order to keep a graphical meaning. + (Our notation follows that of section 4.5 of [HNT05]_.) + + .. SEEALSO:: + + :meth:`under` + + EXAMPLES: + + Showing only the nodes of a binary tree, here is an + example for the over operation:: + + | o __o__ _o_ | + | / \ / / \ = / \ | + | o o o o o o | + | \ / \ | + | o o __o__ | + | / \ | + | o o | + | \ / | + | o o | + + A Sage example:: + + sage: b1 = BinaryTree([[],[[],[]]]) + sage: b2 = BinaryTree([[None, []],[]]) + sage: ascii_art((b1, b2, b1/b2)) + ( _o_ _o_ _o_ ) + ( / \ / \ / \ ) + ( o o o o o o_ ) + ( / \ \ / \ ) + ( o o, o , o o ) + ( \ ) + ( _o_ ) + ( / \ ) + ( o o ) + ( \ ) + ( o ) + + TESTS:: + + sage: b1 = BinaryTree([[],[]]); ascii_art([b1]) + [ o ] + [ / \ ] + [ o o ] + sage: b2 = BinaryTree([[None,[]],[[],None]]); ascii_art([b2]) + [ __o__ ] + [ / \ ] + [ o o ] + [ \ / ] + [ o o ] + sage: ascii_art([b1.over(b2)]) + [ _o_ ] + [ / \ ] + [ o o ] + [ \ ] + [ __o__ ] + [ / \ ] + [ o o ] + [ \ / ] + [ o o ] + + The same in the labelled case:: + + sage: b1 = b1.canonical_labelling() + sage: b2 = b2.canonical_labelling() + sage: ascii_art([b1.over(b2)]) + [ _2_ ] + [ / \ ] + [ 1 3 ] + [ \ ] + [ __3__ ] + [ / \ ] + [ 1 5 ] + [ \ / ] + [ 2 4 ] + """ + B = self.parent()._element_constructor_ + if self.is_empty(): + return bt + if hasattr(self, "label"): + lab = self.label() + return B([self[0], self[1].over(bt)], lab) + else: + return B([self[0], self[1].over(bt)]) + + __div__ = over + + @combinatorial_map(name="Under operation on Binary Trees") + def under(self, bt): + r""" + Return ``self`` under ``bt``, where "under" is the ``under`` + (`\backslash`) operation. + + If `T` and `T'` are two binary trees, then `T` under `T'` + (written `T \backslash T'`) is defined as the tree obtained + by grafting `T` on the leftmost leaf of `T'`. More precisely, + `T \backslash T'` is defined by identifying the root of `T` + with the leftmost leaf of `T'`. + + If `T'` is empty, then `T \backslash T' = T`. + + The definition of this "under" operation goes back to + Loday-Ronco [LodRon0102066]_ (Definition 2.2), but it is + denoted by `/` and called the "over" operation there. In fact, + trees in sage have their root at the top, contrary to the trees + in [LodRon0102066]_ which are growing upwards. For this reason, + the names of the over and under operations are swapped, in + order to keep a graphical meaning. + (Our notation follows that of section 4.5 of [HNT05]_.) + + .. SEEALSO:: + + :meth:`over` + + EXAMPLES: + + Showing only the nodes of a binary tree, here is an + example for the under operation:: + + sage: b1 = BinaryTree([[],[]]) + sage: b2 = BinaryTree([None,[]]) + sage: ascii_art((b1, b2, b1 \ b2)) + ( o o _o_ ) + ( / \ \ / \ ) + ( o o, o, o o ) + ( / \ ) + ( o o ) + + TESTS:: + + sage: b1 = BinaryTree([[],[[None,[]],None]]); ascii_art([b1]) + [ _o_ ] + [ / \ ] + [ o o ] + [ / ] + [ o ] + [ \ ] + [ o ] + sage: b2 = BinaryTree([[],[None,[]]]); ascii_art([b2]) + [ o ] + [ / \ ] + [ o o ] + [ \ ] + [ o ] + sage: ascii_art([b1.under(b2)]) + [ o_ ] + [ / \ ] + [ o o ] + [ / \ ] + [ _o_ o ] + [ / \ ] + [ o o ] + [ / ] + [ o ] + [ \ ] + [ o ] + + The same in the labelled case:: + + sage: b1 = b1.canonical_labelling() + sage: b2 = b2.canonical_labelling() + sage: ascii_art([b1.under(b2)]) + [ 2_ ] + [ / \ ] + [ 1 3 ] + [ / \ ] + [ _2_ 4 ] + [ / \ ] + [ 1 5 ] + [ / ] + [ 3 ] + [ \ ] + [ 4 ] + """ + B = self.parent()._element_constructor_ + if bt.is_empty(): + return self + lab = None + if hasattr(bt, "label"): + lab = bt.label() + return B([self.under(bt[0]), bt[1]], lab) + else: + return B([self.under(bt[0]), bt[1]]) + + _backslash_ = under + + def sylvester_class(self, left_to_right=False): + r""" + Iterate over the sylvester class corresponding to the binary tree + ``self``. + + The sylvester class of a tree `T` is the set of permutations + `\sigma` whose binary search tree (a notion defined in [HNT05]_, + Definition 7) is `T` after forgetting the labels. This is an + equivalence class of the sylvester congruence (the congruence on + words which holds two words `uacvbw` and `ucavbw` congruent + whenever `a`, `b`, `c` are letters satisfying `a \leq b < c`, and + extends by transitivity) on the symmetric group. + + For example the following tree's sylvester class consists of the + permutations `(1,3,2)` and `(3,1,2)`:: + + [ o ] + [ / \ ] + [ o o ] + + (only the nodes are drawn here). + + The binary search tree of a word is constructed by an RSK-like + insertion algorithm which proceeds as follows: Start with an + empty labelled binary tree, and read the word from left to right. + Each time a letter is read from the word, insert this letter in + the existing tree using binary search tree insertion + (:meth:`~sage.combinat.binary_tree.LabelledBinaryTree.binary_search_insert`). + If a left-to-right reading is to be employed instead, the + ``left_to_right`` optional keyword variable should be set to + ``True``. + + TESTS:: + + sage: list(BinaryTree([[],[]]).sylvester_class()) + [[1, 3, 2], [3, 1, 2]] + sage: bt = BinaryTree([[[],None],[[],[]]]) + sage: l = list(bt.sylvester_class()); l + [[1, 2, 4, 6, 5, 3], + [1, 4, 2, 6, 5, 3], + [1, 4, 6, 2, 5, 3], + [1, 4, 6, 5, 2, 3], + [4, 1, 2, 6, 5, 3], + [4, 1, 6, 2, 5, 3], + [4, 1, 6, 5, 2, 3], + [4, 6, 1, 2, 5, 3], + [4, 6, 1, 5, 2, 3], + [4, 6, 5, 1, 2, 3], + [1, 2, 6, 4, 5, 3], + [1, 6, 2, 4, 5, 3], + [1, 6, 4, 2, 5, 3], + [1, 6, 4, 5, 2, 3], + [6, 1, 2, 4, 5, 3], + [6, 1, 4, 2, 5, 3], + [6, 1, 4, 5, 2, 3], + [6, 4, 1, 2, 5, 3], + [6, 4, 1, 5, 2, 3], + [6, 4, 5, 1, 2, 3]] + sage: len(l) == Integer(bt.q_hook_length_fraction()(q=1)) + True + + Border cases:: + + sage: list(BinaryTree().sylvester_class()) + [[]] + sage: list(BinaryTree([]).sylvester_class()) + [[1]] + """ + if self.is_empty(): + yield [] + return + from itertools import product + from sage.combinat.words.word import Word as W + from sage.combinat.words.shuffle_product import ShuffleProduct_w1w2 \ + as shuffle + + if left_to_right: + builder = lambda i, p: [i] + list(p) + else: + builder = lambda i, p: list(p) + [i] + + shift = self[0].node_number() + 1 + for l, r in product(self[0].sylvester_class(), + self[1].sylvester_class()): + for p in shuffle(W(l), W([shift + ri for ri in r])): + yield builder(shift, p) + + def is_full(self): + r""" + Return ``True`` if ``self`` is full, else return ``False``. + + A full binary tree is a tree in which every node either has two + child nodes or has two child leaves. + + This is also known as *proper binary tree* or *2-tree* or *strictly + binary tree*. + + For example:: + + | __o__ | + | / \ | + | o o | + | / \ | + | o o | + | / \ | + | o o | + + is not full but the next one is:: + + | ___o___ | + | / \ | + | __o__ o | + | / \ | + | o o | + | / \ / \ | + | o o o o | + + EXAMPLES:: + + sage: BinaryTree([[[[],None],[None,[]]], []]).is_full() + False + sage: BinaryTree([[[[],[]],[[],[]]], []]).is_full() + True + sage: ascii_art(filter(lambda bt: bt.is_full(), BinaryTrees(5))) + [ _o_ _o_ ] + [ / \ / \ ] + [ o o o o ] + [ / \ / \ ] + [ o o, o o ] + """ + if self.is_empty(): + return True + if self[0].is_empty() != self[1].is_empty(): + return False + return self[0].is_full() and self[1].is_full() + + def is_perfect(self): + r""" + Return ``True`` if ``self`` is perfect, else return ``False``. + + A perfect binary tree is a full tree in which all leaves are at the + same depth. + + For example:: + + | ___o___ | + | / \ | + | __o__ o | + | / \ | + | o o | + | / \ / \ | + | o o o o | + + is not perfect but the next one is:: + + | __o__ | + | / \ | + | o o | + | / \ / \ | + | o o o o | + + EXAMPLES:: + + sage: lst = lambda i: filter(lambda bt: bt.is_perfect(), BinaryTrees(i)) + sage: for i in range(10): ascii_art(lst(i)) # long time + [ ] + [ o ] + [ ] + [ o ] + [ / \ ] + [ o o ] + [ ] + [ ] + [ ] + [ __o__ ] + [ / \ ] + [ o o ] + [ / \ / \ ] + [ o o o o ] + [ ] + [ ] + """ + return 2 ** self.depth() - 1 == self.node_number() + + def is_complete(self): + r""" + Return ``True`` if ``self`` is complete, else return ``False``. + + In a nutshell, a complete binary tree is a perfect binary tree + except possibly in the last level, with all nodes in the last + level "flush to the left". + + In more detail: + A complete binary tree (also called binary heap) is a binary tree in + which every level, except possibly the last one (the deepest), is + completely filled. At depth `n`, all nodes must be as far left as + possible. + + For example:: + + | ___o___ | + | / \ | + | __o__ o | + | / \ | + | o o | + | / \ / \ | + | o o o o | + + is not complete but the following ones are:: + + | __o__ _o_ ___o___ | + | / \ / \ / \ | + | o o o o __o__ o | + | / \ / \ / \ / \ / \ | + | o o o o, o o , o o o o | + | / \ / | + | o o o | + + EXAMPLES:: + + sage: lst = lambda i: filter(lambda bt: bt.is_complete(), BinaryTrees(i)) + sage: for i in range(9): ascii_art(lst(i)) # long time + [ ] + [ o ] + [ o ] + [ / ] + [ o ] + [ o ] + [ / \ ] + [ o o ] + [ o ] + [ / \ ] + [ o o ] + [ / ] + [ o ] + [ _o_ ] + [ / \ ] + [ o o ] + [ / \ ] + [ o o ] + [ __o__ ] + [ / \ ] + [ o o ] + [ / \ / ] + [ o o o ] + [ __o__ ] + [ / \ ] + [ o o ] + [ / \ / \ ] + [ o o o o ] + [ __o__ ] + [ / \ ] + [ o o ] + [ / \ / \ ] + [ o o o o ] + [ / ] + [ o ] + """ + if self.is_empty(): + return True + # self := L ^ R + dL = self[0].depth() + dR = self[1].depth() + # if L is perfect + if self[0].is_perfect(): + # if the depth of R == depth of L then R must be complete + if dL == dR: + return self[1].is_complete() + # else R is perfect with depth equals depth of L - 1 + elif dL == dR + 1: + return self[1].is_perfect() + return False + # L is not perfect then R is perfect and the depth of L = the depth of + # R + 1 + return self[0].is_complete() and self[1].is_perfect() and dL == dR + 1 from sage.structure.parent import Parent from sage.structure.unique_representation import UniqueRepresentation @@ -1103,10 +2516,10 @@ class BinaryTrees(UniqueRepresentation, Parent): sage: BinaryTrees(2) Binary trees of size 2 - .. NOTE:: this in a factory class whose constructor returns instances of + .. NOTE:: this is a factory class whose constructor returns instances of subclasses. - .. NOTE:: the fact that OrderedTrees is a class instead of a simple callable + .. NOTE:: the fact that BinaryTrees is a class instead of a simple callable is an implementation detail. It could be changed in the future and one should not rely on it. """ @@ -1131,13 +2544,13 @@ def __classcall_private__(cls, n=None): return BinaryTrees_all() else: if not (isinstance(n, (Integer, int)) and n >= 0): - raise ValueError("n must be a non negative integer") + raise ValueError("n must be a nonnegative integer") return BinaryTrees_size(Integer(n)) @cached_method def leaf(self): """ - Return a left tree with ``self`` as parent. + Return a leaf tree with ``self`` as parent. EXAMPLES:: @@ -1147,7 +2560,7 @@ def leaf(self): TEST:: sage: (BinaryTrees().leaf() is - ... sage.combinat.binary_tree.BinaryTrees_all().leaf()) + ....: sage.combinat.binary_tree.BinaryTrees_all().leaf()) True """ return self(None) @@ -1176,7 +2589,7 @@ def __init__(self): sage: B is BinaryTrees_all() True - sage: TestSuite(B).run() + sage: TestSuite(B).run() # long time """ DisjointUnionEnumeratedSets.__init__( self, Family(NonNegativeIntegers(), BinaryTrees_size), @@ -1217,7 +2630,7 @@ def __call__(self, x=None, *args, **keywords): def unlabelled_trees(self): """ - Return the set of unlabelled trees associated to ``self`` + Return the set of unlabelled trees associated to ``self``. EXAMPLES:: @@ -1228,7 +2641,7 @@ def unlabelled_trees(self): def labelled_trees(self): """ - Return the set of labelled trees associated to ``self`` + Return the set of labelled trees associated to ``self``. EXAMPLES:: @@ -1254,7 +2667,6 @@ def _element_constructor_(self, *args, **keywords): Element = BinaryTree from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets -from combinat import catalan_number ################################################################# # Enumerated set of binary trees of a given size ################################################################# @@ -1324,6 +2736,7 @@ def cardinality(self): sage: BinaryTrees(5).cardinality() 42 """ + from combinat import catalan_number return catalan_number(self._size) def __iter__(self): @@ -1352,7 +2765,7 @@ def __iter__(self): @lazy_attribute def _parent_for(self): """ - The parent of the element generated by ``self`` + The parent of the elements generated by ``self``. TESTS:: @@ -1400,13 +2813,105 @@ def _element_constructor_(self, *args, **keywords): class LabelledBinaryTree(AbstractLabelledClonableTree, BinaryTree): """ - The class of labelled binary tree + Labelled binary trees. + + A labelled binary tree is a binary tree (see :class:`BinaryTree` for + the meaning of this) with a label assigned to each node. + The labels need not be integers, nor are they required to be distinct. + ``None`` can be used as a label. + + .. WARNING:: + + While it is possible to assign values to leaves (not just nodes) + using this class, these labels are disregarded by various + methods such as + :meth:`~sage.combinat.abstract_tree.AbstractLabelledTree.labels`, + :meth:`~sage.combinat.abstract_tree.AbstractLabelledTree.map_labels`, + and (ironically) + :meth:`~sage.combinat.abstract_tree.AbstractLabelledTree.leaf_labels`. + + INPUT: + + - ``children`` -- ``None`` (default) or a list, tuple or iterable of + length `2` of labelled binary trees or convertible objects. This + corresponds to the standard recursive definition of a labelled + binary tree as being either a leaf, or a pair of: + + - a pair of labelled binary trees, + - and a label. + + (The label is specified in the keyword variable ``label``; see + below.) - EXAMPLE:: + Syntactic sugar allows leaving out all but the outermost calls + of the ``LabelledBinaryTree()`` constructor, so that, e. g., + ``LabelledBinaryTree([LabelledBinaryTree(None),LabelledBinaryTree(None)])`` + can be shortened to ``LabelledBinaryTree([None,None])``. However, + using this shorthand, it is impossible to label any vertex of + the tree other than the root (because there is no way to pass a + ``label`` variable without calling ``LabelledBinaryTree`` + explicitly). + + It is also allowed to abbreviate ``[None, None]`` by ``[]`` if + one does not want to label the leaves (which one should not do + anyway!). + + - ``label`` -- (default: ``None``) the label to be put on the root + of this tree. + + - ``check`` -- (default: ``True``) whether checks should be + performed or not. + + .. TODO:: + + It is currently not possible to use ``LabelledBinaryTree()`` + as a shorthand for ``LabelledBinaryTree(None)`` (in analogy to + similar syntax in the ``BinaryTree`` class). + + EXAMPLES:: + + sage: LabelledBinaryTree(None) + . + sage: LabelledBinaryTree(None, label="ae") # not well supported + 'ae' + sage: LabelledBinaryTree([]) + None[., .] + sage: LabelledBinaryTree([], label=3) # not well supported + 3[., .] + sage: LabelledBinaryTree([None, None]) + None[., .] + sage: LabelledBinaryTree([None, None], label=5) + 5[., .] + sage: LabelledBinaryTree([None, []]) + None[., None[., .]] + sage: LabelledBinaryTree([None, []], label=4) + 4[., None[., .]] + sage: LabelledBinaryTree([[], None]) + None[None[., .], .] + sage: LabelledBinaryTree("[[], .]", label=False) + False[None[., .], .] + sage: LabelledBinaryTree([None, LabelledBinaryTree([None, None], label=4)], label=3) + 3[., 4[., .]] + sage: LabelledBinaryTree([None, BinaryTree([None, None])], label=3) + 3[., None[., .]] + + sage: LabelledBinaryTree([[], None, []]) + Traceback (most recent call last): + ... + ValueError: this is not a binary tree sage: LBT = LabelledBinaryTree sage: t1 = LBT([[LBT([], label=2), None], None], label=4); t1 4[None[2[., .], .], .] + + TESTS:: + + sage: t1 = LabelledBinaryTree([[None, [[],[[], None]]],[[],[]]]) + sage: t2 = LabelledBinaryTree([[[],[]],[]]) + sage: with t1.clone() as t1c: + ....: t1c[1,1,1] = t2 + sage: t1 == t1c + False """ __metaclass__ = ClasscallMetaclass @@ -1414,7 +2919,7 @@ class LabelledBinaryTree(AbstractLabelledClonableTree, BinaryTree): def __classcall_private__(cls, *args, **opts): """ Ensure that trees created by the sets and directly are the same and - that they are instances of :class:`LabelledTree` + that they are instances of :class:`LabelledTree`. TESTS:: @@ -1431,7 +2936,7 @@ def __classcall_private__(cls, *args, **opts): @lazy_class_attribute def _auto_parent(cls): """ - The automatic parent of the element of this class + The automatic parent of the elements of this class. When calling the constructor of an element of this class, one needs a parent. This class attribute specifies which parent is used. @@ -1442,7 +2947,7 @@ def _auto_parent(cls): Labelled binary trees sage: LabelledBinaryTree([], label = 3).parent() Labelled binary trees - """ + """ return LabelledBinaryTrees() def _repr_(self): @@ -1465,16 +2970,79 @@ def _repr_(self): def binary_search_insert(self, letter): """ - Insert a letter in a binary search tree + Return the result of inserting a letter ``letter`` into the + right strict binary search tree ``self``. INPUT: - - ``letter`` -- any object comparable with the label of ``self`` + - ``letter`` -- any object comparable with the labels of ``self`` - .. NOTE:: ``self`` is supposed to be a binary search tree. No check is - performed. + OUTPUT: - EXAMPLES:: + The right strict binary search tree ``self`` with ``letter`` + inserted into it according to the binary search insertion + algorithm. + + .. NOTE:: ``self`` is supposed to be a binary search tree. + This is not being checked! + + A right strict binary search tree is defined to be a labelled + binary tree such that for each node `n` with label `x`, + every descendant of the left child of `n` has a label `\leq x`, + and every descendant of the right child of `n` has a label + `> x`. (Here, only nodes count as descendants, and every node + counts as its own descendant too.) Leaves are assumed to have + no labels. + + Given a right strict binary search tree `t` and a letter `i`, + the result of inserting `i` into `t` (denoted `Ins(i, t)` in + the following) is defined recursively as follows: + + - If `t` is empty, then `Ins(i, t)` is the tree with one node + only, and this node is labelled with `i`. + + - Otherwise, let `j` be the label of the root of `t`. If + `i > j`, then `Ins(i, t)` is obtained by replacing the + right child of `t` by `Ins(i, r)` in `t`, where `r` denotes + the right child of `t`. If `i \leq j`, then `Ins(i, t)` is + obtained by replacing the left child of `t` by `Ins(i, l)` + in `t`, where `l` denotes the left child of `t`. + + See, for example, [HNT05]_ for properties of this algorithm. + + .. WARNING:: + + If `t` is nonempty, then inserting `i` into `t` does not + change the root label of `t`. Hence, as opposed to + algorithms like Robinson-Schensted-Knuth, binary + search tree insertion involves no bumping. + + EXAMPLES: + + The example from Fig. 2 of [HNT05]_:: + + sage: LBT = LabelledBinaryTree + sage: x = LBT(None) + sage: x + . + sage: x = x.binary_search_insert("b"); x + b[., .] + sage: x = x.binary_search_insert("d"); x + b[., d[., .]] + sage: x = x.binary_search_insert("e"); x + b[., d[., e[., .]]] + sage: x = x.binary_search_insert("a"); x + b[a[., .], d[., e[., .]]] + sage: x = x.binary_search_insert("b"); x + b[a[., b[., .]], d[., e[., .]]] + sage: x = x.binary_search_insert("d"); x + b[a[., b[., .]], d[d[., .], e[., .]]] + sage: x = x.binary_search_insert("a"); x + b[a[a[., .], b[., .]], d[d[., .], e[., .]]] + sage: x = x.binary_search_insert("c"); x + b[a[a[., .], b[., .]], d[d[c[., .], .], e[., .]]] + + Other examples:: sage: LBT = LabelledBinaryTree sage: LBT(None).binary_search_insert(3) @@ -1485,7 +3053,7 @@ def binary_search_insert(self, letter): 3[1[., .], .] sage: res = LBT(None) sage: for i in [3,1,5,2,4,6]: - ... res = res.binary_search_insert(i) + ....: res = res.binary_search_insert(i) sage: res 3[1[., 2[., .]], 5[4[., .], 6[., .]]] """ @@ -1500,13 +3068,280 @@ def binary_search_insert(self, letter): fils = self[1].binary_search_insert(letter) return LT([self[0], fils], label=self.label()) + def semistandard_insert(self, letter): + """ + Return the result of inserting a letter ``letter`` into the + semistandard tree ``self`` using the bumping algorithm. + + INPUT: + + - ``letter`` -- any object comparable with the labels of ``self`` + + OUTPUT: + + The semistandard tree ``self`` with ``letter`` inserted into it + according to the bumping algorithm. + + .. NOTE:: ``self`` is supposed to be a semistandard tree. + This is not being checked! + + A semistandard tree is defined to be a labelled binary tree + such that for each node `n` with label `x`, every descendant of + the left child of `n` has a label `> x`, and every descendant + of the right child of `n` has a label `\geq x`. (Here, only + nodes count as descendants, and every node counts as its own + descendant too.) Leaves are assumed to have no labels. + + Given a semistandard tree `t` and a letter `i`, the result of + inserting `i` into `t` (denoted `Ins(i, t)` in the following) + is defined recursively as follows: + + - If `t` is empty, then `Ins(i, t)` is the tree with one node + only, and this node is labelled with `i`. + + - Otherwise, let `j` be the label of the root of `t`. If + `i \geq j`, then `Ins(i, t)` is obtained by replacing the + right child of `t` by `Ins(i, r)` in `t`, where `r` denotes + the right child of `t`. If `i < j`, then `Ins(i, t)` is + obtained by replacing the label at the root of `t` by `i`, + and replacing the left child of `t` by `Ins(j, l)` + in `t`, where `l` denotes the left child of `t`. + + This algorithm is similar to the Robinson-Schensted-Knuth + insertion algorithm for semistandard Young tableaux. + + AUTHORS: + + - Darij Grinberg (10 Nov 2013). + + EXAMPLES:: + + sage: LBT = LabelledBinaryTree + sage: x = LBT(None) + sage: x + . + sage: x = x.semistandard_insert("b"); x + b[., .] + sage: x = x.semistandard_insert("d"); x + b[., d[., .]] + sage: x = x.semistandard_insert("e"); x + b[., d[., e[., .]]] + sage: x = x.semistandard_insert("a"); x + a[b[., .], d[., e[., .]]] + sage: x = x.semistandard_insert("b"); x + a[b[., .], b[d[., .], e[., .]]] + sage: x = x.semistandard_insert("d"); x + a[b[., .], b[d[., .], d[e[., .], .]]] + sage: x = x.semistandard_insert("a"); x + a[b[., .], a[b[d[., .], .], d[e[., .], .]]] + sage: x = x.semistandard_insert("c"); x + a[b[., .], a[b[d[., .], .], c[d[e[., .], .], .]]] + + Other examples:: + + sage: LBT = LabelledBinaryTree + sage: LBT(None).semistandard_insert(3) + 3[., .] + sage: LBT([], label = 1).semistandard_insert(3) + 1[., 3[., .]] + sage: LBT([], label = 3).semistandard_insert(1) + 1[3[., .], .] + sage: res = LBT(None) + sage: for i in [3,1,5,2,4,6]: + ....: res = res.semistandard_insert(i) + sage: res + 1[3[., .], 2[5[., .], 4[., 6[., .]]]] + """ + LT = self.parent()._element_constructor_ + if not self: + return LT([], label = letter) + else: + root_label = self.label() + if letter < root_label: + fils = self[0].semistandard_insert(root_label) + return LT([fils, self[1]], label=letter) + else: + fils = self[1].semistandard_insert(letter) + return LT([self[0], fils], label=root_label) + + def right_rotate(self): + r""" + Return the result of right rotation applied to the labelled + binary tree ``self``. + + Right rotation on labelled binary trees is defined as + follows: Let `T` be a labelled binary tree such that the + left child of the root of `T` is a node. Let + `C` be the right child of the root of `T`, and let `A` + and `B` be the left and right children of the left child + of the root of `T`. (Keep in mind that nodes of trees are + identified with the subtrees consisting of their + descendants.) Furthermore, let `y` be the label at the + root of `T`, and `x` be the label at the left child of the + root of `T`. + Then, the right rotation of `T` is the labelled binary + tree in which the root is labelled `x`, the left child of + the root is `A`, whereas the right child of the root is a + node labelled `y` whose left and right children are `B` + and `C`. In pictures:: + + | y x | + | / \ / \ | + | x C -right-rotate-> A y | + | / \ / \ | + | A B B C | + + Right rotation is the inverse operation to left rotation + (:meth:`left_rotate`). + + TESTS:: + + sage: LB = LabelledBinaryTree + sage: b = LB([LB([LB([],"A"), LB([],"B")],"x"),LB([],"C")], "y"); b + y[x[A[., .], B[., .]], C[., .]] + sage: b.right_rotate() + x[A[., .], y[B[., .], C[., .]]] + """ + B = self.parent()._element_constructor_ + s0 = self[0] + return B([s0[0], B([s0[1], self[1]], self.label())], s0.label()) + + def left_rotate(self): + r""" + Return the result of left rotation applied to the labelled + binary tree ``self``. + + Left rotation on labelled binary trees is defined as + follows: Let `T` be a labelled binary tree such that the + right child of the root of `T` is a node. Let + `A` be the left child of the root of `T`, and let `B` + and `C` be the left and right children of the right child + of the root of `T`. (Keep in mind that nodes of trees are + identified with the subtrees consisting of their + descendants.) Furthermore, let `x` be the label at the + root of `T`, and `y` be the label at the right child of the + root of `T`. + Then, the left rotation of `T` is the labelled binary tree + in which the root is labelled `y`, the right child of the + root is `C`, whereas the left child of the root is a node + labelled `x` whose left and right children are `A` and `B`. + In pictures:: + + | y x | + | / \ / \ | + | x C <-left-rotate- A y | + | / \ / \ | + | A B B C | + + Left rotation is the inverse operation to right rotation + (:meth:`right_rotate`). + + TESTS:: + + sage: LB = LabelledBinaryTree + sage: b = LB([LB([LB([],"A"), LB([],"B")],"x"),LB([],"C")], "y"); b + y[x[A[., .], B[., .]], C[., .]] + sage: b == b.right_rotate().left_rotate() + True + """ + B = self.parent()._element_constructor_ + s1 = self[1] + return B([B([self[0], s1[0]], self.label()), s1[1]], s1.label()) + + def heap_insert(self, l): + r""" + Return the result of inserting a letter ``l`` into the binary + heap (tree) ``self``. + + A binary heap is a labelled complete binary tree such that for + each node, the label at the node is greater or equal to the + label of each of its child nodes. (More precisely, this is + called a max-heap.) + + For example:: + + | _7_ | + | / \ | + | 5 6 | + | / \ | + | 3 4 | + + is a binary heap. + + See :wikipedia:`Binary_heap#Insert` for a description of how to + insert a letter into a binary heap. The result is another binary + heap. + + INPUT: + + - ``letter`` -- any object comparable with the labels of ``self`` + + .. NOTE:: + + ``self`` is assumed to be a binary heap (tree). No check is + performed. + + TESTS:: + + sage: h = LabelledBinaryTree(None) + sage: h = h.heap_insert(3); ascii_art([h]) + [ 3 ] + sage: h = h.heap_insert(4); ascii_art([h]) + [ 4 ] + [ / ] + [ 3 ] + sage: h = h.heap_insert(6); ascii_art([h]) + [ 6 ] + [ / \ ] + [ 3 4 ] + sage: h = h.heap_insert(2); ascii_art([h]) + [ 6 ] + [ / \ ] + [ 3 4 ] + [ / ] + [ 2 ] + sage: ascii_art([h.heap_insert(5)]) + [ _6_ ] + [ / \ ] + [ 5 4 ] + [ / \ ] + [ 2 3 ] + """ + B = self.parent()._element_constructor_ + if self.is_empty(): + return B([], l) + + if self.label() < l: + label_root = l + label_insert = self.label() + else: + label_root = self.label() + label_insert = l + L, R = self + dL = L.depth() + dR = R.depth() + # if depth of L is greater than the depth of R + if dL > dR: + # if L is perfect we insert in R + if L.is_perfect(): + return B([L, R.heap_insert(label_insert)], label_root) + # we insert in L + return B([L.heap_insert(label_insert), R], label_root) + # else ==> dL == dR + # if R is perfect we have to insert on the leftmost leaf + if R.is_perfect(): + # ## TODO:: can be optimized... + return B([L.heap_insert(label_insert), R], label_root) + # else we insert on the right + return B([L, R.heap_insert(label_insert)], label_root) + _UnLabelled = BinaryTree class LabelledBinaryTrees(LabelledOrderedTrees): """ This is a parent stub to serve as a factory class for trees with various - labels constraints + labels constraints. """ def _repr_(self): """ @@ -1519,7 +3354,7 @@ def _repr_(self): def _an_element_(self): """ - Return a labelled binary tree + Return a labelled binary tree. EXAMPLE:: @@ -1534,7 +3369,7 @@ def _an_element_(self): def unlabelled_trees(self): """ - Return the set of unlabelled trees associated to ``self`` + Return the set of unlabelled trees associated to ``self``. EXAMPLES:: @@ -1558,7 +3393,7 @@ def unlabelled_trees(self): def labelled_trees(self): """ - Return the set of labelled trees associated to ``self`` + Return the set of labelled trees associated to ``self``. EXAMPLES:: @@ -1592,7 +3427,7 @@ def labelled_trees(self): # sage: BTsp_to_bintrees(BT.isotypes(range(5))[0]) # [., [., [., [., [., .]]]]] # sage: def spls(size): -# ... return map(BTsp_to_bintrees, BT.isotypes(range(size)).list()) +# ....: return map(BTsp_to_bintrees, BT.isotypes(range(size)).list()) # sage: spls(3) # [[., [., [., .]]], [., [[., .], .]], [[., .], [., .]], [[., [., .]], .], [[[., .], .], .]] # sage: all(spls(i) == BinaryTrees(i).list() for i in range(5)) diff --git a/src/sage/combinat/cluster_algebra_quiver/mutation_class.py b/src/sage/combinat/cluster_algebra_quiver/mutation_class.py index 175d9fb94af..cebf5f9e9ed 100644 --- a/src/sage/combinat/cluster_algebra_quiver/mutation_class.py +++ b/src/sage/combinat/cluster_algebra_quiver/mutation_class.py @@ -507,6 +507,6 @@ def _is_valid_digraph_edge_set( edges, frozen=0 ): return False return True - except StandardError: + except Exception: print "Could not even build a digraph from the input data." return False 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..f3c6ea3f2ef 100644 --- a/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py +++ b/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py @@ -2212,7 +2212,7 @@ def _is_mutation_type( data ): try: QuiverMutationType( data ) return True - except StandardError: + except Exception: return False def _mutation_type_error( data ): diff --git a/src/sage/combinat/composition.py b/src/sage/combinat/composition.py index ca28259ebf1..de42bc2ede4 100644 --- a/src/sage/combinat/composition.py +++ b/src/sage/combinat/composition.py @@ -195,18 +195,35 @@ def __setstate__(self, state): self._set_parent(state[0]) self.__dict__ = state[1] - @combinatorial_map(name='conjugate') + @combinatorial_map(order=2, name='conjugate') def conjugate(self): r""" Return the conjugate of the composition ``self``. - Algorithm from mupad-combinat. + The conjugate of a composition `I` is defined as the + complement (see :meth:`complement`) of the reverse composition + (see :meth:`reversed`) of `I`. + + An equivalent definition of the conjugate goes by saying that + the ribbon shape of the conjugate of a composition `I` is the + conjugate of the ribbon shape of `I`. (The ribbon shape of a + composition is returned by :meth:`to_skew_partition`.) + + This implementation uses the algorithm from mupad-combinat. EXAMPLES:: sage: Composition([1, 1, 3, 1, 2, 1, 3]).conjugate() [1, 1, 3, 3, 1, 3] + The ribbon shape of the conjugate of `I` is the conjugate of + the ribbon shape of `I`:: + + sage: all( I.conjugate().to_skew_partition() + ....: == I.to_skew_partition().conjugate() + ....: for I in Compositions(4) ) + True + TESTS:: sage: parent(list(Compositions(1))[0].conjugate()) @@ -227,11 +244,14 @@ def conjugate(self): return self.parent()([cocjg[0]] + [cocjg[i]-cocjg[i-1]+1 for i in range(1,len(cocjg))]) - @combinatorial_map(name='reversed') + @combinatorial_map(order=2, name='reversed') def reversed(self): - """ + r""" Return the reverse composition of ``self``. + The reverse composition of a composition `(i_1, i_2, \ldots, i_k)` + is defined as the composition `(i_k, i_{k-1}, \ldots, i_1)`. + EXAMPLES:: sage: Composition([1, 1, 3, 1, 2, 1, 3]).reversed() @@ -239,11 +259,25 @@ def reversed(self): """ return self.parent()(reversed(self)) - @combinatorial_map(name = 'complement') + @combinatorial_map(order=2, name='complement') def complement(self): - """ - Return the complement composition of ``self``. The complement is the - reverse of the conjugate composition of ``self``. + r""" + Return the complement of the composition ``self``. + + The complement of a composition `I` is defined as follows: + + If `I` is the empty composition, then the complement is the empty + composition as well. Otherwise, let `S` be the descent set of `I` + (that is, the subset + `\{ i_1, i_1 + i_2, \ldots, i_1 + i_2 + \cdots + i_{k-1} \}` + of `\{ 1, 2, \ldots, |I|-1 \}`, where `I` is written as + `(i_1, i_2, \ldots, i_k)`). Then, the complement of `I` is + defined as the composition of size `|I|` whose descent set is + `\{ 1, 2, \ldots, |I|-1 \} \setminus S`. + + The complement of a composition `I` also is the reverse + composition (:meth:`reversed`) of the conjugate + (:meth:`conjugate`) of `I`. EXAMPLES:: @@ -268,7 +302,7 @@ def __add__(self, other): sage: Composition([]) + Composition([]) == Composition([]) True """ - return Composition(list(self)+list(other)) + return Compositions()(list(self)+list(other)) def size(self): """ @@ -305,7 +339,7 @@ def sum(compositions): sage: Composition.sum([]) == Composition([]) True """ - return sum(compositions, Composition([])) + return sum(compositions, Compositions()([])) def near_concatenation(self, other): r""" @@ -341,7 +375,7 @@ def near_concatenation(self, other): """ if len(self) == 0 or len(other) == 0: return None - return Composition(list(self)[:-1] + [self[-1] + other[0]] + list(other)[1:]) + return Compositions()(list(self)[:-1] + [self[-1] + other[0]] + list(other)[1:]) def ribbon_decomposition(self, other, check=True): r""" @@ -422,13 +456,6 @@ def ribbon_decomposition(self, other, check=True): ... ValueError: [3, 1, 1, 3, 1] is not the same size as [4, 3, 1] - REFERENCES: - - .. [NCSF1] Israel Gelfand, D. Krob, Alain Lascoux, B. Leclerc, - V. S. Retakh, J.-Y. Thibon, - *Noncommutative symmetric functions*. - :arxiv:`hep-th/9407124v1` - AUTHORS: - Darij Grinberg (2013-08-29) @@ -452,7 +479,7 @@ def ribbon_decomposition(self, other, check=True): try: i = I_iter.next() except StopIteration: - factors.append(Composition(current_factor)) + factors.append(Compositions()(current_factor)) return (tuple(factors), tuple(signs)) if current_factor_size + i <= j: current_factor.append(i) @@ -465,7 +492,7 @@ def ribbon_decomposition(self, other, check=True): current_factor.append(j - current_factor_size) i -= j - current_factor_size signs.append(1) - factors.append(Composition(current_factor)) + factors.append(Compositions()(current_factor)) break return (tuple(factors), tuple(signs)) @@ -584,7 +611,7 @@ def join(self, other, check=True): try: i = I_iter.next() except StopIteration: - return Composition(factors) + return Compositions()(factors) if current_factor_size + i <= j: factors.append(i) current_factor_size += i @@ -595,7 +622,7 @@ def join(self, other, check=True): i -= j - current_factor_size break - return Composition(factors) + return Compositions()(factors) sup = join @@ -705,7 +732,7 @@ def meet(self, other, check=True): i = I_iter.next() except StopIteration: factors.append(current_part) - return Composition(factors) + return Compositions()(factors) if current_factor_size + i <= j: current_part += i current_factor_size += i @@ -719,7 +746,7 @@ def meet(self, other, check=True): current_part += j - current_factor_size break - return Composition(factors) + return Compositions()(factors) inf = meet @@ -816,7 +843,7 @@ def fatten(self, grouping): for i in range(len(grouping)): result[i] = sum(self[j:j+grouping[i]]) j += grouping[i] - return Composition(result) + return Compositions()(result) def fatter(self): """ @@ -894,7 +921,7 @@ def refinement_splitting(self, J): sum1 += new_comp[-1] if sum1 > sum2: raise ValueError("composition J (= %s) does not refine self (= %s)"%(I, J)) - decomp.append(Composition(new_comp)) + decomp.append(Compositions()(new_comp)) return decomp def refinement_splitting_lengths(self, J): @@ -921,7 +948,7 @@ def refinement_splitting_lengths(self, J): ... ValueError: composition J (= [2, 1]) does not refine self (= [1, 2]) """ - return Composition(map(len,self.refinement_splitting(J))) + return Compositions()(map(len,self.refinement_splitting(J))) refinement = deprecated_function_alias(13243, refinement_splitting_lengths) @@ -1685,6 +1712,11 @@ def from_subset(self, S, n): sage: Compositions().from_subset({2,1,5,9}, 12) [1, 1, 3, 4, 3] + sage: Compositions().from_subset([], 12) + [12] + sage: Compositions().from_subset([], 0) + [] + TESTS:: sage: Compositions().from_subset([2,1,5,9],9) diff --git a/src/sage/combinat/crystals/tensor_product.py b/src/sage/combinat/crystals/tensor_product.py index 4753f677d7e..d39b8d1ebf7 100644 --- a/src/sage/combinat/crystals/tensor_product.py +++ b/src/sage/combinat/crystals/tensor_product.py @@ -1545,7 +1545,7 @@ def __classcall_private__(cls, cartan_type, shapes = None, shape = None): spin_shapes = tuple( tuple(shape) for shape in shapes ) try: shapes = tuple( tuple(trunc(i) for i in shape) for shape in spin_shapes ) - except StandardError: + except Exception: raise ValueError("shapes should all be partitions or half-integer partitions") if spin_shapes == shapes: return super(CrystalOfTableaux, cls).__classcall__(cls, cartan_type, shapes) diff --git a/src/sage/combinat/designs/block_design.py b/src/sage/combinat/designs/block_design.py index 6916bdb4d86..ab07d3472dc 100644 --- a/src/sage/combinat/designs/block_design.py +++ b/src/sage/combinat/designs/block_design.py @@ -89,7 +89,7 @@ def ProjectiveGeometryDesign(n, d, F, algorithm=None): A projective geometry design of parameters `n,d,F` has for points the lines of `F^{n+1}`, and for blocks the `d+1`-dimensional subspaces of `F^{n+1}`, - each of which contains `\frac {|F|^{d+1}-1} {|F|-1}` lines. + each of which contains `\\frac {|F|^{d+1}-1} {|F|-1}` lines. INPUT: @@ -107,8 +107,8 @@ def ProjectiveGeometryDesign(n, d, F, algorithm=None): EXAMPLES: - The points of the following design are the `\frac {2^{2+1}-1} {2-1}=7` lines - of `\mathbb{Z}_2^{2+1}`. It has `7` blocks, corresponding to each + The points of the following design are the `\\frac {2^{2+1}-1} {2-1}=7` + lines of `\mathbb{Z}_2^{2+1}`. It has `7` blocks, corresponding to each 2-dimensional subspace of `\mathbb{Z}_2^{2+1}`:: sage: designs.ProjectiveGeometryDesign(2, 1, GF(2)) @@ -247,20 +247,26 @@ def AffineGeometryDesign(n, d, F): EXAMPLES:: sage: BD = designs.AffineGeometryDesign(3, 1, GF(2)) - sage: BD.parameters() + sage: BD.parameters(t=2) (2, 8, 2, 1) sage: BD.is_block_design() (True, [2, 8, 2, 1]) sage: BD = designs.AffineGeometryDesign(3, 2, GF(2)) - sage: BD.parameters() - (2, 8, 4, 3) + sage: BD.parameters(t=3) + (3, 8, 4, 1) sage: BD.is_block_design() (True, [3, 8, 4, 1]) + A 3-design:: + + sage: D = IncidenceStructure(range(32),designs.steiner_quadruple_system(32)) + sage: D.is_block_design() + (True, [3, 32, 4, 1]) + With an integer instead of a Finite Field:: sage: BD = designs.AffineGeometryDesign(3, 2, 4) - sage: BD.parameters() + sage: BD.parameters(t=2) (2, 64, 16, 5) """ try: @@ -301,14 +307,14 @@ def WittDesign(n): EXAMPLES:: sage: BD = designs.WittDesign(9) # optional - gap_packages (design package) - sage: BD.parameters() # optional - gap_packages (design package) + sage: BD.is_block_design() # optional - gap_packages (design package) (2, 9, 3, 1) sage: BD # optional - gap_packages (design package) Incidence structure with 9 points and 12 blocks sage: print BD # optional - gap_packages (design package) WittDesign sage: BD = designs.WittDesign(12) # optional - gap_packages (design package) - sage: BD.parameters(t=5) # optional - gap_packages (design package) + sage: BD.is_block_design() # optional - gap_packages (design package) (5, 12, 6, 1) """ from sage.interfaces.gap import gap, GapElement @@ -383,7 +389,7 @@ def steiner_triple_system(n): As any pair of vertices is covered once, its parameters are :: - sage: sts.parameters() + sage: sts.parameters(t=2) (2, 9, 3, 1) An exception is raised for invalid values of ``n`` :: @@ -455,7 +461,7 @@ def BlockDesign(max_pt, blks, name=None, test=True): if not(test): return BD else: - pars = BD.parameters() + pars = BD.parameters(t=2) if BD.block_design_checker(pars[0],pars[1],pars[2],pars[3]): return BD else: diff --git a/src/sage/combinat/designs/ext_rep.py b/src/sage/combinat/designs/ext_rep.py index 13ae27f00d6..8feac581c20 100644 --- a/src/sage/combinat/designs/ext_rep.py +++ b/src/sage/combinat/designs/ext_rep.py @@ -1010,7 +1010,7 @@ def designs_from_XML(fname): sage: d = BlockDesign(v, blocks) sage: d.blocks() [[0, 1], [0, 1]] - sage: d.parameters() + sage: d.parameters(t=2) (2, 2, 2, 2) """ diff --git a/src/sage/combinat/designs/incidence_structures.py b/src/sage/combinat/designs/incidence_structures.py index 1edaafc840c..0bc6a32633e 100644 --- a/src/sage/combinat/designs/incidence_structures.py +++ b/src/sage/combinat/designs/incidence_structures.py @@ -66,7 +66,6 @@ def coordinatewise_product(L): ans = [ans[i]*x[i] for i in range(n)] return ans - def IncidenceStructureFromMatrix(M, name=None): """ Builds and incidence structure from a matrix. @@ -157,7 +156,7 @@ def __init__(self, pts, blks, inc_mat=None, name=None, test=True): y = block[:] y.sort() bs.append(y) - except StandardError: + except Exception: bs.append(block) bs.sort(cmp) self.v = v @@ -284,8 +283,8 @@ def block_design_checker(self, t, v, k, lmbda, type=None): sage: from sage.combinat.designs.block_design import BlockDesign sage: BD = BlockDesign(7,[[0,1,2],[0,3,4],[0,5,6],[1,3,5],[1,4,6],[2,3,6],[2,4,5]]) - sage: BD.parameters() - (2, 7, 3, 1) + sage: BD.is_block_design() + (True, [2, 7, 3, 1]) sage: BD.block_design_checker(2, 7, 3, 1) True sage: BD.block_design_checker(2, 7, 3, 1,"binary") @@ -533,60 +532,81 @@ def is_block_design(self): sage: BD.is_block_design() (True, [2, 8, 2, 1]) """ - from sage.combinat.designs.incidence_structures import coordinatewise_product - from sage.combinat.combination import Combinations - A = self.incidence_matrix() + from sage.rings.arith import binomial + from itertools import combinations v = len(self.points()) - b = len(self.blocks()) - k = sum(A.columns()[0]) - rowsA = A.rows() - VS = rowsA[0].parent() - r = sum(rowsA[0]) - for i in range(b): - if not(sum(A.columns()[i]) == k): - return False - for i in range(v): - if not(sum(A.rows()[i]) == r): + b = len(self.blcks) + + # Definition and consistency of 'k' and 'r' + # + # r_list stores the degree of each point + k = len(self.blcks[0]) + r_list = [0]*v + for block in self.blcks: + if len(block) != k: return False + for x in block: + r_list[x] += 1 + + r = r_list[0] + if any(x!=r for x in r_list): + return False + + # Definition and consistency of 'l' (lambda) and 't' t_found_yet = False - lambdas = [] - for t in range(2, min(v, 11)): - #print t - L1 = Combinations(range(v), t) - L2 = [[rowsA[i] for i in L] for L in L1] - #print t,len(L2) - lmbda = VS(coordinatewise_product(L2[0])).hamming_weight() - lambdas.append(lmbda) - pars = [t, v, k, lmbda] - #print pars - for ell in L2: - a = VS(coordinatewise_product(ell)).hamming_weight() - if not(a == lmbda) or a == 0: - if not(t_found_yet): - pars = [t-1, v, k, lambdas[t-3]] - return False, pars - else: - #print pars, lambdas - pars = [t-1, v, k, lambdas[t-3]] - return True, pars + + for t in range(2,min(v,k+1)): + + # Is lambda an integer ? + if (b*binomial(k,t)) % binomial(v,t) == 0: + l = (b*binomial(k,t))/binomial(v,t) + else: + continue + + # Associates to every t-subset of [v] the number of its occurrences + # as a subset of a block + t_counts = {} + for block in self.blcks: + for t_set in combinations(sorted(block),t): + t_counts[t_set] = t_counts.get(t_set,0)+1 + + # Checking the consistency of l + l_values = t_counts.values() + + if all(l == x for x in l_values): t_found_yet = True - pars = [t-1, v, k, lambdas[t-3]] - return True, pars + t_lambda = t,l - def parameters(self, t=2): + if t_found_yet: + t,l = t_lambda + return (True, [t,v,k,l]) + else: + return (False, [0,0,0,0]) + + def parameters(self, t=None): """ Returns `(t,v,k,lambda)`. Does not check if the input is a block - design. Uses `t=2` by default. + design. + + INPUT: + + - ``t`` -- `t` such that the design is a `t`-design. EXAMPLES:: sage: from sage.combinat.designs.block_design import BlockDesign sage: BD = BlockDesign(7,[[0,1,2],[0,3,4],[0,5,6],[1,3,5],[1,4,6],[2,3,6],[2,4,5]], name="FanoPlane") - sage: BD.parameters() + sage: BD.parameters(t=2) (2, 7, 3, 1) sage: BD.parameters(t=3) (3, 7, 3, 0) """ + if t is None: + from sage.misc.superseded import deprecation + deprecation(15664, "the 't' argument will become mandatory soon. 2"+ + " is used when none is provided.") + t = 2 + v = len(self.points()) blks = self.blocks() k = len(blks[int(0)]) diff --git a/src/sage/combinat/free_module.py b/src/sage/combinat/free_module.py index d48d751a8e0..b532ce61aba 100644 --- a/src/sage/combinat/free_module.py +++ b/src/sage/combinat/free_module.py @@ -157,7 +157,7 @@ def _sorted_items_for_printing(self): try: v.sort(cmp = print_options['monomial_cmp'], key = lambda (monomial,coeff): monomial) - except StandardError: # Sorting the output is a plus, but if we can't, no big deal + except Exception: # Sorting the output is a plus, but if we can't, no big deal pass return v @@ -1369,13 +1369,13 @@ def _an_element_(self): R = self.base_ring() try: x = x + self.monomial(I.an_element()) - except StandardError: + except Exception: pass try: g = iter(self.basis().keys()) for c in range(1,4): x = x + self.term(g.next(), R(c)) - except (StandardError, StopIteration): + except Exception: pass return x @@ -1885,7 +1885,7 @@ def _ascii_art_term(self, el): try: if el == self.one_basis(): return AsciiArt(["1"]) - except StandardError: + except Exception: pass pref = AsciiArt([self.prefix()]) r = pref * (AsciiArt([" "**Integer(len(pref))]) + ascii_art(el)) diff --git a/src/sage/combinat/integer_vector.py b/src/sage/combinat/integer_vector.py index 7d66fecc120..e4a1e6bfcc5 100644 --- a/src/sage/combinat/integer_vector.py +++ b/src/sage/combinat/integer_vector.py @@ -1018,7 +1018,7 @@ def rank(self, x): TESTS:: - sage: IV = IntegerVectors(4,5) + sage: IV = IntegerVectors(4,5) sage: range(IV.cardinality()) == [IV.rank(x) for x in IV] True """ @@ -1030,9 +1030,9 @@ def rank(self, x): r = 0 for i in range(k-1): - k -= 1 - n -= x[i] - r += binomial(k+n-1,k) + k -= 1 + n -= x[i] + r += binomial(k+n-1,k) return r diff --git a/src/sage/combinat/integer_vectors_mod_permgroup.py b/src/sage/combinat/integer_vectors_mod_permgroup.py index 5553f4e28a4..186af926856 100644 --- a/src/sage/combinat/integer_vectors_mod_permgroup.py +++ b/src/sage/combinat/integer_vectors_mod_permgroup.py @@ -455,7 +455,7 @@ def __contains__(self, v): """ try: return self.is_canonical(self.element_class(self, list(v), check=False), check=False) - except StandardError: + except Exception: return False def __call__(self, v, check=True): @@ -474,7 +474,7 @@ def __call__(self, v, check=True): return v else: raise ValueError, '%s shoud be a Python list of integer'%(v) - except StandardError: + except Exception: return self.element_class(self, list(v), check=check) def orbit(self, v): @@ -505,7 +505,7 @@ def orbit(self, v): if v.parent() is self: return orbit(self._sgs, v) raise TypeError - except StandardError: + except Exception: return orbit(self._sgs, self.element_class(self, v, check=False)) def subset(self, sum=None, max_part=None): @@ -698,7 +698,7 @@ def __contains__(self, v): """ try: return (self(v)).parent() is self - except StandardError: + except Exception: return False def __call__(self, v, check=True): @@ -720,7 +720,7 @@ def __call__(self, v, check=True): return v else: raise ValueError, '%s shoud be a Python list of integer'%(v) - except StandardError: + except Exception: return self.element_class(self, list(v), check=check) def __iter__(self): @@ -930,7 +930,7 @@ def orbit(self, v): try: if v.parent() is self: return orbit(self._sgs, v) - except StandardError: + except Exception: return orbit(self._sgs, self.element_class(self, v, check=False)) class Element(ClonableIntArray): diff --git a/src/sage/combinat/kazhdan_lusztig.py b/src/sage/combinat/kazhdan_lusztig.py index 624b93a7030..5be8dd564f7 100644 --- a/src/sage/combinat/kazhdan_lusztig.py +++ b/src/sage/combinat/kazhdan_lusztig.py @@ -164,7 +164,7 @@ def P(self, x, y): tr = floor((y.length()-x.length()+1)/2) try: ret = p.truncate(tr) - except StandardError: + except Exception: ret = laurent_polynomial_truncate(p, tr) if self._trace: print " P(%s,%s)=%s"%(x, y, ret) diff --git a/src/sage/combinat/matrices/latin.py b/src/sage/combinat/matrices/latin.py index 9547a030035..d67d545e1b8 100644 --- a/src/sage/combinat/matrices/latin.py +++ b/src/sage/combinat/matrices/latin.py @@ -1251,14 +1251,36 @@ def tau123(T1, T2): return (cells_map, t1, t2, t3) - def isotopism(p): """ - Returns a Permutation object that represents an isotopism (for - rows, columns or symbols of a partial latin square). Since matrices - in Sage are indexed from 0, this function translates +1 to agree - with the Permutation class. We also handle - PermutationGroupElements. + Return a Permutation object that represents an isotopism (for rows, + columns or symbols of a partial latin square). + + Technically, all this function does is take as input a + representation of a permutation of `0,...,n-1` and return a + :class:`Permutation` object defined on `1,...,n`. + + For a definition of isotopism, see the :wikipedia:`wikipedia section on + isotopism `. + + INPUT: + + According to the type of input (see examples below) : + + - an integer `n` -- the function returns the identity on `1,...,n`. + + - a string representing a permutation in disjoint cycles notation, + e.g. `(0,1,2)(3,4,5)` -- the corresponding permutation is returned, + shifted by 1 to act on `1,...,n`. + + - list/tuple of tuples -- assumes disjoint cycle notation, see previous + entry. + + - a list of integers -- the function adds `1` to each member of the + list, and returns the corresponding permutation. + + - a :class:`PermutationGroupElement` ``p`` -- returns a permutation + describing ``p`` **without** any shift. EXAMPLES:: @@ -1315,7 +1337,7 @@ def isotopism(p): x = isotopism(p[0]) for i in range(1, len(p)): - x = x * isotopism(p[i]) + x = x._left_to_right_multiply_on_left(isotopism(p[i])) return x diff --git a/src/sage/combinat/ncsf_qsym/generic_basis_code.py b/src/sage/combinat/ncsf_qsym/generic_basis_code.py index 81d95c68541..378f48fd54d 100644 --- a/src/sage/combinat/ncsf_qsym/generic_basis_code.py +++ b/src/sage/combinat/ncsf_qsym/generic_basis_code.py @@ -29,7 +29,7 @@ from sage.misc.cachefunc import cached_method from sage.categories.realizations import Category_realization_of_parent from sage.categories.modules_with_basis import ModulesWithBasis, ModuleMorphismByLinearity -from sage.combinat.composition import Composition +from sage.combinat.composition import Compositions, Composition from sage.combinat.partition import Partition from sage.combinat.permutation import Permutations from sage.rings.integer import Integer @@ -114,9 +114,9 @@ def __getitem__(self, c, *rest): assert len(rest) == 0 else: if len(rest) > 0 or isinstance(c, (int, Integer)): - c = Composition([c] + list(rest)) + c = self._basis_keys([c] + list(rest)) else: - c = Composition(list(c)) + c = self._basis_keys(list(c)) return self.monomial(c) # could go to Algebras(...).Graded().Connected() or Modules(...).Graded().Connected() @@ -137,7 +137,7 @@ def one_basis(self): sage: parent(L).one_basis() [] """ - return Composition([]) + return Compositions()([]) # Combinatorial rules @@ -294,7 +294,7 @@ def sum_of_partition_rearrangements(self, par): sage: elementary.sum_of_partition_rearrangements(Partition([])) L[] """ - return self.sum_of_monomials( Composition(comp) for comp in Permutations(par) ) + return self.sum_of_monomials( self._basis_keys(comp) for comp in Permutations(par) ) def _comp_to_par(self, comp): """ @@ -680,6 +680,61 @@ def counit_on_basis(self, I): else: return self.base_ring().one() + def degree_negation(self, element): + r""" + Return the image of ``element`` under the degree negation + automorphism of ``self``. + + The degree negation is the automorphism which scales every + homogeneous element of degree `k` by `(-1)^k` (for all `k`). + + INPUT: + + - ``element`` -- element of ``self`` + + EXAMPLES:: + + sage: NSym = NonCommutativeSymmetricFunctions(ZZ) + sage: S = NSym.S() + sage: f = 2*S[2,1] + 4*S[1,1] - 5*S[1,2] - 3*S[[]] + sage: S.degree_negation(f) + -3*S[] + 4*S[1, 1] + 5*S[1, 2] - 2*S[2, 1] + + sage: QSym = QuasiSymmetricFunctions(QQ) + sage: dI = QSym.dualImmaculate() + sage: f = -3*dI[2,1] + 4*dI[2] + 2*dI[1] + sage: dI.degree_negation(f) + -2*dI[1] + 4*dI[2] + 3*dI[2, 1] + + TESTS: + + Using :meth:`degree_negation` on an element of a different + basis works correctly:: + + sage: NSym = NonCommutativeSymmetricFunctions(QQ) + sage: S = NSym.S() + sage: Phi = NSym.Phi() + sage: S.degree_negation(Phi[2]) + -S[1, 1] + 2*S[2] + sage: S.degree_negation(Phi[3]) + -S[1, 1, 1] + 3/2*S[1, 2] + 3/2*S[2, 1] - 3*S[3] + sage: Phi.degree_negation(S[3]) + -1/6*Phi[1, 1, 1] - 1/4*Phi[1, 2] - 1/4*Phi[2, 1] - 1/3*Phi[3] + + The zero element behaves well:: + + sage: a = Phi.degree_negation(S.zero()); a + 0 + sage: parent(a) + Non-Commutative Symmetric Functions over the Rational Field in the Phi basis + + .. TODO:: + + Generalize this to all graded vector spaces? + """ + return self.sum_of_terms([ (lam, (-1)**(sum(lam)%2) * a) + for lam, a in self(element) ]) + class ElementMethods: def duality_pairing(self, y): diff --git a/src/sage/combinat/ncsf_qsym/ncsf.py b/src/sage/combinat/ncsf_qsym/ncsf.py index 7f2c3ba2d81..8a48f910d88 100644 --- a/src/sage/combinat/ncsf_qsym/ncsf.py +++ b/src/sage/combinat/ncsf_qsym/ncsf.py @@ -20,7 +20,7 @@ ######################################## # TODO: -# 1. Make Coersion run faster between multiple bases. +# 1. Make Coercion run faster between multiple bases. ######################################## from sage.misc.bindable_class import BindableClass @@ -29,19 +29,21 @@ from sage.misc.misc_c import prod from sage.structure.parent import Parent from sage.structure.unique_representation import UniqueRepresentation +from sage.functions.other import factorial from sage.categories.realizations import Category_realization_of_parent from sage.categories.rings import Rings from sage.categories.graded_hopf_algebras import GradedHopfAlgebras -from sage.combinat.composition import Composition, Compositions +from sage.combinat.composition import Compositions from sage.combinat.free_module import CombinatorialFreeModule from sage.combinat.ncsf_qsym.generic_basis_code import BasesOfQSymOrNCSF -from sage.combinat.ncsf_qsym.combinatorics import * +from sage.combinat.ncsf_qsym.combinatorics import (coeff_pi, coeff_lp, + coeff_sp, coeff_ell, m_to_s_stat, number_of_fCT) from sage.combinat.partition import Partition from sage.combinat.permutation import Permutations class NonCommutativeSymmetricFunctions(UniqueRepresentation, Parent): r""" - The abstract algebra of non-commutative symmetric functions + The abstract algebra of non-commutative symmetric functions. We construct the abstract algebra of non-commutative symmetric functions over the rational numbers:: @@ -579,8 +581,8 @@ def verschiebung(self, n): \mathbf{V}_n(S_r) = S_{r/n}, \quad \mathbf{V}_n(\Lambda_r) = (-1)^{r - r/n} \Lambda_{r/n}, - \quad \mathbf{V}_n(\Psi_r) = n \Psi_r, - \quad \mathbf{V}_n(\Phi_r) = n \Phi_r + \quad \mathbf{V}_n(\Psi_r) = n \Psi_{r/n}, + \quad \mathbf{V}_n(\Phi_r) = n \Phi_{r/n} (where `S_r` denotes the `r`-th complete non-commutative symmetric function, `\Lambda_r` denotes the `r`-th elementary @@ -588,7 +590,7 @@ def verschiebung(self, n): power-sum non-commutative symmetric function of the first kind, and `\Phi_r` denotes the `r`-th power-sum non-commutative symmetric function of the second kind). For every positive - integer `r` with `n \not\mid r`, it satisfes + integer `r` with `n \nmid r`, it satisfes .. MATH:: @@ -610,11 +612,10 @@ def verschiebung(self, n): .. MATH:: \mathbf{V}_n ( R_I ) - = (-1)^{\ell(I) - \ell(J)} - \cdot R_{J/n}, + = (-1)^{\ell(I) - \ell(J)} \cdot R_{J / n}, where `J` denotes the meet of the compositions `I` and - `(\underbrace{n, n, \ldots, n}_{\ell\mbox{ times}})`, + `(\underbrace{n, n, \ldots, n}_{|I|/n \mbox{ times}})`, where `\ell(I)` is the length of `I`, and where `J / n` denotes the composition obtained by dividing every entry of `J` by `n`. @@ -623,6 +624,7 @@ def verschiebung(self, n): .. SEEALSO:: + :meth:`sage.combinat.ncsf_qsym.qsym.QSym.Bases.ElementMethods.frobenius`, :meth:`sage.combinat.sf.sfa.SymmetricFunctionAlgebra_generic_Element.verschiebung` INPUT: @@ -684,11 +686,269 @@ def verschiebung(self, n): # componentwise, then convert back. parent = self.parent() S = parent.realization_of().S() - dct = {Composition(map(lambda i: i // n, I)): coeff + C = parent._basis_keys + dct = {C(map(lambda i: i // n, I)): coeff for (I, coeff) in S(self).monomial_coefficients().items() if all(i % n == 0 for i in I)} return parent(S._from_dict(dct)) + def star_involution(self): + r""" + Return the image of the noncommutative symmetric function + ``self`` under the star involution. + + The star involution is defined as the algebra antihomomorphism + `NCSF \to NCSF` which, for every positive integer `n`, sends + the `n`-th complete non-commutative symmetric function `S_n` to + `S_n`. Denoting by `f^{\ast}` the image of an element + `f \in NCSF` under this star involution, it can be shown that + every composition `I` satisfies + + .. MATH:: + + (S^I)^{\ast} = S^{I^r}, \quad + (\Lambda^I)^{\ast} = \Lambda^{I^r}, \quad + R_I^{\ast} = R_{I^r}, \quad + (\Phi^I)^{\ast} = \Phi^{I^r}, + + where `I^r` denotes the reversed composition of `I`, and + standard notations for classical bases of `NCSF` are being used + (`S` for the complete basis, `\Lambda` for the elementary basis, + `R` for the ribbon basis, and `\Phi` for that of the power-sums + of the second kind). The star involution is an involution and a + coalgebra automorphism of `NCSF`. It is an automorphism of the + graded vector space `NCSF`. Under the canonical isomorphism + between the `n`-th graded component of `NCSF` and the descent + algebra of the symmetric group `S_n` (see + :meth:`to_descent_algebra`), the star involution (restricted to + the `n`-th graded component) corresponds to the automorphism + of the descent algebra given by + `x \mapsto \omega_n x \omega_n`, where `\omega_n` is the + permutation `(n, n-1, ..., 1) \in S_n` (written here in + one-line notation). If `\pi` denotes the projection from `NCSF` + to the ring of symmetric functions + (:meth:`to_symmetric_function`), then `\pi(f^{\ast}) = \pi(f)` + for every `f \in NCSF`. + + The star involution on `NCSF` is adjoint to the star involution + on `QSym` by the standard adjunction between `NCSF` and `QSym`. + + The star involution has been denoted by `\rho` in [LMvW13]_, + section 3.6. + See [NCSF2]_, section 2.3 for the properties of this map. + + .. SEEALSO:: + + :meth:`sage.combinat.ncsf_qsym.qsym.QSym.Bases.ElementMethods.star_involution`, + :meth:`sage.combinat.ncsf_qsym.qsym.NCSF.Bases.ElementMethods.psi_involution`. + + EXAMPLES:: + + sage: NSym = NonCommutativeSymmetricFunctions(ZZ) + sage: S = NSym.S() + sage: S[3,2].star_involution() + S[2, 3] + sage: S[6,3].star_involution() + S[3, 6] + sage: (S[9,1] - S[8,2] + 2*S[6,4] - 3*S[3] + 4*S[[]]).star_involution() + 4*S[] + S[1, 9] - S[2, 8] - 3*S[3] + 2*S[4, 6] + sage: (S[3,3] - 2*S[2]).star_involution() + -2*S[2] + S[3, 3] + sage: S([4,2]).star_involution() + S[2, 4] + sage: R = NSym.R() + sage: R([4,2]).star_involution() + R[2, 4] + sage: R.zero().star_involution() + 0 + sage: NSym = NonCommutativeSymmetricFunctions(QQ) + sage: Phi = NSym.Phi() + sage: Phi([2,1]).star_involution() + Phi[1, 2] + + The Psi basis doesn't behave as nicely:: + + sage: Psi = NSym.Psi() + sage: Psi([2,1]).star_involution() + Psi[1, 2] + sage: Psi([3,1]).star_involution() + 1/2*Psi[1, 1, 2] - 1/2*Psi[1, 2, 1] + Psi[1, 3] + + The star involution commutes with the antipode:: + + sage: all( R(I).star_involution().antipode() + ....: == R(I).antipode().star_involution() + ....: for I in Compositions(4) ) + True + + Checking the relation with the descent algebra described + above:: + + sage: def descent_test(n): + ....: DA = DescentAlgebra(QQ, n) + ....: NSym = NonCommutativeSymmetricFunctions(QQ) + ....: S = NSym.S() + ....: DAD = DA.D() + ....: w_n = DAD(set(range(1, n))) + ....: for I in Compositions(n): + ....: if not (S[I].star_involution() + ....: == w_n * S[I].to_descent_algebra(n) * w_n): + ....: return False + ....: return True + sage: all( descent_test(i) for i in range(4) ) # not tested + True + sage: all( descent_test(i) for i in range(6) ) # not tested + True + + .. TODO:: + + Once :trac:`10963` is in, remove the first "not tested" above, + and replace the second one by "long time". + + Testing the `\pi(f^{\ast}) = \pi(f)` relation noticed above:: + + sage: NSym = NonCommutativeSymmetricFunctions(QQ) + sage: R = NSym.R() + sage: all( R(I).star_involution().to_symmetric_function() + ....: == R(I).to_symmetric_function() + ....: for I in Compositions(4) ) + True + + The star involution on `QSym` is adjoint to the star involution + on `NSym` with respect to the duality pairing:: + + sage: QSym = QuasiSymmetricFunctions(QQ) + sage: M = QSym.M() + sage: NSym = NonCommutativeSymmetricFunctions(QQ) + sage: S = NSym.S() + sage: all( all( M(I).star_involution().duality_pairing(S(J)) + ....: == M(I).duality_pairing(S(J).star_involution()) + ....: for I in Compositions(2) ) + ....: for J in Compositions(3) ) + True + """ + # Convert to the homogeneous basis, there apply the star + # involution componentwise, then convert back. + parent = self.parent() + S = parent.realization_of().S() + dct = {I.reversed(): coeff + for (I, coeff) in S(self).monomial_coefficients().items()} + return parent(S._from_dict(dct)) + + def psi_involution(self): + r""" + Return the image of the noncommutative symmetric function + ``self`` under the involution `\psi`. + + The involution `\psi` is defined as the linear map + `NCSF \to NCSF` which, for every composition `I`, sends the + complete noncommutative symmetric function `S^I` to the + elementary noncommutative symmetric function `\Lambda^I`. + It can be shown that every composition `I` satisfies + + .. MATH:: + + \psi(R_I) = R^{I^c}, \quad \psi(S^I) = \Lambda^I, \quad + \psi(\Lambda^I) = S^I, \quad + \psi(\Phi^I) = (-1)^{|I| - \ell(I)} \Phi^I + + where `I^c` denotes the complement of the composition `I`, and + `\ell(I)` denotes the length of `I`, and where standard + notations for classical bases of `NCSF` are being used + (`S` for the complete basis, `\Lambda` for the elementary basis, + `\Phi` for the basis of the power sums of the second kind, + and `R` for the ribbon basis). The map `\psi` is an involution + and a graded Hopf algebra automorphism of `NCSF`. If `\pi` + denotes the projection from `NCSF` to the ring of symmetric + functions (:meth:`to_symmetric_function`), then + `\pi(\psi(f)) = \omega(\pi(f))` for every `f \in NCSF`, where + the `\omega` on the right hand side denotes the omega + automorphism of `Sym`. + + The involution `\psi` of `NCSF` is adjoint to the involution + `\psi` of `QSym` by the standard adjunction between `NCSF` and + `QSym`. + + The involution `\psi` has been denoted by `\psi` in [LMvW13]_, + section 3.6. + + .. SEEALSO:: + + :meth:`sage.combinat.ncsf_qsym.qsym.QSym.Bases.ElementMethods.psi_involution`, + :meth:`sage.combinat.ncsf_qsym.qsym.NCSF.Bases.ElementMethods.star_involution`. + + EXAMPLES:: + + sage: NSym = NonCommutativeSymmetricFunctions(ZZ) + sage: R = NSym.R() + sage: R[3,2].psi_involution() + R[1, 1, 2, 1] + sage: R[6,3].psi_involution() + R[1, 1, 1, 1, 1, 2, 1, 1] + sage: (R[9,1] - R[8,2] + 2*R[2,4] - 3*R[3] + 4*R[[]]).psi_involution() + 4*R[] - 3*R[1, 1, 1] + R[1, 1, 1, 1, 1, 1, 1, 1, 2] - R[1, 1, 1, 1, 1, 1, 1, 2, 1] + 2*R[1, 2, 1, 1, 1] + sage: (R[3,3] - 2*R[2]).psi_involution() + -2*R[1, 1] + R[1, 1, 2, 1, 1] + sage: R([2,1,1]).psi_involution() + R[1, 3] + sage: S = NSym.S() + sage: S([2,1]).psi_involution() + S[1, 1, 1] - S[2, 1] + sage: S.zero().psi_involution() + 0 + sage: NSym = NonCommutativeSymmetricFunctions(QQ) + sage: Phi = NSym.Phi() + sage: Phi([2,1]).psi_involution() + -Phi[2, 1] + sage: Phi([3,1]).psi_involution() + Phi[3, 1] + + The Psi basis doesn't behave as nicely:: + + sage: Psi = NSym.Psi() + sage: Psi([2,1]).psi_involution() + -Psi[2, 1] + sage: Psi([3,1]).psi_involution() + 1/2*Psi[1, 2, 1] - 1/2*Psi[2, 1, 1] + Psi[3, 1] + + The involution `\psi` commutes with the antipode:: + + sage: all( R(I).psi_involution().antipode() + ....: == R(I).antipode().psi_involution() + ....: for I in Compositions(4) ) + True + + Testing the `\pi(\psi(f)) = \omega(\pi(f))` relation noticed + above:: + + sage: NSym = NonCommutativeSymmetricFunctions(QQ) + sage: R = NSym.R() + sage: all( R(I).psi_involution().to_symmetric_function() + ....: == R(I).to_symmetric_function().omega() + ....: for I in Compositions(4) ) + True + + The involution `\psi` of `QSym` is adjoint to the involution + `\psi` of `NSym` with respect to the duality pairing:: + + sage: QSym = QuasiSymmetricFunctions(QQ) + sage: M = QSym.M() + sage: NSym = NonCommutativeSymmetricFunctions(QQ) + sage: S = NSym.S() + sage: all( all( M(I).psi_involution().duality_pairing(S(J)) + ....: == M(I).duality_pairing(S(J).psi_involution()) + ....: for I in Compositions(2) ) + ....: for J in Compositions(3) ) + True + """ + # Convert to the ribbon basis, there apply the psi + # involution componentwise, then convert back. + parent = self.parent() + R = parent.realization_of().R() + dct = {I.complement(): coeff + for (I, coeff) in R(self).monomial_coefficients().items()} + return parent(R._from_dict(dct)) + def to_descent_algebra(self, n): r""" Return the image of the ``n``-th degree homogeneous component @@ -872,7 +1132,7 @@ def algebra_generators(self): """ from sage.sets.family import Family from sage.sets.positive_integers import PositiveIntegers - return Family(PositiveIntegers(), lambda i: self.monomial(Composition([i]))) + return Family(PositiveIntegers(), lambda i: self.monomial(self._basis_keys([i]))) def product_on_basis(self, composition1, composition2): """ @@ -1117,7 +1377,7 @@ def coproduct_on_generators(self, i): """ if i<1: return "Not a positive integer: %s" % `i` - def C(i): return Composition([i]) if i else Composition([]) + def C(i): return self._basis_keys([i]) if i else self._basis_keys([]) T = self.tensor_square() return T.sum_of_monomials( (C(j), C(i-j)) for j in range(0,i+1) ) @@ -1360,8 +1620,46 @@ def product_on_basis(self, I, J): elif J == []: return self.monomial(I) else: - return self.monomial(Composition(I[:] + J[:])) + \ - self.monomial(Composition(I[:-1] + [I[-1]+J[0]] + J[1:])) + return self.monomial(self._basis_keys(I[:] + J[:])) + \ + self.monomial(self._basis_keys(I[:-1] + [I[-1]+J[0]] + J[1:])) + + def antipode_on_basis(self, composition): + """ + Return the application of the antipode to a basis element + of the ribbon basis ``self``. + + INPUT: + + - ``composition`` -- a composition + + OUTPUT: + + - The image of the basis element indexed by ``composition`` + under the antipode map. + + EXAMPLES:: + + sage: R = NonCommutativeSymmetricFunctions(QQ).ribbon() + sage: R.antipode_on_basis(Composition([2,1])) + -R[2, 1] + sage: R[3,1].antipode() # indirect doctest + R[2, 1, 1] + sage: R[[]].antipode() # indirect doctest + R[] + + We check that the implementation of the antipode at hand does + not contradict the generic one:: + + sage: S = NonCommutativeSymmetricFunctions(QQ).S() + sage: all( S(R[I].antipode()) == S(R[I]).antipode() + ....: for I in Compositions(4) ) + True + """ + # TODO: avoid this -1^... by using properly + if composition.size() % 2 == 0: + return self[composition.conjugate()] + else: + return - self[composition.conjugate()] def to_symmetric_function_on_basis(self, I): r""" @@ -1394,6 +1692,225 @@ def to_symmetric_function_on_basis(self, I): return s([]) return s(I.to_skew_partition()) + class Element(CombinatorialFreeModule.Element): + + def verschiebung(self, n): + r""" + Return the image of the noncommutative symmetric function + ``self`` under the `n`-th Verschiebung operator. + + The `n`-th Verschiebung operator `\mathbf{V}_n` is defined + to be the map from the `\mathbf{k}`-algebra of noncommutative + symmetric functions to itself that sends the complete function + `S^I` indexed by a composition `I = (i_1, i_2, \ldots , i_k)` + to `S^{(i_1/n, i_2/n, \ldots , i_k/n)}` if all of the numbers + `i_1, i_2, \ldots, i_k` are divisible by `n`, and to `0` + otherwise. This operator `\mathbf{V}_n` is a Hopf algebra + endomorphism. For every positive integer `r` with `n \mid r`, + it satisfies + + .. MATH:: + + \mathbf{V}_n(S_r) = S_{r/n}, + \quad \mathbf{V}_n(\Lambda_r) = (-1)^{r - r/n} \Lambda_{r/n}, + \quad \mathbf{V}_n(\Psi_r) = n \Psi_{r/n}, + \quad \mathbf{V}_n(\Phi_r) = n \Phi_{r/n} + + (where `S_r` denotes the `r`-th complete non-commutative + symmetric function, `\Lambda_r` denotes the `r`-th elementary + non-commutative symmetric function, `\Psi_r` denotes the `r`-th + power-sum non-commutative symmetric function of the first kind, + and `\Phi_r` denotes the `r`-th power-sum non-commutative + symmetric function of the second kind). For every positive + integer `r` with `n \nmid r`, it satisfes + + .. MATH:: + + \mathbf{V}_n(S_r) = \mathbf{V}_n(\Lambda_r) + = \mathbf{V}_n(\Psi_r) = \mathbf{V}_n(\Phi_r) = 0. + + The `n`-th Verschiebung operator is also called the `n`-th + Verschiebung endomorphism. + + It is a lift of the `n`-th Verschiebung operator on the ring + of symmetric functions ( + :meth:`sage.combinat.sf.sfa.SymmetricFunctionAlgebra_generic_Element.verschiebung` + ) to the ring of noncommutative symmetric functions. + + The action of the `n`-th Verschiebung operator can also be + described on the ribbon Schur functions. Namely, every + composition `I` of size `n \ell` satisfies + + .. MATH:: + + \mathbf{V}_n ( R_I ) + = (-1)^{\ell(I) - \ell(J)} \cdot R_{J / n}, + + where `J` denotes the meet of the compositions `I` and + `(\underbrace{n, n, \ldots, n}_{|I|/n \mbox{ times}})`, + where `\ell(I)` is the length of `I`, and + where `J / n` denotes the composition obtained by + dividing every entry of `J` by `n`. + For a composition `I` of size not divisible by `n`, we + have `\mathbf{V}_n ( R_I ) = 0`. + + .. SEEALSO:: + + :meth:`sage.combinat.ncsf_qsym.qsym.NCSF.Bases.ElementMethods.verschiebung`, + :meth:`sage.combinat.ncsf_qsym.qsym.QSym.Bases.ElementMethods.frobenius`, + :meth:`sage.combinat.sf.sfa.SymmetricFunctionAlgebra_generic_Element.verschiebung` + + INPUT: + + - ``n`` -- a positive integer + + OUTPUT: + + The result of applying the `n`-th Verschiebung operator (on the + ring of noncommutative symmetric functions) to ``self``. + + EXAMPLES:: + + sage: NSym = NonCommutativeSymmetricFunctions(ZZ) + sage: R = NSym.R() + sage: R([4,2]).verschiebung(2) + R[2, 1] + sage: R([2,1]).verschiebung(3) + -R[1] + sage: R([3]).verschiebung(2) + 0 + sage: R([]).verschiebung(2) + R[] + sage: R([5, 1]).verschiebung(3) + -R[2] + sage: R([5, 1]).verschiebung(6) + -R[1] + sage: R([5, 1]).verschiebung(2) + -R[3] + sage: R([1, 2, 3, 1]).verschiebung(7) + -R[1] + sage: R([1, 2, 3, 1]).verschiebung(5) + 0 + sage: (R[1] - R[2] + 2*R[3]).verschiebung(1) + R[1] - R[2] + 2*R[3] + + TESTS: + + The current implementation on the ribbon basis gives the + same results as the default implementation:: + + sage: S = NSym.S() + sage: def test_ribbon(N, n): + ....: for I in Compositions(N): + ....: if S(R[I].verschiebung(n)) != S(R[I]).verschiebung(n): + ....: return False + ....: return True + sage: test_ribbon(4, 2) + True + sage: test_ribbon(6, 2) + True + sage: test_ribbon(6, 3) + True + sage: test_ribbon(8, 4) # long time + True + """ + parent = self.parent() + C = parent._basis_keys + def ribbon_mapper(I, coeff): + # return \mathbf{V}_n ( coeff * R_I ) as pair + # (composition, coefficient) + M = sum(I) + m = M // n + J = I.meet([n] * m) + Jn = C([j // n for j in J]) + if (len(I) - len(J)) % 2 == 1: + return (Jn, - coeff) + else: + return (Jn, coeff) + return parent.sum_of_terms([ribbon_mapper(I, coeff) + for (I, coeff) in self + if sum(I) % n == 0]) + + def star_involution(self): + r""" + Return the image of the noncommutative symmetric function + ``self`` under the star involution. + + The star involution is defined as the algebra antihomomorphism + `NCSF \to NCSF` which, for every positive integer `n`, sends + the `n`-th complete non-commutative symmetric function `S_n` to + `S_n`. Denoting by `f^{\ast}` the image of an element + `f \in NCSF` under this star involution, it can be shown that + every composition `I` satisfies + + .. MATH:: + + (S^I)^{\ast} = S^{I^r}, \quad + (\Lambda^I)^{\ast} = \Lambda^{I^r}, \quad + R_I^{\ast} = R_{I^r}, \quad + (\Phi^I)^{\ast} = \Phi^{I^r}, + + where `I^r` denotes the reversed composition of `I`, and + standard notations for classical bases of `NCSF` are being used + (`S` for the complete basis, `\Lambda` for the elementary basis, + `R` for the ribbon basis, and `\Phi` for that of the power-sums + of the second kind). The star involution is an involution and a + coalgebra automorphism of `NCSF`. It is an automorphism of the + graded vector space `NCSF`. Under the canonical isomorphism + between the `n`-th graded component of `NCSF` and the descent + algebra of the symmetric group `S_n` (see + :meth:`to_descent_algebra`), the star involution (restricted to + the `n`-th graded component) corresponds to the automorphism + of the descent algebra given by + `x \mapsto \omega_n x \omega_n`, where `\omega_n` is the + permutation `(n, n-1, ..., 1) \in S_n` (written here in + one-line notation). If `\pi` denotes the projection from `NCSF` + to the ring of symmetric functions + (:meth:`to_symmetric_function`), then `\pi(f^{\ast}) = \pi(f)` + for every `f \in NCSF`. + + The star involution on `NCSF` is adjoint to the star involution + on `QSym` by the standard adjunction between `NCSF` and `QSym`. + + The star involution has been denoted by `\rho` in [LMvW13]_, + section 3.6. + See [NCSF2]_, section 2.3 for the properties of this map. + + .. SEEALSO:: + + :meth:`sage.combinat.ncsf_qsym.qsym.NCSF.Bases.ElementMethods.star_involution`, + :meth:`sage.combinat.ncsf_qsym.qsym.QSym.Bases.ElementMethods.star_involution`, + :meth:`sage.combinat.ncsf_qsym.qsym.NCSF.Bases.ElementMethods.psi_involution`. + + EXAMPLES:: + + sage: NSym = NonCommutativeSymmetricFunctions(ZZ) + sage: R = NSym.R() + sage: R[3,1,4,2].star_involution() + R[2, 4, 1, 3] + sage: R[4,1,2].star_involution() + R[2, 1, 4] + sage: (R[1] - R[2] + 2*R[5,4] - 3*R[3] + 4*R[[]]).star_involution() + 4*R[] + R[1] - R[2] - 3*R[3] + 2*R[4, 5] + sage: (R[3,3] - 21*R[1]).star_involution() + -21*R[1] + R[3, 3] + sage: R([14,1]).star_involution() + R[1, 14] + + The implementation at hand is tailored to the ribbon basis. + It is equivalent to the generic implementation via the + complete basis:: + + sage: S = NSym.S() + sage: all( S(R[I].star_involution()) == S(R[I]).star_involution() + ....: for I in Compositions(4) ) + True + """ + parent = self.parent() + dct = {I.reversed(): coeff + for (I, coeff) in self.monomial_coefficients().items()} + return parent._from_dict(dct) + R = ribbon = Ribbon class Complete(CombinatorialFreeModule, BindableClass): @@ -1544,8 +2061,8 @@ def _to_symmetric_group_algebra_on_basis(self, I): r""" Return the image of the complete non-commutative symmetric function indexed by the composition ``I`` in the symmetric group algebra under the canonical - embedding of the non-commutative symmetric functions into the symmetric - group algebra. + embedding of the degree-`|I|` homogeneous non-commutative symmetric + functions into the `|I|`-th symmetric group algebra. This embedding sends the complete basis element indexed by the composition ``I`` to the sum of all permutations whose descent composition is fatter @@ -1558,7 +2075,8 @@ def _to_symmetric_group_algebra_on_basis(self, I): OUTPUT: - - The sum of all permutations with right descent set contained in ``I``. + - The sum of all permutations of `\{ 1, 2, \ldots, |I| \}` with right + descent set contained in ``I``. EXAMPLES:: @@ -1641,6 +2159,83 @@ def to_ncsym_on_basis(self, I): return prod(m.sum_of_terms([(P(A), R(c_num(A) / factorial(n))) for A in SetPartitions(n)], distinct=True) for n in I) + class Element(CombinatorialFreeModule.Element): + """ + An element in the Complete basis. + """ + def psi_involution(self): + r""" + Return the image of the noncommutative symmetric function + ``self`` under the involution `\psi`. + + The involution `\psi` is defined as the linear map + `NCSF \to NCSF` which, for every composition `I`, sends the + complete noncommutative symmetric function `S^I` to the + elementary noncommutative symmetric function `\Lambda^I`. + It can be shown that every composition `I` satisfies + + .. MATH:: + + \psi(R_I) = R^{I^c}, \quad \psi(S^I) = \Lambda^I, \quad + \psi(\Lambda^I) = S^I, \quad + \psi(\Phi^I) = (-1)^{|I| - \ell(I)} \Phi^I + + where `I^c` denotes the complement of the composition `I`, and + `\ell(I)` denotes the length of `I`, and where standard + notations for classical bases of `NCSF` are being used + (`S` for the complete basis, `\Lambda` for the elementary + basis, `\Phi` for the basis of the power sums of the second + kind, and `R` for the ribbon basis). The map `\psi` is an + involution and a graded Hopf algebra automorphism of `NCSF`. + If `\pi` denotes the projection from `NCSF` to the ring of + symmetric functions (:meth:`to_symmetric_function`), then + `\pi(\psi(f)) = \omega(\pi(f))` for every `f \in NCSF`, where + the `\omega` on the right hand side denotes the omega + automorphism of `Sym`. + + The involution `\psi` of `NCSF` is adjoint to the involution + `\psi` of `QSym` by the standard adjunction between `NCSF` and + `QSym`. + + The involution `\psi` has been denoted by `\psi` in [LMvW13]_, + section 3.6. + + .. SEEALSO:: + + :meth:`sage.combinat.ncsf_qsym.qsym.NCSF.Bases.ElementMethods.psi_involution`, + :meth:`sage.combinat.ncsf_qsym.qsym.QSym.Bases.ElementMethods.psi_involution`, + :meth:`sage.combinat.ncsf_qsym.qsym.NCSF.Bases.ElementMethods.star_involution`. + + EXAMPLES:: + + sage: NSym = NonCommutativeSymmetricFunctions(ZZ) + sage: S = NSym.S() + sage: L = NSym.L() + sage: S[3,1].psi_involution() + S[1, 1, 1, 1] - S[1, 2, 1] - S[2, 1, 1] + S[3, 1] + sage: L(S[3,1].psi_involution()) + L[3, 1] + sage: S[[]].psi_involution() + S[] + sage: S[1,1].psi_involution() + S[1, 1] + sage: (S[2,1] - 2*S[2]).psi_involution() + -2*S[1, 1] + S[1, 1, 1] + 2*S[2] - S[2, 1] + + The implementation at hand is tailored to the complete basis. + It is equivalent to the generic implementation via the + ribbon basis:: + + sage: R = NSym.R() + sage: all( R(S[I].psi_involution()) == R(S[I]).psi_involution() + ....: for I in Compositions(4) ) + True + """ + parent = self.parent() + return parent.sum( (-1) ** (I.size() - len(I)) * coeff + * parent.alternating_sum_of_finer_compositions(I) + for I, coeff in self._monomial_coefficients.items() ) + S = complete = Complete class Elementary(CombinatorialFreeModule, BindableClass): @@ -1741,6 +2336,165 @@ def _from_complete_on_basis(self, I): minus_one = -self.base_ring().one() return self.sum_of_terms( (compo, minus_one**(len(compo)-n)) for compo in I.finer() ) + class Element(CombinatorialFreeModule.Element): + + def star_involution(self): + r""" + Return the image of the noncommutative symmetric function + ``self`` under the star involution. + + The star involution is defined as the algebra antihomomorphism + `NCSF \to NCSF` which, for every positive integer `n`, sends + the `n`-th complete non-commutative symmetric function `S_n` to + `S_n`. Denoting by `f^{\ast}` the image of an element + `f \in NCSF` under this star involution, it can be shown that + every composition `I` satisfies + + .. MATH:: + + (S^I)^{\ast} = S^{I^r}, \quad + (\Lambda^I)^{\ast} = \Lambda^{I^r}, \quad + R_I^{\ast} = R_{I^r}, \quad + (\Phi^I)^{\ast} = \Phi^{I^r}, + + where `I^r` denotes the reversed composition of `I`, and + standard notations for classical bases of `NCSF` are being used + (`S` for the complete basis, `\Lambda` for the elementary basis, + `R` for the ribbon basis, and `\Phi` for that of the power-sums + of the second kind). The star involution is an involution and a + coalgebra automorphism of `NCSF`. It is an automorphism of the + graded vector space `NCSF`. Under the canonical isomorphism + between the `n`-th graded component of `NCSF` and the descent + algebra of the symmetric group `S_n` (see + :meth:`to_descent_algebra`), the star involution (restricted to + the `n`-th graded component) corresponds to the automorphism + of the descent algebra given by + `x \mapsto \omega_n x \omega_n`, where `\omega_n` is the + permutation `(n, n-1, ..., 1) \in S_n` (written here in + one-line notation). If `\pi` denotes the projection from `NCSF` + to the ring of symmetric functions + (:meth:`to_symmetric_function`), then `\pi(f^{\ast}) = \pi(f)` + for every `f \in NCSF`. + + The star involution on `NCSF` is adjoint to the star involution + on `QSym` by the standard adjunction between `NCSF` and `QSym`. + + The star involution has been denoted by `\rho` in [LMvW13]_, + section 3.6. + See [NCSF2]_, section 2.3 for the properties of this map. + + .. SEEALSO:: + + :meth:`sage.combinat.ncsf_qsym.qsym.NCSF.Bases.ElementMethods.star_involution`, + :meth:`sage.combinat.ncsf_qsym.qsym.NCSF.Bases.ElementMethods.psi_involution`, + :meth:`sage.combinat.ncsf_qsym.qsym.QSym.Bases.ElementMethods.star_involution`. + + EXAMPLES:: + + sage: NSym = NonCommutativeSymmetricFunctions(ZZ) + sage: L = NSym.L() + sage: L[3,3,2,3].star_involution() + L[3, 2, 3, 3] + sage: L[6,3,3].star_involution() + L[3, 3, 6] + sage: (L[1,9,1] - L[8,2] + 2*L[6,4] - 3*L[3] + 4*L[[]]).star_involution() + 4*L[] + L[1, 9, 1] - L[2, 8] - 3*L[3] + 2*L[4, 6] + sage: (L[3,3] - 2*L[2]).star_involution() + -2*L[2] + L[3, 3] + sage: L([4,1]).star_involution() + L[1, 4] + + The implementation at hand is tailored to the elementary basis. + It is equivalent to the generic implementation via the + complete basis:: + + sage: S = NSym.S() + sage: all( S(L[I].star_involution()) == S(L[I]).star_involution() + ....: for I in Compositions(4) ) + True + """ + parent = self.parent() + dct = {I.reversed(): coeff + for (I, coeff) in self.monomial_coefficients().items()} + return parent._from_dict(dct) + + def psi_involution(self): + r""" + Return the image of the noncommutative symmetric function + ``self`` under the involution `\psi`. + + The involution `\psi` is defined as the linear map + `NCSF \to NCSF` which, for every composition `I`, sends the + complete noncommutative symmetric function `S^I` to the + elementary noncommutative symmetric function `\Lambda^I`. + It can be shown that every composition `I` satisfies + + .. MATH:: + + \psi(R_I) = R^{I^c}, \quad \psi(S^I) = \Lambda^I, \quad + \psi(\Lambda^I) = S^I, \quad + \psi(\Phi^I) = (-1)^{|I| - \ell(I)} \Phi^I + + where `I^c` denotes the complement of the composition `I`, and + `\ell(I)` denotes the length of `I`, and where standard + notations for classical bases of `NCSF` are being used + (`S` for the complete basis, `\Lambda` for the elementary basis, + `\Phi` for the basis of the power sums of the second kind, + and `R` for the ribbon basis). The map `\psi` is an involution + and a graded Hopf algebra automorphism of `NCSF`. If `\pi` + denotes the projection from `NCSF` to the ring of symmetric + functions (:meth:`to_symmetric_function`), then + `\pi(\psi(f)) = \omega(\pi(f))` for every `f \in NCSF`, where + the `\omega` on the right hand side denotes the omega + automorphism of `Sym`. + + The involution `\psi` of `NCSF` is adjoint to the involution + `\psi` of `QSym` by the standard adjunction between `NCSF` and + `QSym`. + + The involution `\psi` has been denoted by `\psi` in [LMvW13]_, + section 3.6. + + .. SEEALSO:: + + :meth:`sage.combinat.ncsf_qsym.qsym.NCSF.Bases.ElementMethods.psi_involution`, + :meth:`sage.combinat.ncsf_qsym.qsym.QSym.Bases.ElementMethods.psi_involution`, + :meth:`sage.combinat.ncsf_qsym.qsym.NCSF.Bases.ElementMethods.star_involution`. + + EXAMPLES:: + + sage: NSym = NonCommutativeSymmetricFunctions(QQ) + sage: S = NSym.S() + sage: L = NSym.L() + sage: L[3,1].psi_involution() + L[1, 1, 1, 1] - L[1, 2, 1] - L[2, 1, 1] + L[3, 1] + sage: S(L[3,1].psi_involution()) + S[3, 1] + sage: L[[]].psi_involution() + L[] + sage: L[1,1].psi_involution() + L[1, 1] + sage: (L[2,1] - 2*L[2]).psi_involution() + -2*L[1, 1] + L[1, 1, 1] + 2*L[2] - L[2, 1] + + The implementation at hand is tailored to the elementary basis. + It is equivalent to the generic implementation via the + ribbon basis:: + + sage: R = NSym.R() + sage: all( R(L[I].psi_involution()) == R(L[I]).psi_involution() + ....: for I in Compositions(3) ) + True + sage: all( R(L[I].psi_involution()) == R(L[I]).psi_involution() + ....: for I in Compositions(4) ) + True + """ + parent = self.parent() + return parent.sum( (-1) ** (I.size() - len(I)) * coeff + * parent.alternating_sum_of_finer_compositions(I) + for I, coeff in + self._monomial_coefficients.items() ) + L = elementary = Elementary class Psi(CombinatorialFreeModule, BindableClass): @@ -1775,6 +2529,9 @@ class Psi(CombinatorialFreeModule, BindableClass): `\QQ`-algebra (although the `\Psi^I` can be defined over any base ring). The elements of the `\Psi`-basis are known as the "power-sum non-commutative symmetric functions of the first kind". + The generators `\Psi_n` correspond to the Dynkin + (quasi-)idempotents in the descent algebras of the symmetric + groups (see [NCSF1]_, 5.2 for details). EXAMPLES:: @@ -1831,7 +2588,7 @@ def _from_complete_on_generators(self, n): """ # Equation (58) of NCSF I article one = self.base_ring().one() - I = Composition([n]) + I = self._basis_keys([n]) # TODO: I being trivial, there is no refinement going on here, so # one can probably be a bit more explicit / fast return self.sum_of_terms((J, one/coeff_pi(J,I)) for J in Compositions(n)) @@ -1911,6 +2668,142 @@ def _to_complete_on_basis(self, I): return complete.sum_of_terms((J, minus_one**(len(J)-len(I))*coeff_lp(J,I)) for J in I.finer()) + class Element(CombinatorialFreeModule.Element): + + def verschiebung(self, n): + r""" + Return the image of the noncommutative symmetric function + ``self`` under the `n`-th Verschiebung operator. + + The `n`-th Verschiebung operator `\mathbf{V}_n` is defined + to be the map from the `\mathbf{k}`-algebra of noncommutative + symmetric functions to itself that sends the complete function + `S^I` indexed by a composition `I = (i_1, i_2, \ldots , i_k)` + to `S^{(i_1/n, i_2/n, \ldots , i_k/n)}` if all of the numbers + `i_1, i_2, \ldots, i_k` are divisible by `n`, and to `0` + otherwise. This operator `\mathbf{V}_n` is a Hopf algebra + endomorphism. For every positive integer `r` with `n \mid r`, + it satisfies + + .. MATH:: + + \mathbf{V}_n(S_r) = S_{r/n}, + \quad \mathbf{V}_n(\Lambda_r) = (-1)^{r - r/n} \Lambda_{r/n}, + \quad \mathbf{V}_n(\Psi_r) = n \Psi_{r/n}, + \quad \mathbf{V}_n(\Phi_r) = n \Phi_{r/n} + + (where `S_r` denotes the `r`-th complete non-commutative + symmetric function, `\Lambda_r` denotes the `r`-th elementary + non-commutative symmetric function, `\Psi_r` denotes the `r`-th + power-sum non-commutative symmetric function of the first kind, + and `\Phi_r` denotes the `r`-th power-sum non-commutative + symmetric function of the second kind). For every positive + integer `r` with `n \nmid r`, it satisfes + + .. MATH:: + + \mathbf{V}_n(S_r) = \mathbf{V}_n(\Lambda_r) + = \mathbf{V}_n(\Psi_r) = \mathbf{V}_n(\Phi_r) = 0. + + The `n`-th Verschiebung operator is also called the `n`-th + Verschiebung endomorphism. + + It is a lift of the `n`-th Verschiebung operator on the ring + of symmetric functions ( + :meth:`sage.combinat.sf.sfa.SymmetricFunctionAlgebra_generic_Element.verschiebung` + ) to the ring of noncommutative symmetric functions. + + The action of the `n`-th Verschiebung operator can also be + described on the ribbon Schur functions. Namely, every + composition `I` of size `n \ell` satisfies + + .. MATH:: + + \mathbf{V}_n ( R_I ) + = (-1)^{\ell(I) - \ell(J)} \cdot R_{J / n}, + + where `J` denotes the meet of the compositions `I` and + `(\underbrace{n, n, \ldots, n}_{|I|/n \mbox{ times}})`, + where `\ell(I)` is the length of `I`, and + where `J / n` denotes the composition obtained by + dividing every entry of `J` by `n`. + For a composition `I` of size not divisible by `n`, we + have `\mathbf{V}_n ( R_I ) = 0`. + + .. SEEALSO:: + + :meth:`sage.combinat.ncsf_qsym.qsym.NCSF.Bases.ElementMethods.verschiebung`, + :meth:`sage.combinat.ncsf_qsym.qsym.QSym.Bases.ElementMethods.frobenius`, + :meth:`sage.combinat.sf.sfa.SymmetricFunctionAlgebra_generic_Element.verschiebung` + + INPUT: + + - ``n`` -- a positive integer + + OUTPUT: + + The result of applying the `n`-th Verschiebung operator (on the + ring of noncommutative symmetric functions) to ``self``. + + EXAMPLES:: + + sage: NSym = NonCommutativeSymmetricFunctions(ZZ) + sage: Psi = NSym.Psi() + sage: Psi([4,2]).verschiebung(2) + 4*Psi[2, 1] + sage: Psi([2,4]).verschiebung(2) + 4*Psi[1, 2] + sage: Psi([6]).verschiebung(2) + 2*Psi[3] + sage: Psi([2,1]).verschiebung(3) + 0 + sage: Psi([3]).verschiebung(2) + 0 + sage: Psi([]).verschiebung(2) + Psi[] + sage: Psi([5, 1]).verschiebung(3) + 0 + sage: Psi([5, 1]).verschiebung(6) + 0 + sage: Psi([5, 1]).verschiebung(2) + 0 + sage: Psi([1, 2, 3, 1]).verschiebung(7) + 0 + sage: Psi([7]).verschiebung(7) + 7*Psi[1] + sage: Psi([1, 2, 3, 1]).verschiebung(5) + 0 + sage: (Psi[1] - Psi[2] + 2*Psi[3]).verschiebung(1) + Psi[1] - Psi[2] + 2*Psi[3] + + TESTS: + + The current implementation on the Psi basis gives the + same results as the default implementation:: + + sage: S = NSym.S() + sage: def test_psi(N, n): + ....: for I in Compositions(N): + ....: if S(Psi[I].verschiebung(n)) != S(Psi[I]).verschiebung(n): + ....: return False + ....: return True + sage: test_psi(4, 2) + True + sage: test_psi(6, 2) + True + sage: test_psi(6, 3) + True + sage: test_psi(8, 4) # long time + True + """ + parent = self.parent() + C = parent._basis_keys + return parent.sum_of_terms([(C([i // n for i in I]), + coeff * (n ** len(I))) + for (I, coeff) in self + if all(i % n == 0 for i in I)], + distinct=True) + class Phi(CombinatorialFreeModule, BindableClass): r""" The Hopf algebra of non-commutative symmetric functions in the @@ -1938,6 +2831,10 @@ class Phi(CombinatorialFreeModule, BindableClass): "power-sum non-commutative symmetric functions of the second kind". + The generators `\Phi_n` are related to the (first) Eulerian + idempotents in the descent algebras of the symmetric groups (see + [NCSF1]_, 5.4 for details). + EXAMPLES:: sage: NCSF = NonCommutativeSymmetricFunctions(QQ) @@ -2042,6 +2939,294 @@ def _to_complete_on_basis(self, I): return complete.sum_of_terms((J, minus_one**(len(J)-len(I)) * prod(I) / coeff_ell(J,I)) for J in I.finer()) + class Element(CombinatorialFreeModule.Element): + + def verschiebung(self, n): + r""" + Return the image of the noncommutative symmetric function + ``self`` under the `n`-th Verschiebung operator. + + The `n`-th Verschiebung operator `\mathbf{V}_n` is defined + to be the map from the `\mathbf{k}`-algebra of noncommutative + symmetric functions to itself that sends the complete function + `S^I` indexed by a composition `I = (i_1, i_2, \ldots , i_k)` + to `S^{(i_1/n, i_2/n, \ldots , i_k/n)}` if all of the numbers + `i_1, i_2, \ldots, i_k` are divisible by `n`, and to `0` + otherwise. This operator `\mathbf{V}_n` is a Hopf algebra + endomorphism. For every positive integer `r` with `n \mid r`, + it satisfies + + .. MATH:: + + \mathbf{V}_n(S_r) = S_{r/n}, + \quad \mathbf{V}_n(\Lambda_r) = (-1)^{r - r/n} \Lambda_{r/n}, + \quad \mathbf{V}_n(\Psi_r) = n \Psi_{r/n}, + \quad \mathbf{V}_n(\Phi_r) = n \Phi_{r/n} + + (where `S_r` denotes the `r`-th complete non-commutative + symmetric function, `\Lambda_r` denotes the `r`-th elementary + non-commutative symmetric function, `\Psi_r` denotes the `r`-th + power-sum non-commutative symmetric function of the first kind, + and `\Phi_r` denotes the `r`-th power-sum non-commutative + symmetric function of the second kind). For every positive + integer `r` with `n \nmid r`, it satisfes + + .. MATH:: + + \mathbf{V}_n(S_r) = \mathbf{V}_n(\Lambda_r) + = \mathbf{V}_n(\Psi_r) = \mathbf{V}_n(\Phi_r) = 0. + + The `n`-th Verschiebung operator is also called the `n`-th + Verschiebung endomorphism. + + It is a lift of the `n`-th Verschiebung operator on the ring + of symmetric functions ( + :meth:`sage.combinat.sf.sfa.SymmetricFunctionAlgebra_generic_Element.verschiebung` + ) to the ring of noncommutative symmetric functions. + + The action of the `n`-th Verschiebung operator can also be + described on the ribbon Schur functions. Namely, every + composition `I` of size `n \ell` satisfies + + .. MATH:: + + \mathbf{V}_n ( R_I ) + = (-1)^{\ell(I) - \ell(J)} \cdot R_{J / n}, + + where `J` denotes the meet of the compositions `I` and + `(\underbrace{n, n, \ldots, n}_{|I|/n \mbox{ times}})`, + where `\ell(I)` is the length of `I`, and + where `J / n` denotes the composition obtained by + dividing every entry of `J` by `n`. + For a composition `I` of size not divisible by `n`, we + have `\mathbf{V}_n ( R_I ) = 0`. + + .. SEEALSO:: + + :meth:`sage.combinat.ncsf_qsym.qsym.NCSF.Bases.ElementMethods.verschiebung`, + :meth:`sage.combinat.ncsf_qsym.qsym.QSym.Bases.ElementMethods.frobenius`, + :meth:`sage.combinat.sf.sfa.SymmetricFunctionAlgebra_generic_Element.verschiebung` + + INPUT: + + - ``n`` -- a positive integer + + OUTPUT: + + The result of applying the `n`-th Verschiebung operator (on the + ring of noncommutative symmetric functions) to ``self``. + + EXAMPLES:: + + sage: NSym = NonCommutativeSymmetricFunctions(ZZ) + sage: Phi = NSym.Phi() + sage: Phi([4,2]).verschiebung(2) + 4*Phi[2, 1] + sage: Phi([2,4]).verschiebung(2) + 4*Phi[1, 2] + sage: Phi([6]).verschiebung(2) + 2*Phi[3] + sage: Phi([2,1]).verschiebung(3) + 0 + sage: Phi([3]).verschiebung(2) + 0 + sage: Phi([]).verschiebung(2) + Phi[] + sage: Phi([5, 1]).verschiebung(3) + 0 + sage: Phi([5, 1]).verschiebung(6) + 0 + sage: Phi([5, 1]).verschiebung(2) + 0 + sage: Phi([1, 2, 3, 1]).verschiebung(7) + 0 + sage: Phi([7]).verschiebung(7) + 7*Phi[1] + sage: Phi([1, 2, 3, 1]).verschiebung(5) + 0 + sage: (Phi[1] - Phi[2] + 2*Phi[3]).verschiebung(1) + Phi[1] - Phi[2] + 2*Phi[3] + + TESTS: + + The current implementation on the Phi basis gives the + same results as the default implementation:: + + sage: S = NSym.S() + sage: def test_phi(N, n): + ....: for I in Compositions(N): + ....: if S(Phi[I].verschiebung(n)) != S(Phi[I]).verschiebung(n): + ....: return False + ....: return True + sage: test_phi(4, 2) + True + sage: test_phi(6, 2) + True + sage: test_phi(6, 3) + True + sage: test_phi(8, 4) # long time + True + """ + parent = self.parent() + C = parent._basis_keys + return parent.sum_of_terms([(C([i // n for i in I]), + coeff * (n ** len(I))) + for (I, coeff) in self + if all(i % n == 0 for i in I)], + distinct=True) + + def star_involution(self): + r""" + Return the image of the noncommutative symmetric function + ``self`` under the star involution. + + The star involution is defined as the algebra antihomomorphism + `NCSF \to NCSF` which, for every positive integer `n`, sends + the `n`-th complete non-commutative symmetric function `S_n` to + `S_n`. Denoting by `f^{\ast}` the image of an element + `f \in NCSF` under this star involution, it can be shown that + every composition `I` satisfies + + .. MATH:: + + (S^I)^{\ast} = S^{I^r}, \quad + (\Lambda^I)^{\ast} = \Lambda^{I^r}, \quad + R_I^{\ast} = R_{I^r}, \quad + (\Phi^I)^{\ast} = \Phi^{I^r}, + + where `I^r` denotes the reversed composition of `I`, and + standard notations for classical bases of `NCSF` are being used + (`S` for the complete basis, `\Lambda` for the elementary basis, + `R` for the ribbon basis, and `\Phi` for that of the power-sums + of the second kind). The star involution is an involution and a + coalgebra automorphism of `NCSF`. It is an automorphism of the + graded vector space `NCSF`. Under the canonical isomorphism + between the `n`-th graded component of `NCSF` and the descent + algebra of the symmetric group `S_n` (see + :meth:`to_descent_algebra`), the star involution (restricted to + the `n`-th graded component) corresponds to the automorphism + of the descent algebra given by + `x \mapsto \omega_n x \omega_n`, where `\omega_n` is the + permutation `(n, n-1, ..., 1) \in S_n` (written here in + one-line notation). If `\pi` denotes the projection from `NCSF` + to the ring of symmetric functions + (:meth:`to_symmetric_function`), then `\pi(f^{\ast}) = \pi(f)` + for every `f \in NCSF`. + + The star involution on `NCSF` is adjoint to the star involution + on `QSym` by the standard adjunction between `NCSF` and `QSym`. + + The star involution has been denoted by `\rho` in [LMvW13]_, + section 3.6. + See [NCSF2]_, section 2.3 for the properties of this map. + + .. SEEALSO:: + + :meth:`sage.combinat.ncsf_qsym.qsym.NCSF.Bases.ElementMethods.star_involution`, + :meth:`sage.combinat.ncsf_qsym.qsym.NCSF.Bases.ElementMethods.psi_involution`, + :meth:`sage.combinat.ncsf_qsym.qsym.QSym.Bases.ElementMethods.star_involution`. + + EXAMPLES:: + + sage: NSym = NonCommutativeSymmetricFunctions(QQ) + sage: Phi = NSym.Phi() + sage: Phi[3,1,1,4].star_involution() + Phi[4, 1, 1, 3] + sage: Phi[4,2,1].star_involution() + Phi[1, 2, 4] + sage: (Phi[1,4] - Phi[2,3] + 2*Phi[5,4] - 3*Phi[3] + 4*Phi[[]]).star_involution() + 4*Phi[] - 3*Phi[3] - Phi[3, 2] + Phi[4, 1] + 2*Phi[4, 5] + sage: (Phi[3,3] + 3*Phi[1]).star_involution() + 3*Phi[1] + Phi[3, 3] + sage: Phi([2,1]).star_involution() + Phi[1, 2] + + The implementation at hand is tailored to the Phi basis. + It is equivalent to the generic implementation via the + complete basis:: + + sage: S = NSym.S() + sage: all( S(Phi[I].star_involution()) == S(Phi[I]).star_involution() + ....: for I in Compositions(4) ) + True + """ + parent = self.parent() + dct = {I.reversed(): coeff + for (I, coeff) in self.monomial_coefficients().items()} + return parent._from_dict(dct) + + def psi_involution(self): + r""" + Return the image of the noncommutative symmetric function + ``self`` under the involution `\psi`. + + The involution `\psi` is defined as the linear map + `NCSF \to NCSF` which, for every composition `I`, sends the + complete noncommutative symmetric function `S^I` to the + elementary noncommutative symmetric function `\Lambda^I`. + It can be shown that every composition `I` satisfies + + .. MATH:: + + \psi(R_I) = R^{I^c}, \quad \psi(S^I) = \Lambda^I, \quad + \psi(\Lambda^I) = S^I, \quad + \psi(\Phi^I) = (-1)^{|I| - \ell(I)} \Phi^I + + where `I^c` denotes the complement of the composition `I`, and + `\ell(I)` denotes the length of `I`, and where standard + notations for classical bases of `NCSF` are being used + (`S` for the complete basis, `\Lambda` for the elementary basis, + `\Phi` for the basis of the power sums of the second kind, + and `R` for the ribbon basis). The map `\psi` is an involution + and a graded Hopf algebra automorphism of `NCSF`. If `\pi` + denotes the projection from `NCSF` to the ring of symmetric + functions (:meth:`to_symmetric_function`), then + `\pi(\psi(f)) = \omega(\pi(f))` for every `f \in NCSF`, where + the `\omega` on the right hand side denotes the omega + automorphism of `Sym`. + + The involution `\psi` of `NCSF` is adjoint to the involution + `\psi` of `QSym` by the standard adjunction between `NCSF` and + `QSym`. + + The involution `\psi` has been denoted by `\psi` in [LMvW13]_, + section 3.6. + + .. SEEALSO:: + + :meth:`sage.combinat.ncsf_qsym.qsym.NCSF.Bases.ElementMethods.psi_involution`, + :meth:`sage.combinat.ncsf_qsym.qsym.QSym.Bases.ElementMethods.psi_involution`, + :meth:`sage.combinat.ncsf_qsym.qsym.NCSF.Bases.ElementMethods.star_involution`. + + EXAMPLES:: + + sage: NSym = NonCommutativeSymmetricFunctions(QQ) + sage: Phi = NSym.Phi() + sage: Phi[3,2].psi_involution() + -Phi[3, 2] + sage: Phi[2,2].psi_involution() + Phi[2, 2] + sage: Phi[[]].psi_involution() + Phi[] + sage: (Phi[2,1] - 2*Phi[2]).psi_involution() + 2*Phi[2] - Phi[2, 1] + sage: Phi(0).psi_involution() + 0 + + The implementation at hand is tailored to the Phi basis. + It is equivalent to the generic implementation via the + ribbon basis:: + + sage: R = NSym.R() + sage: all( R(Phi[I].psi_involution()) == R(Phi[I]).psi_involution() + ....: for I in Compositions(4) ) + True + """ + parent = self.parent() + dct = {I: (-1) ** (I.size() - len(I)) * coeff + for (I, coeff) in self.monomial_coefficients().items()} + return parent._from_dict(dct) + class Monomial(CombinatorialFreeModule, BindableClass): def __init__(self, NCSF): r""" @@ -2111,7 +3296,10 @@ def _to_complete_on_basis(self, I): S[1, 1, 1] - 2*S[1, 2] - S[2, 1] + 3*S[3] """ S = NonCommutativeSymmetricFunctions(self.base_ring()).S() - return sum(m_to_s_stat(self.base_ring(),I,K) * S(K) for K in Compositions(Composition(I).size())) + return sum( m_to_s_stat(self.base_ring(),I,K) * S(K) for K in Compositions(sum(I)) ) + # Note: sum(I) works both if I is a list and if I is a composition + # (although the latter case doesn't work in IPython, cf. + # :trac:`15163`). def _from_psi_on_basis(self, I): r""" @@ -2145,7 +3333,7 @@ def _from_psi_on_basis(self, I): for J in Compositions(I.size()): if I.is_finer(J): len_of_J = len(J) - p = [0] + Composition(I).refinement_splitting_lengths(J).partial_sums() + p = [0] + self._basis_keys(I).refinement_splitting_lengths(J).partial_sums() sum_of_elements += prod( (len_of_J - k)**(p[k+1]-p[k]) for k in range(len_of_J) ) * M(J) return sum_of_elements @@ -2282,7 +3470,7 @@ def _from_complete_on_basis(self, comp_content): - The expansion in the Immaculate basis of the basis element of the complete basis indexed by the composition - ``comp_content`` . + ``comp_content``. EXAMPLES:: @@ -2297,6 +3485,6 @@ def _from_complete_on_basis(self, comp_content): return I([]) else: return sum( number_of_fCT(comp_content,comp_shape) * I(comp_shape) \ - for comp_shape in Compositions(Composition(comp_content).size()) ) + for comp_shape in Compositions(sum(comp_content)) ) I = Immaculate diff --git a/src/sage/combinat/ncsf_qsym/qsym.py b/src/sage/combinat/ncsf_qsym/qsym.py index 583ca87f18c..dcc5ce779e8 100644 --- a/src/sage/combinat/ncsf_qsym/qsym.py +++ b/src/sage/combinat/ncsf_qsym/qsym.py @@ -27,6 +27,21 @@ .. [Rad1979] David E. Radford, *A natural ring basis for the shuffle algebra and an application to group schemes*, J. Algebra **58** (1979), 432-454. +.. [NCSF1] Israel Gelfand, D. Krob, Alain Lascoux, B. Leclerc, + V. S. Retakh, J.-Y. Thibon, + *Noncommutative symmetric functions*. + :arxiv:`hep-th/9407124v1` + +.. [NCSF2] D. Krob, B. Leclerc, J.-Y. Thibon, + *Noncommutative symmetric functions II: Transformations of alphabets*. + http://www-igm.univ-mlv.fr/~jyt/ARTICLES/NCSF2.ps + +.. [LMvW13] Kurt Luoto, Stefan Mykytiuk and Stephanie van Willigenburg, + *An introduction to quasisymmetric Schur functions -- Hopf algebras, + quasisymmetric functions, and Young composition tableaux*, + May 23, 2013, Springer. + http://www.math.ubc.ca/%7Esteph/papers/QuasiSchurBook.pdf + AUTHOR: - Jason Bandlow @@ -53,7 +68,7 @@ from sage.combinat.permutation import Permutations from sage.combinat.composition import Composition, Compositions from sage.combinat.composition_tableau import CompositionTableaux -from sage.combinat.partition import Partitions +from sage.combinat.partition import Partitions, _Partitions from sage.combinat.free_module import CombinatorialFreeModule from sage.combinat.sf.sf import SymmetricFunctions from sage.combinat.ncsf_qsym.generic_basis_code import BasesOfQSymOrNCSF @@ -622,7 +637,7 @@ def from_polynomial(self, f, check=True): exponent_coefficient = f.dict() z = {} for (e, c) in exponent_coefficient.iteritems(): - I = Composition([ei for ei in e if ei > 0]) + I = Compositions()([ei for ei in e if ei > 0]) if I not in z: z[I] = c out = self.Monomial()._from_dict(z) @@ -735,6 +750,43 @@ def from_polynomial(self, f, check=True): g = self.realization_of().from_polynomial(f, check=check) return self(g) + def Eulerian(self, n, j, k=None): + """ + Return the Eulerian (quasi)symmetric function `Q_{n,j}` in + terms of ``self``. + + INPUT: + + - ``n`` -- the value `n` or a partition + - ``j`` -- the number of excedances + - ``k`` -- (optional) if specified, determines the number of + fixed points of the permtutation + + EXAMPLES:: + + sage: QSym = QuasiSymmetricFunctions(QQ) + sage: M = QSym.M() + sage: M.Eulerian(3, 1) + 4*M[1, 1, 1] + 3*M[1, 2] + 3*M[2, 1] + 2*M[3] + sage: M.Eulerian(4, 1, 2) + 6*M[1, 1, 1, 1] + 4*M[1, 1, 2] + 4*M[1, 2, 1] + + 2*M[1, 3] + 4*M[2, 1, 1] + 3*M[2, 2] + 2*M[3, 1] + M[4] + sage: QS = QSym.QS() + sage: QS.Eulerian(4, 2) + 2*QS[1, 3] + QS[2, 2] + 2*QS[3, 1] + 3*QS[4] + sage: QS.Eulerian([2, 2, 1], 2) + QS[1, 2, 2] + QS[1, 4] + QS[2, 1, 2] + QS[2, 2, 1] + + QS[2, 3] + QS[3, 2] + QS[4, 1] + QS[5] + sage: dI = QSym.dI() + sage: dI.Eulerian(5, 2) + -dI[1, 3, 1] - 5*dI[1, 4] + dI[2, 2, 1] + dI[3, 1, 1] + + 5*dI[3, 2] + 6*dI[4, 1] + 6*dI[5] + """ + F = self.realization_of().F() + if n in _Partitions: + n = _Partitions(n) + return self(F.Eulerian(n, j, k)) + class ElementMethods: r""" Methods common to all elements of ``QuasiSymmetricFunctions``. @@ -1041,13 +1093,159 @@ def frobenius(self, n): # then convert back. parent = self.parent() M = parent.realization_of().M() - dct = {Composition(map(lambda i: n * i, I)): coeff + C = parent._basis_keys + dct = {C(map(lambda i: n * i, I)): coeff for (I, coeff) in M(self).monomial_coefficients().items()} result_in_M_basis = M._from_dict(dct) return parent(result_in_M_basis) adams_operation = frobenius + def star_involution(self): + r""" + Return the image of the quasisymmetric function ``self`` under + the star involution. + + The star involution is defined as the linear map + `QSym \to QSym` which, for every composition `I`, sends the + monomial quasisymmetric function `M_I` to `M_{I^r}`. Here, if + `I` is a composition, we denote by `I^r` the reversed + composition of `I`. Denoting by `f^{\ast}` the image of an + element `f \in QSym` under the star involution, it can be shown + that every composition `I` satisfies + + .. MATH:: + + (M_I)^{\ast} = M_{I^r}, \quad (F_I)^{\ast} = F_{I^r}, + + where `F_I` denotes the fundamental quasisymmetric function + corresponding to the composition `I`. The star involution is an + involution, an algebra automorphism and a coalgebra + anti-automorphism of `QSym`. It also is an automorphism of the + graded vector space `QSym`, and is the identity on the subspace + `Sym` of `QSym`. It is adjoint to the star involution on `NCSF` + by the standard adjunction between `NCSF` and `QSym`. + + The star involution has been denoted by `\rho` in [LMvW13]_, + section 3.6. + + .. SEEALSO:: + + :meth:`sage.combinat.ncsf_qsym.qsym.NCSF.Bases.ElementMethods.star_involution`. + + EXAMPLES:: + + sage: QSym = QuasiSymmetricFunctions(ZZ) + sage: M = QSym.M() + sage: M[3,2].star_involution() + M[2, 3] + sage: M[6,3].star_involution() + M[3, 6] + sage: (M[9,1] - M[6,2] + 2*M[6,4] - 3*M[3] + 4*M[[]]).star_involution() + 4*M[] + M[1, 9] - M[2, 6] - 3*M[3] + 2*M[4, 6] + sage: (M[3,3] - 2*M[2]).star_involution() + -2*M[2] + M[3, 3] + sage: M([4,2]).star_involution() + M[2, 4] + sage: dI = QSym.dI() + sage: dI([1,2]).star_involution() + -dI[1, 2] + dI[2, 1] + sage: dI.zero().star_involution() + 0 + + The star involution commutes with the antipode:: + + sage: all( M(I).star_involution().antipode() + ....: == M(I).antipode().star_involution() + ....: for I in Compositions(4) ) + True + + The star involution is the identity on `Sym`:: + + sage: Sym = SymmetricFunctions(ZZ) + sage: e = Sym.e() + sage: all( M(e(lam)).star_involution() == M(e(lam)) + ....: for lam in Partitions(4) ) + True + """ + # Convert to the homogeneous basis, there apply the star + # involution componentwise, then convert back. + parent = self.parent() + M = parent.realization_of().M() + dct = {I.reversed(): coeff + for (I, coeff) in M(self).monomial_coefficients().items()} + return parent(M._from_dict(dct)) + + def psi_involution(self): + r""" + Return the image of the quasisymmetric function ``self`` + under the involution `\psi`. + + The involution `\psi` is defined as the linear map + `QSym \to QSym` which, for every composition `I`, sends the + fundamental quasisymmetric function `F_I` to `F_{I^c}`, where + `I^c` denotes the complement of the composition `I`. + The map `\psi` is an involution and a graded Hopf algebra + automorphism of `QSym`. Its restriction to the ring of + symmetric functions coincides with the omega automorphism of + the latter ring. + + The involution `\psi` of `QSym` is adjoint to the involution + `\psi` of `NCSF` by the standard adjunction between `NCSF` and + `QSym`. + + The involution `\psi` has been denoted by `\psi` in [LMvW13]_, + section 3.6. + + .. SEEALSO:: + + :meth:`sage.combinat.ncsf_qsym.qsym.NCSF.Bases.ElementMethods.psi_involution`, + :meth:`sage.combinat.ncsf_qsym.qsym.QSym.Bases.ElementMethods.star_involution`. + + EXAMPLES:: + + sage: QSym = QuasiSymmetricFunctions(ZZ) + sage: F = QSym.F() + sage: F[3,2].psi_involution() + F[1, 1, 2, 1] + sage: F[6,3].psi_involution() + F[1, 1, 1, 1, 1, 2, 1, 1] + sage: (F[9,1] - F[8,2] + 2*F[2,4] - 3*F[3] + 4*F[[]]).psi_involution() + 4*F[] - 3*F[1, 1, 1] + F[1, 1, 1, 1, 1, 1, 1, 1, 2] - F[1, 1, 1, 1, 1, 1, 1, 2, 1] + 2*F[1, 2, 1, 1, 1] + sage: (F[3,3] - 2*F[2]).psi_involution() + -2*F[1, 1] + F[1, 1, 2, 1, 1] + sage: F([2,1,1]).psi_involution() + F[1, 3] + sage: M = QSym.M() + sage: M([2,1]).psi_involution() + -M[2, 1] - M[3] + sage: M.zero().psi_involution() + 0 + + The involution `\psi` commutes with the antipode:: + + sage: all( F(I).psi_involution().antipode() + ....: == F(I).antipode().psi_involution() + ....: for I in Compositions(4) ) + True + + Testing the fact that the restriction of `\psi` to `Sym` + is the omega automorphism of `Sym`:: + + sage: Sym = SymmetricFunctions(ZZ) + sage: e = Sym.e() + sage: all( F(e[lam]).psi_involution() == F(e[lam].omega()) + ....: for lam in Partitions(4) ) + True + """ + # Convert to the fundamental basis, there apply the psi + # involution componentwise, then convert back. + parent = self.parent() + F = parent.realization_of().F() + dct = {I.complement(): coeff + for (I, coeff) in F(self).monomial_coefficients().items()} + return parent(F._from_dict(dct)) + def expand(self, n, alphabet='x'): r""" Expand the quasi-symmetric function into ``n`` variables in @@ -1290,7 +1488,8 @@ def coproduct_on_basis(self, compo): sage: M.coproduct_on_basis(Composition([])) M[] # M[] """ - return self.tensor_square().sum_of_monomials((Composition(compo[:i]), Composition(compo[i:])) + return self.tensor_square().sum_of_monomials((self._basis_keys(compo[:i]), + self._basis_keys(compo[i:])) for i in range(0,len(compo)+1)) def lambda_of_monomial(self, I, n): @@ -1398,7 +1597,7 @@ def lambda_of_monomial(self, I, n): QQ_result = QQM.zero() for lam in Partitions(n): coeff = QQ((-1) ** len(lam)) / lam.centralizer_size() - QQ_result += coeff * QQM.prod([QQM(Composition([k * i for i in I])) + QQ_result += coeff * QQM.prod([QQM(self._basis_keys([k * i for i in I])) for k in lam]) QQ_result *= (-1) ** n # QQ_result is now \lambda^n(M_I) over QQ. @@ -1412,6 +1611,72 @@ class Element(CombinatorialFreeModule.Element): Element methods of the ``Monomial`` basis of ``QuasiSymmetricFunctions``. """ + def psi_involution(self): + r""" + Return the image of the quasisymmetric function ``self`` + under the involution `\psi`. + + The involution `\psi` is defined as the linear map + `QSym \to QSym` which, for every composition `I`, sends the + fundamental quasisymmetric function `F_I` to `F_{I^c}`, where + `I^c` denotes the complement of the composition `I`. + The map `\psi` is an involution and a graded Hopf algebra + automorphism of `QSym`. Its restriction to the ring of + symmetric functions coincides with the omega automorphism of + the latter ring. + + The involution `\psi` of `QSym` is adjoint to the involution + `\psi` of `NCSF` by the standard adjunction between `NCSF` and + `QSym`. + + The involution `\psi` has been denoted by `\psi` in [LMvW13]_, + section 3.6. + + .. SEEALSO:: + + :meth:`sage.combinat.ncsf_qsym.qsym.QSym.Bases.ElementMethods.psi_involution`, + :meth:`sage.combinat.ncsf_qsym.qsym.NCSF.Bases.ElementMethods.psi_involution`, + :meth:`sage.combinat.ncsf_qsym.qsym.QSym.Bases.ElementMethods.star_involution`. + + EXAMPLES:: + + sage: QSym = QuasiSymmetricFunctions(ZZ) + sage: M = QSym.M() + sage: M[3,2].psi_involution() + -M[3, 2] - M[5] + sage: M[3,1].psi_involution() + M[3, 1] + M[4] + sage: M[3,1,1].psi_involution() + M[3, 1, 1] + M[3, 2] + M[4, 1] + M[5] + sage: M[1,1,1].psi_involution() + M[1, 1, 1] + M[1, 2] + M[2, 1] + M[3] + sage: M[[]].psi_involution() + M[] + sage: M(0).psi_involution() + 0 + sage: (2*M[[]] - M[3,1] + 4*M[2]).psi_involution() + 2*M[] - 4*M[2] - M[3, 1] - M[4] + + This particular implementation is tailored to the monomial + basis. It is semantically equivalent to the generic + implementation it overshadows:: + + sage: F = QSym.F() + sage: all( F(M[I].psi_involution()) == F(M[I]).psi_involution() + ....: for I in Compositions(3) ) + True + + sage: F = QSym.F() + sage: all( F(M[I].psi_involution()) == F(M[I]).psi_involution() + ....: for I in Compositions(4) ) + True + """ + parent = self.parent() + return parent.sum( (-1) ** (I.size() - len(I)) * coeff + * parent.sum_of_fatter_compositions(I) + for I, coeff in + self._monomial_coefficients.items() ) + def expand(self, n, alphabet='x'): r""" Expand the quasi-symmetric function written in the monomial basis in @@ -1551,7 +1816,7 @@ def to_symmetric_function(self): m = SymmetricFunctions(self.parent().base_ring()).monomial() if self.is_symmetric(): return m.sum_of_terms([(I, coeff) for (I, coeff) in self - if list(I) in Partitions()], distinct=True) + if list(I) in _Partitions], distinct=True) else: raise ValueError, "%s is not a symmetric function"%self @@ -1679,7 +1944,145 @@ def coproduct_on_basis(self, compo): for i in range(len(compo)) for j in range(1, compo[i]) ) + @cached_method + def Eulerian(self, n, j, k=None): + r""" + Return the Eulerian (quasi)symmetric function `Q_{n,j}` (with + `n` either an integer or a partition) defined in [SW2010]_ in + terms of the fundamental quasisymmetric functions. + Or, if the optional argument ``k`` is specified, return the + function `Q_{n,j,k}` defined ibidem. + + If `n` and `j` are nonnegative integers, then the Eulerian + quasisymmetric function `Q_{n,j}` is defined as + + .. MATH:: + + Q_{n,j} := \sum_{\sigma} F_{\mathrm{Dex}(\sigma)}, + + where we sum over all permutations `\sigma \in S_n` such that + the number of excedances of `\sigma` is `j`, and where + `\mathrm{Dex}(\sigma)` is a composition of `n` defined as follows: + Let `S` be the set of all `i \in \{ 1, 2, \ldots, n-1 \}` such + that either `\sigma_i > \sigma_{i+1} > i+1` or + `i \geq \sigma_i > \sigma_{i+1}` or + `\sigma_{i+1} > i + 1 > \sigma_i`. Then, + `\mathrm{Dex}(\sigma)` is set to be the composition of `n` whose + descent set is `S`. + + Here, an excedance of a permutation `\sigma \in S_n` means an + element `i \in \{ 1, 2, \ldots, n-1 \}` satisfying `\sigma_i > i`. + + Similarly we can define a quasisymmetric function `Q_{\lambda, j}` + for every partition `\lambda` and every nonnegative integer `j`. + This differs from `Q_{n,j}` only in that the sum is restricted to + all permutations `\sigma \in S_n` whose cycle type is `\lambda` + (where `n = |\lambda|`, and where we still require the number of + excedances to be `j`). The method at hand allows computing these + functions by passing `\lambda` as the ``n`` parameter. + + Analogously we can define a quasisymmetric function `Q_{n,j,k}` for + any nonnegative integers `n`, `j` and `k` by restricting the sum to + all permutations `\sigma \in S_n` that have exactly `k` fixed + points (and `j` excedances). This can be obtained by specifying the + optional ``k`` argument in this method. + + All three versions of Eulerian quasisymmetric functions + (`Q_{n,j}`, `Q_{\lambda,j}` and `Q_{n,j,k}`) are actually + symmetric functions. See + :meth:`~sage.combinat.sf.SymmetricFunctionsBases.ParentMethods.Eulerian`. + + INPUT: + + - ``n`` -- the nonnegative integer `n` or a partition + - ``j`` -- the number of excedances + - ``k`` -- (optional) if specified, determines the number of fixed + points of the permutations which are being summed over + + REFERENCES: + + .. [SW2010] John Shareshian and Michelle Wachs. + *Eulerian quasisymmetric functions*. (2010). + :arxiv:`0812.0764v2` + + EXAMPLES:: + + sage: F = QuasiSymmetricFunctions(QQ).F() + sage: F.Eulerian(3, 1) + F[1, 2] + F[2, 1] + 2*F[3] + sage: F.Eulerian(4, 2) + F[1, 2, 1] + 2*F[1, 3] + 3*F[2, 2] + 2*F[3, 1] + 3*F[4] + sage: F.Eulerian(5, 2) + F[1, 1, 2, 1] + F[1, 1, 3] + F[1, 2, 1, 1] + 7*F[1, 2, 2] + 6*F[1, 3, 1] + 6*F[1, 4] + 2*F[2, 1, 2] + 7*F[2, 2, 1] + 11*F[2, 3] + F[3, 1, 1] + 11*F[3, 2] + 6*F[4, 1] + 6*F[5] + sage: F.Eulerian(4, 0) + F[4] + sage: F.Eulerian(4, 3) + F[4] + sage: F.Eulerian(4, 1, 2) + F[1, 2, 1] + F[1, 3] + 2*F[2, 2] + F[3, 1] + F[4] + sage: F.Eulerian(Partition([2, 2, 1]), 2) + F[1, 1, 2, 1] + F[1, 2, 1, 1] + 2*F[1, 2, 2] + F[1, 3, 1] + + F[1, 4] + F[2, 1, 2] + 2*F[2, 2, 1] + 2*F[2, 3] + + 2*F[3, 2] + F[4, 1] + F[5] + sage: F.Eulerian(0, 0) + F[] + sage: F.Eulerian(0, 1) + 0 + sage: F.Eulerian(1, 0) + F[1] + sage: F.Eulerian(1, 1) + 0 + + TESTS:: + + sage: F = QuasiSymmetricFunctions(QQ).F() + sage: F.Eulerian(Partition([3, 1]), 1, 1) + Traceback (most recent call last): + ... + ValueError: invalid input, k cannot be specified + """ + from sage.combinat.partition import _Partitions + if n in _Partitions: + if k is not None: + raise ValueError("invalid input, k cannot be specified") + la = _Partitions(n) + n = sum(la) + else: + la = None + + if n == 0: + if k is not None and k != 0: + return self.zero() + if j != 0: + return self.zero() + return self.one() + + monomials = [] + for p in Permutations(n): + dex = [] + exc = 0 + for i in range(n-1): + if p[i] > i + 1: + exc += 1 + if (p[i] > p[i+1] or (p[i] <= i+1 and p[i+1] > i+2)) \ + and not (p[i] > i+1 and p[i+1] <= i+2): + dex.append(i) + + if exc != j: + continue + if k is not None and p.number_of_fixed_points() != k: + continue + if la is not None and p.cycle_type() != la: + continue + + # Converting to a composition + d = [-1] + dex + [n-1] + monomials.append(Compositions()( [d[i+1]-d[i] for i in range(len(d)-1)] )) + + return self.sum_of_monomials(monomials) + class Element(CombinatorialFreeModule.Element): + def internal_coproduct(self): r""" Return the inner coproduct of ``self`` in the Fundamental basis. @@ -1801,6 +2204,64 @@ def internal_coproduct(self): kronecker_coproduct = internal_coproduct + def star_involution(self): + r""" + Return the image of the quasisymmetric function ``self`` under + the star involution. + + The star involution is defined as the linear map + `QSym \to QSym` which, for every composition `I`, sends the + monomial quasisymmetric function `M_I` to `M_{I^r}`. Here, if + `I` is a composition, we denote by `I^r` the reversed + composition of `I`. Denoting by `f^{\ast}` the image of an + element `f \in QSym` under the star involution, it can be shown + that every composition `I` satisfies + + .. MATH:: + + (M_I)^{\ast} = M_{I^r}, \quad (F_I)^{\ast} = F_{I^r}, + + where `F_I` denotes the fundamental quasisymmetric function + corresponding to the composition `I`. The star involution is an + involution, an algebra automorphism and a coalgebra + anti-automorphism of `QSym`. It also is an automorphism of the + graded vector space `QSym`, and is the identity on the subspace + `Sym` of `QSym`. It is adjoint to the star involution on `NCSF` + by the standard adjunction between `NCSF` and `QSym`. + + The star involution has been denoted by `\rho` in [LMvW13]_, + section 3.6. + + .. SEEALSO:: + + :meth:`sage.combinat.ncsf_qsym.qsym.QSym.Bases.ElementMethods.star_involution`, + :meth:`sage.combinat.ncsf_qsym.qsym.NCSF.Bases.ElementMethods.star_involution`. + + EXAMPLES:: + + sage: QSym = QuasiSymmetricFunctions(ZZ) + sage: F = QSym.F() + sage: F[3,1].star_involution() + F[1, 3] + sage: F[5,3].star_involution() + F[3, 5] + sage: (F[9,1] - F[6,2] + 2*F[6,4] - 3*F[3] + 4*F[[]]).star_involution() + 4*F[] + F[1, 9] - F[2, 6] - 3*F[3] + 2*F[4, 6] + sage: (F[3,3] - 2*F[2]).star_involution() + -2*F[2] + F[3, 3] + sage: F([4,2]).star_involution() + F[2, 4] + sage: dI = QSym.dI() + sage: dI([1,2]).star_involution() + -dI[1, 2] + dI[2, 1] + sage: dI.zero().star_involution() + 0 + """ + parent = self.parent() + dct = {I.reversed(): coeff + for (I, coeff) in self.monomial_coefficients().items()} + return parent._from_dict(dct) + F = Fundamental class Quasisymmetric_Schur(CombinatorialFreeModule, BindableClass): @@ -1808,7 +2269,10 @@ class Quasisymmetric_Schur(CombinatorialFreeModule, BindableClass): The Hopf algebra of quasi-symmetric function in the Quasisymmetric Schur basis. - The basis of Quasisymmetric Schur functions is defined in [QSCHUR]_. + The basis of Quasisymmetric Schur functions is defined in [QSCHUR]_ + and in Definition 5.1.1 of [LMvW13]_. + Don't mistake them for the completely unrelated quasi-Schur + functions of [NCSF1]_! EXAMPLES:: @@ -2087,10 +2551,11 @@ def _matrix_monomial_to_dual_immaculate(self, n): S = N.S() mat = [] C = Compositions() - for alp in Compositions(n): + C_n = Compositions(n) + for alp in C_n: row = [] expansion = S(I(C(alp))) - for bet in Compositions(n): + for bet in C_n: row.append(expansion.coefficient(C(bet))) mat.append(row) return mat @@ -2411,7 +2876,7 @@ def _precompute_cache(self, n, to_self_cache, from_self_cache, transition_matric # Handle the n == 0 case separately if n == 0: - part = Composition([]) + part = self._basis_keys([]) to_self_cache[ part ] = { part: base_ring(1) } from_self_cache[ part ] = { part: base_ring(1) } transition_matrices[n] = matrix(base_ring, [[1]]) @@ -2439,7 +2904,7 @@ def _precompute_cache(self, n, to_self_cache, from_self_cache, transition_matric # M_coeffs will be M(self[I])._monomial_coefficients M_coeffs = {} - self_I_in_M_basis = M.prod([from_self_gen_function(Composition(list(J))) + self_I_in_M_basis = M.prod([from_self_gen_function(self._basis_keys(list(J))) for J in Word(I).lyndon_factorization()]) j = 0 @@ -2663,5 +3128,5 @@ def product_on_basis(self, I, J): # either some i satisfies a_i > b_i and (a_j == b_j for all # j < i), or we have n > m and all i <= m satisfy a_i == b_i. new_factors = sorted(I_factors + J_factors, reverse=True) - return self[Composition(flatten(new_factors))] + return self.monomial(self._basis_keys(flatten(new_factors))) diff --git a/src/sage/combinat/ncsf_qsym/tutorial.py b/src/sage/combinat/ncsf_qsym/tutorial.py index 91deaf411ab..cb5ac6108d7 100644 --- a/src/sage/combinat/ncsf_qsym/tutorial.py +++ b/src/sage/combinat/ncsf_qsym/tutorial.py @@ -10,7 +10,7 @@ series ring in countably many variables. `QSym` contains the symmetric functions. These functions first arose in the theory of `P`-partitions. The initial ideas in this field are attributed to -MacMahon, Knuth, Kreweras, Glâffrwd Thomas, Stanley. In 1984, Gessel +MacMahon, Knuth, Kreweras, Glânffrwd Thomas, Stanley. In 1984, Gessel formalized the study of quasisymmetric functions and introduced the basis of fundamental quasisymmetric functions [Ges]_. In 1995, Gelfand, Krob, Lascoux, Leclerc, Retakh, and Thibon showed that the ring of @@ -38,10 +38,10 @@ Quasisymmetric functions over the Integer Ring All bases of `QSym` are indexed by compositions e.g. `[3,1,1,4]`. The -convention is to use capitol letters for bases of `QSym` and lowercase +convention is to use capital letters for bases of `QSym` and lowercase letters for bases of the symmetric functions `Sym`. Next set up names for the known bases by running ``inject_shorthands()``. As with symmetric functions, -you do not need to run this commmand and you could assign these bases other +you do not need to run this command and you could assign these bases other names. :: sage: QSym = QuasiSymmetricFunctions(QQ) @@ -137,7 +137,8 @@ The quasisymmetric functions are a ring which contains the symmetric functions as a subring. The Monomial quasisymmetric functions are related to the monomial symmetric functions by `m_\lambda = -\sum_{sort(c) = \lambda} M_c`:: +\sum_{\mathrm{sort}(c) = \lambda} M_c`, where `\mathrm{sort}(c)` +means the partition obtained by sorting the composition `c`:: sage: SymmetricFunctions(QQ).inject_shorthands() doctest:...: RuntimeWarning: redefining global value `e` @@ -220,7 +221,7 @@ QSym is a Hopf algebra ---------------------- -The product on this space is commutative and is inherited from the +The product on `QSym` is commutative and is inherited from the product by the realization within the polynomial ring:: sage: M[3]*M[1,1] == M[1,1]*M[3] @@ -324,7 +325,7 @@ sage: X = S[2,1,4,1].coproduct() sage: def linear_morphism(x, y): - ... return x.duality_pairing(M[1,3]) * y.duality_pairing(M[2,1,1]) + ....: return x.duality_pairing(M[1,3]) * y.duality_pairing(M[2,1,1]) sage: X.apply_multilinear_morphism(linear_morphism, codomain=ZZ) 1 @@ -354,7 +355,7 @@ sage: X = F[2,3,1].coproduct() sage: def linear_morphism(x, y): - ... return x.duality_pairing(R[2,1]) * y.duality_pairing(R[2,1]) + ....: return x.duality_pairing(R[2,1]) * y.duality_pairing(R[2,1]) sage: X.apply_multilinear_morphism(linear_morphism, codomain=ZZ) 1 @@ -375,10 +376,9 @@ :meth:`~sage.combinat.ncsf_qsym.generic_basis_code.BasesOfQSymOrNCSF.ElementMethods.skew_by()`. Explicitly, if ``H`` is a quasisymmetric function and ``g`` a non-commutative symmetric function, then ``H.skew_by(g)`` and -``H.skew_by(g, side='right')`` are expressions that satisfy -for any non-commutative symmetric function ``h``. - -:: +``H.skew_by(g, side='right')`` are expressions that satisfy, +for any non-commutative symmetric function ``h``, the following +identities:: H.skew_by(g).duality_pairing(h) == H.duality_pairing(g*h) H.skew_by(g, side='right').duality_pairing(h) == H.duality_pairing(h*g) diff --git a/src/sage/combinat/ordered_tree.py b/src/sage/combinat/ordered_tree.py index 3b8d1fe1b92..78b24cce436 100644 --- a/src/sage/combinat/ordered_tree.py +++ b/src/sage/combinat/ordered_tree.py @@ -26,12 +26,13 @@ class OrderedTree(AbstractClonableTree, ClonableList): """ - The class for (ordered rooted) Trees + The class of (ordered rooted) trees. - An ordered tree is constructed from a node called the root on which one + An ordered tree is constructed from a node, called the root, on which one has grafted a possibly empty list of trees. There is a total order on the children of a node which is given by the order of the elements in the - list. Note that there is no empty ordered tree. + list. Note that there is no empty ordered tree (so the smallest ordered + tree consists of just one node). INPUT: @@ -62,11 +63,11 @@ class OrderedTree(AbstractClonableTree, ClonableList): sage: tt1.__hash__() == tt2.__hash__() True - Trees are usually immutable. However they inherits from - :class:`sage.structure.list_clone.ClonableList`. So that they can be - modified using the clone protocol: + Trees are usually immutable. However they inherit from + :class:`sage.structure.list_clone.ClonableList`, so that they can be + modified using the clone protocol. Let us now see what this means. - Trying to modify a non mutable tree raises an error:: + Trying to modify a non-mutable tree raises an error:: sage: tt1[1] = tt2 Traceback (most recent call last): @@ -76,21 +77,21 @@ class OrderedTree(AbstractClonableTree, ClonableList): Here is the correct way to do it:: sage: with tt2.clone() as tt2: - ... tt2[1] = tt1 + ....: tt2[1] = tt1 sage: tt2 [[], [[], [[], []], [[], []]], [[], []]] It is also possible to append a child to a tree:: sage: with tt2.clone() as tt3: - ... tt3.append(OrderedTree([])) + ....: tt3.append(OrderedTree([])) sage: tt3 [[], [[], [[], []], [[], []]], [[], []], []] Or to insert a child in a tree:: sage: with tt2.clone() as tt3: - ... tt3.insert(2, OrderedTree([])) + ....: tt3.insert(2, OrderedTree([])) sage: tt3 [[], [[], [[], []], [[], []]], [], [[], []]] @@ -108,7 +109,7 @@ class OrderedTree(AbstractClonableTree, ClonableList): sage: tt1bis = OrderedTree(tt1) sage: with tt1.clone() as tt1: - ... tt1[1] = tt1bis + ....: tt1[1] = tt1bis sage: tt1 [[], [[], [[], []], [[], []]], [[], []]] sage: tt1 == tt2 @@ -159,7 +160,7 @@ class OrderedTree(AbstractClonableTree, ClonableList): Check that the hash value is correctly updated after modification:: sage: with tt2.clone() as tt2: - ... tt2[1,1] = tt1 + ....: tt2[1,1] = tt1 sage: tt1.__hash__() == tt2.__hash__() False """ @@ -199,7 +200,7 @@ def __classcall_private__(cls, *args, **opts): @lazy_class_attribute def _auto_parent(cls): """ - The automatic parent of the element of this class + The automatic parent of the elements of this class. When calling the constructor of an element of this class, one needs a parent. This class attribute specifies which parent is used. @@ -246,9 +247,9 @@ def __init__(self, parent=None, children=[], check=True): def is_empty(self): """ - Return if ``self`` is the empty tree + Return if ``self`` is the empty tree. - For ordered trees, returns always ``False`` + For ordered trees, this always returns ``False``. .. NOTE:: this is different from ``bool(t)`` which returns whether ``t`` has some child or not. @@ -266,7 +267,8 @@ def is_empty(self): def _to_binary_tree_rec(self, bijection="left"): r""" Internal recursive method to obtain a binary tree from an ordered - tree. + tree. See :meth:`to_binary_tree_left_branch` and + :meth:`to_binary_tree_right_branch` for what it does. EXAMPLES:: @@ -283,10 +285,10 @@ def _to_binary_tree_rec(self, bijection="left"): """ from sage.combinat.binary_tree import BinaryTree root = BinaryTree() - if(bijection=="left"): + if (bijection == "left"): for child in self: root = BinaryTree([root,child._to_binary_tree_rec(bijection)]) - elif(bijection=="right"): + elif (bijection == "right"): children = list(self) children.reverse() for child in children: @@ -298,12 +300,16 @@ def _to_binary_tree_rec(self, bijection="left"): @combinatorial_map(name="To binary tree, left brother = left child") def to_binary_tree_left_branch(self): r""" - Return a binary tree of size `n-1` by the following recursive rule: + Return a binary tree of size `n-1` (where `n` is the size of `t`, + and where `t` is ``self``) obtained from `t` by the following + recursive rule: - - if `x` is the left brother of `y`, `x` becomes the left child - of `y` - - if `x` is the last child of `y`, `x` becomes the right child - of `y` + - if `x` is the left brother of `y` in `t`, then `x` becomes the + left child of `y`; + - if `x` is the last child of `y` in `t`, then `x` becomes the + right child of `y`, + + and removing the root of `t`. EXAMPLES:: @@ -328,12 +334,16 @@ def to_binary_tree_left_branch(self): @combinatorial_map(name="To binary tree, right brother = right child") def to_binary_tree_right_branch(self): r""" - Return a binary tree of size n-1 by the following recursive rule: + Return a binary tree of size `n-1` (where `n` is the size of `t`, + and where `t` is ``self``) obtained from `t` by the following + recursive rule: + + - if `x` is the right brother of `y` in `t`, then`x` becomes the + right child of `y`; + - if `x` is the first child of `y` in `t`, then `x` becomes the + left child of `y`, - - if `x` is the right brother of `y`, `x` becomes the right child - of `y` - - if `x` is the first child of `y`, `x` becomes the left child - of `y` + and removing the root of `t`. EXAMPLES:: @@ -358,7 +368,7 @@ def to_binary_tree_right_branch(self): @combinatorial_map(name="To Dyck path") def to_dyck_word(self): r""" - Return the dyck path corresponding to ``self`` where the maximal + Return the Dyck path corresponding to ``self`` where the maximal height of the Dyck path is the depth of ``self`` . EXAMPLES:: @@ -573,14 +583,14 @@ def leaf(self): TEST:: sage: (OrderedTrees().leaf() is - ... sage.combinat.ordered_tree.OrderedTrees_all().leaf()) + ....: sage.combinat.ordered_tree.OrderedTrees_all().leaf()) True """ return self([]) class OrderedTrees_all(DisjointUnionEnumeratedSets, OrderedTrees): """ - The set of all ordered trees + The set of all ordered trees. EXAMPLES:: @@ -674,7 +684,6 @@ def _element_constructor_(self, *args, **keywords): from sage.misc.lazy_attribute import lazy_attribute from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets -from combinat import catalan_number from sage.combinat.composition import Compositions from sage.combinat.cartesian_product import CartesianProduct ################################################################# @@ -740,7 +749,7 @@ def cardinality(self): """ The cardinality of ``self`` - This is a Catalan number + This is a Catalan number. TESTS:: @@ -754,6 +763,7 @@ def cardinality(self): if self._size == 0: return Integer(0) else: + from combinat import catalan_number return catalan_number(self._size-1) def __iter__(self): @@ -832,7 +842,7 @@ def _element_constructor_(self, *args, **keywords): class LabelledOrderedTree(AbstractLabelledClonableTree, OrderedTree): """ - Labelled ordered trees + Labelled ordered trees. A labelled ordered tree is an ordered tree with a label attached at each node. @@ -877,7 +887,7 @@ def __classcall_private__(cls, *args, **opts): @lazy_class_attribute def _auto_parent(cls): """ - The automatic parent of the element of this class + The automatic parent of the elements of this class. When calling the constructor of an element of this class, one needs a parent. This class attribute specifies which parent is used. @@ -888,7 +898,7 @@ def _auto_parent(cls): Labelled ordered trees sage: LabelledOrderedTree([], label = 3).parent() Labelled ordered trees - """ + """ return LabelledOrderedTrees() _UnLabelled = OrderedTree @@ -898,7 +908,7 @@ def _auto_parent(cls): class LabelledOrderedTrees(UniqueRepresentation, Parent): """ This is a parent stub to serve as a factory class for trees with various - labels constraints + label constraints. EXAMPLES:: @@ -934,7 +944,7 @@ def _repr_(self): def cardinality(self): """ - Return the cardinality of `self` + Return the cardinality of `self`. EXAMPLE:: @@ -945,7 +955,7 @@ def cardinality(self): def _an_element_(self): """ - Return a labelled tree + Return a labelled ordered tree. EXAMPLE:: @@ -970,7 +980,10 @@ def _element_constructor_(self, *args, **keywords): def unlabelled_trees(self): """ - Return the set of unlabelled trees associated to ``self`` + Return the set of unlabelled trees associated to ``self``. + + This is the set of ordered trees, since ``self`` is the set of + labelled ordered trees. EXAMPLES:: @@ -981,7 +994,10 @@ def unlabelled_trees(self): def labelled_trees(self): """ - Return the set of labelled trees associated to ``self`` + Return the set of labelled trees associated to ``self``. + + This is precisely ``self``, because ``self`` already is the set + of labelled ordered trees. EXAMPLES:: diff --git a/src/sage/combinat/partition.py b/src/sage/combinat/partition.py index 0ba14cb172e..2368d51b63c 100644 --- a/src/sage/combinat/partition.py +++ b/src/sage/combinat/partition.py @@ -245,7 +245,8 @@ sage: Partitions().from_zero_one([1, 1, 1, 1, 0, 1, 0]) [5, 4] - sage: all(Partitions().from_zero_one(mu.zero_one_sequence()) == mu for n in range(5) for mu in Partitions(n)) + sage: all(Partitions().from_zero_one(mu.zero_one_sequence()) + ....: == mu for n in range(5) for mu in Partitions(n)) True We can compute the Frobenius coordinates and go back and forth:: @@ -254,8 +255,8 @@ ([6, 1], [2, 0]) sage: Partition(frobenius_coordinates=([6,1],[2,0])) [7, 3, 1] - sage: all(mu == Partition(frobenius_coordinates=mu.frobenius_coordinates()) for n in range(30)\ - for mu in Partitions(n)) + sage: all(mu == Partition(frobenius_coordinates=mu.frobenius_coordinates()) + ....: for n in range(30) for mu in Partitions(n)) True We use the lexicographic ordering:: @@ -479,10 +480,14 @@ class Partition(CombinatorialObject, Element): non-increasing list of positive integers (the *parts* of the partition) with total sum `n`. - A partition is often representation by a diagram consisting of **cells**, - or **boxes**, placed in rows on top of each other with the number of cells - in the `i^{th}` row, reading from top to bottom, is the `i^{th}` part of - the partition. + A partition is often represented as a diagram consisting of **cells**, + or **boxes**, placed in rows on top of each other such that the number of + cells in the `i^{th}` row, reading from top to bottom, is the `i^{th}` + part of the partition. The rows are left-justified (and become shorter + and shorter the farther down one goes). This diagram is called the + **Young diagram** of the partition, or more precisely its Young diagram + in English notation. (French and Russian notations are variations on this + representation.) The coordinate system related to a partition applies from the top to the bottom and from left to right. So, the corners of the @@ -1403,6 +1408,197 @@ def down_list(self): """ return [p for p in self.down()] + def cell_poset(self, orientation="SE"): + """ + Return the Young diagram of ``self`` as a poset. The optional + keyword variable ``orientation`` determines the order relation + of the poset. + + The poset always uses the set of cells of the Young diagram + of ``self`` as its ground set. The order relation of the poset + depends on the ``orientation`` variable (which defaults to + ``"SE"``). Concretely, ``orientation`` has to be specified to + one of the strings ``"NW"``, ``"NE"``, ``"SW"``, and ``"SE"``, + standing for "northwest", "northeast", "southwest" and + "southeast", respectively. If ``orientation`` is ``"SE"``, then + the order relation of the poset is such that a cell `u` is + greater or equal to a cell `v` in the poset if and only if `u` + lies weakly southeast of `v` (this means that `u` can be + reached from `v` by a sequence of south and east steps; the + sequence is allowed to consist of south steps only, or of east + steps only, or even be empty). Similarly the order relation is + defined for the other three orientations. The Young diagram is + supposed to be drawn in English notation. + + The elements of the poset are the cells of the Young diagram + of ``self``, written as tuples of zero-based coordinates (so + that `(3, 7)` stands for the `8`-th cell of the `4`-th row, + etc.). + + EXAMPLES:: + + sage: p = Partition([3,3,1]) + sage: Q = p.cell_poset(); Q + Finite poset containing 7 elements + sage: sorted(Q) + [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0)] + sage: sorted(Q.maximal_elements()) + [(1, 2), (2, 0)] + sage: Q.minimal_elements() + [(0, 0)] + sage: sorted(Q.upper_covers((1, 0))) + [(1, 1), (2, 0)] + sage: Q.upper_covers((1, 1)) + [(1, 2)] + + sage: P = p.cell_poset(orientation="NW"); P + Finite poset containing 7 elements + sage: sorted(P) + [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0)] + sage: sorted(P.minimal_elements()) + [(1, 2), (2, 0)] + sage: P.maximal_elements() + [(0, 0)] + sage: P.upper_covers((2, 0)) + [(1, 0)] + sage: sorted(P.upper_covers((1, 2))) + [(0, 2), (1, 1)] + sage: sorted(P.upper_covers((1, 1))) + [(0, 1), (1, 0)] + sage: sorted([len(P.upper_covers(v)) for v in P]) + [0, 1, 1, 1, 1, 2, 2] + + sage: R = p.cell_poset(orientation="NE"); R + Finite poset containing 7 elements + sage: sorted(R) + [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0)] + sage: R.maximal_elements() + [(0, 2)] + sage: R.minimal_elements() + [(2, 0)] + sage: sorted([len(R.upper_covers(v)) for v in R]) + [0, 1, 1, 1, 1, 2, 2] + sage: R.is_isomorphic(P) + False + sage: R.is_isomorphic(P.dual()) + False + + Linear extensions of ``p.cell_poset()`` are in 1-to-1 correspondence + with standard Young tableaux of shape `p`:: + + sage: all( len(p.cell_poset().linear_extensions()) + ....: == len(p.standard_tableaux()) + ....: for n in range(8) for p in Partitions(n) ) + True + + This is not the case for northeast orientation:: + + sage: q = Partition([3, 1]) + sage: q.cell_poset(orientation="NE").is_chain() + True + + TESTS: + + We check that the posets are really what they should be for size + up to `7`:: + + sage: def check_NW(n): + ....: for p in Partitions(n): + ....: P = p.cell_poset(orientation="NW") + ....: for c in p.cells(): + ....: for d in p.cells(): + ....: if P.le(c, d) != (c[0] >= d[0] + ....: and c[1] >= d[1]): + ....: return False + ....: return True + sage: all( check_NW(n) for n in range(8) ) + True + + sage: def check_NE(n): + ....: for p in Partitions(n): + ....: P = p.cell_poset(orientation="NE") + ....: for c in p.cells(): + ....: for d in p.cells(): + ....: if P.le(c, d) != (c[0] >= d[0] + ....: and c[1] <= d[1]): + ....: return False + ....: return True + sage: all( check_NE(n) for n in range(8) ) + True + + sage: def test_duality(n, ori1, ori2): + ....: for p in Partitions(n): + ....: P = p.cell_poset(orientation=ori1) + ....: Q = p.cell_poset(orientation=ori2) + ....: for c in p.cells(): + ....: for d in p.cells(): + ....: if P.lt(c, d) != Q.lt(d, c): + ....: return False + ....: return True + sage: all( test_duality(n, "NW", "SE") for n in range(8) ) + True + sage: all( test_duality(n, "NE", "SW") for n in range(8) ) + True + sage: all( test_duality(n, "NE", "SE") for n in range(4) ) + False + """ + from sage.combinat.posets.posets import Poset + covers = {} + if orientation == "NW": + for i, row in enumerate(self): + if i == 0: + covers[(0, 0)] = [] + for j in range(1, row): + covers[(0, j)] = [(0, j - 1)] + else: + covers[(i, 0)] = [(i - 1, 0)] + for j in range(1, row): + covers[(i, j)] = [(i - 1, j), (i, j - 1)] + elif orientation == "NE": + for i, row in enumerate(self): + if i == 0: + covers[(0, row - 1)] = [] + for j in range(row - 1): + covers[(0, j)] = [(0, j + 1)] + else: + covers[(i, row - 1)] = [(i - 1, row - 1)] + for j in range(row - 1): + covers[(i, j)] = [(i - 1, j), (i, j + 1)] + elif orientation == "SE": + l = len(self) - 1 + for i, row in enumerate(self): + if i == l: + covers[(i, row - 1)] = [] + for j in range(row - 1): + covers[(i, j)] = [(i, j + 1)] + else: + next_row = self[i + 1] + if row == next_row: + covers[(i, row - 1)] = [(i + 1, row - 1)] + for j in range(row - 1): + covers[(i, j)] = [(i + 1, j), (i, j + 1)] + else: + covers[(i, row - 1)] = [] + for j in range(next_row): + covers[(i, j)] = [(i + 1, j), (i, j + 1)] + for j in range(next_row, row - 1): + covers[(i, j)] = [(i, j + 1)] + elif orientation == "SW": + l = len(self) - 1 + for i, row in enumerate(self): + if i == l: + covers[(i, 0)] = [] + for j in range(1, row): + covers[(i, j)] = [(i, j - 1)] + else: + covers[(i, 0)] = [(i + 1, 0)] + next_row = self[i + 1] + for j in range(1, next_row): + covers[(i, j)] = [(i + 1, j), (i, j - 1)] + for j in range(next_row, row): + covers[(i, j)] = [(i, j - 1)] + return Poset(covers) + def frobenius_coordinates(self): """ Return a pair of sequences of Frobenius coordinates aka beta numbers @@ -1678,7 +1874,8 @@ def generalized_pochhammer_symbol(self, a, alpha): def get_part(self, i, default=Integer(0)): r""" - Return the `i^{th}` part of self, or ``default`` if it does not exist. + Return the `i^{th}` part of ``self``, or ``default`` if it does + not exist. EXAMPLES:: @@ -3948,7 +4145,7 @@ def jacobi_trudi(self): """ Return the Jacobi-Trudi matrix of ``self`` thought of as a skew partition. See :meth:`SkewPartition.jacobi_trudi() - `. + `. EXAMPLES:: @@ -4029,15 +4226,16 @@ def character_polynomial(self): def dimension(self, smaller = [], k = 1): r""" - This function computes the number of paths from the - ``smaller`` partition to the partition ``self``, where each step - consists of adding a `k`-ribbon while keeping a partition. + Return the number of paths from the ``smaller`` partition to + the partition ``self``, where each step consists of adding a + `k`-ribbon while keeping a partition. - Note that a 1-ribbon is just a single cell, so this gives path - lengths in the Young graph when `k = 1`. + Note that a 1-ribbon is just a single cell, so this counts paths + in the Young graph when `k = 1`. - Note also that the defaut case (`k = 1` and ``smaller = []``) gives the - dimension of characters of the symmetric groups. + Note also that the default case (`k = 1` and ``smaller = []``) + gives the dimension of the irreducible representation of the + symmetric group corresponding to ``self``. INPUT: @@ -4085,13 +4283,16 @@ def dimension(self, smaller = [], k = 1): A check coming from the theory of `k`-differentiable posets:: sage: k=2; core = Partition([2,1]) - sage: all(sum(mu.dimension(core,k=2)^2 for mu in Partitions(3+i*2) if mu.core(2) == core)==2^i*factorial(i) for i in range(10)) + sage: all(sum(mu.dimension(core,k=2)^2 + ....: for mu in Partitions(3+i*2) if mu.core(2) == core) + ....: == 2^i*factorial(i) for i in range(10)) True Checks that the dimension satisfies the obvious recursion relation:: sage: test = lambda larger, smaller: larger.dimension(smaller) == sum(mu.dimension(smaller) for mu in larger.down()) - sage: all(test(larger,smaller) for l in xrange(1,10) for s in xrange(0,10) for larger in Partitions(l) for smaller in Partitions(s) if smaller!=larger) + sage: all(test(larger,smaller) for l in xrange(1,10) for s in xrange(0,10) + ....: for larger in Partitions(l) for smaller in Partitions(s) if smaller != larger) True ALGORITHM: @@ -5188,7 +5389,7 @@ def random_element_uniform(self): TESTS:: sage: all(Part.random_element_uniform() in Part - ... for Part in map(Partitions, range(10))) + ....: for Part in map(Partitions, range(10))) True ALGORITHM: diff --git a/src/sage/combinat/permutation.py b/src/sage/combinat/permutation.py index 68c0b4c1de8..51496ff4f8a 100644 --- a/src/sage/combinat/permutation.py +++ b/src/sage/combinat/permutation.py @@ -21,7 +21,7 @@ i.e. the :meth:`Permutation` method and the :class:`~sage.combinat.permutation.Permutation` class. Global options for elements of the permutation class can be set through the -:meth:`PermutationOptions` method. +``PermutationOptions`` object. Below are listed all methods and classes defined in this file. @@ -240,7 +240,6 @@ from sage.graphs.digraph import DiGraph import itertools from combinat import CombinatorialObject, catalan_number -from necklace import Necklaces from sage.misc.misc import uniq from sage.misc.cachefunc import cached_method from backtrack import GenericBacktracker @@ -471,6 +470,9 @@ class Permutation(CombinatorialObject, Element): [] sage: Permutation( [[], []] ) [] + + .. automethod:: _left_to_right_multiply_on_right + .. automethod:: _left_to_right_multiply_on_left """ __metaclass__ = ClasscallMetaclass @@ -490,7 +492,6 @@ def __classcall_private__(cls, l, check_input = True): return l elif isinstance(l, PermutationGroupElement): l = l.domain() - #if l is a string, then assume it is in cycle notation elif isinstance(l, str): if l == "()" or l == "": @@ -506,10 +507,10 @@ def __classcall_private__(cls, l, check_input = True): #if l is a pair of standard tableaux or a pair of lists elif isinstance(l, (tuple, list)) and len(l) == 2 and \ - all(map(lambda x: isinstance(x, tableau.Tableau), l)): + all(isinstance(x, tableau.Tableau) for x in l): return RSK_inverse(*l, output='permutation') elif isinstance(l, (tuple, list)) and len(l) == 2 and \ - all(map(lambda x: isinstance(x, list), l)): + all(isinstance(x, list) for x in l): P,Q = map(tableau.Tableau, l) return RSK_inverse(P, Q, 'permutation') @@ -517,7 +518,7 @@ def __classcall_private__(cls, l, check_input = True): # notation elif isinstance(l, tuple) or \ (isinstance(l, list) and len(l) > 0 and - all(map(lambda x: isinstance(x, tuple), l))): + all(isinstance(x, tuple) for x in l)): if len(l) >= 1 and (isinstance(l[0],(int,Integer)) or len(l[0]) > 0): if isinstance(l[0], tuple): n = max( map(max, l) ) @@ -5489,6 +5490,9 @@ def from_reduced_word(rw): return Permutation(p) from sage.misc.superseded import deprecated_function_alias + +# Don't forget to remove the robinson_schensted_inverse entry in the index at +# the top of the file when this line will be removed robinson_schensted_inverse = deprecated_function_alias(8392, RSK_inverse) def bistochastic_as_sum_of_permutations(M, check = True): @@ -6398,6 +6402,7 @@ def __iter__(self, distinct=False): for i in index_list: content[i] += 1 + from necklace import Necklaces for necklace in Necklaces(content): yield [self.mset[x-1] for x in necklace] diff --git a/src/sage/combinat/permutation_cython.pyx b/src/sage/combinat/permutation_cython.pyx index 3c2d2147cab..63495529fa6 100644 --- a/src/sage/combinat/permutation_cython.pyx +++ b/src/sage/combinat/permutation_cython.pyx @@ -162,7 +162,7 @@ def permutation_iterator_transposition_list(int n): try: T = PyList_New(N-1) - except StandardError: + except Exception: sage_free(c) raise MemoryError, "Failed to allocate memory in permutation_iterator_transposition_list" diff --git a/src/sage/combinat/posets/hasse_diagram.py b/src/sage/combinat/posets/hasse_diagram.py index 51f5fb73477..085abbae54e 100644 --- a/src/sage/combinat/posets/hasse_diagram.py +++ b/src/sage/combinat/posets/hasse_diagram.py @@ -46,11 +46,6 @@ class HasseDiagram(DiGraph): Hasse diagram of a poset containing 4 elements sage: TestSuite(H).run() """ - - # Hasse diagrams are immutable. This temporary hack enables the - # __hash__ method of DiGraph - _immutable = True - def _repr_(self): r""" TESTS:: diff --git a/src/sage/combinat/posets/poset_examples.py b/src/sage/combinat/posets/poset_examples.py index a1850d8b620..2b9645cb3ba 100644 --- a/src/sage/combinat/posets/poset_examples.py +++ b/src/sage/combinat/posets/poset_examples.py @@ -355,7 +355,7 @@ def RandomPoset(n,p): raise ValueError("number of elements must be non-negative, not {0}".format(n)) try: p = float(p) - except StandardError: + except Exception: raise TypeError("probability must be a real number, not {0}".format(p)) if p < 0 or p> 1: raise ValueError("probability must be between 0 and 1, not {0}".format(p)) diff --git a/src/sage/combinat/posets/posets.py b/src/sage/combinat/posets/posets.py index 590cea342d3..66398856558 100644 --- a/src/sage/combinat/posets/posets.py +++ b/src/sage/combinat/posets/posets.py @@ -544,7 +544,7 @@ def Poset(data=None, element_labels=None, cover_relations=False, linear_extensio # Compute a linear extension of the poset (a topological sort). try: lin_ext = D.topological_sort() - except StandardError: + except Exception: raise ValueError, "Hasse diagram contains cycles." # Relabel using the linear_extension. @@ -740,7 +740,7 @@ def __classcall__(cls, hasse_diagram, elements = None, category = None, facade = facade = hasse_diagram in Sets().Facades() hasse_diagram = hasse_diagram._hasse_diagram else: - hasse_diagram = HasseDiagram(hasse_diagram) + hasse_diagram = HasseDiagram(hasse_diagram, data_structure="static_sparse") if elements is None: elements = hasse_diagram.vertices() if facade is None: @@ -1477,21 +1477,23 @@ def to_graph(self): EXAMPLES:: sage: P = Poset({0:[1,2],1:[3],2:[3],3:[]}) - sage: P.to_graph() - Graph on 4 vertices - sage: P = Poset() sage: G = P.to_graph(); G + Graph on 4 vertices + sage: S = Poset() + sage: H = S.to_graph(); H Graph on 0 vertices - Check that it is hashable:: + Check that it is hashable and coincides with the Hasse diagram as a + graph:: sage: hash(G) == hash(G) True + sage: G == Graph(P.hasse_diagram()) + True + """ from sage.graphs.graph import Graph - G = Graph(self.hasse_diagram()) - G._immutable = True - return G + return Graph(self.hasse_diagram(), immutable=True) def level_sets(self): """ diff --git a/src/sage/combinat/rigged_configurations/bij_type_B.py b/src/sage/combinat/rigged_configurations/bij_type_B.py index ab436141679..2ea4fcdccf3 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_B.py +++ b/src/sage/combinat/rigged_configurations/bij_type_B.py @@ -437,7 +437,7 @@ def next_state(self, val): if singular_max_width: try: self.ret_rig_con.check() - except StandardError: + except Exception: self.other_outcome(cp, pos_val, width_n) def other_outcome(self, rc, pos_val, width_n): diff --git a/src/sage/combinat/root_system/branching_rules.py b/src/sage/combinat/root_system/branching_rules.py index 986d255e955..9ee05fdac1c 100644 --- a/src/sage/combinat/root_system/branching_rules.py +++ b/src/sage/combinat/root_system/branching_rules.py @@ -1348,7 +1348,7 @@ def br(x): if Stype.is_compound() and s == r-1: try: return branching_rule(Rtype, Stype, rule="levi") - except StandardError: + except Exception: pass if Rtype[0] == "A": if Stype[0] == "B" and r == 2*s: @@ -1365,7 +1365,7 @@ def br(x): if s == r-1: try: return branching_rule(Rtype, Stype, rule="levi") - except StandardError: + except Exception: pass raise ValueError("No default rule found (you must specify the rule)") elif rule == "identity": diff --git a/src/sage/combinat/root_system/cartan_matrix.py b/src/sage/combinat/root_system/cartan_matrix.py index d1a3897915d..ee2f34c514d 100644 --- a/src/sage/combinat/root_system/cartan_matrix.py +++ b/src/sage/combinat/root_system/cartan_matrix.py @@ -211,6 +211,18 @@ def __classcall_private__(cls, *args, **kwds): sage: C3 = CartanMatrix(matrix([[2, -2], [-2, 2]]), [0, 1]) sage: C == C2 and C == C3 True + + TESTS: + + Check that :trac:`15740` is fixed:: + + sage: d = DynkinDiagram() + sage: d.add_edge('a', 'b', 2) + sage: d.index_set() + ('a', 'b') + sage: cm = CartanMatrix(d) + sage: cm.index_set() + ('a', 'b') """ # Special case with 0 args and kwds has cartan type if "cartan_type" in kwds and len(args) == 0: @@ -251,7 +263,7 @@ def __classcall_private__(cls, *args, **kwds): else: M = matrix(args[0]) if not is_generalized_cartan_matrix(M): - raise ValueError("The input matrix is not a generalized Cartan matrix.") + raise ValueError("the input matrix is not a generalized Cartan matrix") n = M.ncols() if "cartan_type" in kwds: cartan_type = CartanType(kwds["cartan_type"]) @@ -265,14 +277,14 @@ def __classcall_private__(cls, *args, **kwds): if len(args) == 1: if cartan_type is not None: index_set = tuple(cartan_type.index_set()) - else: + elif dynkin_diagram is None: index_set = tuple(range(n)) elif len(args) == 2: index_set = tuple(args[1]) if len(index_set) != n and len(set(index_set)) != n: - raise ValueError("The given index set is not valid.") + raise ValueError("the given index set is not valid") else: - raise ValueError("Too many arguments.") + raise ValueError("too many arguments") mat = typecall(cls, MatrixSpace(ZZ, n, sparse=True), data, cartan_type, index_set) mat._subdivisions = subdivisions diff --git a/src/sage/combinat/root_system/cartan_type.py b/src/sage/combinat/root_system/cartan_type.py index 592904fe8e4..1f2066afabf 100644 --- a/src/sage/combinat/root_system/cartan_type.py +++ b/src/sage/combinat/root_system/cartan_type.py @@ -1223,7 +1223,7 @@ def is_implemented(self): try: self.coxeter_diagram() return True - except StandardError: + except Exception: return False def root_system(self): diff --git a/src/sage/combinat/root_system/dynkin_diagram.py b/src/sage/combinat/root_system/dynkin_diagram.py index 3c5eeb47b1e..886bbfbafc2 100644 --- a/src/sage/combinat/root_system/dynkin_diagram.py +++ b/src/sage/combinat/root_system/dynkin_diagram.py @@ -558,6 +558,36 @@ def is_crystallographic(self): is_crystalographic = deprecated_function_alias(14673, is_crystallographic) + def symmetrizer(self): + """ + Return the symmetrizer of the corresponding Cartan matrix. + + EXAMPLES:: + + sage: d = DynkinDiagram() + sage: d.add_edge(1,2,3) + sage: d.add_edge(2,3) + sage: d.add_edge(3,4,3) + sage: d.symmetrizer() + Finite family {1: 9, 2: 3, 3: 3, 4: 1} + + TESTS: + + We check that :trac:`15740` is fixed:: + + sage: d = DynkinDiagram() + sage: d.add_edge(1,2,3) + sage: d.add_edge(2,3) + sage: d.add_edge(3,4,3) + sage: L = d.root_system().root_lattice() + sage: al = L.simple_roots() + sage: al[1].associated_coroot() + alphacheck[1] + sage: al[1].reflection(al[2]) + alpha[1] + 3*alpha[2] + """ + return self.cartan_matrix().symmetrizer() + def __getitem__(self, i): r""" With a tuple (i,j) as argument, returns the scalar product diff --git a/src/sage/combinat/root_system/root_system.py b/src/sage/combinat/root_system/root_system.py index 544e015c602..2c699768006 100644 --- a/src/sage/combinat/root_system/root_system.py +++ b/src/sage/combinat/root_system/root_system.py @@ -336,7 +336,7 @@ def __init__(self, cartan_type, as_dual_of=None): # still fails for CartanType G2xA1 try: self.dual = RootSystem(self._cartan_type.dual(), as_dual_of=self); - except StandardError: + except Exception: pass else: self.dual_side = True diff --git a/src/sage/combinat/root_system/weyl_characters.py b/src/sage/combinat/root_system/weyl_characters.py index f4ca0e154bd..e9e59302341 100644 --- a/src/sage/combinat/root_system/weyl_characters.py +++ b/src/sage/combinat/root_system/weyl_characters.py @@ -2009,6 +2009,6 @@ def demazure_lusztig(self, i, v): else: try: return self.demazure_lusztig(i.reduced_word(),v) - except StandardError: + except Exception: raise ValueError("unknown index {}".format(i)) diff --git a/src/sage/combinat/root_system/weyl_group.py b/src/sage/combinat/root_system/weyl_group.py index 69b6ccbd148..c59c47077c6 100644 --- a/src/sage/combinat/root_system/weyl_group.py +++ b/src/sage/combinat/root_system/weyl_group.py @@ -348,7 +348,7 @@ def reflections(self): r = self(m) ret[r] = alp return Family(ret) - except StandardError: + except Exception: raise NotImplementedError, "reflections are only implemented for finite Weyl groups" def _repr_(self): diff --git a/src/sage/combinat/sf/classical.py b/src/sage/combinat/sf/classical.py index f3ac3bb99ed..ef4ff281f51 100644 --- a/src/sage/combinat/sf/classical.py +++ b/src/sage/combinat/sf/classical.py @@ -325,7 +325,7 @@ def _element_constructor_(self, x): else: try: return eclass(self, {sage.combinat.partition.Partition([]):R(x)}) - except StandardError: + except Exception: raise TypeError, "do not know how to make x (= %s) an element of self"%(x) # This subclass is currently needed for the test above: diff --git a/src/sage/combinat/sf/monomial.py b/src/sage/combinat/sf/monomial.py index f0a8433dfc2..cf73a5a371a 100644 --- a/src/sage/combinat/sf/monomial.py +++ b/src/sage/combinat/sf/monomial.py @@ -173,7 +173,7 @@ def from_polynomial(self, f, check=True): out = self.sum_of_terms((Partition(e), c) for (e,c) in f.dict().iteritems() if tuple(sorted(e)) == tuple(reversed(e))) - if check and out.expand(f.parent().ngens(),f.parent().gens()) <> f: + if check and out.expand(f.parent().ngens(),f.parent().gens()) != f: raise ValueError, "%s is not a symmetric polynomial"%f return out diff --git a/src/sage/combinat/sf/sfa.py b/src/sage/combinat/sf/sfa.py index 52700def14f..4943228da17 100644 --- a/src/sage/combinat/sf/sfa.py +++ b/src/sage/combinat/sf/sfa.py @@ -214,12 +214,11 @@ from sage.misc.cachefunc import cached_method from sage.rings.all import Integer, PolynomialRing, is_Polynomial, is_MPolynomial, QQ import sage.combinat.partition -from sage.combinat.partition import Partitions +from sage.combinat.partition import _Partitions, Partitions import sage.libs.symmetrica.all as symmetrica # used in eval() from sage.combinat.free_module import CombinatorialFreeModule from sage.matrix.constructor import matrix from sage.misc.misc import prod, uniq -from functools import partial from copy import copy @@ -829,6 +828,54 @@ def corresponding_basis_over(self, R): #This code relied heavily on the construction of bases of #``SymmetricFunctions`` and on their reduction. + def Eulerian(self, n, j, k=None): + """ + Return the Eulerian symmetric function `Q_{n,j}` (with `n` + either an integer or a partition) or `Q_{n,j,k}` (if the + optional argument ``k`` is specified) in terms of the basis + ``self``. + + It is known that the Eulerian quasisymmetric functions are + in fact symmetric functions [SW2010]_. For more information, + see :meth:`QuasiSymmetricFunctions.Fundamental.Eulerian()`, + which accepts the same syntax as this method. + + INPUT: + + - ``n`` -- the nonnegative integer `n` or a partition + - ``j`` -- the number of excedances + - ``k`` -- (optional) if specified, determines the number of fixed + points of the permutations which are being summed over + + EXAMPLES:: + + sage: Sym = SymmetricFunctions(QQ) + sage: m = Sym.m() + sage: m.Eulerian(3, 1) + 4*m[1, 1, 1] + 3*m[2, 1] + 2*m[3] + sage: h = Sym.h() + sage: h.Eulerian(4, 2) + h[2, 2] + h[3, 1] + h[4] + sage: s = Sym.s() + sage: s.Eulerian(5, 2) + s[2, 2, 1] + s[3, 1, 1] + 5*s[3, 2] + 6*s[4, 1] + 6*s[5] + sage: s.Eulerian([2,2,1], 2) + s[2, 2, 1] + s[3, 2] + s[4, 1] + s[5] + sage: s.Eulerian(5, 2, 2) + s[3, 2] + s[4, 1] + s[5] + + We check Equation (5.4) in [SW2010]_:: + + sage: h.Eulerian([6], 3) + h[3, 2, 1] - h[4, 1, 1] + 2*h[4, 2] + h[5, 1] + sage: s.Eulerian([6], 3) + s[3, 2, 1] + s[3, 3] + 3*s[4, 2] + 3*s[5, 1] + 3*s[6] + """ + from sage.combinat.ncsf_qsym.qsym import QuasiSymmetricFunctions + F = QuasiSymmetricFunctions(self.base_ring()).F() + if n in _Partitions: + n = _Partitions(n) + return self(F.Eulerian(n, j, k).to_symmetric_function()) class ElementMethods: @@ -890,7 +937,7 @@ def __init__(self, Sym, basis_name = None, prefix = None): raise TypeError("Argument R must be a commutative ring.") try: R(Integer(1)) - except StandardError: + except Exception: raise ValueError("R must have a unit element") if basis_name is not None: @@ -898,7 +945,7 @@ def __init__(self, Sym, basis_name = None, prefix = None): if prefix is not None: self._prefix = prefix self._sym = Sym - CombinatorialFreeModule.__init__(self, Sym.base_ring(), sage.combinat.partition.Partitions(), + CombinatorialFreeModule.__init__(self, Sym.base_ring(), _Partitions, category = SymmetricFunctionsBases(Sym), bracket = "", prefix = prefix) @@ -1153,7 +1200,7 @@ def _from_cache(self, element, cache_function, cache_dict, **subs_dict): cache_function(sum(part)) # Make sure it is a partition (for #13605), this is # needed for the old kschur functions - TCS - part = Partitions()(part) + part = _Partitions(part) for part2, c2 in cache_dict[sum(part)][part].iteritems(): if hasattr(c2,'subs'): # c3 may be in the base ring c3 = c*BR(c2.subs(**subs_dict)) @@ -1617,7 +1664,7 @@ def _gram_schmidt(self, n, source, scalar, cache, leading_coeff=None, upper_tria # We are going to be doing everything like we are in the upper-triangular case # We list the partitions in "decreasing order" and work from the beginning forward. # If we are in the lower-triangular case, then we shouldn't reverse the list - l = sage.combinat.partition.Partitions(n).list() + l = Partitions(n).list() if upper_triangular: l.reverse() @@ -1644,6 +1691,150 @@ def _gram_schmidt(self, n, source, scalar, cache, leading_coeff=None, upper_tria cache[l[i]][l[j]] = res.coefficient(l[j]) + def _inner_plethysm_pk_g(self, k, g, cache): + r""" + Return the inner plethysm between the power-sum symmetric + function `p_k` and the symmetric function ``g``. + + See :meth:`inner_plethysm` for the definition of inner + plethysm. + + .. WARNING:: + + The function ``g`` *must* be given in the power-sum + basis for this method to return a correct result. + + ALGORITHM: + + Express ``g`` in the power sum basis as + `g = \sum_\mu c_\mu p_\mu/z_\mu` + (where `z_\mu` is the size of the centralizer of any + permutation with cycle type `\mu`). Then, the inner plethysm + is calculated as + + .. MATH:: + + p_k \{ g \} = \sum_\mu c_\mu p_k \{ p_\mu/z_\mu \}~. + + The inner plethysm `p_k \{ p_mu/z_\mu \}` is given by the formula + + .. MATH:: + + p_k \{ p_\mu/z_\mu \} = \sum_{\nu : \nu^k = \mu } p_{\nu}/z_{\nu}~, + + where `\nu^k` is the `k`-th power of `nu` (see + :~sage.combinat.partition.partition_power`). + + .. SEEALSO:: :func:`~sage.combinat.partition.partition_power`, + :meth:`~sage.combinat.sf.sfa.SymmetricFunctionAlgebra_generic_Element.inner_plethysm` + + INPUT: + + - ``k`` -- a positive integer + + - ``g`` -- a symmetric function in the power sum basis + + - ``cache`` -- a dictionary whose keys are (k, g) pairs + and values are the cached output of this function + + EXAMPLES:: + + sage: p = SymmetricFunctions(QQ).p() + sage: p._inner_plethysm_pk_g(2, p([1,1,1]), {}) + p[1, 1, 1] + 3*p[2, 1] + sage: p._inner_plethysm_pk_g(5, p([2,2,1,1,1]), {}) + p[2, 2, 1, 1, 1] + """ + try: + return cache[(k,g)] + except KeyError: + pass + + p = self.realization_of().p() + res = 0 + degrees = uniq([ sum(m) for m in g.support() ]) + for d in degrees: + for mu in sage.combinat.partition.Partitions(d): + mu_k = mu.power(k) + if mu_k in g: + res += g.coefficient(mu_k)*mu_k.centralizer_size()/mu.centralizer_size()*p(mu) + + cache[(k,g)] = res + return res + + def _inner_plethysm_pnu_g(self, p_x, cache, nu): + r""" + Return the inner plethysm of the power-sum symmetric function + `p_\nu` with another symmetric function ``p_x`` in the + power-sum basis. + + See :meth:`inner_plethysm` for the definition of inner + plethysm. + + .. WARNING:: + + The function ``p_x`` *must* be given in the power-sum + basis for this method to return a correct result. + + The computation uses the inner plethysm of `p_k` and ``p_x`` + and the identity + + .. MATH:: + + (f \cdot g) \{ h \} = (f \{ h \}) \ast (g \{ h \})~. + + .. SEEALSO:: :meth:`_inner_plethysm_pk_g`, + :meth:`~sage.combinat.sf.sfa.SymmetricFunctionAlgebra_generic_Element.itensor`, + :meth:`~sage.combinat.sf.sfa.SymmetricFunctionAlgebra_generic_Element.inner_plethysm` + + INPUT: + + - ``p_x`` -- a symmetric function in the power sum basis + + - ``cache`` -- a cache function + + - ``nu`` -- a partition + + Note that the order of the arguments is somewhat strange in order + to facilitate partial function application. + + OUTPUT: + + - an element of the basis ``self`` + + EXAMPLES:: + + sage: p = SymmetricFunctions(QQ).p() + sage: s = SymmetricFunctions(QQ).s() + sage: p._inner_plethysm_pnu_g( p([1,1,1]), {}, Partition([2,1])) + 6*p[1, 1, 1] + sage: p._inner_plethysm_pnu_g( p([1,1,1]), {}, Partition([])) + 1/6*p[1, 1, 1] + 1/2*p[2, 1] + 1/3*p[3] + sage: s(_) + s[3] + """ + #We handle the constant term case separately. It should be + #the case that p([]).inner_tensor(s(mu)) = s([ mu.size() ]). + #Here, we get the degrees of the homogeneous pieces of + if len(nu) == 0: + s = self.realization_of().s() + degrees = [ part.size() for part in p_x.support() ] + degrees = uniq(degrees) + if 0 in degrees: + ext = self([]) + else: + ext = 0 + return ext + self(sum([s([n]) for n in degrees if n!=0])) + + #For each k in nu, we compute the inner plethysm of + #p_k with p_x + res = [self._inner_plethysm_pk_g(k, p_x, cache) for k in nu] + + #To get the final answer, we compute the inner tensor product + #of all the symmetric functions in res + return self(reduce(lambda x, y: 0 if x==0 else x.itensor(y), res)) + + def _dual_basis_default(self): """ Returns the default value for ``self.dual_basis()`` @@ -2034,141 +2225,101 @@ def plethysm(self, x, include=None, exclude=None): __call__ = plethysm - def _inner_plethysm_pk_g(self, k, g, cache): + def inner_plethysm(self, x): r""" - Return the inner plethysm between `p_k` and ``g``. + Return the inner plethysm of ``self`` with ``x``. - INPUT: + Whenever `R` is a `\QQ`-algebra, and `f` and `g` are two + symmetric functions over `R` such that the constant term of `f` + is zero, the inner plethysm of `f` with `g` is a symmetric + function over `R`, and the degree of this symmetric function is + the same as the degree of `g`. We will denote the inner plethysm + of `f` with `g` by `f \{ g \}` (in contrast to the notation of + outer plethysm which is generally denoted `f [ g ]`); in Sage + syntax, it is ``f.inner_plethysm(g)``. + + First we describe the axiomatic definition of the operation; see + below for a representation-theoretic interpretation. + In the following equations, we denote the outer product + (i.e., the standard product on the ring of symmetric functions, + :meth:`~sage.categories.algebras_with_basis.AlgebrasWithBasis.ParentMethods.product`) + by `\cdot` and the Kronecker product (:meth:`itensor`) by `\ast`). - - ``k`` -- a positive integer + .. MATH:: - - ``g`` -- a symmetric function in the power sum basis + (f + g) \{ h \} = f \{ h \} + g \{ h \} - - ``cache`` -- a dictionary whose keys are (k, g) pairs - and values are the cached output of this function + (f \cdot g) \{ h \} = (f \{ h \}) \ast (g \{ h \}) - EXAMPLES:: + p_k \{ f + g \} = p_k \{ f \} + p_k \{ g \} - sage: p = SymmetricFunctions(QQ).p() - sage: _inner_plethysm_pk_g = p(0)._inner_plethysm_pk_g - sage: _inner_plethysm_pk_g(2, p([1,1,1]), {}) - p[1, 1, 1] + 3*p[2, 1] - sage: _inner_plethysm_pk_g(5, p([2,2,1,1,1]), {}) - p[2, 2, 1, 1, 1] - """ - try: - return cache[(k,g)] - except KeyError: - pass + where `p_k` is the `k`-th power-sum symmetric function for every + `k > 0`. - p = self.parent().realization_of().p() - res = 0 - degrees = uniq([ sum(m) for m in g.support() ]) - for d in degrees: - for mu in sage.combinat.partition.Partitions(d): - mu_k = mu.power(k) - if mu_k in g: - res += g.coefficient(mu_k)*mu_k.centralizer_size()/mu.centralizer_size()*p(mu) + Let `\sigma` be a permutation of cycle type `\mu` and let `\mu^k` + be the cycle type of `\sigma^k`. Then, - cache[(k,g)] = res - return res + .. MATH:: - def _inner_plethysm_pnu_g(self, p_x, cache, nu): - r""" - Return the inner plethysm of `p_\nu` with another symmetric function - ``p_x`` in the power-sum basis. + p_k \{ p_\mu/z_\mu \} = \sum_{\nu : \nu^k = \mu } p_{\nu}/z_{\nu} - INPUT: + Since `(p_\mu/z_\mu)_{\mu}` is a basis for the symmetric + functions, these four formulas define the symmetric function + operation `f \{ g \}` for any symmetric functions `f` and `g` + (where `f` has constant term `0`) by expanding `f` in the + power sum basis and `g` in the dual basis `p_\mu/z_\mu`. - - ``p_x`` -- a symmetric function in the power sum basis + .. SEEALSO:: :meth:`itensor`, :func:`~sage.combinat.partition.partition_power`, + :meth:`plethysm` - - ``cache`` -- a cache function + This operation admits a representation-theoretic interpretation + in the case where `f` is a Schur function `s_\lambda` and + `g` is a homogeneous degree `n` symmetric function with + nonnegative integral coefficients in the Schur basis. + The symmetric function `f \{ g \}` is the Frobenius + image of the `S_n`-representation constructed as follows. - - ``nu`` -- a partition + The assumptions on `g` imply that `g` is the Frobenius image of a + representation `\rho` of the symmetric group `S_n`: - Note that the order of the arguments is somewhat strange in order - to facilitate partial function application. + .. MATH:: - EXAMPLES:: + \rho : S_n \to GL_N. - sage: p = SymmetricFunctions(QQ).p() - sage: s = SymmetricFunctions(QQ).s() - sage: _inner_plethysm_pnu_g = p(0)._inner_plethysm_pnu_g - sage: _inner_plethysm_pnu_g( p([1,1,1]), {}, Partition([2,1])) - 6*p[1, 1, 1] - sage: _inner_plethysm_pnu_g( p([1,1,1]), {}, Partition([])) - 1/6*p[1, 1, 1] + 1/2*p[2, 1] + 1/3*p[3] - sage: s(_) - s[3] - """ - #We handle the constant term case separately. It should be - #the case that p([]).inner_tensor(s(mu)) = s([ mu.size() ]). - #Here, we get the degrees of the homogeneous pieces of - if len(nu) == 0: - s = self.parent().realization_of().s() - p = self.parent().realization_of().p() - degrees = [ part.size() for part in p_x.support() ] - degrees = uniq(degrees) - if 0 in degrees: - ext = p([]) - else: - ext = 0 - return ext + p(sum([s([n]) for n in degrees if n!=0])) + If the degree `N` of this representation is greater than or equal + to the number of parts of `\lambda`, then `f`, which denotes `s_\lambda`, + corresponds to the character of some irreducible `GL_N`-representation, say - #For each k in nu, we compute the inner plethysm of - #p_k with p_x - res = [self._inner_plethysm_pk_g(k, p_x, cache) for k in nu] + .. MATH:: - #To get the final answer, we compute the inner tensor product - #of all the symmetric functions in res - return reduce(lambda x, y: x.itensor(y), res) + \sigma : GL_N \to GL_M. - def inner_plethysm(self, x): - r""" - Return the inner plethysm of ``self`` with ``x``. + The composition `\sigma \circ \rho : S_n \to GL_M` is a representation + of `S_n` whose Frobenius image is precisely `f \{ g \}`. - Whenever `R` is a `\QQ`-algebra, and `f` and `g` are two - symmetric functions over `R` such that the constant term of `f` - is zero, the inner plethysm ``f.inner_plethysm(g)`` is a - well-defined symmetric function over `R`. Here is one way to define - it: - - The result of ``f.inner_plethysm(g)`` is linear in `f` and linear in - 'homogeneous pieces' of `g` (the latter statement meaning that - ``f.inner_plethysm(g + h) == f.inner_plethysm(g) + f.inner_plethysm(h)`` - when `g` and `h` are homogeneous of different degrees). So, to - describe this function, we assume without loss that `f` is some Schur - function `s_\lambda` and `g` is a homogeneous symmetric function of - degree `n`. In this situation, the value of ``f.inner_plethysm(g)`` - is a polynomial in the coefficients of `g` (in the Schur basis) - depending only on `f`. Hence, in order to determine its values, we - only need to determine its values in the case when `g` is - Schur-positive with integral coefficients in the Schur basis (the - values at all the other `g` will then be computable using Lagrange - interpolation). Assuming this, we can think of the function `g` - as the character of a representation of the general linear group, - and hence (by Schur-Weyl duality) as the character of a representation - `\rho` of the symmetric group `S_n`. Let `N` be the dimension of - this representation. If the number of parts of `\lambda` is greater - than `N`, then ``f.inner_plethysm(g)`` `= 0` by definition. Otherwise, - we can interpret `f` as the character of an irreducible - `GL_N`-representation, call it `\sigma`. Now - `\sigma \circ \rho` is an `S_n`-representation, hence (by - Schur-Weyl duality) corresponds to a representation of the general - linear group. By definition, the character of this representation is - ``f.inner_plethysm(g)``. + If `N` is less than the number of parts of `\lambda`, + then `f \{ g \}` is `0` by definition. When `f` is a symmetric function with constant term `\neq 0`, the - inner plethysm ``f.inner_plethysm(g)`` isn't well-defined in the - ring of symmetric functions. Indeed, it is not clear how to define - ``1.inner_plethysm(g)``. The most sensible way to get around this - probably is defining it as the infinite sum `h_0 + h_1 + h_2 + \cdots` - (where `h_i` means the `i`-th complete homogeneous symmetric function) + inner plethysm `f \{ g \}` isn't well-defined in the ring of + symmetric functions. Indeed, it is not clear how to define + `1 \{ g \}`. The most sensible way to get around this probably is + defining it as the infinite sum `h_0 + h_1 + h_2 + \cdots` (where + `h_i` means the `i`-th complete homogeneous symmetric function) in the completion of this ring with respect to its grading. This is - how [SchaThi1994]_ defines ``1.inner_plethysm(g)``. The present - method, however, sets it to be the sum of `h_i` over all `i` for - which the `i`-th homogeneous component of `g` is nonzero. This is - rather a hack than a reasonable definition. Use with caution! + how [SchaThi1994]_ defines `1 \{ g \}`. The present method, + however, sets it to be the sum of `h_i` over all `i` for which the + `i`-th homogeneous component of `g` is nonzero. This is rather a + hack than a reasonable definition. Use with caution! + + .. NOTE:: + + If a symmetric function `g` is written in the form + `g = g_0 + g_1 + g_2 + \cdots` with each `g_i` homogeneous + of degree `i`, then + `f \{ g \} = f \{ g_0 \} + f \{ g_1 \} + f \{ g_2 \} + \cdots` + for every `f` with constant term `0`. But in general, inner + plethysm is not linear in the second variable. REFERENCES: @@ -2186,6 +2337,10 @@ def inner_plethysm(self, x): - ``x`` -- element of the ring of symmetric functions over the same base ring as ``self`` + OUTPUT: + + - an element of symmetric functions in the parent of ``self`` + EXAMPLES:: sage: Sym = SymmetricFunctions(QQ) @@ -2200,14 +2355,6 @@ def inner_plethysm(self, x): s[1, 1, 1] sage: s[2,1].inner_tensor(s[2,1]) s[1, 1, 1] + s[2, 1] + s[3] - sage: s(0).inner_plethysm(s(0)) - 0 - sage: s(1).inner_plethysm(s(0)) - 0 - sage: s(0).inner_plethysm(s(1)) - 0 - sage: s(1).inner_plethysm(s(1)) - s[] :: @@ -2221,20 +2368,51 @@ def inner_plethysm(self, x): sage: s([]).inner_plethysm(s([1,1]) + 2*s([2,1])+s([3])) s[2] + s[3] - sage: [s([]).inner_plethysm(s(p)) for p in Partitions(4)] + sage: [s([]).inner_plethysm(s(la)) for la in Partitions(4)] [s[4], s[4], s[4], s[4], s[4]] + sage: s([3]).inner_plethysm(s([])) + s[] + sage: s[1,1,1,1].inner_plethysm(s[2,1]) + 0 + sage: s[1,1,1,1].inner_plethysm(2*s[2,1]) + s[3] + + :: + + sage: p[3].inner_plethysm(p[3]) + 0 + sage: p[3,3].inner_plethysm(p[3]) + 0 + sage: p[3].inner_plethysm(p[1,1,1]) + p[1, 1, 1] + 2*p[3] + sage: p[4].inner_plethysm(p[1,1,1,1]/24) + 1/24*p[1, 1, 1, 1] + 1/4*p[2, 1, 1] + 1/8*p[2, 2] + 1/4*p[4] + sage: p[3,3].inner_plethysm(p[1,1,1]) + 6*p[1, 1, 1] + 12*p[3] + + TESTS:: + + sage: s(0).inner_plethysm(s(0)) + 0 + sage: s(1).inner_plethysm(s(0)) + 0 + sage: s(0).inner_plethysm(s(1)) + 0 + sage: s(1).inner_plethysm(s(1)) + s[] + sage: s(2).inner_plethysm(s(1)) + 2*s[] + sage: s(1).inner_plethysm(s(2)) + s[] """ parent = self.parent() if self == parent.zero(): return self p = parent.realization_of().power() - - p_x = p(x) - cache = {} - f = partial(self._inner_plethysm_pnu_g, p_x, cache) + ip_pnu_g = parent._inner_plethysm_pnu_g + return sum(c*ip_pnu_g(p(x), cache, nu) for (nu, c) in p(self).monomial_coefficients().iteritems()) - return parent(p._apply_module_morphism(p(self), f)) def omega(self): r""" diff --git a/src/sage/combinat/skew_partition.py b/src/sage/combinat/skew_partition.py index 029b71b6a55..76624f2b6a5 100644 --- a/src/sage/combinat/skew_partition.py +++ b/src/sage/combinat/skew_partition.py @@ -709,6 +709,135 @@ def inner_corners(self): icorners += [(nn, 0)] return icorners + def cell_poset(self, orientation="SE"): + """ + Return the Young diagram of ``self`` as a poset. The optional + keyword variable ``orientation`` determines the order relation + of the poset. + + The poset always uses the set of cells of the Young diagram + of ``self`` as its ground set. The order relation of the poset + depends on the ``orientation`` variable (which defaults to + ``"SE"``). Concretely, ``orientation`` has to be specified to + one of the strings ``"NW"``, ``"NE"``, ``"SW"``, and ``"SE"``, + standing for "northwest", "northeast", "southwest" and + "southeast", respectively. If ``orientation`` is ``"SE"``, then + the order relation of the poset is such that a cell `u` is + greater or equal to a cell `v` in the poset if and only if `u` + lies weakly southeast of `v` (this means that `u` can be + reached from `v` by a sequence of south and east steps; the + sequence is allowed to consist of south steps only, or of east + steps only, or even be empty). Similarly the order relation is + defined for the other three orientations. The Young diagram is + supposed to be drawn in English notation. + + The elements of the poset are the cells of the Young diagram + of ``self``, written as tuples of zero-based coordinates (so + that `(3, 7)` stands for the `8`-th cell of the `4`-th row, + etc.). + + EXAMPLES:: + + sage: p = SkewPartition([[3,3,1], [2,1]]) + sage: Q = p.cell_poset(); Q + Finite poset containing 4 elements + sage: sorted(Q) + [(0, 2), (1, 1), (1, 2), (2, 0)] + sage: sorted(Q.maximal_elements()) + [(1, 2), (2, 0)] + sage: sorted(Q.minimal_elements()) + [(0, 2), (1, 1), (2, 0)] + sage: sorted(Q.upper_covers((1, 1))) + [(1, 2)] + sage: sorted(Q.upper_covers((0, 2))) + [(1, 2)] + + sage: P = p.cell_poset(orientation="NW"); P + Finite poset containing 4 elements + sage: sorted(P) + [(0, 2), (1, 1), (1, 2), (2, 0)] + sage: sorted(P.minimal_elements()) + [(1, 2), (2, 0)] + sage: sorted(P.maximal_elements()) + [(0, 2), (1, 1), (2, 0)] + sage: sorted(P.upper_covers((1, 2))) + [(0, 2), (1, 1)] + + sage: R = p.cell_poset(orientation="NE"); R + Finite poset containing 4 elements + sage: sorted(R) + [(0, 2), (1, 1), (1, 2), (2, 0)] + sage: R.maximal_elements() + [(0, 2)] + sage: R.minimal_elements() + [(2, 0)] + sage: R.upper_covers((2, 0)) + [(1, 1)] + sage: sorted([len(R.upper_covers(v)) for v in R]) + [0, 1, 1, 1] + + TESTS: + + We check that the posets are really what they should be for size + up to `6`:: + + sage: def check_NW(n): + ....: for p in SkewPartitions(n): + ....: P = p.cell_poset(orientation="NW") + ....: for c in p.cells(): + ....: for d in p.cells(): + ....: if P.le(c, d) != (c[0] >= d[0] + ....: and c[1] >= d[1]): + ....: return False + ....: return True + sage: all( check_NW(n) for n in range(7) ) + True + + sage: def check_NE(n): + ....: for p in SkewPartitions(n): + ....: P = p.cell_poset(orientation="NE") + ....: for c in p.cells(): + ....: for d in p.cells(): + ....: if P.le(c, d) != (c[0] >= d[0] + ....: and c[1] <= d[1]): + ....: return False + ....: return True + sage: all( check_NE(n) for n in range(7) ) + True + + sage: def test_duality(n, ori1, ori2): + ....: for p in SkewPartitions(n): + ....: P = p.cell_poset(orientation=ori1) + ....: Q = p.cell_poset(orientation=ori2) + ....: for c in p.cells(): + ....: for d in p.cells(): + ....: if P.lt(c, d) != Q.lt(d, c): + ....: return False + ....: return True + sage: all( test_duality(n, "NW", "SE") for n in range(7) ) + True + sage: all( test_duality(n, "NE", "SW") for n in range(7) ) + True + sage: all( test_duality(n, "NE", "SE") for n in range(4) ) + False + """ + from sage.combinat.posets.posets import Poset + # Getting the cover relations seems hard, so let's just compute + # the comparison function. + if orientation == "NW": + def poset_le(u, v): + return u[0] >= v[0] and u[1] >= v[1] + elif orientation == "NE": + def poset_le(u, v): + return u[0] >= v[0] and u[1] <= v[1] + elif orientation == "SE": + def poset_le(u, v): + return u[0] <= v[0] and u[1] <= v[1] + elif orientation == "SW": + def poset_le(u, v): + return u[0] <= v[0] and u[1] >= v[1] + return Poset((self.cells(), poset_le)) + def frobenius_rank(self): r""" Return the Frobenius rank of the skew partition ``self``. diff --git a/src/sage/combinat/sloane_functions.py b/src/sage/combinat/sloane_functions.py index 60d8c6d4def..dd44375078c 100644 --- a/src/sage/combinat/sloane_functions.py +++ b/src/sage/combinat/sloane_functions.py @@ -375,7 +375,7 @@ def _eval(self, n): return self._small[n-1] try: return Integer(gap.gap.eval('NumberSmallGroups(%s)'%n)) - except StandardError: # help, don't know what to do here? Jaap + except Exception: # help, don't know what to do here? Jaap print "Install database_gap first. See optional packages" diff --git a/src/sage/combinat/species/series.py b/src/sage/combinat/species/series.py index 4fcd576b133..f2a6da6a3e2 100644 --- a/src/sage/combinat/species/series.py +++ b/src/sage/combinat/species/series.py @@ -54,7 +54,7 @@ def __init__(self, R, element_class = None, names=None): raise TypeError, "Argument R must be a ring." try: z = R(Integer(1)) - except StandardError: + except Exception: raise ValueError, "R must have a unit element" #Take care of the names diff --git a/src/sage/combinat/species/stream.py b/src/sage/combinat/species/stream.py index c804dfce45f..28ea0aa3927 100644 --- a/src/sage/combinat/species/stream.py +++ b/src/sage/combinat/species/stream.py @@ -44,7 +44,7 @@ def _apply_function(func, list): while True: try: yield func(list) - except StandardError: + except Exception: break def Stream(x=None, const=None): diff --git a/src/sage/combinat/tableau.py b/src/sage/combinat/tableau.py index ab5bf799390..4377d0c4bda 100644 --- a/src/sage/combinat/tableau.py +++ b/src/sage/combinat/tableau.py @@ -1557,10 +1557,10 @@ def restrict(self, n): # attempt to return a tableau of the same type try: return self.parent()( res ) - except StandardError: + except Exception: try: return self.parent().Element( res ) - except StandardError: + except Exception: return Tableau(res) def restriction_shape(self, n): @@ -2423,7 +2423,7 @@ def last_letter_lequal(self, tab2): if not isinstance(tab2, Tableau): try: tab2 = Tableau(tab2) - except StandardError: + except Exception: raise TypeError("tab2 must be a standard tableau") if tab2.size() != n: @@ -2551,7 +2551,7 @@ def add_entry(self,cell,m): else: try: return self.parent().Element(tab) - except StandardError: + except Exception: return Tableau(tab) @@ -2885,7 +2885,7 @@ def symmetric_group_action_on_entries(self, w): w = w + [i+1 for i in range(len(w), self.size())] #need to ensure that it belongs to Sym_size try: return self.parent()([[w[entry-1] for entry in row] for row in self]) - except StandardError: + except Exception: return Tableau([[w[entry-1] for entry in row] for row in self]) def is_key_tableau(self): diff --git a/src/sage/combinat/tools.py b/src/sage/combinat/tools.py index ac8f7f55cc6..21bf8450351 100644 --- a/src/sage/combinat/tools.py +++ b/src/sage/combinat/tools.py @@ -17,13 +17,23 @@ #***************************************************************************** def transitive_ideal(f, x): - """ - Given an initial value x and a successor function f, return a list - containing x and all of its successors. The successor function - should return a list of all the successors of f. - - Note that if x has an infinite number of successors, - transitive_ideal won't return. + r""" + Return a list of all elements reachable from `x` in the abstract + reduction system whose reduction relation is given by the function + `f`. + + In more elementary terms: + If `S` is a set, and `f` is a function sending every element of `S` + to a list of elements of `S`, then we can define a digraph on the + vertex set `S` by drawing an edge from `s` to `t` for every + `s \in S` and every `t \in f(s)`. + If `x \in S`, then an element `y \in S` is said to be reachable + from `x` if there is a path `x \to y` in this graph. + Given `f` and `x`, this method computes the list of all elements of + `S` reachable from `x`. + + Note that if there are infinitely many such elements, then this + method will never halt. EXAMPLES:: diff --git a/src/sage/combinat/words/alphabet.py b/src/sage/combinat/words/alphabet.py index da5576b5442..f771861957b 100644 --- a/src/sage/combinat/words/alphabet.py +++ b/src/sage/combinat/words/alphabet.py @@ -60,7 +60,33 @@ def build_alphabet(data=None, names=None, name=None): r""" - Returns an object representing an ordered alphabet. + Return an object representing an ordered alphabet. + + INPUT: + + - ``data`` -- the letters of the alphabet; it can be: + + * a list/tuple/iterable of letters; the iterable may be infinite + * an integer `n` to represent `\{1, \ldots, n\}`, or infinity to + represent `\NN` + + - ``names`` -- (optional) a list for the letters (i.e. variable names) or + a string for prefix for all letters; if given a list, it must have the + same cardinality as the set represented by ``data`` + + - ``name`` -- (optional) if given, then return a named set and can be + equal to : ``'lower', 'upper', 'space', + 'underscore', 'punctuation', 'printable', 'binary', 'octal', 'decimal', + 'hexadecimal', 'radix64'``. + + You can use many of them at once, separated by spaces : ``'lower + punctuation'`` represents the union of the two alphabets ``'lower'`` and + ``'punctuation'``. + + Alternatively, ``name`` can be set to ``"positive integers"`` (or + ``"PP"``) or ``"natural numbers"`` (or ``"NN"``). + + ``name`` cannot be combined with ``data``. EXAMPLES: @@ -82,6 +108,18 @@ def build_alphabet(data=None, names=None, name=None): sage: print type(F).__name__ TotallyOrderedFiniteSet_with_category + If an integer and a set is given, then it constructs a + :class:`~sage.sets.totally_ordered_finite_set.TotallyOrderedFiniteSet`:: + + sage: build_alphabet(3, ['a','b','c']) + {'a', 'b', 'c'} + + If an integer and a string is given, then it considers that string as a + prefix:: + + sage: build_alphabet(3, 'x') + {'x0', 'x1', 'x2'} + If no data is provided, ``name`` may be a string which describe an alphabet. The available names decompose into two families. The first one are 'positive integers', 'PP', 'natural numbers' or 'NN' which refer to standard set of @@ -137,51 +175,101 @@ def build_alphabet(data=None, names=None, name=None): False sage: 1 == A(1) False + + We give an example of an infinite alphabet indexed by the positive + integers and the prime numbers:: + + sage: build_alphabet(oo, 'x') + Lazy family (x(i))_{i in Non negative integers} + sage: build_alphabet(Primes(), 'y') + Lazy family (y(i))_{i in Set of all prime numbers: 2, 3, 5, 7, ...} + + TESTS:: + + sage: Alphabet(3, name="punctuation") + Traceback (most recent call last): + ... + ValueError: name cannot be specified with any other argument + sage: Alphabet(8, ['e']*10) + Traceback (most recent call last): + ... + ValueError: invalid value for names + sage: Alphabet(8, x) + Traceback (most recent call last): + ... + ValueError: invalid value for names + sage: Alphabet(name=x, names="punctuation") + Traceback (most recent call last): + ... + ValueError: name cannot be specified with any other argument + sage: Alphabet(x) + Traceback (most recent call last): + ... + ValueError: unable to construct an alphabet from the given parameters """ - if data in Sets(): - return data + # If both 'names' and 'data' are defined + if name is not None and (data is not None or names is not None): + raise ValueError("name cannot be specified with any other argument") + + # Swap arguments if we need to to try and make sure we have "good" user input + if isinstance(names, (int,long,Integer)) or names == Infinity \ + or (data is None and names is not None): + data,names = names,data + + # data is an integer if isinstance(data, (int,long,Integer)): if names is None: from sage.sets.integer_range import IntegerRange return IntegerRange(Integer(data)) - elif len(names) == data: - return TotallyOrderedFiniteSet(data) - elif isinstance(names, str): - return TotallyOrderedFiniteSet( - [names + '%d'%i for i in xrange(data)]) - raise ValueError("not possible") - elif data == Infinity: - if names is None: + if isinstance(names, str): + return TotallyOrderedFiniteSet([names + '%d'%i for i in xrange(data)]) + if len(names) == data: + return TotallyOrderedFiniteSet(names) + raise ValueError("invalid value for names") + + if data == Infinity: + data = NonNegativeIntegers() + + # data is an iterable + if isinstance(data, (tuple,list,str)) or data in Sets(): + if names is not None: + if not isinstance(names, str): + raise TypeError("names must be a string when data is a set") + return Family(data, lambda i: names + str(i), name=names) + if data in Sets(): + return data + return TotallyOrderedFiniteSet(data) + + # Alphabet defined from a name + if name is not None: + if not isinstance(name, str): + raise TypeError("name must be a string") + if name == "positive integers" or name == "PP": + from sage.sets.positive_integers import PositiveIntegers + return PositiveIntegers() + if name == "natural numbers" or name == "NN": return NonNegativeIntegers() - else: - Family(NonNegativeIntegers(), lambda i: 'x%d'%i) - if data is None and name is None: + + data = [] + for alpha_name in name.split(' '): + try: + data.extend(list(set_of_letters[alpha_name])) + except KeyError: + raise TypeError("name is not recognized") + return TotallyOrderedFiniteSet(data) + + # Alphabet(**nothing**) + if data is None: # name is also None from sage.structure.parent import Set_PythonType return Set_PythonType(object) - if data is None: - if name == "positive integers" or name == "PP": - from sage.sets.positive_integers import PositiveIntegers - return PositiveIntegers() - elif name == "natural numbers" or name == "NN": - return NonNegativeIntegers() - else: - names = name.split(' ') - data = [] - for name in names: - if name in set_of_letters: - data.extend(list(set_of_letters[name])) - else: - raise TypeError("name is not recognized") - return TotallyOrderedFiniteSet(data) - raise TypeError("name is not recognized") - elif isinstance(data, (tuple,list,str)): - return TotallyOrderedFiniteSet(data) + + raise ValueError("unable to construct an alphabet from the given parameters") # TODO: should it be deprecated as it is no more a class ? Alphabet = build_alphabet # NOTE: all of the classes below are here for backward compatibility (pickling). -# More precisely, the ticket #8290 suppress several classes. The following code +# More precisely, the ticket #8920 suppress several classes. The following code # just allows to unpickle old style alphabet saved from previous version of # Sage. diff --git a/src/sage/combinat/words/finite_word.py b/src/sage/combinat/words/finite_word.py index 7a6b2fb1763..9ab08cbc786 100644 --- a/src/sage/combinat/words/finite_word.py +++ b/src/sage/combinat/words/finite_word.py @@ -296,11 +296,11 @@ def coerce(self, other): try: other = self.parent()(other) other.parent()._check(other, length=None) - except StandardError: + except Exception: try: self = other.parent()(self) self.parent()._check(self, length=None) - except StandardError: + except Exception: raise TypeError, "no coercion rule between %r and %r" % (self.parent(), other.parent()) return self, other diff --git a/src/sage/combinat/words/morphism.py b/src/sage/combinat/words/morphism.py index 32c71934e0a..43f56636d01 100644 --- a/src/sage/combinat/words/morphism.py +++ b/src/sage/combinat/words/morphism.py @@ -402,7 +402,7 @@ def _build_codomain(self, data): for key,val in data.iteritems(): try: it = iter(val) - except StandardError: + except Exception: it = [val] codom_alphabet.update(it) return Words(sorted(codom_alphabet)) diff --git a/src/sage/combinat/words/shuffle_product.py b/src/sage/combinat/words/shuffle_product.py index 0cbcd2993eb..548844c569f 100644 --- a/src/sage/combinat/words/shuffle_product.py +++ b/src/sage/combinat/words/shuffle_product.py @@ -25,14 +25,45 @@ class ShuffleProduct_w1w2(CombinatorialClass): def __init__(self, w1, w2): - """ + r""" + The shuffle product of the two words ``w1`` and ``w2``. + + If `u` and `v` are two words, then the *shuffle product* of + `u` and `v` is a certain multiset of words defined as follows: + Let `a` and `b` be the lengths of `u` and `v`, respectively. + For every `a`-element subset `I` of `\{1, 2, \cdots, a+b\}`, + let `w(I)` be the length-`a+b` word such that: + + - for every `1 \leq k \leq a`, the `i_k`-th letter of `w(I)` + is the `k`-th letter of `u`, where `i_k` is the + `k`-th smallest element of `I`; + + - for every `1 \leq l \leq b`, the `j_l`-th letter of `w(I)` + is the `l`-th letter of `v`, where `j_l` is the + `l`-th smallest element of + `\{1, 2, \cdots, a+b\} \setminus I`. + + The shuffle product of `u` and `v` is then the multiset of + all `w(I)` with `I` ranging over the `a`-element subsets of + `\{1, 2, \cdots, a+b\}`. + EXAMPLES:: sage: from sage.combinat.words.shuffle_product import ShuffleProduct_w1w2 sage: W = Words([1,2,3,4]) sage: s = ShuffleProduct_w1w2(W([1,2]),W([3,4])) + sage: sorted(list(s)) + [word: 1234, word: 1324, word: 1342, word: 3124, word: 3142, word: 3412] sage: s == loads(dumps(s)) True + + sage: s = ShuffleProduct_w1w2(W([1,4,3]),W([2])) + sage: sorted(list(s)) + [word: 1243, word: 1423, word: 1432, word: 2143] + + sage: s = ShuffleProduct_w1w2(W([1,4,3]),W([])) + sage: sorted(list(s)) + [word: 143] """ self._w1 = w1 self._w2 = w2 @@ -95,11 +126,15 @@ def __contains__(self, x): return len(wx) == 0 def cardinality(self): - """ - Returns the number of words in the shuffle product - of w1 and w2. + r""" + Return the number of words in the shuffle product + of ``w1`` and ``w2``. + + This is understood as a multiset cardinality, not as a + set cardinality; it does not count the distinct words only. - It is given by binomial(len(w1)+len(w2), len(w1)). + It is given by `\binom{l_1+l_2}{l_1}`, where `l_1` is the + length of ``w1`` and where `l_2` is the length of ``w2``. EXAMPLES:: @@ -108,7 +143,12 @@ def cardinality(self): sage: S = ShuffleProduct_w1w2(w,u) sage: S.cardinality() 6 - """ + + sage: w, u = map(Words("ab"), ["ab", "ab"]) + sage: S = ShuffleProduct_w1w2(w,u) + sage: S.cardinality() + 6 + """ return binomial(self._w1.length()+self._w2.length(), self._w1.length()) def _proc(self, vect): @@ -224,10 +264,15 @@ def __repr__(self): class ShuffleProduct_overlapping_r(CombinatorialClass): def __init__(self, w1, w2, r): """ + The overlapping shuffle product of the two words ``w1`` and ``w2`` + with precisely ``r`` overlaps. + + See :class:`ShuffleProduct_overlapping` for a definition. + EXAMPLES:: sage: from sage.combinat.words.shuffle_product import ShuffleProduct_overlapping_r - sage: w, u = map(Words("abcdef"), ["ab", "cd"]) + sage: w, u = map(Words(range(20)), [[2, 9], [9, 1]]) sage: S = ShuffleProduct_overlapping_r(w,u,1) sage: S == loads(dumps(S)) True @@ -246,9 +291,9 @@ def __repr__(self): EXAMPLES:: sage: from sage.combinat.words.shuffle_product import ShuffleProduct_overlapping_r - sage: w, u = map(Words("abcdef"), ["ab", "cd"]) + sage: w, u = map(Words(range(20)), [[2, 9], [9, 1]]) sage: ShuffleProduct_overlapping_r(w,u,1).__repr__() - 'Overlapping shuffle product of word: ab and word: cd with 1 overlaps' + 'Overlapping shuffle product of word: 29 and word: 91 with 1 overlaps' """ return "Overlapping shuffle product of %s and %s with %s overlaps"%(repr(self._w1), repr(self._w2), self.r) @@ -321,12 +366,65 @@ def __iter__(self): class ShuffleProduct_overlapping(CombinatorialClass): def __init__(self, w1, w2): - """ + r""" + The overlapping shuffle product of the two words ``w1`` and + ``w2``. + + If `u` and `v` are two words whose letters belong to an + additive monoid or to another kind of alphabet on which addition + is well-defined, then the *overlapping shuffle product* of + `u` and `v` is a certain multiset of words defined as follows: + Let `a` and `b` be the lengths of `u` and `v`, respectively. + Let `A` be the set `\{(0, 1), (0, 2), \cdots, (0, a)\}`, and + let `B` be the set `\{(1, 1), (1, 2), \cdots, (1, b)\}`. + Notice that the sets `A` and `B` are disjoint. We can make + `A` and `B` into posets by setting `(k, i) \leq (k, j)` for + all `k \in \{0, 1\}` and `i \leq j`. Then, `A \cup B` becomes + a poset by disjoint union (we don't set `(0, i) \leq (1, i)`). + Let `p` be the map from `A \cup B` to the set of all letters + which sends every `(0, i)` to the `i`-th letter of `u`, and + every `(1, j)` to the `j`-th letter of `v`. For every + nonnegative integer `c` and every surjective map + `f : A \cup B \to \{ 1, 2, \cdots, c \}` for which both + restrictions `f \mid_A` and `f \mid_B` are strictly increasing, + let `w(f)` be the length-`c` word such that for every + `1 \leq k \leq c`, the `k`-th letter of `w(f)` equals + `\sum_{j \in f^{-1}(k)} p(j)` (this sum always has either + one or two addends). The overlapping shuffle product of `u` + and `v` is then the multiset of all `w(f)` with `c` ranging + over all nonnegative integers and `f` ranging + over the surjective maps + `f : A \cup B \to \{ 1, 2, \cdots, c \}` for which both + restrictions `f \mid_A` and `f \mid_B` are strictly increasing. + + If one restricts `c` to a particular fixed nonnegative + integer, then the multiset is instead called the *overlapping + shuffle product with precisely `a + b - c` overlaps*. This is + nonempty only if `\max \{a, b\} \leq c \leq a + b`. + + If `c = a + b`, then the overlapping shuffle product with + precisely `a + b - c` overlaps is plainly the shuffle product + (:class:`ShuffleProduct_w1w2`). + EXAMPLES:: sage: from sage.combinat.words.shuffle_product import ShuffleProduct_overlapping - sage: w, u = map(Words("abcdef"), ["ab", "cd"]) + sage: w, u = map(Words(range(20)), [[2, 9], [9, 1]]) sage: S = ShuffleProduct_overlapping(w,u) + sage: sorted([list(i) for i in list(S)]) + [[2, 9, 1, 9], + [2, 9, 9, 1], + [2, 9, 9, 1], + [2, 9, 10], + [2, 18, 1], + [9, 1, 2, 9], + [9, 2, 1, 9], + [9, 2, 9, 1], + [9, 2, 10], + [9, 3, 9], + [11, 1, 9], + [11, 9, 1], + [11, 10]] sage: S == loads(dumps(S)) True """ @@ -338,9 +436,9 @@ def __repr__(self): EXAMPLES:: sage: from sage.combinat.words.shuffle_product import ShuffleProduct_overlapping - sage: w, u = map(Words("abcdef"), ["ab", "cd"]) + sage: w, u = map(Words(range(20)), [[2, 9], [9, 1]]) sage: ShuffleProduct_overlapping(w,u).__repr__() - 'Overlapping shuffle product of word: ab and word: cd' + 'Overlapping shuffle product of word: 29 and word: 91' """ return "Overlapping shuffle product of %s and %s"%(repr(self._w1), repr(self._w2)) diff --git a/src/sage/crypto/classical.py b/src/sage/crypto/classical.py index 543a0bb7a0e..ee21cf94133 100644 --- a/src/sage/crypto/classical.py +++ b/src/sage/crypto/classical.py @@ -346,7 +346,7 @@ def __call__(self, a, b): return AffineCipher(self, key=(a,b)) else: raise ValueError - except StandardError: + except Exception: raise ValueError("(a, b) = (%s, %s) is outside the range of acceptable values for a key of this affine cryptosystem." % (a, b)) def _repr_(self): @@ -1150,7 +1150,7 @@ def encoding(self, S): return D(strip_encoding(S)) try: return D.encoding(S) - except StandardError: + except Exception: raise TypeError("Argument S = %s does not encode in the cipher domain" % S) def inverse_key(self, a, b): @@ -1242,7 +1242,7 @@ def inverse_key(self, a, b): aInv = inverse_mod(a, n) bInv = Mod(-b * aInv, n).lift() return (aInv, bInv) - except StandardError: + except Exception: raise ValueError("(a, b) = (%s, %s) is outside the range of acceptable values for a key of this affine cipher." % (a, b)) def random_key(self): @@ -1393,7 +1393,7 @@ def __call__(self, A): if isinstance(A, list): try: A = M(A) - except StandardError: + except Exception: raise TypeError("A (= %s) must specify a square matrix of degree %s." % (A, m)) return HillCipher(self, A) @@ -1538,7 +1538,7 @@ def encoding(self, M): return S(strip_encoding(M)) try: return S.encoding(M) - except StandardError: + except Exception: raise TypeError("Argument M = %s does not encode in the cipher domain" % M) def deciphering(self, A, C): @@ -2846,7 +2846,7 @@ def encoding(self, S): return D(strip_encoding(S)) try: return D.encoding(S) - except StandardError: + except Exception: raise TypeError("Argument S = %s does not encode in the cipher domain" % S) def inverse_key(self, K): @@ -3204,7 +3204,7 @@ def encoding(self, M): return S(strip_encoding(M)) try: return S.encoding(M) - except StandardError: + except Exception: raise TypeError("Argument M = %s does not encode in the cipher domain" % M) def deciphering(self, K, C): @@ -3337,7 +3337,7 @@ def __call__(self, K): if isinstance(K, list): try: K = G(K) - except StandardError: + except Exception: raise TypeError("K (= %s) must specify a permutation." % K) if not isinstance(K, PermutationGroupElement) and K.parent() == G: raise TypeError("K (= %s) must be a permutation or list specifying a permutation." % K) @@ -3448,7 +3448,7 @@ def encoding(self, M): return S(strip_encoding(M)) try: return S.encoding(M) - except StandardError: + except Exception: raise TypeError("Argument M = %s does not encode in the cipher domain" % M) def deciphering(self, K, C): @@ -3584,7 +3584,7 @@ def __call__(self, K): if isinstance(K, list): try: K = S(K) - except StandardError: + except Exception: raise TypeError("K (= %s) must specify a string of length %s." % (K, m)) if not len(K) == m: raise TypeError("K (= %s) must specify a string of length %s." % (K, m)) @@ -3691,7 +3691,7 @@ def encoding(self, M): return S(strip_encoding(M)) try: return S.encoding(M) - except StandardError: + except Exception: raise TypeError("Argument M = %s does not encode in the cipher domain" % M) def deciphering(self, K, C): diff --git a/src/sage/crypto/classical_cipher.py b/src/sage/crypto/classical_cipher.py index ab4b6fbb6a7..c409a5a9668 100644 --- a/src/sage/crypto/classical_cipher.py +++ b/src/sage/crypto/classical_cipher.py @@ -230,7 +230,7 @@ def inverse(self): E = self.parent() try: B = E.inverse_key(self.key()) - except StandardError: + except Exception: raise ValueError, "Argument\n\n%s\n\nmust be an invertible cipher." % self return E(B) diff --git a/src/sage/crypto/stream.py b/src/sage/crypto/stream.py index 0b2fe42cc97..05fe000578a 100644 --- a/src/sage/crypto/stream.py +++ b/src/sage/crypto/stream.py @@ -97,7 +97,7 @@ def encoding(self,M): S = self.cipher_domain() try: return S.encoding(M) - except StandardError: + except Exception: raise TypeError, "Argument M = %s does not encode in the cipher domain" % M class ShrinkingGeneratorCryptosystem(SymmetricKeyCryptosystem): @@ -159,7 +159,7 @@ def encoding(self,M): S = self.cipher_domain() try: return S.encoding(M) - except StandardError: + except Exception: raise TypeError, "Argument M = %s does not encode in the cipher domain" % M def blum_blum_shub(length, seed=None, p=None, q=None, diff --git a/src/sage/databases/sql_db.py b/src/sage/databases/sql_db.py index 92075e0bbce..47dfa14db74 100644 --- a/src/sage/databases/sql_db.py +++ b/src/sage/databases/sql_db.py @@ -663,7 +663,7 @@ def show(self, **kwds): try: cur = self.__database__.__connection__.cursor() cur.execute(self.__query_string__, self.__param_tuple__) - except StandardError: + except Exception: raise RuntimeError('Failure to fetch query.') print(_create_print_table(cur, [des[0] for des in cur.description], \ @@ -1281,7 +1281,7 @@ def show(self, table_name, **kwds): try: cur = self.__connection__.cursor() cur.execute('SELECT * FROM ' + table_name) - except StandardError: + except Exception: raise RuntimeError('Failure to fetch data.') print(_create_print_table(cur, [des[0] for des in cur.description], \ **kwds)) @@ -2069,7 +2069,7 @@ def delete_rows(self, query): try: cur = self.get_cursor() cur.execute(delete_statement, query.__param_tuple__) - except StandardError: + except Exception: raise RuntimeError('Failure to complete delete. Check your data.') def add_rows(self, table_name, rows, entry_order=None): diff --git a/src/sage/doctest/control.py b/src/sage/doctest/control.py index 255f3424730..1a5af8cddc7 100644 --- a/src/sage/doctest/control.py +++ b/src/sage/doctest/control.py @@ -309,7 +309,7 @@ def load_stats(self, filename): try: with open(filename) as stats_file: self.stats.update(json.load(stats_file)) - except StandardError: + except Exception: self.log("Error loading stats from %s"%filename) def save_stats(self, filename): @@ -486,7 +486,7 @@ def all_files(): if (set(status).issubset("MARCU") and filename.startswith("src/sage") and (filename.endswith(".py") or filename.endswith(".pyx"))): - self.files.append(filename) + self.files.append(os.path.relpath(opj(SAGE_ROOT,filename))) if self.options.sagenb: if not self.options.all: self.log("Doctesting the Sage notebook.") diff --git a/src/sage/doctest/reporting.py b/src/sage/doctest/reporting.py index 0f055f9d817..829b550e0b2 100644 --- a/src/sage/doctest/reporting.py +++ b/src/sage/doctest/reporting.py @@ -440,7 +440,7 @@ def report(self, source, timeout, return_code, results, output, pid=None): log(" [%s, %s%.2f s]" % (count_noun(ntests, "test"), "%s, "%(count_noun(f, "failure")) if f else "", wall)) self.sources_completed += 1 - except StandardError: + except Exception: import traceback log(traceback.format_exc(), end="") diff --git a/src/sage/functions/generalized.py b/src/sage/functions/generalized.py index b6a1ccecbd2..d51a996e0c7 100644 --- a/src/sage/functions/generalized.py +++ b/src/sage/functions/generalized.py @@ -143,7 +143,7 @@ def _eval_(self, x): return None else: return 0 - except StandardError: # x is symbolic + except Exception: # x is symbolic pass return None @@ -249,7 +249,7 @@ def _eval_(self, x): return 1 else: return 0 - except StandardError: # x is symbolic + except Exception: # x is symbolic pass return None @@ -358,7 +358,7 @@ def _eval_(self, x): return 1 else: return 0 - except StandardError: # x is symbolic + except Exception: # x is symbolic pass return None @@ -494,7 +494,7 @@ def _eval_(self, x): return ZZ(1) else: return ZZ(-1) - except StandardError: # x is symbolic + except Exception: # x is symbolic pass return None @@ -599,7 +599,7 @@ def _eval_(self, m, n): return 0 else: return 0 # x is complex - except StandardError: # x is symbolic + except Exception: # x is symbolic pass return None diff --git a/src/sage/functions/orthogonal_polys.py b/src/sage/functions/orthogonal_polys.py index 0b83b0305e3..7b5adcb1ba0 100644 --- a/src/sage/functions/orthogonal_polys.py +++ b/src/sage/functions/orthogonal_polys.py @@ -510,7 +510,7 @@ def __call__(self, n, *args, **kwds): if n in ZZ and not kwds.get('hold', False): try: return self._eval_(n, *args) - except StandardError: + except Exception: pass return super(ChebyshevPolynomial,self).__call__(n, *args, **kwds) @@ -577,7 +577,7 @@ def _eval_(self, n, x): warnings.warn("mpmath failed, keeping expression unevaluated", RuntimeWarning) return None - except StandardError: + except Exception: # Numerical evaluation failed => keep symbolic return None diff --git a/src/sage/functions/special.py b/src/sage/functions/special.py index b51d18c4a7a..c716a8051f0 100644 --- a/src/sage/functions/special.py +++ b/src/sage/functions/special.py @@ -1128,7 +1128,7 @@ def error_fcn(t): from sage.rings.real_mpfr import RR try: return RR(t).erfc() - except StandardError: + except Exception: raise NotImplementedError diff --git a/src/sage/games/hexad.py b/src/sage/games/hexad.py index 81b74c8f7a8..06f94c323f9 100644 --- a/src/sage/games/hexad.py +++ b/src/sage/games/hexad.py @@ -535,29 +535,29 @@ def find_hexad(self, pts): if list(L2)[0] == MINIMOG[2][1]: L1 = LL - L2 H,WHAT = self.find_hexad3(L1,MINIMOG[0][0],MINIMOG[2][1]) - if H <> []: + if H != []: return list(H),WHAT L1 = LL - L2 H,WHAT = self.find_hexad3(L1,MINIMOG[0][2],MINIMOG[2][1]) - if H <> []: + if H != []: return list(H),WHAT if list(L2)[0] == MINIMOG[0][0]: L1 = (LL - L2) H,WHAT = self.find_hexad3(L1,MINIMOG[0][0],MINIMOG[2][1]) - if H <> []: + if H != []: return list(H),WHAT L1 = (LL - L2) H,WHAT = self.find_hexad3(L1,MINIMOG[0][0],MINIMOG[0][2]) - if H <> []: + if H != []: return list(H),WHAT if list(L2)[0] == MINIMOG[0][2]: L1 = (LL - L2) H,WHAT = self.find_hexad3(L1,MINIMOG[0][0],MINIMOG[0][2]) - if H <> []: + if H != []: return list(H),WHAT L1 = (LL - L2) H,WHAT = self.find_hexad3(L1,MINIMOG[2][1],MINIMOG[0][2]) - if H <> []: + if H != []: return list(H),WHAT return list(H),WHAT ## a cross in a pic at infty diff --git a/src/sage/graphs/base/c_graph.pyx b/src/sage/graphs/base/c_graph.pyx index 91557088cbe..140d7aba784 100644 --- a/src/sage/graphs/base/c_graph.pyx +++ b/src/sage/graphs/base/c_graph.pyx @@ -1165,7 +1165,7 @@ cdef int get_vertex(object u, dict vertex_ints, dict vertex_labels, return vertex_ints[u] try: u_int = u - except StandardError: + except Exception: return -1 if u_int < 0 or u_int >= G.active_vertices.size or u_int in vertex_labels or u_int != u: return -1 @@ -1738,18 +1738,13 @@ class CGraphBackend(GenericGraphBackend): self._cg) # Sparse if self._cg_rev is not None: - return iter([vertex_label(u_int, - self.vertex_ints, - self.vertex_labels, - self._cg) - for u_int in self._cg_rev.out_neighbors(v_int)]) + for u_int in self._cg_rev.out_neighbors(v_int): + yield vertex_label(u_int, self.vertex_ints, self.vertex_labels, self._cg) + # Dense else: - return iter([vertex_label(u_int, - self.vertex_ints, - self.vertex_labels, - self._cg) - for u_int in self._cg.in_neighbors(v_int)]) + for u_int in self._cg.in_neighbors(v_int): + yield vertex_label(u_int, self.vertex_ints, self.vertex_labels, self._cg) def iterator_out_nbrs(self, v): """ @@ -1782,11 +1777,9 @@ class CGraphBackend(GenericGraphBackend): self.vertex_ints, self.vertex_labels, self._cg) - return iter([vertex_label(u_int, - self.vertex_ints, - self.vertex_labels, - self._cg) - for u_int in self._cg.out_neighbors(v_int)]) + + for u_int in self._cg.out_neighbors(v_int): + yield vertex_label(u_int, self.vertex_ints, self.vertex_labels, self._cg) def iterator_verts(self, verts=None): """ @@ -1836,7 +1829,7 @@ class CGraphBackend(GenericGraphBackend): try: v = hash(verts) is_hashable = True - except StandardError: + except Exception: pass if is_hashable and self.has_vertex(verts): return iter([verts]) @@ -1880,33 +1873,6 @@ class CGraphBackend(GenericGraphBackend): else: self._loops = False - def name(self, new=None): - """ - Returns the name of this graph. - - INPUT: - - - ``new`` -- (default: ``None``); boolean (to set) or ``None`` - (to get). - - OUTPUT: - - - If ``new=None``, return the name of this graph. Otherwise, set the - name of this graph to the value of ``new``. - - EXAMPLE:: - - sage: G = Graph(graphs.PetersenGraph(), implementation="c_graph") - sage: G._backend.name() - 'Petersen graph' - sage: G._backend.name("Peter Pan's graph") - sage: G._backend.name() - "Peter Pan's graph" - """ - if new is None: - return self._name - self._name = new - def num_edges(self, directed): """ Returns the number of edges in ``self``. diff --git a/src/sage/graphs/base/sparse_graph.pyx b/src/sage/graphs/base/sparse_graph.pyx index 990eee46334..272140f079b 100644 --- a/src/sage/graphs/base/sparse_graph.pyx +++ b/src/sage/graphs/base/sparse_graph.pyx @@ -1666,7 +1666,7 @@ class SparseGraphBackend(CGraphBackend): for e in edges: try: u,v,l = e - except StandardError: + except Exception: u,v = e l = None self.add_edge(u,v,l,directed) @@ -1826,8 +1826,9 @@ class SparseGraphBackend(CGraphBackend): assumed to be undirected. INPUT: - - ``vertices`` - a list of vertex labels - - ``labels`` - boolean, whether to return labels as well + + - ``vertices`` - a list of vertex labels + - ``labels`` - boolean, whether to return labels as well EXAMPLE:: @@ -1842,52 +1843,45 @@ class SparseGraphBackend(CGraphBackend): # Improvement possible in the code below ! # # It is through this function that Sage answers to G.edges(). That's so - # unefficient that it hurts to see it. Basically, to answer G.edges(), + # inefficient that it hurts to see it. Basically, to answer G.edges(), # Sage first builds the list L of all vertices, then and returns all the # edges which have at least one endpoint in L. That is, absolutely *ALL* # the edges, but it checks this condition on the endpoints for each of # them. It tests containment in a LIST, not even a set. That should # REALLY be updated. - cdef object v, l, L + cdef object u, v, l, L vertices = [get_vertex(v, self.vertex_ints, self.vertex_labels, self._cg) for v in vertices if self.has_vertex(v)] cdef int u_int, v_int, l_int if labels: - L = [] for v_int in vertices: v = vertex_label(v_int, self.vertex_ints, self.vertex_labels, self._cg) for u_int in self._cg.out_neighbors(v_int): if u_int >= v_int or u_int not in vertices: + u = vertex_label(u_int, self.vertex_ints, self.vertex_labels, self._cg) for l_int in self._cg.all_arcs(v_int, u_int): if l_int == 0: l = None else: l = self.edge_labels[l_int] - L.append(tuple(sorted( - (v, - vertex_label(u_int, self.vertex_ints, self.vertex_labels, self._cg) - )))+(l,)) - return iter(L) + yield tuple(sorted((v, u))) + (l,) else: - L = [] for v_int in vertices: v = vertex_label(v_int, self.vertex_ints, self.vertex_labels, self._cg) for u_int in self._cg.out_neighbors(v_int): if u_int >= v_int or u_int not in vertices: + u = vertex_label(u_int, self.vertex_ints, self.vertex_labels, self._cg) for l_int in self._cg.all_arcs(v_int, u_int): - L.append(tuple(sorted( - (v, - vertex_label(u_int, self.vertex_ints, self.vertex_labels, self._cg) - )))) - return iter(L) + yield tuple(sorted((v, u))) def iterator_in_edges(self, object vertices, bint labels): """ Iterate over the incoming edges incident to a sequence of vertices. INPUT: - - ``vertices`` - a list of vertex labels - - ``labels`` - boolean, whether to return labels as well + + - ``vertices`` - a list of vertex labels + - ``labels`` - boolean, whether to return labels as well EXAMPLE:: @@ -1901,61 +1895,40 @@ class SparseGraphBackend(CGraphBackend): [(1, 2, 3)] """ - cdef object v, L, l + cdef object u, v, L, l vertices = [get_vertex(v, self.vertex_ints, self.vertex_labels, self._cg) for v in vertices if self.has_vertex(v)] cdef int u_int, v_int, l_int if self.multiple_edges(None): if labels: - L = [] for v_int in vertices: v = vertex_label(v_int, self.vertex_ints, self.vertex_labels, self._cg) for u_int in self._cg_rev.out_neighbors(v_int): + u = vertex_label(u_int, self.vertex_ints, self.vertex_labels, self._cg) for l_int in self._cg.all_arcs(u_int, v_int): - if l_int == 0: - l = None - else: - l = self.edge_labels[l_int] - L.append( - (vertex_label(u_int, self.vertex_ints, self.vertex_labels, self._cg), - v, - l)) - return iter(L) + yield (u, v, None if l_int == 0 else self.edge_labels[l_int]) else: - L = [] for v_int in vertices: v = vertex_label(v_int, self.vertex_ints, self.vertex_labels, self._cg) for u_int in self._cg_rev.out_neighbors(v_int): + u = vertex_label(u_int, self.vertex_ints, self.vertex_labels, self._cg) for l_int in self._cg.all_arcs(u_int, v_int): - L.append( - (vertex_label(u_int, self.vertex_ints, self.vertex_labels, self._cg), - v)) - return iter(L) + yield (u, v) else: if labels: - L = [] for v_int in vertices: v = vertex_label(v_int, self.vertex_ints, self.vertex_labels, self._cg) for u_int in self._cg_rev.out_neighbors(v_int): l_int = self._cg.arc_label(u_int, v_int) - if l_int == 0: - l = None - else: - l = self.edge_labels[l_int] - L.append( - (vertex_label(u_int, self.vertex_ints, self.vertex_labels, self._cg), - v, - l)) - return iter(L) + yield (vertex_label(u_int, self.vertex_ints, self.vertex_labels, self._cg), + v, + None if l_int == 0 else self.edge_labels[l_int]) else: - L = [] for v_int in vertices: v = vertex_label(v_int, self.vertex_ints, self.vertex_labels, self._cg) for u_int in self._cg_rev.out_neighbors(v_int): - L.append( - (vertex_label(u_int, self.vertex_ints, self.vertex_labels, self._cg), - v)) - return iter(L) + yield (vertex_label(u_int, self.vertex_ints, self.vertex_labels, self._cg), + v) def iterator_out_edges(self, object vertices, bint labels): """ @@ -1983,55 +1956,34 @@ class SparseGraphBackend(CGraphBackend): cdef int u_int, v_int, l_int if self.multiple_edges(None): if labels: - L = [] for v_int in vertices: v = vertex_label(v_int, self.vertex_ints, self.vertex_labels, self._cg) for u_int in self._cg.out_neighbors(v_int): + u = vertex_label(u_int, self.vertex_ints, self.vertex_labels, self._cg) for l_int in self._cg.all_arcs(v_int, u_int): - if l_int == 0: - l = None - else: - l = self.edge_labels[l_int] - L.append( - (v, - vertex_label(u_int, self.vertex_ints, self.vertex_labels, self._cg), - l)) - return iter(L) + yield (v, u, None if l_int == 0 else self.edge_labels[l_int]) else: - L = [] for v_int in vertices: v = vertex_label(v_int, self.vertex_ints, self.vertex_labels, self._cg) for u_int in self._cg.out_neighbors(v_int): + u = vertex_label(u_int, self.vertex_ints, self.vertex_labels, self._cg) for l_int in self._cg.all_arcs(v_int, u_int): - L.append( - (v, - vertex_label(u_int, self.vertex_ints, self.vertex_labels, self._cg))) - return iter(L) + yield (v, u) else: if labels: - L = [] for v_int in vertices: v = vertex_label(v_int, self.vertex_ints, self.vertex_labels, self._cg) for u_int in self._cg.out_neighbors(v_int): l_int = self._cg.arc_label(v_int, u_int) - if l_int == 0: - l = None - else: - l = self.edge_labels[l_int] - L.append( - (v, - vertex_label(u_int, self.vertex_ints, self.vertex_labels, self._cg), - l)) - return iter(L) + yield (v, + vertex_label(u_int, self.vertex_ints, self.vertex_labels, self._cg), + None if l_int == 0 else self.edge_labels[l_int]) else: - L = [] for v_int in vertices: v = vertex_label(v_int, self.vertex_ints, self.vertex_labels, self._cg) for u_int in self._cg.out_neighbors(v_int): - L.append( - (v, - vertex_label(u_int, self.vertex_ints, self.vertex_labels, self._cg))) - return iter(L) + yield (v, + vertex_label(u_int, self.vertex_ints, self.vertex_labels, self._cg)) def multiple_edges(self, new): """ diff --git a/src/sage/graphs/base/static_sparse_backend.pyx b/src/sage/graphs/base/static_sparse_backend.pyx index 167c375371f..14c21c21960 100644 --- a/src/sage/graphs/base/static_sparse_backend.pyx +++ b/src/sage/graphs/base/static_sparse_backend.pyx @@ -40,6 +40,7 @@ from sage.graphs.base.static_sparse_graph cimport (init_short_digraph, from c_graph import CGraphBackend from sage.misc.bitset cimport FrozenBitset from libc.stdint cimport uint32_t +include 'sage/misc/bitset.pxi' cdef class StaticSparseCGraph(CGraph): """ @@ -64,10 +65,14 @@ cdef class StaticSparseCGraph(CGraph): has_labels = any(not l is None for _,_,l in G.edge_iterator()) self.directed = G.is_directed() - init_short_digraph(self.g,G, edge_labelled = has_labels) + init_short_digraph(self.g, G, edge_labelled = has_labels) if self.directed: init_reverse(self.g_rev,self.g) + # Defining the meaningless set of 'active' vertices. Because of CGraph. + bitset_init(self.active_vertices, self.g.n+1) + bitset_set_first_n(self.active_vertices, self.g.n) + def __dealloc__(self): r""" Freeing the memory @@ -77,6 +82,7 @@ cdef class StaticSparseCGraph(CGraph): sage: from sage.graphs.base.static_sparse_backend import StaticSparseCGraph sage: g = StaticSparseCGraph(graphs.PetersenGraph()) """ + bitset_free(self.active_vertices) free_short_digraph(self.g) if self.g_rev != NULL: free_short_digraph(self.g_rev) @@ -361,7 +367,9 @@ class StaticSparseBackend(CGraphBackend): """ cdef StaticSparseCGraph cg = StaticSparseCGraph(G) self._cg = cg - self._directed = cg.directed + + # .directed and not ._directed. Because of CGraph. + self.directed = cg.directed vertices = G.vertices() self._order = len(vertices) @@ -374,6 +382,12 @@ class StaticSparseBackend(CGraphBackend): self._vertex_to_labels = vertices self._vertex_to_int = {v:i for i,v in enumerate(vertices)} + # Needed by CGraph. The first one is just an alias, and the second is + # useless : accessing _vertex_to_labels (which is a list) is faster than + # vertex_labels (which is a dictionary) + self.vertex_ints = self._vertex_to_int + self.vertex_labels = {i:v for i,v in enumerate(vertices)} + def __reduce__(self): """ Return a tuple used for pickling this graph. @@ -416,7 +430,7 @@ class StaticSparseBackend(CGraphBackend): sage: loads(dumps(gi)) == gi True """ - if self._directed: + if self.directed: from sage.graphs.digraph import DiGraph G = DiGraph(loops=self._loops, multiedges=self._multiedges) G.add_edges(list(self.iterator_out_edges(self.iterator_verts(None),True))) @@ -592,6 +606,13 @@ class StaticSparseBackend(CGraphBackend): [(0, 1), (0, 4), (0, 5)] sage: list(g.iterator_in_edges([0],True)) [(0, 1, None), (0, 4, None), (0, 5, None)] + + :: + + sage: DiGraph(digraphs.Path(5),immutable=False).incoming_edges([2]) + [(1, 2, None)] + sage: DiGraph(digraphs.Path(5),immutable=True).incoming_edges([2]) + [(1, 2, None)] """ cdef StaticSparseCGraph cg = self._cg if not cg.directed: @@ -609,11 +630,11 @@ class StaticSparseBackend(CGraphBackend): vi = self._vertex_to_labels[i] for j in range(out_degree(cg.g_rev,i)): if labels: - yield (vi, - self._vertex_to_labels[cg.g_rev.neighbors[i][j]], + yield (self._vertex_to_labels[cg.g_rev.neighbors[i][j]], + vi, edge_label(cg.g_rev,cg.g_rev.neighbors[i]+j)) else: - yield vi,self._vertex_to_labels[cg.g_rev.neighbors[i][j]] + yield self._vertex_to_labels[cg.g_rev.neighbors[i][j]], vi def iterator_out_edges(self, object vertices, bint labels): """ @@ -633,6 +654,7 @@ class StaticSparseBackend(CGraphBackend): [(0, 1), (0, 4), (0, 5)] sage: list(g.iterator_out_edges([0],True)) [(0, 1, None), (0, 4, None), (0, 5, None)] + """ try: vertices = [self._vertex_to_int[x] for x in vertices] diff --git a/src/sage/graphs/bipartite_graph.py b/src/sage/graphs/bipartite_graph.py index 4ce37118280..54ab674e13e 100644 --- a/src/sage/graphs/bipartite_graph.py +++ b/src/sage/graphs/bipartite_graph.py @@ -361,7 +361,7 @@ def __init__(self, data=None, partition=None, check=True, *args, **kwds): Graph.__init__(self, data, *args, **kwds) try: self.left, self.right = self.bipartite_sets() - except StandardError: + except Exception: raise TypeError("Input graph is not bipartite!") else: import networkx @@ -384,7 +384,7 @@ def __init__(self, data=None, partition=None, check=True, *args, **kwds): if not (hasattr(self, "left") and hasattr(self, "right")): try: self.left, self.right = self.bipartite_sets() - except StandardError: + except Exception: raise TypeError("Input graph is not bipartite!") # restore vertex partition checking @@ -670,10 +670,10 @@ def delete_vertex(self, vertex, in_order=False): # vertex) try: self.left.remove(vertex) - except StandardError: + except Exception: try: self.right.remove(vertex) - except StandardError: + except Exception: raise RuntimeError( "Vertex (%s) not found in partitions" % vertex) @@ -714,10 +714,10 @@ def delete_vertices(self, vertices): for vertex in vertices: try: self.left.remove(vertex) - except StandardError: + except Exception: try: self.right.remove(vertex) - except StandardError: + except Exception: raise RuntimeError( "Vertex (%s) not found in partitions" % vertex) @@ -771,7 +771,7 @@ def add_edge(self, u, v=None, label=None): if v is None: try: u, v, label = u - except StandardError: + except Exception: u, v = u label = None else: @@ -1009,24 +1009,24 @@ def save_afile(self, fname): sage: file_name = os.path.join(SAGE_TMP, 'deleteme.alist.txt') sage: for order in range(3, 13, 3): - ... num_chks = int(order / 3) - ... num_vars = order - num_chks - ... partition = (range(num_vars), range(num_vars, num_vars+num_chks)) - ... for idx in range(100): - ... g = graphs.RandomGNP(order, 0.5) - ... try: - ... b = BipartiteGraph(g, partition, check=False) - ... b.save_afile(file_name) - ... b2 = BipartiteGraph(file_name) - ... if b != b2: - ... print "Load/save failed for code with edges:" - ... print b.edges() - ... break - ... except StandardError: - ... print "Exception encountered for graph of order "+ str(order) - ... print "with edges: " - ... g.edges() - ... raise + ....: num_chks = int(order / 3) + ....: num_vars = order - num_chks + ....: partition = (range(num_vars), range(num_vars, num_vars+num_chks)) + ....: for idx in range(100): + ....: g = graphs.RandomGNP(order, 0.5) + ....: try: + ....: b = BipartiteGraph(g, partition, check=False) + ....: b.save_afile(file_name) + ....: b2 = BipartiteGraph(file_name) + ....: if b != b2: + ....: print "Load/save failed for code with edges:" + ....: print b.edges() + ....: break + ....: except Exception: + ....: print "Exception encountered for graph of order "+ str(order) + ....: print "with edges: " + ....: g.edges() + ....: raise """ # open the file try: diff --git a/src/sage/graphs/cliquer/cl.c b/src/sage/graphs/cliquer/cl.c new file mode 100644 index 00000000000..71a51ad94c3 --- /dev/null +++ b/src/sage/graphs/cliquer/cl.c @@ -0,0 +1,114 @@ +#include "cl.h" +#include "cliquer/cliquer.h" + +static int maximal; +static int sage_clique_count=0; +static set_t *sage_clique_list; +static int sage_clique_list_size=0; + +// As the global variables remain between two SAGE call, they +// have to be reset each time +void sage_reset_global_variables(){ + maximal=FALSE; // reachable from read_options + sage_clique_count=0; + sage_clique_list_size=0; +} + +static boolean sage_record_clique_func(set_t s,graph_t *g,clique_options *opts) { + if (sage_clique_count>=sage_clique_list_size) { + sage_clique_list=realloc(sage_clique_list,(sage_clique_list_size+512) * + sizeof(set_t)); + sage_clique_list_size+=512; + } + sage_clique_list[sage_clique_count]=set_duplicate(s); + sage_clique_count++; + return TRUE; +} + +static int *(*reorder)(graph_t *, boolean)=reorder_by_default; +static int quiet=0; +// The opt structure has to be initialised in each SAGE function +clique_options * sage_init_clique_opt(){ + sage_reset_global_variables(); + clique_options *opts; + quiet++; + opts=malloc(sizeof(clique_options)); + if (quiet) + opts->time_function=NULL; + else + opts->time_function=clique_print_time; + opts->output=stderr; + opts->reorder_function=reorder; + opts->reorder_map=NULL; + opts->user_function=sage_record_clique_func; + opts->user_data=NULL; + opts->clique_list=NULL; + opts->clique_list_length=0; + return opts; +} + +// Computes a maximum clique of the graph g and return its size +// The table list contains the ID of the vertices +int sage_clique_max(graph_t *g,int **list){ + sage_reset_global_variables(); + quiet++; + set_t s; + int i,l; + clique_options *opts = sage_init_clique_opt(); + s=clique_unweighted_find_single(g,/*min_weight*/0, + /*max_weight*/0,/*maximal*/TRUE, + opts); + free(opts); + + // Writing the answer into a int [] to be read by Sage + int size=set_size(s); + *list=malloc(sizeof(int)*size); + l=0; + for (i=0; i +#include +#include + +#ifdef ENABLE_LONG_OPTIONS +#include +#endif + +#include "cliquer/cliquer.h" + + +#define TRYFORHELP "Try `%s -h' for more information.\n",argv[0] + +void printhelp(char *prog); +void read_options(int argc, char **argv); +void print_search(graph_t *g); +boolean record_clique_func(set_t s,graph_t *g,clique_options *opts); +boolean print_clique_func(set_t s,graph_t *g,clique_options *opts); +void print_clique(set_t s,graph_t *g); + +// As the global variables remain between two SAGE call, they +// have to be reset each time +void sage_reset_global_variables(); +// The opt structure has to be initialised in each SAGE function +clique_options * sage_init_clique_opt(); +// Computes a maximum clique of the graph g and return its size +// The table list contains the ID of the vertices +int sage_clique_max(graph_t *g,int **list); +int sage_all_clique_max(graph_t *g,int **list); +int sage_clique_number(graph_t *g); + + diff --git a/src/sage/graphs/digraph.py b/src/sage/graphs/digraph.py index 05d4ebc6790..f869bb07cfc 100644 --- a/src/sage/graphs/digraph.py +++ b/src/sage/graphs/digraph.py @@ -723,7 +723,7 @@ def __init__(self, data=None, pos=None, loops=None, format=None, try: e = int(e) assert e >= 0 - except StandardError: + except Exception: if weighted is False: raise ValueError("Non-weighted digraph's"+ " adjacency matrix must have only nonnegative"+ @@ -1937,16 +1937,16 @@ def reverse_edge(self, u, v=None, label=None, inplace=True, multiedges=None): if v is None: try: u, v, label = u - except StandardError: + except Exception: try: u, v = u - except StandardError: + except Exception: pass else: if v is None: try: u, v = u - except StandardError: + except Exception: pass if not self.has_edge(u,v,label): diff --git a/src/sage/graphs/dot2tex_utils.py b/src/sage/graphs/dot2tex_utils.py index c99b5e72718..0b808000dc8 100644 --- a/src/sage/graphs/dot2tex_utils.py +++ b/src/sage/graphs/dot2tex_utils.py @@ -27,7 +27,7 @@ def have_dot2tex(): import dot2tex # Test for this required feature from dot2tex 2.8.7 return dot2tex.dot2tex("graph {}", format = "positions") == {} - except StandardError: + except Exception: return False return True diff --git a/src/sage/graphs/generators/random.py b/src/sage/graphs/generators/random.py index e30c2b5cf95..4b74922178a 100644 --- a/src/sage/graphs/generators/random.py +++ b/src/sage/graphs/generators/random.py @@ -700,7 +700,7 @@ def RandomRegular(d, n, seed=None): N = networkx.random_regular_graph(d, n, seed=seed) if N is False: return False return Graph(N, sparse=True) - except StandardError: + except Exception: return False def RandomShell(constructor, seed=None): diff --git a/src/sage/graphs/generators/smallgraphs.py b/src/sage/graphs/generators/smallgraphs.py index 0acf5b26187..9b14fa35159 100644 --- a/src/sage/graphs/generators/smallgraphs.py +++ b/src/sage/graphs/generators/smallgraphs.py @@ -1419,8 +1419,8 @@ def KittellGraph(): r""" Returns the Kittell Graph. - For more information on the Kittell Graph, see the `corresponding Wolfram - page `_. + For more information, see the `Wolfram page about the Kittel Graph + `_. EXAMPLES:: @@ -3153,8 +3153,8 @@ def MarkstroemGraph(): Returns the Markström Graph. The Markström Graph is a cubic planar graph with no cycles of length 4 nor - 8, but containing cycles of length 16. For more information on the Markström - Graph, see the `corresponding Wolfram page + 8, but containing cycles of length 16. For more information, see the + `Wolfram page about the Markström Graph `_. EXAMPLES:: @@ -4137,10 +4137,10 @@ def WienerArayaGraph(): Returns the Wiener-Araya Graph. The Wiener-Araya Graph is a planar hypohamiltonian graph on 42 vertices and - 67 edges. For more information on the Wiener-Araya Graph, see its - corresponding `Wolfram Page - `_ or its `(french) - Wikipedia page `_. + 67 edges. For more information, see the `Wolfram Page on the Wiener-Araya + Graph `_ or its + `(french) Wikipedia page + `_. EXAMPLES:: diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 406b2c9063d..b12e6215450 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -315,8 +315,6 @@ class GenericGraph(GenericGraph_pyx): """ Base class for graphs and digraphs. - - .. autofunction:: _scream_if_not_simple """ # Nice defaults for plotting arrays of graphs (see sage.misc.functional.show) @@ -1066,7 +1064,7 @@ def networkx_graph(self, copy=True): return self._backend._nxg.copy() else: return self._backend._nxg - except StandardError: + except Exception: import networkx if self._directed and self.allows_multiple_edges(): class_type = networkx.MultiDiGraph @@ -2304,8 +2302,25 @@ def name(self, new=None): Graph on 10 vertices sage: G.name() '' + + Name of an immutable graph :trac:`15681` :: + + sage: g = graphs.PetersenGraph() + sage: gi = g.copy(immutable=True) + sage: gi.name() + 'Petersen graph' + sage: gi.name("Hey") + Traceback (most recent call last): + ... + NotImplementedError: An immutable graph does not change name """ - return self._backend.name(new) + if new is None: + return getattr(self, '_name', "") + + if getattr(self, '_immutable', False): + raise NotImplementedError("An immutable graph does not change name") + + self._name = str(new) def get_pos(self, dim = 2): """ @@ -8362,7 +8377,7 @@ def has_vertex(self, vertex): """ try: hash(vertex) - except StandardError: + except Exception: return False return self._backend.has_vertex(vertex) @@ -8671,11 +8686,7 @@ def neighbor_iterator(self, vertex): sage: list(D.neighbor_iterator(0)) [1, 2, 3] """ - if self._directed: - return iter(set(self.neighbor_out_iterator(vertex)) \ - | set(self.neighbor_in_iterator(vertex))) - else: - return self._backend.iterator_nbrs(vertex) + return self._backend.iterator_nbrs(vertex) def vertices(self, key=None, boundary_first=False): r""" @@ -8923,16 +8934,16 @@ def add_edge(self, u, v=None, label=None): if v is None: try: u, v, label = u - except StandardError: + except Exception: try: u, v = u - except StandardError: + except Exception: pass else: if v is None: try: u, v = u - except StandardError: + except Exception: pass if not self.allows_loops() and u==v: return @@ -9208,7 +9219,7 @@ def delete_edge(self, u, v=None, label=None): if v is None: try: u, v, label = u - except StandardError: + except Exception: u, v = u label = None self._backend.del_edge(u, v, label, self._directed) @@ -9387,7 +9398,7 @@ def has_edge(self, u, v=None, label=None): if v is None: try: u, v, label = u - except StandardError: + except Exception: u, v = u label = None return self._backend.has_edge(u, v, label) @@ -11036,15 +11047,12 @@ def is_chordal(self, certificate = False, algorithm = "B"): TESTS: - This shouldn't fail (trac 10899):: + This shouldn't raise exceptions (:trac:`10899`):: sage: Graph(1).is_chordal() True sage: for g in graphs(5): - ... try: - ... forget = g.is_chordal() - ... except StandardError: - ... print("Oh no.") + ....: _ = g.is_chordal() REFERENCES: @@ -12140,7 +12148,7 @@ def center(self): e = self.eccentricity(with_labels=True) try: r = min(e.values()) - except StandardError: + except Exception: return [] return [v for v in e if e[v]==r] @@ -12480,7 +12488,7 @@ def periphery(self): e = self.eccentricity(with_labels=True) try: r = max(e.values()) - except StandardError: + except Exception: return [] return [v for v in e if e[v]==r] @@ -12784,7 +12792,7 @@ def shortest_path(self, u, v, by_weight=False, bidirectional=True): except AttributeError: try: L = networkx.bidirectional_dijkstra(self.networkx_graph(copy=False), u, v)[1] - except StandardError: + except Exception: L = False else: L = networkx.dijkstra_path(self.networkx_graph(copy=False), u, v) @@ -12798,7 +12806,7 @@ def shortest_path(self, u, v, by_weight=False, bidirectional=True): else: try: L = networkx.single_source_shortest_path(self.networkx_graph(copy=False), u)[v] - except StandardError: + except Exception: L = False if L: return L @@ -13708,18 +13716,27 @@ def complement(self): Traceback (most recent call last): ... TypeError: complement not well defined for (di)graphs with multiple edges + + TESTS: + + We check that :trac:`15699` is fixed:: + + sage: G = graphs.PathGraph(5).copy(immutable=True) + sage: G.complement() + complement(Path Graph): Graph on 5 vertices """ if self.has_multiple_edges(): raise TypeError('complement not well defined for (di)graphs with multiple edges') self._scream_if_not_simple() - from copy import copy - G = copy(self) + G = self.copy(immutable=False) # Make sure it's a mutable copy G.delete_edges(G.edges()) G.name('complement(%s)'%self.name()) for u in self: for v in self: if not self.has_edge(u,v): G.add_edge(u,v) + if getattr(self, '_immutable', False): + return G.copy(immutable=True) return G def to_simple(self): @@ -16638,21 +16655,11 @@ def relabel(self, perm=None, inplace=True, return_map=False, check_input = True, Traceback (most recent call last): ... ValueError: To relabel an immutable graph use inplace=False - - A couple of lines to remove when hasse diagrams will not have a - ``._immutable`` attribute by default:: - - sage: from sage.combinat.posets.hasse_diagram import HasseDiagram - sage: if getattr(HasseDiagram,'_immutable', "YES") == "YES": - ....: print "two lines must be removed from this function" - """ from sage.groups.perm_gps.permgroup_element import PermutationGroupElement if not inplace: G = self.copy(immutable=False) - if getattr(G, "_immutable", False): # can be removed when posets - G._immutable = False # have immutable backends perm2 = G.relabel(perm, return_map= return_map, check_input = check_input, diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index 538d8dfd6f8..a3f1dcdbcda 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -1089,6 +1089,12 @@ def __init__(self, data=None, pos=None, loops=None, format=None, sage: g = graphs.PetersenGraph() sage: g = Graph(g.edges(),immutable=False) sage: g.add_edge("Hey", "Heyyyyyyy") + + And their name is set:: + + sage: g = graphs.PetersenGraph() + sage: Graph(g, immutable=True) + Petersen graph: Graph on 10 vertices """ GenericGraph.__init__(self) msg = '' @@ -1316,7 +1322,7 @@ def __init__(self, data=None, pos=None, loops=None, format=None, try: e = int(e) assert e >= 0 - except StandardError: + except Exception: if weighted is False: raise ValueError("Non-weighted graph's"+ " adjacency matrix must have only nonnegative"+ @@ -1790,7 +1796,7 @@ def is_tree(self, certificate=False, output='vertex'): When the certificate cycle is given as a list of edges, the edges are given as `(v_i, v_{i+1}, l)` where `v_1, v_2, \dots, - v\n` are the vertices of the cycles (in their cyclic order). + v_n` are the vertices of the cycles (in their cyclic order). EXAMPLES:: @@ -4094,7 +4100,7 @@ def independent_set_of_representatives(self, family, solver=None, verbose=0): try: p.solve(log=verbose) - except StandardError: + except Exception: return None classss=p.get_values(classss) diff --git a/src/sage/graphs/graph_latex.py b/src/sage/graphs/graph_latex.py index a0d643a4bf0..8dbd8e02715 100644 --- a/src/sage/graphs/graph_latex.py +++ b/src/sage/graphs/graph_latex.py @@ -1124,7 +1124,7 @@ def set_option(self, option_name, option_value = None): elif name in color_options: try: cc.to_rgb(value) - except StandardError: + except Exception: raise ValueError('%s option needs to be a matplotlib color (always as a string), not %s' % (name, value)) elif name in boolean_options and not type(value) == bool: raise ValueError('%s option must be True or False, not %s' % (name, value)) @@ -1148,7 +1148,7 @@ def set_option(self, option_name, option_value = None): for key, c in value.items(): try: cc.to_rgb(c) - except StandardError: + except Exception: raise ValueError('%s option for %s needs to be a matplotlib color (always as a string), not %s' % (name, key, c)) elif name in positive_scalar_dicts: if not type(value) == dict: diff --git a/src/sage/graphs/linearextensions.py b/src/sage/graphs/linearextensions.py index 3c6a4d15616..aff540431aa 100644 --- a/src/sage/graphs/linearextensions.py +++ b/src/sage/graphs/linearextensions.py @@ -79,8 +79,7 @@ def __init__(self, dag): ################ #Precomputation# ################ - from copy import copy - dag_copy = copy(dag) + dag_copy = dag.copy(immutable=False) le = [] a = [] b = [] diff --git a/src/sage/graphs/planarity.pyx b/src/sage/graphs/planarity.pyx index 25c4fa2531f..1ff52a0baf9 100644 --- a/src/sage/graphs/planarity.pyx +++ b/src/sage/graphs/planarity.pyx @@ -66,13 +66,9 @@ def is_planar(g, kuratowski=False, set_pos=False, set_embedding=False, circular= so let's check if this this runs without exception:: sage: for i,g in enumerate(atlas_graphs): # long time - ... if (not g.is_connected() or i==0): # long time - ... continue # long time - ... try: # long time - ... _ = g.is_planar(set_embedding=True, set_pos=True) # long time - ... except StandardError: # long time - ... print "There is something wrong here !" # long time - ... break # long time + ....: if (not g.is_connected() or i==0): + ....: continue + ....: _ = g.is_planar(set_embedding=True, set_pos=True) """ if set_pos and not g.is_connected(): raise ValueError("is_planar() cannot set vertex positions for a disconnected graph") diff --git a/src/sage/graphs/schnyder.py b/src/sage/graphs/schnyder.py index 5cb784dd245..d850b6c1446 100644 --- a/src/sage/graphs/schnyder.py +++ b/src/sage/graphs/schnyder.py @@ -190,7 +190,7 @@ def _normal_label(g, comb_emb, external_face): while g.order() > 3: try: v = contractible.pop() - except StandardError: + except Exception: raise RuntimeError('Contractible list is empty but graph still has %d vertices. (Expected 3.)'%g.order()) break diff --git a/src/sage/groups/generic.py b/src/sage/groups/generic.py index 2f0a6ad934c..c0f67c10506 100644 --- a/src/sage/groups/generic.py +++ b/src/sage/groups/generic.py @@ -557,7 +557,7 @@ def discrete_log_rho(a, base, ord=None, operation='*', hash_function=hash): sage: def test(): ....: try: ....: discrete_log_rho(I(123456),I(1),operation='+') - ....: except StandardError: + ....: except Exception: ....: print "FAILURE" sage: test() # random failure FAILURE @@ -785,17 +785,17 @@ def discrete_log(a, base, ord=None, bounds=None, operation='*', identity=None, i if operation in multiplication_names: try: ord = base.multiplicative_order() - except StandardError: + except Exception: ord = base.order() elif operation in addition_names: try: ord = base.additive_order() - except StandardError: + except Exception: ord = base.order() else: try: ord = base.order() - except StandardError: + except Exception: raise ValueError, "ord must be specified" try: from sage.rings.infinity import Infinity @@ -984,7 +984,7 @@ def linear_relation(P, Q, operation='+', identity=None, inverse=None, op=None): try: n = P.multiplicative_order() m = Q.multiplicative_order() - except StandardError: + except Exception: n = P.order() m = Q.order() elif operation in addition_names: @@ -992,7 +992,7 @@ def linear_relation(P, Q, operation='+', identity=None, inverse=None, op=None): try: n = P.additive_order() m = Q.additive_order() - except StandardError: + except Exception: n = P.order() m = Q.order() else: diff --git a/src/sage/groups/perm_gps/permgroup.py b/src/sage/groups/perm_gps/permgroup.py index a63fc604b2e..de6fd53668c 100644 --- a/src/sage/groups/perm_gps/permgroup.py +++ b/src/sage/groups/perm_gps/permgroup.py @@ -153,7 +153,7 @@ def load_hap(): """ try: gap.load_package("hap") - except StandardError: + except Exception: gap.load_package("hap") def hap_decorator(f): @@ -739,7 +739,7 @@ def __contains__(self, item): """ try: item = self(item, check=True) - except StandardError: + except Exception: return False return True @@ -1933,7 +1933,7 @@ def conjugate(self, g): """ try: g = PermutationGroupElement(g) - except StandardError: + except Exception: raise TypeError("{0} does not convert to a permutation group element".format(g)) return PermutationGroup(gap_group=gap.ConjugateGroup(self, g)) diff --git a/src/sage/gsl/fft.pyx b/src/sage/gsl/fft.pyx index 07beff34f09..d3bd8ca846c 100644 --- a/src/sage/gsl/fft.pyx +++ b/src/sage/gsl/fft.pyx @@ -3,9 +3,11 @@ Fast Fourier Transforms Using GSL AUTHORS: -- William Stein (2006-9) - initial file (radix2) -- D. Joyner (2006-10) - Minor modifications (from radix2 to general case - and some documentation). +- William Stein (2006-9): initial file (radix2) +- D. Joyner (2006-10): Minor modifications (from radix2 to general case\ + and some documentation). +- M. Hansen (2013-3): Fix radix2 backwards transformation +- L.F. Tabera Alonso (2013-3): Documentation """ #***************************************************************************** @@ -32,19 +34,51 @@ from sage.rings.complex_number import ComplexNumber def FastFourierTransform(size, base_ring=None): """ - The fast Fourier transform. + Create an array for fast Fourier transform conversion using gsl. - EXAMPLES:: + INPUT: + + - ``size`` -- The size of the array + - ``base_ring`` -- Unused (2013-03) + + EXAMPLES: + + We create an array of the desired size:: + + sage: a = FastFourierTransform(8) + sage: a + [(0.0, 0.0), (0.0, 0.0), (0.0, 0.0), (0.0, 0.0), (0.0, 0.0), (0.0, 0.0), (0.0, 0.0), (0.0, 0.0)] + + Now, set the values of the array:: + + sage: for i in range(8): a[i] = i + 1 + sage: a + [(1.0, 0.0), (2.0, 0.0), (3.0, 0.0), (4.0, 0.0), (5.0, 0.0), (6.0, 0.0), (7.0, 0.0), (8.0, 0.0)] + + We can perform the forward Fourier transform on the array:: + + sage: a.forward_transform() + sage: a #abs tol 1e-2 + [(36.0, 0.0), (-4.00, 9.65), (-4.0, 4.0), (-3.99, 1.65), (-4.0, 0.0), (-4.0, -1.65), (-4.0, -4.0), (-3.99, -9.65)] + + And backwards:: + + sage: a.backward_transform() + sage: a #abs tol 1e-2 + [(8.0, 0.0), (16.0, 0.0), (24.0, 0.0), (32.0, 0.0), (40.0, 0.0), (48.0, 0.0), (56.0, 0.0), (64.0, 0.0)] + + Other example:: sage: a = FastFourierTransform(128) sage: for i in range(1, 11): - ... a[i] = 1 - ... a[128-i] = 1 + ....: a[i] = 1 + ....: a[128-i] = 1 sage: a[:6:2] [(0.0, 0.0), (1.0, 0.0), (1.0, 0.0)] sage: a.plot().show(ymin=0) sage: a.forward_transform() sage: a.plot().show() + """ return FastFourierTransform_complex(int(size)) @@ -59,6 +93,22 @@ cdef class FastFourierTransform_complex(FastFourierTransform_base): """ def __init__(self, size_t n, size_t stride=1): + """ + Create an array-like object of fixed size that will contain the vector to + apply the Fast Fourier Transform. + + INPUT: + + - ``n`` -- An integer, the size of the array + - ``stride`` -- The stride to be applied when manipulating the array. + + EXAMPLES:: + + sage: a = FastFourierTransform(1) # indirect doctest + sage: a + [(0.0, 0.0)] + + """ self.n = n self.stride = stride self.data = sage_malloc(sizeof(double)*(2*n)) @@ -67,12 +117,59 @@ cdef class FastFourierTransform_complex(FastFourierTransform_base): self.data[i] = 0 def __dealloc__(self): + """ + Frees allocated memory. + + EXAMPLE:: + + sage: a = FastFourierTransform(128) + sage: del a + + """ sage_free(self.data) def __len__(self): + """ + Return the size of the array. + + OUTPUT: The size of the array. + + EXAMPLE:: + + sage: a = FastFourierTransform(48) + sage: len(a) + 48 + + """ return self.n def __setitem__(self, size_t i, xy): + """ + Assign a value to an index of the array. Currently the input has to be + en element that can be coerced to ``float` or a ``ComplexNumber`` element. + + INPUT: + + - ``i`` -- An integer peresenting the index. + - ``xy`` -- An object to store as `i`-th element of the array ``self[i]``. + + EXAMPLE:: + + sage: I = CC(I) + sage: a = FastFourierTransform(4) + sage: a[0] = 1 + sage: a[1] = I + sage: a[2] = 1+I + sage: a[3] = (2,2) + sage: a + [(1.0, 0.0), (0.0, 1.0), (1.0, 1.0), (2.0, 2.0)] + sage: I = CDF(I) + sage: a[1] = I + Traceback (most recent call last): + ... + TypeError: Unable to convert 1.0*I to float; use abs() or real_part() as desired + + """ # just set real for now if i < 0 or i >= self.n: raise IndexError @@ -83,6 +180,27 @@ cdef class FastFourierTransform_complex(FastFourierTransform_base): self.data[2*i] = xy def __getitem__(self, i): + """ + Gets the `i`-th element of the array. + + INPUT: + + - ``i``: An integer. + + OUTPUT: + + - The `i`-th element of the array ``self[i]``. + + EXAMPLES:: + + sage: a = FastFourierTransform(4) + sage: a[0] + (0.0, 0.0) + sage: a[0] = 1 + sage: a[0] == (1,0) + True + + """ if isinstance(i, slice): start, stop, step = i.indices(self.n) return list(self)[start:stop:step] @@ -92,30 +210,83 @@ cdef class FastFourierTransform_complex(FastFourierTransform_base): return self.data[2*i], self.data[2*i+1] def __repr__(self): + """ + String representation of the array. + + OUTPUT: + + - A string representing this array. The complex numbers are + presented as a tuple of two float elements. + + EXAMPLES:: + + sage: a = FastFourierTransform(4) + sage: for i in range(4): a[i] = i + sage: a + [(0.0, 0.0), (1.0, 0.0), (2.0, 0.0), (3.0, 0.0)] + + """ return str(list(self)) def _plot_polar(self, xmin, xmax, **args): + """ + Plot a slice of the array using polar coordinates. + + INPUT: + + - ``xmin`` -- The lower bound of the slice to plot. + - ``xmax`` -- The upper bound of the slice to plot. + - ``**args`` -- passed on to the line plotting function. + + OUTPUT: + + - A plot of the array interpreting each element as polar coordinates. + + This method should not be called directly. See :meth:`plot` for the details. + + EXAMPLE:: + + sage: a = FastFourierTransform(4) + sage: a._plot_polar(0,2) + + """ cdef int i v = [] - pari = sage.libs.pari.all.pari point = sage.plot.all.point - pi = pari('Pi') + pi = sage.symbolic.constants.pi.n() + I = sage.symbolic.constants.I.n() s = 1/(3*pi) # so arg gets scaled between -1/3 and 1/3. for i from xmin <= i < xmax: - z = pari('%s + I*%s'%(self.data[2*i], self.data[2*i+1])) + z = self.data[2*i] + I*self.data[2*i+1] mag = z.abs() - if mag > 0: - arg = z.arg()*s - else: - arg = 0 - if i > 0: - v.append(point([(i-1, prev_mag), (i,mag)], hue=arg, **args)) - prev_mag = mag + arg = z.arg()*s + v.append(point((i,mag), hue=arg, **args)) return sum(v) def _plot_rect(self, xmin, xmax, **args): + """ + Plot a slice of the array. + + INPUT: + + - ``xmin`` -- The lower bound of the slice to plot. + - ``xmax`` -- The upper bound of the slice to plot. + - ``**args`` -- passed on to the line plotting function. + + OUTPUT: + + - A plot of the array. + + This method should not be called directly. See :meth:`plot` for the details. + + EXAMPLE:: + + sage: a = FastFourierTransform(4) + sage: a._plot_rect(0,3) + + """ cdef int i cdef double pr_x, x, h v = [] @@ -125,24 +296,36 @@ cdef class FastFourierTransform_complex(FastFourierTransform_base): for i from xmin <= i < xmax: x = self.data[2*i] h = self.data[2*i+1] - if i > 0: - v.append(point([(i-1, pr_x), (i,x)], hue=h, **args)) - pr_x = x + v.append(point((i,x), hue=h, **args)) return sum(v) def plot(self, style='rect', xmin=None, xmax=None, **args): """ - INPUT: - - ``style`` -- (Default: ``'rect'``) Can be one of the following: + Plot a slice of the array. + + - ``style`` -- Style of the plot, options are ``"rect"`` or ``"polar"`` + - ``rect`` -- height represents real part, color represents + imaginary part. + - ``polar`` -- height represents absolute value, color + represents argument. + - ``xmin`` -- The lower bound of the slice to plot. 0 by default. + - ``xmax`` -- The upper bound of the slice to plot. ``len(self)`` by default. + - ``**args`` -- passed on to the line plotting function. - * ``'rect'`` -- height represents the real part, color represents - the imaginary part - * ``'polar'`` -- height represents absolute value + OUTPUT: - - ``**args`` -- passed on to the line plotting function. + - A plot of the array. - EXAMPLES:: + EXAMPLE:: + sage: a = FastFourierTransform(16) + sage: for i in range(16): a[i] = (random(),random()) + sage: A = plot(a) + sage: B = plot(a, style='polar') + sage: type(A) + + sage: type(B) + sage: a = FastFourierTransform(125) sage: b = FastFourierTransform(125) sage: for i in range(1, 60): a[i]=1 @@ -150,6 +333,7 @@ cdef class FastFourierTransform_complex(FastFourierTransform_base): sage: a.forward_transform() sage: a.inverse_transform() sage: (a.plot()+b.plot()) + """ if xmin is None: xmin = 0 @@ -169,20 +353,24 @@ cdef class FastFourierTransform_complex(FastFourierTransform_base): def forward_transform(self): """ Compute the in-place forward Fourier transform of this data - using the Cooley-Tukey algorithm. If the number of sample - points in the input is a power of 2 then the function - ``gsl_fft_complex_radix2_forward()`` is automatically called. - Otherwise, ``gsl_fft_complex_forward()`` is called. + using the Cooley-Tukey algorithm. + + OUTPUT: + + - None, the transformation is done in-place. + + If the number of sample points in the input is a power of 2 then the + gsl function ``gsl_fft_complex_radix2_forward`` is automatically called. + Otherwise, ``gsl_fft_complex_forward`` is called. EXAMPLES:: - sage: a = FastFourierTransform(125) - sage: b = FastFourierTransform(125) - sage: for i in range(1, 60): a[i]=1 - sage: for i in range(1, 60): b[i]=1 + sage: a = FastFourierTransform(4) + sage: for i in range(4): a[i] = i sage: a.forward_transform() - sage: a.inverse_transform() - sage: (a.plot()+b.plot()) + sage: a #abs tol 1e-2 + [(6.0, 0.0), (-2.0, 2.0), (-2.0, 0.0), (-2.0, -2.0)] + """ cdef gsl_fft_complex_wavetable * wt cdef gsl_fft_complex_workspace * mem @@ -190,9 +378,7 @@ cdef class FastFourierTransform_complex(FastFourierTransform_base): e = N.exact_log(2) if N==2**e: gsl_fft_complex_radix2_forward(self.data, self.stride, self.n) - if N!=2**e: - #cdef gsl_fft_complex_wavetable * wt - #cdef gsl_fft_complex_workspace * mem + else: mem = gsl_fft_complex_workspace_alloc(self.n) wt = gsl_fft_complex_wavetable_alloc(self.n) gsl_fft_complex_forward(self.data, self.stride, self.n, wt, mem) @@ -201,11 +387,19 @@ cdef class FastFourierTransform_complex(FastFourierTransform_base): def inverse_transform(self): """ - Compute the in-place forward Fourier transform of this data - using the Cooley-Tukey algorithm. If the number of sample - points in the input is a power of 2 then the function - ``gsl_fft_complex_radix2_inverse()`` is automatically called. - Otherwise, ``gsl_fft_complex_inverse()`` is called. + Compute the in-place inverse Fourier transform of this data + using the Cooley-Tukey algorithm. + + OUTPUT: + + - None, the transformation is done in-place. + + If the number of sample points in the input is a power of 2 then the + function ``gsl_fft_complex_radix2_inverse`` is automatically called. + Otherwise, ``gsl_fft_complex_inverse`` is called. + + This transform is normalized so ``f.forward_transform().inverse_transform() == f`` + modulo round-off errors. See also :meth:`backward_transform`. EXAMPLES:: @@ -216,14 +410,27 @@ cdef class FastFourierTransform_complex(FastFourierTransform_base): sage: a.forward_transform() sage: a.inverse_transform() sage: (a.plot()+b.plot()) + sage: abs(sum([CDF(a[i])-CDF(b[i]) for i in range(125)])) < 2**-16 + True + + Here we check it with a power of two:: + + sage: a = FastFourierTransform(128) + sage: b = FastFourierTransform(128) + sage: for i in range(1, 60): a[i]=1 + sage: for i in range(1, 60): b[i]=1 + sage: a.forward_transform() + sage: a.inverse_transform() + sage: (a.plot()+b.plot()) + """ cdef gsl_fft_complex_wavetable * wt cdef gsl_fft_complex_workspace * mem N = Integer(self.n) e = N.exact_log(2) if N==2**e: - gsl_fft_complex_inverse(self.data, self.stride, self.n, wt, mem) - if N!=2**e: + gsl_fft_complex_radix2_inverse(self.data, self.stride, self.n) + else: mem = gsl_fft_complex_workspace_alloc(self.n) wt = gsl_fft_complex_wavetable_alloc(self.n) gsl_fft_complex_inverse(self.data, self.stride, self.n, wt, mem) @@ -233,8 +440,15 @@ cdef class FastFourierTransform_complex(FastFourierTransform_base): def backward_transform(self): """ Compute the in-place backwards Fourier transform of this data - using the Cooley-Tukey algorithm. This is the same as "inverse" - but lacks normalization so that ``backwards*forwards(f) = n*f``. + using the Cooley-Tukey algorithm. + + OUTPUT: + + - None, the transformation is done in-place. + + This is the same as :meth:`inverse_transform` but lacks normalization + so that ``f.forward_transform().backward_transform() == n*f``. Where + ``n`` is the size of the array. EXAMPLES:: @@ -245,14 +459,26 @@ cdef class FastFourierTransform_complex(FastFourierTransform_base): sage: a.forward_transform() sage: a.backward_transform() sage: (a.plot() + b.plot()).show(ymin=0) # long time (2s on sage.math, 2011) + sage: abs(sum([CDF(a[i])/125-CDF(b[i]) for i in range(125)])) < 2**-16 + True + + Here we check it with a power of two:: + + sage: a = FastFourierTransform(128) + sage: b = FastFourierTransform(128) + sage: for i in range(1, 60): a[i]=1 + sage: for i in range(1, 60): b[i]=1 + sage: a.forward_transform() + sage: a.backward_transform() + sage: (a.plot() + b.plot()).show(ymin=0) """ cdef gsl_fft_complex_wavetable * wt cdef gsl_fft_complex_workspace * mem N = Integer(self.n) e = N.exact_log(2) if N==2**e: - gsl_fft_complex_backward(self.data, self.stride, self.n, wt, mem) - if N!=2**e: + gsl_fft_complex_radix2_backward(self.data, self.stride, self.n) + else: mem = gsl_fft_complex_workspace_alloc(self.n) wt = gsl_fft_complex_wavetable_alloc(self.n) gsl_fft_complex_backward(self.data, self.stride, self.n, wt, mem) diff --git a/src/sage/gsl/ode.pyx b/src/sage/gsl/ode.pyx index b41578e895d..01b00e055ff 100644 --- a/src/sage/gsl/ode.pyx +++ b/src/sage/gsl/ode.pyx @@ -84,7 +84,7 @@ cdef int c_jac(double t,double *y,double *dfdy,double *dfdt,void *params): dfdt[i]=jac_list[y_n][i] return GSL_SUCCESS - except StandardError: + except Exception: return -1 cdef int c_f(double t,double* y, double* dydt,void *params): @@ -106,7 +106,7 @@ cdef int c_f(double t,double* y, double* dydt,void *params): for i from 0<=isage_malloc(sizeof(double)*2) self.parameters[0] = parameters[0] @@ -671,7 +671,7 @@ cdef class RealDistribution(ProbabilityDistribution): elif name == 'gaussian': try: float(parameters) - except StandardError: + except Exception: raise TypeError, "gaussian distribution requires parameter sigma coercible to float" self.parameters = sage_malloc(sizeof(double)) self.parameters[0] = float(parameters) @@ -681,7 +681,7 @@ cdef class RealDistribution(ProbabilityDistribution): raise TypeError, "pareto distribution has two parameters" try: map(float, parameters) - except StandardError: + except Exception: raise TypeError, "parameters must be coercible to float" self.parameters = sage_malloc(sizeof(double)*2) self.parameters[0] = float(parameters[0]) @@ -691,7 +691,7 @@ cdef class RealDistribution(ProbabilityDistribution): self.distribution_type = rayleigh try: float(parameters) - except StandardError: + except Exception: raise TypeError, "rayleigh distribution requires parameter sigma coercible to float" self.parameters = sage_malloc(sizeof(double)) self.parameters[0] = float(parameters) @@ -702,7 +702,7 @@ cdef class RealDistribution(ProbabilityDistribution): for x in parameters: try: float(x) - except StandardError: + except Exception: raise TypeError, "Lognormal distribution requires real parameters" self.parameters = sage_malloc(sizeof(double)*2) self.parameters[0] = float(parameters[0]) @@ -711,7 +711,7 @@ cdef class RealDistribution(ProbabilityDistribution): elif name == 't': try: float(parameters) - except StandardError: + except Exception: raise TypeError, "parameter to t distribution must be coercible to float" self.parameters = sage_malloc(sizeof(double)) self.parameters[0] = float(parameters) @@ -721,7 +721,7 @@ cdef class RealDistribution(ProbabilityDistribution): raise TypeError, "F-distribution requires two real parameters" try: map(float, parameters) - except StandardError: + except Exception: raise TypeError, "F-distribution requires real parameters" self.parameters = sage_malloc(sizeof(double)*2) self.parameters[0] = float(parameters[0]) @@ -730,7 +730,7 @@ cdef class RealDistribution(ProbabilityDistribution): elif name == 'chisquared': try: float(parameters) - except StandardError: + except Exception: raise TypeError, "parameters to t distribution must be coercible to float" self.parameters = sage_malloc(sizeof(double)) self.parameters[0] = float(parameters) @@ -741,7 +741,7 @@ cdef class RealDistribution(ProbabilityDistribution): for x in parameters: try: float(x) - except StandardError: + except Exception: raise TypeError, "exponential power distribution requires real parameters" self.parameters = sage_malloc(sizeof(double)*2) self.parameters[0] = float(parameters[0]) @@ -752,7 +752,7 @@ cdef class RealDistribution(ProbabilityDistribution): raise TypeError, "weibull distribution requires two real parameters" try: map(float, parameters) - except StandardError: + except Exception: raise TypeError, "weibull distribution requires real parameters" self.parameters = sage_malloc(sizeof(double)*2) self.parameters[0] = float(parameters[0]) @@ -763,7 +763,7 @@ cdef class RealDistribution(ProbabilityDistribution): raise TypeError, "beta distribution requires two real parameters" try: map(float, parameters) - except StandardError: + except Exception: raise TypeError, "beta distribution requires real parameters" self.parameters = sage_malloc(sizeof(double)*2) self.parameters[0] = float(parameters[0]) diff --git a/src/sage/homology/chain_complex.py b/src/sage/homology/chain_complex.py index b8182526285..b5140f571ec 100644 --- a/src/sage/homology/chain_complex.py +++ b/src/sage/homology/chain_complex.py @@ -236,7 +236,7 @@ def ChainComplex(data=None, **kwds): degree = kwds.get('degree_of_differential', kwds.get('degree', 1)) try: degree = grading_group(degree) - except StandardError: + except Exception: raise ValueError('degree is not an element of the grading group') # transform data into data_dict @@ -1018,7 +1018,7 @@ def __cmp__(self, other): return 0 return -1 - def _homology_chomp(deg, base_ring, verbose, generators): + def _homology_chomp(self, deg, base_ring, verbose, generators): """ Helper function for :meth:`homology`. @@ -1026,15 +1026,16 @@ def _homology_chomp(deg, base_ring, verbose, generators): sage: C = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0])}, base_ring=GF(2)) sage: C._homology_chomp(None, GF(2), False, False) # optional - CHomP - + {0: Vector space of dimension 2 over Finite Field of size 2, 1: Vector space of dimension 1 over Finite Field of size 2} """ + from sage.interfaces.chomp import homchain H = homchain(self, base_ring=base_ring, verbose=verbose, generators=generators) if H is None: raise RuntimeError('ran CHomP, but no output') if deg is None: return H try: - return H[d] + return H[deg] except KeyError: return HomologyGroup(0, base_ring) @@ -1504,6 +1505,9 @@ def _chomp_repr_(self): else: diffs = self._flip_().differential() + if len(diffs) == 0: + diffs = {0: matrix(ZZ, 0,0)} + maxdim = max(diffs) mindim = min(diffs) # will shift chain complex by subtracting mindim from diff --git a/src/sage/homology/delta_complex.py b/src/sage/homology/delta_complex.py index b88d9386fbf..2fe5d2ce348 100644 --- a/src/sage/homology/delta_complex.py +++ b/src/sage/homology/delta_complex.py @@ -588,7 +588,7 @@ def chain_complex(self, **kwds): Z sage: circle.cohomology(dim=1) Z - sage: T = T = delta_complexes.Torus() + sage: T = delta_complexes.Torus() sage: T.chain_complex(subcomplex=T) Trivial chain complex over Integer Ring sage: T.homology(subcomplex=T) diff --git a/src/sage/homology/simplicial_complex.py b/src/sage/homology/simplicial_complex.py index 22b3c5a22ac..dde9afa9407 100644 --- a/src/sage/homology/simplicial_complex.py +++ b/src/sage/homology/simplicial_complex.py @@ -876,7 +876,7 @@ def __init__(self, vertex_set=None, maximal_faces=None, **kwds): # build dictionary of generator names try: gen_dict[v] = 'x%s'%int(v) - except StandardError: + except Exception: gen_dict[v] = v # build set of facets good_faces = [] @@ -1265,6 +1265,84 @@ def g_vector(self): g.append(h[i] - h[i-1]) return g + def flip_graph(self): + """ + If ``self`` is pure, then it returns the the flip graph of ``self``, + otherwise, it returns ``None``. + + The flip graph of a pure simplicial complex is the (undirected) graph + with vertices being the facets, such that two facets are joined by + an edge if they meet in a codimension `1` face. + + The flip graph is used to detect if ``self`` is a pseudomanifold. + + EXAMPLES:: + + sage: S0 = simplicial_complexes.Sphere(0) + sage: G = S0.flip_graph() + sage: G.vertices(); G.edges(labels=False) + [(0,), (1,)] + [((0,), (1,))] + + sage: G = (S0.wedge(S0)).flip_graph() + sage: G.vertices(); G.edges(labels=False) + [(0,), ('L1',), ('R1',)] + [((0,), ('L1',)), ((0,), ('R1',)), (('L1',), ('R1',))] + + sage: S1 = simplicial_complexes.Sphere(1) + sage: S2 = simplicial_complexes.Sphere(2) + sage: G = (S1.wedge(S1)).flip_graph() + sage: G.vertices(); G.edges(labels=False) + [(0, 'L1'), (0, 'L2'), (0, 'R1'), (0, 'R2'), ('L1', 'L2'), ('R1', 'R2')] + [((0, 'L1'), (0, 'L2')), + ((0, 'L1'), (0, 'R1')), + ((0, 'L1'), (0, 'R2')), + ((0, 'L1'), ('L1', 'L2')), + ((0, 'L2'), (0, 'R1')), + ((0, 'L2'), (0, 'R2')), + ((0, 'L2'), ('L1', 'L2')), + ((0, 'R1'), (0, 'R2')), + ((0, 'R1'), ('R1', 'R2')), + ((0, 'R2'), ('R1', 'R2'))] + + sage: (S1.wedge(S2)).flip_graph() is None + True + + sage: G = S2.flip_graph() + sage: G.vertices(); G.edges(labels=False) + [(0, 1, 2), (0, 1, 3), (0, 2, 3), (1, 2, 3)] + [((0, 1, 2), (0, 1, 3)), + ((0, 1, 2), (0, 2, 3)), + ((0, 1, 2), (1, 2, 3)), + ((0, 1, 3), (0, 2, 3)), + ((0, 1, 3), (1, 2, 3)), + ((0, 2, 3), (1, 2, 3))] + + sage: T = simplicial_complexes.Torus() + sage: G = T.suspension(4).flip_graph() + sage: len(G.vertices()); len(G.edges(labels=False)) + 46 + 161 + """ + from collections import defaultdict + if not self.is_pure(): + return None + d = self.dimension() + Fs = self.facets() + flipG = Graph() + flipG.add_vertices(Fs) + edges = defaultdict(list) + # go through all codim 1 faces to build the edge + for F in Fs: + F_tuple = sorted(F._Simplex__set) + for i in range(d+1): + coF = tuple(F_tuple[:i]+F_tuple[i+1:]) + if coF in edges: + for G in edges[coF]: + flipG.add_edge((F,G)) + edges[coF].append(F) + return flipG + def is_pseudomanifold(self): """ Return True if self is a pseudomanifold. diff --git a/src/sage/interacts/debugger.py b/src/sage/interacts/debugger.py index 9a2d1f55dc9..db449f240a7 100644 --- a/src/sage/interacts/debugger.py +++ b/src/sage/interacts/debugger.py @@ -124,7 +124,7 @@ def evaluate(self, line): try: code = compile(line + '\n', '', 'single') exec code in globals, locals - except StandardError: + except Exception: import sys t, v = sys.exc_info()[:2] if type(t) == type(''): diff --git a/src/sage/interfaces/axiom.py b/src/sage/interfaces/axiom.py index 0ac5d58f910..af41e70fc65 100644 --- a/src/sage/interfaces/axiom.py +++ b/src/sage/interfaces/axiom.py @@ -886,7 +886,7 @@ def _sage_(self): try: import sage.misc.sage_eval return sage.misc.sage_eval.sage_eval(self.unparsed_input_form()) - except StandardError: + except Exception: raise NotImplementedError diff --git a/src/sage/interfaces/chomp.py b/src/sage/interfaces/chomp.py index a32275c30d0..65a783d39a0 100644 --- a/src/sage/interfaces/chomp.py +++ b/src/sage/interfaces/chomp.py @@ -268,7 +268,7 @@ def __call__(self, program, complex, subcomplex=None, **kwds): if mod_p: return {0: VectorSpace(base_ring, 0)} else: - return {0: HomologyGroup(0)} + return {0: HomologyGroup(0, ZZ)} d = {} h = re.compile("^H_([0-9]*) = (.*)$", re.M) tors = re.compile("Z_([0-9]*)") @@ -287,7 +287,7 @@ def __call__(self, program, complex, subcomplex=None, **kwds): if mod_p: hom = VectorSpace(base_ring, 0) else: - hom = HomologyGroup(0) + hom = HomologyGroup(0, ZZ) else: rk = 0 if hom_str.find("^") != -1: @@ -309,7 +309,7 @@ def __call__(self, program, complex, subcomplex=None, **kwds): invts.append(0) if verbose: print "dimension = %s, number of factors = %s, invariants = %s" %(dim, n, invts) - hom = HomologyGroup(n, invts) + hom = HomologyGroup(n, ZZ, invts) # # generators @@ -370,10 +370,13 @@ def __call__(self, program, complex, subcomplex=None, **kwds): if chain: new_d = {} - bottom = min(complex.differential()) - top = max(complex.differential()) + diff = complex.differential() + if len(diff) == 0: + return {} + bottom = min(diff) + top = max(diff) for dim in d: - if complex._degree == -1: # chain complex + if complex._degree_of_differential == -1: # chain complex new_dim = bottom + dim else: # cochain complex new_dim = top - dim @@ -577,12 +580,12 @@ def homchain(complex=None, **kwds): sage: homchain(C, generators=True) # optional - CHomP {-4: (C4 x C4, [(1, 0), (0, 1)])} """ - from sage.homology.all import ChainComplex + from sage.homology.chain_complex import ChainComplex_class help = kwds.get('help', False) if help: return CHomP().help('homchain') # Type-checking just in case. - if isinstance(complex, ChainComplex): + if isinstance(complex, ChainComplex_class): return CHomP()('homchain', complex, **kwds) else: raise TypeError, "Complex is not a chain complex." diff --git a/src/sage/interfaces/expect.py b/src/sage/interfaces/expect.py index 418d643ddee..0b2553d9c2e 100644 --- a/src/sage/interfaces/expect.py +++ b/src/sage/interfaces/expect.py @@ -979,9 +979,9 @@ def _expect_expr(self, expr=None, timeout=None): sage: t = walltime() sage: try: - ... r._expect_expr('25', timeout=0.5) - ... except Exception: - ... print 'Did not get expression' + ....: r._expect_expr('25', timeout=0.5) + ....: except Exception: + ....: print 'Did not get expression' Did not get expression A quick consistency check on the time that the above took:: diff --git a/src/sage/interfaces/giac.py b/src/sage/interfaces/giac.py index 5071ccf8531..fdfec259ce4 100644 --- a/src/sage/interfaces/giac.py +++ b/src/sage/interfaces/giac.py @@ -1048,7 +1048,7 @@ def _sage_(self): try: from sage.symbolic.all import SR return SR(result) - except StandardError: + except Exception: raise NotImplementedError, "Unable to parse Giac output: %s" % result else: return [entry.sage() for entry in self] diff --git a/src/sage/interfaces/interface.py b/src/sage/interfaces/interface.py index d1cfa247525..6d94b539e20 100644 --- a/src/sage/interfaces/interface.py +++ b/src/sage/interfaces/interface.py @@ -738,7 +738,7 @@ def __cmp__(self, other): try: if P.eval("%s %s %s"%(self.name(), P._greaterthan_symbol(), other.name())) == P._true_symbol(): return 1 - except StandardError: + except Exception: pass # everything is supposed to be comparable in Python, so we define @@ -851,7 +851,7 @@ def _sage_(self): string = self._sage_repr() try: return sage.misc.sage_eval.sage_eval(string) - except StandardError: + except Exception: raise NotImplementedError, "Unable to parse output: %s" % string diff --git a/src/sage/interfaces/macaulay2.py b/src/sage/interfaces/macaulay2.py index df202469d56..812a601013f 100644 --- a/src/sage/interfaces/macaulay2.py +++ b/src/sage/interfaces/macaulay2.py @@ -1097,7 +1097,7 @@ def to_sage(self): from sage.misc.sage_eval import sage_eval try: return sage_eval(repr_str) - except StandardError: + except Exception: raise NotImplementedError, "cannot convert %s to a Sage object"%repr_str diff --git a/src/sage/interfaces/magma.py b/src/sage/interfaces/magma.py index 641474e2404..f092c504ab9 100644 --- a/src/sage/interfaces/magma.py +++ b/src/sage/interfaces/magma.py @@ -1036,7 +1036,7 @@ def _next_var_name(self): else: try: self.eval('Append(~_sage_, 0);') - except StandardError: + except Exception: # this exception could happen if the Magma process # was interrupted during startup / initialization. self.eval('_sage_ := [* 0 : i in [1..%s] *];'%self.__seq) diff --git a/src/sage/interfaces/maple.py b/src/sage/interfaces/maple.py index 715a098e9be..7b0b5904734 100644 --- a/src/sage/interfaces/maple.py +++ b/src/sage/interfaces/maple.py @@ -1100,7 +1100,7 @@ def _sage_(self): try: from sage.symbolic.all import SR return SR(result) - except StandardError: + except Exception: raise NotImplementedError, "Unable to parse Maple output: %s" % result # An instance diff --git a/src/sage/interfaces/mathematica.py b/src/sage/interfaces/mathematica.py index 0a55f56052b..f60372ba27c 100644 --- a/src/sage/interfaces/mathematica.py +++ b/src/sage/interfaces/mathematica.py @@ -797,7 +797,7 @@ def _sage_(self, locals={}): try: return symbolic_expression_from_string(res, lsymbols, accept_sequence=True) - except StandardError: + except Exception: raise NotImplementedError, "Unable to parse Mathematica \ output: %s" % res diff --git a/src/sage/interfaces/mwrank.py b/src/sage/interfaces/mwrank.py index a8088224827..369837df26d 100644 --- a/src/sage/interfaces/mwrank.py +++ b/src/sage/interfaces/mwrank.py @@ -65,6 +65,79 @@ def Mwrank(options="", server=None, server_tmpdir=None): instances[options] = weakref.ref(X) return X +import re +# regex matching '[a1,a2,a3,a4,a6]', no spaces, each ai a possibly signed integer +AINVS_LIST_RE = re.compile(r'\[[+-]?(\d+)(,[+-]?\d+){4}]') +# regex matching ' a1 a2 a3 a4 a6 ', any whitespace, each ai a possibly signed integer +AINVS_PLAIN_RE = re.compile(r'^(\s*)([+-]?(\d+)(\s+)){4}([+-]?(\d+))(\s*)$') + + +def validate_mwrank_input(s): + r""" + Returns a string suitable for mwrank input, or raises an error. + + INPUT: + + - `s` -- one of the following: + + - a list or tuple of 5 integers [a1,a2,a3,a4,a6] or (a1,a2,a3,a4,a6) + - a string of the form '[a1,a2,a3,a4,a6]' or 'a1 a2 a3 a4 a6' where a1, a2, a3, a4, a6 are integers + + OUTPUT: + + For valid input, a string of the form '[a1,a2,a3,a4,a6]'. For invalid input a ValueError is raised. + + EXAMPLES: + + A list or tuple of 5 integers:: + + sage: from sage.interfaces.mwrank import validate_mwrank_input + sage: validate_mwrank_input([1,2,3,4,5]) + '[1, 2, 3, 4, 5]' + sage: validate_mwrank_input((-1,2,-3,4,-55)) + '[-1, 2, -3, 4, -55]' + sage: validate_mwrank_input([1,2,3,4]) + Traceback (most recent call last): + ... + ValueError: [1, 2, 3, 4] is not valid input to mwrank (should have 5 entries) + sage: validate_mwrank_input([1,2,3,4,i]) + Traceback (most recent call last): + ... + ValueError: [1, 2, 3, 4, I] is not valid input to mwrank (entries should be integers) + + + A string of the form '[a1,a2,a3,a4,a6]' with any whitespace and integers ai:: + + sage: validate_mwrank_input('0 -1 1 -7 6') + '[0,-1,1,-7,6]' + sage: validate_mwrank_input("[0,-1,1,0,0]\n") + '[0,-1,1,0,0]' + sage: validate_mwrank_input('0\t -1\t 1\t 0\t 0\n') + '[0,-1,1,0,0]' + sage: validate_mwrank_input('0 -1 1 -7 ') + Traceback (most recent call last): + ... + ValueError: 0 -1 1 -7 is not valid input to mwrank + + """ + if isinstance(s,(list,tuple)): + from sage.rings.all import ZZ + if len(s)!=5: + raise ValueError, "%s is not valid input to mwrank (should have 5 entries)" % s + try: + ai = [ZZ(a) for a in s] + return str(ai) + except (TypeError,ValueError): + raise ValueError, "%s is not valid input to mwrank (entries should be integers)" % s + + if isinstance(s,str): + if AINVS_PLAIN_RE.match(s): + ai = s.split() + return "["+",".join(ai)+"]" + ss = s.replace(' ','').replace('\n','').replace('\t','') + if AINVS_LIST_RE.match(ss): + return ss + raise ValueError, "%s is not valid input to mwrank" % s class Mwrank_class(Expect): """ @@ -105,7 +178,7 @@ def __init__(self, options="", server=None,server_tmpdir=None): sage: from sage.interfaces.mwrank import Mwrank_class sage: M = Mwrank_class('-v 0 -l') sage: M('0 -1 1 0 0') - 'Curve [0,-1,1,0,0] : Rank = 0\n\n\nRegulator = 1\n' + 'Curve [0,-1,1,0,0] :\tRank = 0\n\n\nRegulator = 1\n' sage: from sage.interfaces.mwrank import Mwrank_class sage: TestSuite(Mwrank_class).run() @@ -145,22 +218,77 @@ def __reduce__(self): def __call__(self, cmd): """ - Standard call function. + Interface to eval method. - EXAMPLES:: + INPUT: + + - ``cmd`` A string, or Sage object which when converted to a + string gives valid input to ``mwrank``. The conversion is + done by :meth:`validate_mwrank_input`. + + EXAMPLES: + + The input can be five integers separated by whitespace:: + + sage: mwrank('0 -1 1 0 0') + 'Curve [0,-1,1,0,0] :\tBasic pair: I=16, J=-304\n...' - sage: s = mwrank("0 0 0 0 1"); print s - Curve [0,0,0,0,1] : + Or a list or tuple of exactly five integers:: + + sage: s = mwrank([0,-1,1,0,0]) + sage: "Rank = 0" in s and "been determined unconditionally" in s + True + + TESTS: + + Invalid input raises an ValueError (see #10108); this includes + syntactically valid input which defines a singular curve:: + + sage: mwrank(10) + Traceback (most recent call last): + ... + ValueError: Invalid input: 10 is not valid input to mwrank + + sage: mwrank('0 0 0 0 0') + Traceback (most recent call last): ... - Rank = 0 + ValueError: Invalid input ([0,0,0,0,0]) to mwrank (singular curve) + + sage: mwrank('0 0 0 -3 2') + Traceback (most recent call last): ... + ValueError: Invalid input ([0,0,0,-3,2]) to mwrank (singular curve) + """ - return self.eval(str(cmd)) + try: + s = validate_mwrank_input(cmd) + except ValueError as err: + raise ValueError, "Invalid input: %s" % err + try: + return self.eval(s) + except ValueError as err: + raise ValueError, err + except RuntimeError: + raise ValueError, cmd - def eval(self, *args, **kwds): + def eval(self, s, **kwds): """ - Send a line of input to mwrank, then when it finishes return - everything that mwrank output. + Return mwrank's output for the given input. + + INPUT: + + - ``s`` (str) - a Sage object which when converted to a string + gives valid input to ``mwrank``. The conversion is done by + :meth:`validate_mwrank_input`. Possible formats are: + + - a string representing exactly five integers separated by + whitespace, for example '1 2 3 4 5' + + - a string representing exactly five integers separated by + commas, preceded by '[' and followed by ']' (with + arbitrary whitespace), for example '[1 2 3 4 5]' + + - a list or tuple of exactly 5 integers. .. note:: @@ -171,6 +299,12 @@ def eval(self, *args, **kwds): sage: mwrank.eval('12 3 4 5 6') 'Curve [12,3,4,5,6] :...' + sage: mwrank.eval('[12, 3, 4, 5, 6]') + 'Curve [12,3,4,5,6] :...' + sage: mwrank.eval([12, 3, 4, 5, 6]) + 'Curve [12,3,4,5,6] :...' + sage: mwrank.eval((12, 3, 4, 5, 6)) + 'Curve [12,3,4,5,6] :...' """ if self._expect is not None and not self._expect.isalive(): # if mwrank is interrupted twice in rapid succession, @@ -178,7 +312,13 @@ def eval(self, *args, **kwds): # "RuntimeError: [Errno 9] Bad file descriptor" # Doing _start again fixes that always. See trac #5157. self._start() - return Expect.eval(self, *args, **kwds).replace('\t',' ') + try: + ss = validate_mwrank_input(s) + return Expect.eval(self, ss, **kwds) + except ValueError as err: + raise ValueError, 'Invalid input: %s' % err + except RuntimeError: + raise ValueError, 'Invalid input (%s) to mwrank (singular curve)' % s def console(self): """ diff --git a/src/sage/interfaces/phc.py b/src/sage/interfaces/phc.py index 68d4802cd73..0431004a101 100644 --- a/src/sage/interfaces/phc.py +++ b/src/sage/interfaces/phc.py @@ -228,7 +228,7 @@ def save_as_start(self, start_filename = None, sol_filter = ''): start_data += output_list[found_solutions] + '\n\n' try: var_number = int(output_list[found_solutions+1].split(' ')[1]) - except StandardError: + except Exception: # bad error handling var_number = int(output_list[found_solutions+2].split(' ')[1]) sol_count = 0 diff --git a/src/sage/interfaces/tests.py b/src/sage/interfaces/tests.py index 096557c1436..56dd794b31b 100644 --- a/src/sage/interfaces/tests.py +++ b/src/sage/interfaces/tests.py @@ -63,7 +63,7 @@ def manyvars(s, num=70000, inlen=1, step=2000): sys.stdout.flush() v.append(s(t)) print '\nsuccess -- time = cpu: %s, wall: %s'%(cputime(t), walltime(w)) - except StandardError: + except Exception: print "%s -- failed!"%s def manyvars_all(num=70000): diff --git a/src/sage/lfunctions/lcalc.py b/src/sage/lfunctions/lcalc.py index 7a26cb7cb8e..2e11f15935e 100644 --- a/src/sage/lfunctions/lcalc.py +++ b/src/sage/lfunctions/lcalc.py @@ -119,7 +119,6 @@ def zeros(self, n, L=''): sage: lcalc.zeros(5, L='--tau') # long time [9.22237940, 13.9075499, 17.4427770, 19.6565131, 22.3361036] sage: lcalc.zeros(3, EllipticCurve('37a')) # long time - *** Warning:...new stack size = ... [0.000000000, 5.00317001, 6.87039122] """ L = self._compute_L(L) @@ -229,7 +228,6 @@ def values_along_line(self, s0, s1, number_samples, L=''): sage: E = EllipticCurve('389a') sage: E.lseries().values_along_line(0.5, 3, 5) - *** Warning:...new stack size = ... [(0.000000000, 0.209951303), (0.500000000, -...e-16), (1.00000000, 0.133768433), @@ -375,7 +373,6 @@ def analytic_rank(self, L=''): sage: E = EllipticCurve('37a') sage: lcalc.analytic_rank(E) - *** Warning:...new stack size = ... 1 """ L = self._compute_L(L) diff --git a/src/sage/libs/lcalc/lcalc_Lfunction.pxd b/src/sage/libs/lcalc/lcalc_Lfunction.pxd index 6c461e445bf..71935fc526a 100644 --- a/src/sage/libs/lcalc/lcalc_Lfunction.pxd +++ b/src/sage/libs/lcalc/lcalc_Lfunction.pxd @@ -23,6 +23,7 @@ cdef extern from "lcalc_sage.h": ctypedef struct c_Lfunction_I "L_function": c_Complex (* value) (c_Complex s, int derivative, char *whattype) + int (* compute_rank) () double (* N) (double T) void (* find_zeros_v)(double T1, double T2, double stepsize, doublevec result ) void (*find_zeros_via_N_v)(long count,int do_negative,double max_refine, int rank, int test_explicit_formula, doublevec result) @@ -38,6 +39,7 @@ cdef extern from "lcalc_sage.h": ctypedef struct c_Lfunction_D "L_function": c_Complex (* value) (c_Complex s, int derivative, char *whattype) + int (* compute_rank) () double (* N) (double T) double *dirichlet_coefficient void (* find_zeros_v)(double T1, double T2, double stepsize, doublevec result ) @@ -53,7 +55,8 @@ cdef extern from "lcalc_sage.h": ###################### ctypedef struct c_Lfunction_C "L_function": - c_Complex (* value) (c_Complex s, int derivative) + c_Complex (* value) (c_Complex s, int derivative, char *whattype) + int (* compute_rank) () double (* N) (double T) void (* find_zeros_v)(double T1, double T2, double stepsize, doublevec result ) void (*find_zeros_via_N_v)(long count,int do_negative,double max_refine, int rank, int test_explicit_formula, doublevec result) @@ -69,6 +72,7 @@ cdef extern from "lcalc_sage.h": ctypedef struct c_Lfunction_Zeta "L_function": c_Complex (* value) (c_Complex s, int derivative, char *whattype) + int (* compute_rank) () double (* N) (double T) void (* find_zeros_v)(double T1, double T2, double stepsize, doublevec result ) void (*find_zeros_via_N_v)(long count,int do_negative,double max_refine, int rank, int test_explicit_formula, doublevec result)#puts result in vector result @@ -107,6 +111,8 @@ cdef class Lfunction: cdef void *thisptr cdef void __init_fun(self, char *NAME, int what_type, dirichlet_coeff, long long Period, double q, c_Complex w, int A, double *g, c_Complex *l, int n_poles, c_Complex *p, c_Complex *r) cdef c_Complex __value(self,c_Complex s,int derivative) + cdef c_Complex __hardy_z_function(self,c_Complex s) + cdef int __compute_rank(self) #strange bug, replacing Double with double gives me a compile error cdef Double __typedN(self, double T) cdef void __find_zeros_v(self, double T1, double T2, double stepsize,doublevec *result) diff --git a/src/sage/libs/lcalc/lcalc_Lfunction.pyx b/src/sage/libs/lcalc/lcalc_Lfunction.pyx index a78c533a68d..3475e202450 100644 --- a/src/sage/libs/lcalc/lcalc_Lfunction.pyx +++ b/src/sage/libs/lcalc/lcalc_Lfunction.pyx @@ -1,10 +1,14 @@ r""" -This wraps lcalc Library +Rubinstein's lcalc library -AUTHORS: -- Rishikesh (2009): initial version -- Yann Laigle-Chapuy (2009): refactored +This is a wrapper around Michael Rubinstein's lcalc. +See http://oto.math.uwaterloo.ca/~mrubinst/L_function_public/CODE/. + +AUTHORS: +- Rishikesh (2010): added compute_rank() and hardy_z_function() +- Yann Laigle-Chapuy (2009): refactored +- Rishikesh (2009): initial version """ #***************************************************************************** # Copyright (C) 2009 William Stein @@ -30,25 +34,27 @@ from sage.rings.integer cimport Integer from sage.rings.complex_number cimport ComplexNumber from sage.rings.complex_field import ComplexField -CCC=ComplexField() +CCC = ComplexField() from sage.rings.real_mpfr cimport RealNumber from sage.rings.real_mpfr import RealField -RRR= RealField () -pi=RRR.pi() +RRR = RealField() +pi = RRR.pi() initialize_globals() ############################################################################## -# Lfunction: base class for L functions +# Lfunction: base class for L-functions ############################################################################## cdef class Lfunction: # virtual class - def __init__(self, name, what_type_L, dirichlet_coefficient, period, Q, OMEGA, gamma,lambd, pole,residue): + def __init__(self, name, what_type_L, dirichlet_coefficient, + period, Q, OMEGA, gamma, lambd, pole, residue): """ - Initialisation of L-function objects. - See derived class for details, this class is not supposed to be instanciated directly. + Initialization of L-function objects. + See derived class for details, this class is not supposed to be + instantiated directly. EXAMPLES:: @@ -61,14 +67,14 @@ cdef class Lfunction: cdef RealNumber tmpr #for accessing real values cdef ComplexNumber tmpc #for accessing complexe values - cdef char *NAME=name + cdef char *NAME = name cdef int what_type = what_type_L - tmpi=Integer(period) + tmpi = Integer(period) cdef int Period = mpz_get_si(tmpi.value) tmpr = RRR(Q) cdef double q=mpfr_get_d(tmpr.value,GMP_RNDN) - tmpc=CCC(OMEGA) + tmpc = CCC(OMEGA) cdef c_Complex w=new_Complex(mpfr_get_d(tmpc.__re,GMP_RNDN), mpfr_get_d(tmpc.__im, GMP_RNDN)) cdef int A=len(gamma) @@ -113,17 +119,21 @@ cdef class Lfunction: L-function with complex Dirichlet coefficients sage: Lfunction_Zeta() - The Zeta function + The Riemann zeta function """ return self._repr - def value(self,s,derivative=0): + def value(self, s, derivative=0): """ - Computes the value of L-function at s + Computes the value of the L-function at ``s`` INPUT: - s -- a complex number - derivative -- (default 0) the derivative to be evaluated + + - ``s`` - a complex number + - ``derivative`` - integer (default: 0) the derivative to be evaluated + - ``rotate`` - (default: False) If True, this returns the value of the + Hardy Z-function (sometimes called the Riemann-Siegel Z-function or + the Siegel Z-function). EXAMPLES:: @@ -159,10 +169,68 @@ cdef class Lfunction: cdef c_Complex result = self.__value(z, derivative) return CCC(result.real(),result.imag()) + def hardy_z_function(self, s): + """ + Computes the Hardy Z-function of the L-function at s + + INPUT: + + - ``s`` - a complex number with imaginary part between -0.5 and 0.5 + + EXAMPLES:: + + sage: chi=DirichletGroup(5)[2] #This is a quadratic character + sage: from sage.libs.lcalc.lcalc_Lfunction import * + sage: L=Lfunction_from_character(chi, type="int") + sage: L.hardy_z_function(0) + 0.231750947504... + sage: L.hardy_z_function(.5).imag().abs() < 1.0e-16 + True + sage: L.hardy_z_function(.4+.3*I) + 0.2166144222685... - 0.00408187127850...*I + sage: chi=DirichletGroup(5)[1] + sage: L=Lfunction_from_character(chi,type="complex") + sage: L.hardy_z_function(0) + 0.7939675904771... + sage: L.hardy_z_function(.5).imag().abs() < 1.0e-16 + True + sage: E=EllipticCurve([-82,0]) + sage: L=Lfunction_from_elliptic_curve(E, number_of_coeffs=40000) + sage: L.hardy_z_function(2.1) + -0.00643179176869... + sage: L.hardy_z_function(2.1).imag().abs() < 1.0e-16 + True + """ + #This takes s -> .5 + I*s + cdef ComplexNumber complexified_s = CCC(0.5)+ CCC(0,1)*CCC(s) + cdef c_Complex z = new_Complex(mpfr_get_d(complexified_s.__re,GMP_RNDN), mpfr_get_d(complexified_s.__im, GMP_RNDN)) + cdef c_Complex result = self.__hardy_z_function(z) + return CCC(result.real(),result.imag()) + + + def compute_rank(self): + """ + Computes the analytic rank (the order of vanishing at the center) of + of the L-function + + EXAMPLES:: + + sage: chi=DirichletGroup(5)[2] #This is a quadratic character + sage: from sage.libs.lcalc.lcalc_Lfunction import * + sage: L=Lfunction_from_character(chi, type="int") + sage: L.compute_rank() + 0 + sage: E=EllipticCurve([-82,0]) + sage: L=Lfunction_from_elliptic_curve(E, number_of_coeffs=40000) + sage: L.compute_rank() + 3 + """ + return self.__compute_rank() + def __N(self, T): """ - Computes number of zeroes upto height T using the formula for - N(T) with the error of S(T). Please do not use this. It is only + Compute the number of zeroes upto height `T` using the formula for + `N(T)` with the error of `S(T)`. Please do not use this. It is only for debugging EXAMPLES:: @@ -180,23 +248,26 @@ cdef class Lfunction: def find_zeros(self, T1, T2, stepsize): """ - Finds zeros on critical line between T1 and T2 using step size + Finds zeros on critical line between ``T1`` and ``T2`` using step size of stepsize. This function might miss zeros if step size is too large. This function computes the zeros of the L-function by using - change in signs of real valued function whose zeros coincide with + change in signs of areal valued function whose zeros coincide with the zeros of L-function. Use find_zeros_via_N for slower but more rigorous computation. INPUT: - T1 -- a real number giving the lower bound - T2 -- a real number giving the upper bound - stepsize -- step size to be used for search for zeros + + - ``T1`` -- a real number giving the lower bound + - ``T2`` -- a real number giving the upper bound + - ``stepsize`` -- step size to be used for the zero search OUTPUT: - A vector of zeros on the critical line which were found. - EXAMPLES: + list -- A list of the imaginary parts of the zeros which were found. + + EXAMPLES:: + sage: from sage.libs.lcalc.lcalc_Lfunction import * sage: chi=DirichletGroup(5)[2] #This is a quadratic character sage: L=Lfunction_from_character(chi, type="int") @@ -233,26 +304,37 @@ cdef class Lfunction: return returnvalue #The default values are from L.h. See L.h - def find_zeros_via_N(self, count=0, do_negative=False, max_refine=1025, rank=-1, test_explicit_formula=0): + def find_zeros_via_N(self, count=0, do_negative=False, max_refine=1025, + rank=-1, test_explicit_formula=0): """ - Finds "count" number of zeros with positive imaginary part - starting at real axis. This function also verifies if all + Finds ``count`` number of zeros with positive imaginary part + starting at real axis. This function also verifies that all the zeros have been found. INPUT: - count -- number of zeros to be found - do_negative -- (default False) False to ignore zeros below the real axis. - max_refine -- when some zeros are found to be missing, the step size used to find zeros is refined. max_refine gives an upper limit on when lcalc should give up. Use default value unless you know what you are doing. - rank -- analytic rank of the L-function. If it is -1, then lcalccomputes it. (Use default if you are in doubt) - - test_explicit_formula -- test explicit fomula for additional confidence that all the zeros have been found. This is still being tested, so use the default. + - ``count`` - number of zeros to be found + - ``do_negative`` - (default: False) False to ignore zeros below the + real axis. + - ``max_refine`` - when some zeros are found to be missing, the step + size used to find zeros is refined. max_refine gives an upper limit + on when lcalc should give up. Use default value unless you know + what you are doing. + - ``rank`` - integer (default: -1) analytic rank of the L-function. + If -1 is passed, then we attempt to compute it. (Use default if in + doubt) + - ``test_explicit_formula`` - integer (default: 0) If nonzero, test + the explicit fomula for additional confidence that all the zeros + have been found and are accurate. This is still being tested, so + using the default is recommended. OUTPUT: - List of zeros. + + list -- A list of the imaginary parts of the zeros that have been found + + EXAMPLES:: - EXAMPLES: sage: from sage.libs.lcalc.lcalc_Lfunction import * sage: chi=DirichletGroup(5)[2] #This is a quadratic character sage: L=Lfunction_from_character(chi, type="int") @@ -271,7 +353,6 @@ cdef class Lfunction: sage: L=Lfunction_Zeta() sage: L.find_zeros_via_N(3) [14.1347251417..., 21.0220396387..., 25.0108575801...] - """ cdef Integer count_I = Integer(count) cdef Integer do_negative_I = Integer(do_negative) @@ -295,6 +376,12 @@ cdef class Lfunction: cdef c_Complex __value(self,c_Complex s,int derivative): raise NotImplementedError + cdef c_Complex __hardy_z_function(self,c_Complex s): + raise NotImplementedError + + cdef int __compute_rank(self): + raise NotImplementedError + cdef double __typedN(self,double T): raise NotImplementedError @@ -305,14 +392,14 @@ cdef class Lfunction: raise NotImplementedError ############################################################################## -# Lfunction_I: L functions with integer Dirichlet Coefficients +# Lfunction_I: L-functions with integer Dirichlet Coefficients ############################################################################## cdef class Lfunction_I(Lfunction): r""" - The \class{Lfunction_I} class is used to represent L functions - with integer Dirichlet Coefficients. We assume that L functions - satisfy the following functional equation + The ``Lfunction_I`` class is used to represent L-functions + with integer Dirichlet Coefficients. We assume that L-functions + satisfy the following functional equation. .. math:: @@ -329,35 +416,42 @@ cdef class Lfunction_I(Lfunction): See (23) in http://arxiv.org/abs/math/0412181 INPUT: - what_type_L -- 1 for periodic and 0 for general - dirichlet_coefficient -- List of dirichlet coefficients (starting from n=1) - Only first M coefficients are needed if they are periodic + - ``what_type_L`` - integer, this should be set to 1 if the coefficients are + periodic and 0 otherwise. - period -- Period of the dirichlet coeffcients + - ``dirichlet_coefficient`` - List of dirichlet coefficients of the + L-function. Only first `M` coefficients are needed if they are periodic. - Q -- See above + - ``period`` - If the coefficients are periodic, this should be the + period of the coefficients. - OMEGA -- omega above + - ``Q`` - See above - gamma -- list of \gamma_j in Gamma factor, see the reference above + - ``OMEGA`` - See above - lambd -- list of \lambda_j in Gamma see the reference above + - ``kappa`` - List of the values of `\kappa_j` in the functional equation - pole -- list of poles of \Lambda - residue -- list of residues of \Lambda at above poles + - ``gamma`` - List of the values of `\gamma_j` in the functional equation + + - ``pole`` - List of the poles of L-function + + - ``residue`` - List of the residues of the L-function NOTES: - If an L function satisfies \Lambda(s) = \omega Q^s \Lamda(k-s), - by replacing s by s+(k-1)/2, one can get it in the form we need. + + If an L-function satisfies `\Lambda(s) = \omega Q^s \Lambda(k-s)`, + by replacing `s` by `s+(k-1)/2`, one can get it in the form we need. """ - def __init__(self, name, what_type_L, dirichlet_coefficient, period, Q, OMEGA, gamma,lambd, pole,residue): + def __init__(self, name, what_type_L, dirichlet_coefficient, + period, Q, OMEGA, gamma, lambd, pole, residue): r""" - Initiaize L function with integer coefficients + Initialize an L-function with integer coefficients + + EXAMPLES:: - EXAMPLES: sage: from sage.libs.lcalc.lcalc_Lfunction import * sage: chi=DirichletGroup(5)[2] #This is a quadratic character sage: L=Lfunction_from_character(chi, type="int") @@ -380,6 +474,12 @@ cdef class Lfunction_I(Lfunction): cdef inline c_Complex __value(self,c_Complex s,int derivative): return ((self.thisptr)).value(s, derivative, "pure") + + cdef inline c_Complex __hardy_z_function(self,c_Complex s): + return ((self.thisptr)).value(s, 0, "rotated pure") + + cdef int __compute_rank(self): + return ((self.thisptr)).compute_rank() cdef void __find_zeros_v(self, double T1, double T2, double stepsize, doublevec *result): (self.thisptr).find_zeros_v(T1,T2,stepsize,result[0]) @@ -432,14 +532,14 @@ cdef class Lfunction_I(Lfunction): del_c_Lfunction_I((self.thisptr)) ############################################################################## -# Lfunction_D: L functions with double (real) Dirichlet Coefficients +# Lfunction_D: L-functions with double (real) Dirichlet Coefficients ############################################################################## cdef class Lfunction_D(Lfunction): r""" - The \class{Lfunction_D} class is used to represent L functions - with real Dirichlet Coefficients. We assume that L functions - satisfy the following functional equation + The ``Lfunction_D`` class is used to represent L-functions + with real Dirichlet coefficients. We assume that L-functions + satisfy the following functional equation. .. math:: @@ -451,40 +551,42 @@ cdef class Lfunction_D(Lfunction): \Lambda(s) = Q^s \left( \prod_{j=1}^a \Gamma(\kappa_j s + \gamma_j) \right) L(s) - - - See (23) in http://arxiv.org/abs/math/0412181 INPUT: - what_type_L -- 1 for periodic and 0 for general - dirichlet_coefficient -- List of dirichlet coefficients (starting from n=1) - Only first M coefficients are needed in they are periodic + - ``what_type_L`` - integer, this should be set to 1 if the coefficients are + periodic and 0 otherwise. + + - ``dirichlet_coefficient`` - List of dirichlet coefficients of the + L-function. Only first `M` coefficients are needed if they are periodic. - period -- Period of the dirichlet coeffcients + - ``period`` - If the coefficients are periodic, this should be the + period of the coefficients. - Q -- See above + - ``Q`` - See above - OMEGA -- omega above + - ``OMEGA`` - See above - gamma -- list of \gamma_j in Gamma factor, see the reference above + - ``kappa`` - List of the values of `\kappa_j` in the functional equation - lambd -- list of \lambda_j in Gamma see the reference above + - ``gamma`` - List of the values of `\gamma_j` in the functional equation - pole -- list of poles of \Lambda + - ``pole`` - List of the poles of L-function - residue -- list of residues of \Lambda at above poles + - ``residue`` - List of the residues of the L-function NOTES: - If an L function satisfies \Lambda(s) = \omega Q^s \Lamda(k-s), - by replacing s by s+(k-1)/2, one can get it in the form we need. + If an L-function satisfies `\Lambda(s) = \omega Q^s \Lambda(k-s)`, + by replacing `s` by `s+(k-1)/2`, one can get it in the form we need. """ - def __init__(self, name, what_type_L, dirichlet_coefficient, period, Q, OMEGA, gamma,lambd, pole,residue): + def __init__(self, name, what_type_L, dirichlet_coefficient, + period, Q, OMEGA, gamma, lambd, pole, residue): r""" - Initiaize L function with real coefficients + Initialize an L-function with real coefficients + + EXAMPLES:: - EXAMPLES: sage: from sage.libs.lcalc.lcalc_Lfunction import * sage: chi=DirichletGroup(5)[2] #This is a quadratic character sage: L=Lfunction_from_character(chi, type="double") @@ -509,6 +611,13 @@ cdef class Lfunction_D(Lfunction): cdef inline c_Complex __value(self,c_Complex s,int derivative): return ((self.thisptr)).value(s, derivative, "pure") + + cdef inline c_Complex __hardy_z_function(self,c_Complex s): + return ((self.thisptr)).value(s, 0, "rotated pure") + + cdef inline int __compute_rank(self): + return ((self.thisptr)).compute_rank() + cdef void __find_zeros_v(self, double T1, double T2, double stepsize, doublevec *result): (self.thisptr).find_zeros_v(T1,T2,stepsize,result[0]) @@ -561,14 +670,14 @@ cdef class Lfunction_D(Lfunction): del_c_Lfunction_D((self.thisptr)) ############################################################################## -# Lfunction_C: L functions with Complex Dirichlet Coefficients +# Lfunction_C: L-functions with Complex Dirichlet Coefficients ############################################################################## cdef class Lfunction_C: r""" - The \class{Lfunction_C} class is used to represent L functions - with complex Dirichlet Coefficients. We assume that L functions - satisfy the following functional equation + The ``Lfunction_C`` class is used to represent L-functions + with complex Dirichlet Coefficients. We assume that L-functions + satisfy the following functional equation. .. math:: @@ -580,41 +689,43 @@ cdef class Lfunction_C: \Lambda(s) = Q^s \left( \prod_{j=1}^a \Gamma(\kappa_j s + \gamma_j) \right) L(s) - - - See (23) in http://arxiv.org/abs/math/0412181 INPUT: - what_type_L -- 1 for periodic and 0 for general - dirichlet_coefficient -- List of dirichlet coefficients (starting from n=1) - Only first M coefficients are needed in they are periodic + - ``what_type_L`` - integer, this should be set to 1 if the coefficients are + periodic and 0 otherwise. - period -- Period of the dirichlet coeffcients + - ``dirichlet_coefficient`` - List of dirichlet coefficients of the + L-function. Only first `M` coefficients are needed if they are periodic. - Q -- See above + - ``period`` - If the coefficients are periodic, this should be the + period of the coefficients. - OMEGA -- omega above + - ``Q`` - See above - gamma -- list of \gamma_j in Gamma factor, see the reference above + - ``OMEGA`` - See above - lambd -- list of \lambda_j in Gamma see the reference above + - ``kappa`` - List of the values of `\kappa_j` in the functional equation - pole -- list of poles of \Lambda + - ``gamma`` - List of the values of `\gamma_j` in the functional equation - residue -- list of residues of \Lambda at above poles + - ``pole`` - List of the poles of L-function + + - ``residue`` - List of the residues of the L-function NOTES: - If an L function satisfies \Lambda(s) = \omega Q^s \Lamda(k-s), - by replacing s by s+(k-1)/2, one can get it in the form we need. + If an L-function satisfies `\Lambda(s) = \omega Q^s \Lambda(k-s)`, + by replacing `s` by `s+(k-1)/2`, one can get it in the form we need. """ - def __init__(self, name, what_type_L, dirichlet_coefficient, period, Q, OMEGA, gamma,lambd, pole,residue): + def __init__(self, name, what_type_L, dirichlet_coefficient, + period, Q, OMEGA, gamma, lambd, pole, residue): r""" - Initiaize L function with complex coefficients + Initialize an L-function with complex coefficients + + EXAMPLES:: - EXAMPLES: sage: from sage.libs.lcalc.lcalc_Lfunction import * sage: chi=DirichletGroup(5)[1] sage: L=Lfunction_from_character(chi, type="complex") @@ -641,7 +752,15 @@ cdef class Lfunction_C: del_Complexes(coeffs) cdef inline c_Complex __value(self,c_Complex s,int derivative): - return ((self.thisptr)).value(s, derivative) + return ((self.thisptr)).value(s, derivative, "pure") + + + cdef inline c_Complex __hardy_z_function(self,c_Complex s): + return ((self.thisptr)).value(s, 0,"rotated pure") + + cdef inline int __compute_rank(self): + return ((self.thisptr)).compute_rank() + cdef void __find_zeros_v(self, double T1, double T2, double stepsize, doublevec *result): (self.thisptr).find_zeros_v(T1,T2,stepsize,result[0]) @@ -702,26 +821,32 @@ cdef class Lfunction_C: cdef class Lfunction_Zeta(Lfunction): r""" - The \class{Lfunction_Zeta} class is used to generate Zeta function - - INPUT: no input + The ``Lfunction_Zeta`` class is used to generate the Riemann zeta function. """ def __init__(self): r""" - Initialize Zeta function + Initialize the Riemann zeta function. EXAMPLES:: + sage: from sage.libs.lcalc.lcalc_Lfunction import * sage: sage.libs.lcalc.lcalc_Lfunction.Lfunction_Zeta() - The Zeta function + The Riemann zeta function """ - self.thisptr = new_c_Lfunction_Zeta() - self._repr = "The Zeta function" + self._repr = "The Riemann zeta function" cdef inline c_Complex __value(self,c_Complex s,int derivative): return ((self.thisptr)).value(s, derivative, "pure") + + cdef inline c_Complex __hardy_z_function(self,c_Complex s): + return ((self.thisptr)).value(s, 0, "rotated pure") + + cdef inline int __compute_rank(self): + return ((self.thisptr)).compute_rank() + + cdef void __find_zeros_v(self, double T1, double T2, double stepsize, doublevec *result): (self.thisptr).find_zeros_v(T1,T2,stepsize,result[0]) @@ -737,45 +862,24 @@ cdef class Lfunction_Zeta(Lfunction): """ del_c_Lfunction_Zeta((self.thisptr)) -# def find_zeros_via_N_to_file(self, filename, count=0, do_negative=0, max_refine=1025, rank=-1, test_explicit_formula=0): -# """ -# Find the first "count" number of zeros of the Zeta function, and -# write them to the file given by the string filename. This is being -# tested so do not use it. - -# EXAMPLES: -# """ -# tmpfile=open(filename,'w') -# tmpfile.close() -# cdef char *FILE = filename -# #test code begins -# tmpf = FILE -# print -# #test code ends -# cdef Integer count_I = Integer(count) -# cdef Integer do_negative_I = Integer(do_negative) -# cdef RealNumber max_refine_R = RRR(max_refine) -# cdef Integer rank_I = Integer(rank) -# cdef Integer test_explicit_I = Integer(test_explicit_formula) -# sig_on() -# self.thisptr.find_zeros_via_N(mpz_get_si(count_I.value), mpz_get_si(do_negative_I.value), mpfr_get_d(max_refine_R.value, GMP_RNDN), mpz_get_si(rank_I.value), mpz_get_si(test_explicit_I.value),FILE) -# sig_off() - ############################################################################## # Tools ############################################################################## def Lfunction_from_character(chi, type="complex"): """ - Given a primitive Dirichlet Character, this function returns - lcalc L-Function Object for that. + Given a primitive Dirichlet character, this function returns + an lcalc L-function object for the L-function of the character. INPUT: - chi -- A character in Dirichlet Group - use_type -- (default: "complex") type used for Dirichlet coefficients - can be "int", "double" or "complex" + + - `chi` - A Dirichlet character + - `use_type` - string (default: "complex") type used for the Dirichlet + coefficients. This can be "int", "double" or "complex". + OUTPUT: - L-function object for chi + + L-function object for `chi`. EXAMPLES:: @@ -790,6 +894,7 @@ def Lfunction_from_character(chi, type="complex"): Traceback (most recent call last): ... ValueError: For non quadratic characters you must use type="complex" + """ if (not chi.is_primitive()): raise TypeError("Dirichlet character is not primitive") @@ -806,32 +911,37 @@ def Lfunction_from_character(chi, type="complex"): period=modulus OMEGA=1.0/ ( CCC(0,1)**a * (CCC(modulus)).sqrt()/chi.gauss_sum() ) - if type=="complex": + if type == "complex": dir_coeffs=[CCC(chi(n)) for n in xrange(1,modulus+1)] return Lfunction_C("", 1,dir_coeffs, period,Q,OMEGA,[.5],[a/2.],poles,residues) if not type in ["double","int"]: raise ValueError("unknown type") if chi.order() != 2: raise ValueError("For non quadratic characters you must use type=\"complex\"") - if type=="double": + if type == "double": dir_coeffs=[RRR(chi(n)) for n in xrange(1,modulus+1)] return Lfunction_D("", 1,dir_coeffs, period,Q,OMEGA,[.5],[a/2.],poles,residues) - if type=="int": + if type == "int": dir_coeffs=[Integer(chi(n)) for n in xrange(1,modulus+1)] return Lfunction_I("", 1,dir_coeffs, period,Q,OMEGA,[.5],[a/2.],poles,residues) def Lfunction_from_elliptic_curve(E, number_of_coeffs=10000): """ - Given an Elliptic Curve E, it returns an L-function Object - for E. + Given an elliptic curve E, return an L-function object for + the function `L(s, E)`. INPUT: - E -- An Elliptic Curve - number_of_coeffs -- Number of coeffs to be used for contructing L-function object + + - ``E`` - An elliptic curve + - ``number_of_coeffs`` - integer (default: 10000) The number of + coefficients to be used when constructing the L-function object. Right + now this is fixed at object creation time, and is not automatically + set intelligently. OUTPUT: - L-function object for E. + + L-function object for ``L(s, E)``. EXAMPLES:: diff --git a/src/sage/libs/ntl/ntl_lzz_p.pyx b/src/sage/libs/ntl/ntl_lzz_p.pyx index 82f041a46c6..555012a9278 100644 --- a/src/sage/libs/ntl/ntl_lzz_p.pyx +++ b/src/sage/libs/ntl/ntl_lzz_p.pyx @@ -144,7 +144,7 @@ cdef class ntl_zz_p: else: try: modulus = int(modulus) - except StandardError: + except Exception: raise ValueError, "%s is not a valid modulus."%modulus self.c = ntl_zz_pContext(modulus) diff --git a/src/sage/libs/ntl/ntl_lzz_pX.pyx b/src/sage/libs/ntl/ntl_lzz_pX.pyx index 50beefae46f..1f713faab46 100644 --- a/src/sage/libs/ntl/ntl_lzz_pX.pyx +++ b/src/sage/libs/ntl/ntl_lzz_pX.pyx @@ -160,7 +160,7 @@ cdef class ntl_zz_pX: else: try: modulus = int(modulus) - except StandardError: + except Exception: raise ValueError, "%s is not a valid modulus."%modulus self.c = ntl_zz_pContext(modulus) diff --git a/src/sage/libs/pari/gen.pyx b/src/sage/libs/pari/gen.pyx index 03268ad38f0..6c082c36214 100644 --- a/src/sage/libs/pari/gen.pyx +++ b/src/sage/libs/pari/gen.pyx @@ -7768,7 +7768,22 @@ cdef class gen(sage.structure.element.RingElement): def poldisc(self, var=-1): """ - f.poldist(var=x): Return the discriminant of this polynomial. + Return the discriminant of this polynomial. + + EXAMPLES:: + + sage: pari("x^2 + 1").poldisc() + -4 + + Before :trac:`15654`, this used to take a very long time. + Now it takes much less than a second:: + + sage: pari.allocatemem(200000) + PARI stack size set to 200000 bytes + sage: x = polygen(ZpFM(3,10)) + sage: pol = ((x-1)^50 + x) + sage: pari(pol).poldisc() + 2*3 + 3^4 + 2*3^6 + 3^7 + 2*3^8 + 2*3^9 + O(3^10) """ pari_catch_sig_on() return P.new_gen(poldisc0(self.g, P.get_var(var))) @@ -8109,20 +8124,89 @@ cdef class gen(sage.structure.element.RingElement): def lllgramint(self): return self.qflllgram(1) - def qfminim(self, B, max, long flag=0): + def qfminim(self, b=None, m=None, long flag=0, unsigned long precision=0): """ - qfminim(x,bound,maxnum,flag=0): number of vectors of square norm = - bound, maximum norm and list of vectors for the integral and - definite quadratic form x; minimal non-zero vectors if bound=0. - flag is optional, and can be 0: default; 1: returns the first - minimal vector found (ignore maxnum); 2: as 0 but uses a more - robust, slower implementation, valid for non integral quadratic - forms. + Return vectors with bounded norm for this quadratic form. + + INPUT: + + - ``self`` -- a quadratic form + - ``b`` -- a bound on vector norm (finds minimal non-zero + vectors if b=0) + - ``m`` -- maximum number of vectors to return. If ``None`` + (default), return all vectors of norm at most B + - flag (optional) -- + + - 0: default; + - 1: return only the first minimal vector found (ignore ``max``); + - 2: as 0 but uses a more robust, slower implementation, + valid for non integral quadratic forms. + + OUTPUT: + + A triple consisting of + + - the number of vectors of norm <= b, + - the actual maximum norm of vectors listed + - a matrix whose columns are vectors with norm less than or + equal to b for the definite quadratic form. Only one of `v` + and `-v` is returned and the zero vector is never returned. + + .. note:: + + If max is specified then only max vectors will be output, + but all vectors withing the given norm bound will be computed. + + EXAMPLES:: + + sage: A = Matrix(3,3,[1,2,3,2,5,5,3,5,11]) + sage: A.is_positive_definite() + True + + The first 5 vectors of norm at most 10:: + + sage: pari(A).qfminim(10, 5).python() + [ + [-17 -14 -15 -16 -13] + [ 4 3 3 3 2] + 146, 10, [ 3 3 3 3 3] + ] + + + All vectors of minimal norm:: + + sage: pari(A).qfminim(0).python() + [ + [-5 -2 1] + [ 1 1 0] + 6, 1, [ 1 0 0] + ] + + Use flag=2 for non-integral input:: + + sage: pari(A.change_ring(RR)).qfminim(5, m=5, flag=2).python() + [ + [ -5 -10 -2 -7 3] + [ 1 2 1 2 0] + 10, 5.00000000023283..., [ 1 2 0 1 -1] + ] + """ - cdef gen t0 = objtogen(B) - cdef gen t1 = objtogen(max) + cdef gen t0, t1 + cdef GEN g0, g1 + if b is None: + g0 = NULL + else: + t0 = objtogen(b) + g0 = t0.g + if m is None: + g1 = NULL + else: + t1 = objtogen(m) + g1 = t1.g pari_catch_sig_on() - return P.new_gen(qfminim0(self.g, t0.g, t1.g, flag, precdl)) + # precision is only used when flag == 2 + return P.new_gen(qfminim0(self.g, g0, g1, flag, prec_bits_to_words(precision))) def qfrep(self, B, long flag=0): """ diff --git a/src/c_lib/include/pb_wrap.h b/src/sage/libs/polybori/pb_wrap.h similarity index 100% rename from src/c_lib/include/pb_wrap.h rename to src/sage/libs/polybori/pb_wrap.h diff --git a/src/sage/libs/singular/function.pyx b/src/sage/libs/singular/function.pyx index 4f63ad3f307..3fd68534836 100644 --- a/src/sage/libs/singular/function.pyx +++ b/src/sage/libs/singular/function.pyx @@ -1035,7 +1035,15 @@ cdef class LibraryCallHandler(BaseCallHandler): cdef leftv* handle_call(self, Converter argument_list, ring *_ring=NULL): if _ring != currRing: rChangeCurrRing(_ring) - return iiMake_proc(self.proc_idhdl, NULL, argument_list.args) + cdef bint error = iiMake_proc(self.proc_idhdl, NULL, argument_list.args) + cdef leftv * res + if not error: + res = omAllocBin(sleftv_bin) + res.Init() + res.Copy(&iiRETURNEXPR) + iiRETURNEXPR.Init(); + return res + raise RuntimeError("Error raised calling singular function") cdef bint free_res(self): """ diff --git a/src/sage/libs/singular/polynomial.pyx b/src/sage/libs/singular/polynomial.pyx index c0652d5d321..3d50bea0312 100644 --- a/src/sage/libs/singular/polynomial.pyx +++ b/src/sage/libs/singular/polynomial.pyx @@ -282,10 +282,12 @@ cdef int singular_polynomial_div_coeff(poly** ret, poly *p, poly *q, ring *r) ex """ if q == NULL: raise ZeroDivisionError + sig_on() cdef number *n = p_GetCoeff(q, r) n = r.cf.nInvers(n) ret[0] = pp_Mult_nn(p, n, r) n_Delete(&n, r) + sig_off() return 0 cdef int singular_polynomial_pow(poly **ret, poly *p, long exp, ring *r) except -1: diff --git a/src/sage/libs/singular/singular-cdefs.pxi b/src/sage/libs/singular/singular-cdefs.pxi index b678a984f08..bc4b8ef1805 100644 --- a/src/sage/libs/singular/singular-cdefs.pxi +++ b/src/sage/libs/singular/singular-cdefs.pxi @@ -338,6 +338,7 @@ cdef extern from "libsingular.h": void* data #data is some union, so this might be very dangerous, but I am lazy now attr *attribute + void (* Copy)(leftv*) void (* Init)() void (* CleanUp)(ring *r) int rtyp @@ -953,6 +954,7 @@ cdef extern from "libsingular.h": # # INTERPRETER # + leftv iiRETURNEXPR cdef omBin* sleftv_bin @@ -960,7 +962,7 @@ cdef extern from "libsingular.h": idhdl* ggetid(char *n) - leftv * iiMake_proc(idhdl *pn, package *pack, leftv *sl) + bint iiMake_proc(idhdl *pn, package *pack, leftv *sl) bint iiExprArith1(leftv *res, leftv* a, int op) bint iiExprArith2(leftv *res, leftv* a, int op, leftv *b, bint proc_call) diff --git a/src/sage/matrix/constructor.py b/src/sage/matrix/constructor.py index 101611d49f1..657f0b2d28b 100644 --- a/src/sage/matrix/constructor.py +++ b/src/sage/matrix/constructor.py @@ -2122,7 +2122,7 @@ def elementary_matrix(arg0, arg1=None, **kwds): if not scale is None: try: scale = R(scale) - except StandardError: + except Exception: raise TypeError('scale parameter of elementary matrix must an element of {0}, not {1}'.format(R, scale)) # determine type of matrix and adjust an identity matrix diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 984c1896d8c..811759a1098 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -8175,7 +8175,7 @@ cdef class Matrix(matrix1.Matrix): raise NotImplementedError('QR decomposition is implemented over exact rings, try CDF for numerical results, not %s' % R) try: F = R.fraction_field() - except StandardError: + except Exception: raise ValueError("QR decomposition needs a fraction field of %s" % R) m = self.nrows() n = self.ncols() @@ -8787,10 +8787,19 @@ cdef class Matrix(matrix1.Matrix): ... ValueError: Jordan normal form not implemented over inexact rings. - If you need the transformation matrix as well as the Jordan form of - ``self``, then pass the option ``transformation=True``. + Here we need to specify a field, since the eigenvalues are not defined + in the smallest ring containing the matrix entries (:trac:`14508`):: - :: + sage: c = matrix([[0,1,0],[0,0,1],[1,0,0]]); + sage: c.jordan_form(CyclotomicField(3)) + [ 1| 0| 0] + [----------+----------+----------] + [ 0| zeta3| 0] + [----------+----------+----------] + [ 0| 0|-zeta3 - 1] + + If you need the transformation matrix as well as the Jordan form of + ``self``, then pass the option ``transformation=True``. For example:: sage: m = matrix([[5,4,2,1],[0,1,-1,-1],[-1,-1,3,0],[1,1,-1,2]]); m [ 5 4 2 1] @@ -8811,11 +8820,9 @@ cdef class Matrix(matrix1.Matrix): [0 0 4 1] [0 0 0 4] - Note that for matrices over inexact rings and associated numerical - stability problems, we do not attempt to compute the Jordan normal - form. - - :: + Note that for matrices over inexact rings, we do not attempt to + compute the Jordan normal form, since it is not numerically + stable:: sage: b = matrix(ZZ,3,3,range(9)) sage: jf, p = b.jordan_form(RealField(15), transformation=True) @@ -9054,21 +9061,26 @@ cdef class Matrix(matrix1.Matrix): else: return self, self.parent().identity_matrix() - if (base_ring is None and not self.base_ring().is_exact()) or \ - (not base_ring is None and not base_ring.is_exact()): - raise ValueError("Jordan normal form not implemented over inexact rings.") + inferred_base_ring = base_ring if base_ring is None: - A = self - base_ring = self.base_ring() + inferred_base_ring = self.base_ring() + + if not inferred_base_ring.is_exact(): + raise ValueError("Jordan normal form not implemented over inexact rings.") - # make sure we're working with a field.. - if not base_ring.is_field(): + # Make sure we're working with a field. + if inferred_base_ring.is_field(): + if base_ring is not None: + A = self.change_ring(inferred_base_ring) + else: + A = self + else: try: - base_field = base_ring.fraction_field() + base_field = inferred_base_ring.fraction_field() except (NotImplementedError, TypeError, AttributeError): raise ValueError("Matrix entries must be from a field, not {0}". - format(base_ring)) + format(inferred_base_ring)) A = self.change_ring(base_field) # Compute the eigenvalues of the matrix, with multiplicities. Here, @@ -9610,14 +9622,14 @@ cdef class Matrix(matrix1.Matrix): JA, SA = A.jordan_form(transformation=True) else: JA = A.jordan_form(transformation=False) - except StandardError: + except Exception: raise ValueError('unable to compute Jordan canonical form for a matrix') try: if transformation: JB, SB = B.jordan_form(transformation=True) else: JB = B.jordan_form(transformation=False) - except StandardError: + except Exception: raise ValueError('unable to compute Jordan canonical form for a matrix') similar = (JA == JB) transform = None @@ -11004,7 +11016,7 @@ cdef class Matrix(matrix1.Matrix): if not R.is_field(): try: F = R.fraction_field() - except StandardError: + except Exception: msg = 'base ring of the matrix needs a field of fractions, not {0}' raise TypeError(msg.format(R)) else: @@ -11017,7 +11029,7 @@ cdef class Matrix(matrix1.Matrix): try: abs(F.an_element()) pivot = 'partial' - except StandardError: + except Exception: if pivot == 'partial': msg = "cannot take absolute value of matrix entries, try 'pivot=nonzero'" raise TypeError(msg) diff --git a/src/sage/matrix/matrix_double_dense.pyx b/src/sage/matrix/matrix_double_dense.pyx index 2f39b27670c..93a2f63d72b 100644 --- a/src/sage/matrix/matrix_double_dense.pyx +++ b/src/sage/matrix/matrix_double_dense.pyx @@ -2807,7 +2807,7 @@ cdef class Matrix_double_dense(matrix_dense.Matrix_dense): global numpy try: tol = float(tol) - except StandardError: + except Exception: raise TypeError('tolerance must be a real number, not {0}'.format(tol)) if tol <= 0: raise ValueError('tolerance must be positive, not {0}'.format(tol)) diff --git a/src/sage/matrix/operation_table.py b/src/sage/matrix/operation_table.py index 49267458511..3c58297a64e 100644 --- a/src/sage/matrix/operation_table.py +++ b/src/sage/matrix/operation_table.py @@ -375,7 +375,7 @@ def __init__(self, S, operation, names='letters', elements=None): raise ValueError('%s is infinite' % S) try: elems = tuple(S) - except StandardError: + except Exception: raise ValueError('unable to determine elements of %s' % S) else: elems = [] @@ -384,7 +384,7 @@ def __init__(self, S, operation, names='letters', elements=None): coerced = S(e) if not(coerced in elems): elems.append(coerced) - except StandardError: + except Exception: raise TypeError('unable to coerce %s into %s' % (e, S)) self._elts = elems self._n = len(self._elts) @@ -426,7 +426,7 @@ def __init__(self, S, operation, names='letters', elements=None): row.append(self._elts.index(result)) except ValueError: # list/index condition raise ValueError('%s%s%s=%s, and so the set is not closed' % (g, self._ascii_symbol, h, result)) - except StandardError: + except Exception: raise TypeError('elements %s and %s of %s are incompatible with operation: %s' % (g,h,S,self._operation)) self._table.append(row) @@ -476,7 +476,7 @@ def _name_maker(self, names): sage: T._name_maker(['x']) Traceback (most recent call last): ... - ValueError: list of element names must be the same size as the set, 1 <> 3 + ValueError: list of element names must be the same size as the set, 1 != 3 sage: T._name_maker(['x', 'y', 4]) Traceback (most recent call last): ... @@ -516,7 +516,7 @@ def _name_maker(self, names): name_list.append(estr) elif isinstance(names, list): if len(names) != self._n: - raise ValueError('list of element names must be the same size as the set, %s <> %s'%(len(names), self._n)) + raise ValueError('list of element names must be the same size as the set, %s != %s'%(len(names), self._n)) width = 0 for str in names: if not isinstance(str, basestring): diff --git a/src/sage/misc/attached_files.py b/src/sage/misc/attached_files.py index d007a085b42..4be97d967b8 100644 --- a/src/sage/misc/attached_files.py +++ b/src/sage/misc/attached_files.py @@ -35,7 +35,7 @@ sage: load_attach_mode(attach_debug=False) sage: try: ....: attach(src) - ....: except StandardError: + ....: except Exception: ....: traceback.print_exc() Traceback (most recent call last): ... @@ -47,7 +47,7 @@ sage: load_attach_mode(attach_debug=True) sage: try: ....: attach(src) - ....: except StandardError: + ....: except Exception: ....: traceback.print_exc() Traceback (most recent call last): ... diff --git a/src/sage/misc/explain_pickle.py b/src/sage/misc/explain_pickle.py index 5a8fc2ac67d..5a8788e6e7d 100644 --- a/src/sage/misc/explain_pickle.py +++ b/src/sage/misc/explain_pickle.py @@ -2614,7 +2614,7 @@ def test_pickle(p, verbose_eval=False, pedantic=False, args=()): try: cpickle_res = unp.load() cpickle_ok = True - except StandardError: + except Exception: cpickle_ok = False current_repr = repr(current_res) diff --git a/src/sage/misc/functional.py b/src/sage/misc/functional.py index 829a0c028ea..acef1db5eb9 100644 --- a/src/sage/misc/functional.py +++ b/src/sage/misc/functional.py @@ -100,14 +100,11 @@ def base_field(x): try: return x.base_field() except AttributeError: - try: - y = x.base_ring() - if is_field(y): - return y - else: - raise AttributeError, "The base ring of %s is not a field"%x - except StandardError: - raise + y = x.base_ring() + if is_field(y): + return y + else: + raise AttributeError("The base ring of %s is not a field"%x) def basis(x): """ diff --git a/src/sage/misc/getusage.py b/src/sage/misc/getusage.py index 91016c8fc50..21e3094be1c 100644 --- a/src/sage/misc/getusage.py +++ b/src/sage/misc/getusage.py @@ -162,7 +162,7 @@ def VmB(VmKey): t = open(_proc_status) v = t.read() t.close() - except StandardError: + except Exception: return 0.0 # non-Linux? # get VmKey line e.g. 'VmRSS: 9999 kB\n ...' i = v.index(VmKey) diff --git a/src/sage/misc/latex.py b/src/sage/misc/latex.py index 38dab3dcaeb..e7fd7ada750 100644 --- a/src/sage/misc/latex.py +++ b/src/sage/misc/latex.py @@ -605,6 +605,7 @@ def latex_extra_preamble(): sage: from sage.misc.latex import latex_extra_preamble sage: print latex_extra_preamble() ... + \newcommand{\ZZ}{\Bold{Z}} \newcommand{\NN}{\Bold{N}} \newcommand{\RR}{\Bold{R}} @@ -2341,7 +2342,7 @@ def repr_lincomb(symbols, coeffs): try: if bv in CC: s += "%s\cdot %s"%(coeff, b) - except StandardError: + except Exception: s += "%s%s"%(coeff, b) first = False i += 1 diff --git a/src/sage/misc/lazy_list.pyx b/src/sage/misc/lazy_list.pyx index 45fc8bb5f70..08a9e722b7d 100644 --- a/src/sage/misc/lazy_list.pyx +++ b/src/sage/misc/lazy_list.pyx @@ -332,21 +332,21 @@ cdef class lazy_list(object): if not isinstance(start, (int,long)): try: start = start.__index__() - except StandardError: + except Exception: raise TypeError("start must be None or integer") if start < 0: raise ValueError("start must be non negative") if not isinstance(stop, (int,long)): try: stop = stop.__index__() - except StandardError: + except Exception: raise TypeError("stop must be None or integer") if stop < 0: raise ValueError("stop must be larger than -2") if not isinstance(step, (int,long)): try: step = step.__index__() - except StandardError: + except Exception: raise TypeError("step must be None or integer") if step <= 0: raise ValueError("step must be positive") @@ -746,7 +746,7 @@ cdef class lazy_list(object): else: try: start = key.start.__index__() - except StandardError: + except Exception: raise TypeError("slice indices must be integers or None or have an __index__ method") if key.stop is None: @@ -756,7 +756,7 @@ cdef class lazy_list(object): else: try: stop = key.stop.__index__() - except StandardError: + except Exception: raise TypeError("slice indices must be integers or None or have an __index__ method") if key.step is None: @@ -766,7 +766,7 @@ cdef class lazy_list(object): else: try: step = key.step.__index__() - except StandardError: + except Exception: raise TypeError("slice indices must be integers or None or have an __index__ method") if step == 0: diff --git a/src/sage/misc/log.py b/src/sage/misc/log.py index 57f75fe9471..3b720037575 100644 --- a/src/sage/misc/log.py +++ b/src/sage/misc/log.py @@ -254,7 +254,7 @@ def _get_output(self, n): x = self._output[n] try: L = latex.latex(x) - except StandardError: + except Exception: L = "\\mbox{error TeXing object}" single_png = os.path.join(self._images, '%s.png' % n) try: diff --git a/src/sage/misc/misc.py b/src/sage/misc/misc.py index 680047bfc66..40ed951caf4 100644 --- a/src/sage/misc/misc.py +++ b/src/sage/misc/misc.py @@ -1633,7 +1633,7 @@ def is_iterator(it): # see trac #7398 for a discussion try: return it is iter(it) - except StandardError: + except Exception: return False @@ -1935,6 +1935,8 @@ def alarm(seconds): seconds. This is useful for automatically interrupting long computations and can be trapped using exception handling. + Use :func:`cancel_alarm` to cancel a previously scheduled alarm. + INPUT: - ``seconds`` -- positive number, may be floating point @@ -1956,7 +1958,7 @@ def alarm(seconds): def cancel_alarm(): """ - Cancel a previously scheduled alarm (if any). + Cancel a previously scheduled alarm (if any) set by :func:`alarm`. EXAMPLES:: diff --git a/src/sage/misc/random_testing.py b/src/sage/misc/random_testing.py index b765b436380..e7fd64f86f4 100644 --- a/src/sage/misc/random_testing.py +++ b/src/sage/misc/random_testing.py @@ -140,13 +140,13 @@ def wrapped_fun(*args, **kwargs): stdout.flush() try: fn(*args, **kwargs) - except StandardError, e: - # We treat any sort of StandardError as a doctest + except Exception as e: + # We treat any sort of Exception as a doctest # failure. (We have to eat the exception, because if # doctesting sees an exception, it doesn't display # whatever was printed before the exception happened # -- so the text we print here would be lost.) Note - # that KeyboardInterrupt is not a StandardError, so + # that KeyboardInterrupt is not an Exception, so # pressing Control-C doesn't print this message. print "Random testing has revealed a problem in " + fn.__name__ print "Please report this bug! You may be the first" diff --git a/src/sage/misc/sage_extension.py b/src/sage/misc/sage_extension.py index 91f9033979a..0a2f0edde9f 100644 --- a/src/sage/misc/sage_extension.py +++ b/src/sage/misc/sage_extension.py @@ -243,11 +243,11 @@ def display(self, mode): assert(args_split[0] == "ascii_art"), "if a width is given then the mode must be `ascii_art`" try: ascii_art.MAX_WIDTH = int(args_split[1]) - except StandardError: + except Exception: raise AttributeError("Second argument must be a non-negative integer") try: displayhook.SPTextFormatter.set_display(self._magic_display_status) - except StandardError: + except Exception: print mode, args_split raise AttributeError("First argument must be `simple` or `ascii_art` or the method must be call without argument") diff --git a/src/sage/misc/sageinspect.py b/src/sage/misc/sageinspect.py index c53fe01fffe..bf37acae44d 100644 --- a/src/sage/misc/sageinspect.py +++ b/src/sage/misc/sageinspect.py @@ -1194,14 +1194,14 @@ def sage_getargspec(obj): ArgSpec(args=['n', 'proof', 'int_', 'algorithm', 'verbose'], varargs=None, keywords='kwds', defaults=(None, False, 'pari', 0)) - In the case of a class or a class instance, the ``ArgSpec`` of the ``__new__`` or ``__init__`` - methods are returned:: + In the case of a class or a class instance, the ``ArgSpec`` of the + ``__new__``, ``__init__`` or ``__call__`` method is returned:: sage: P. = QQ[] sage: sage_getargspec(P) - ArgSpec(args=['self', 'element'], varargs=None, keywords=None, defaults=None) + ArgSpec(args=['self', 'x'], varargs='args', keywords='kwds', defaults=(0,)) sage: sage_getargspec(P.__class__) - ArgSpec(args=['self', 'element'], varargs=None, keywords=None, defaults=None) + ArgSpec(args=['self', 'x'], varargs='args', keywords='kwds', defaults=(0,)) The following tests against various bugs that were fixed in :trac:`9976`:: diff --git a/src/sage/misc/superseded.py b/src/sage/misc/superseded.py index 7b61ea94253..968897a0591 100644 --- a/src/sage/misc/superseded.py +++ b/src/sage/misc/superseded.py @@ -6,8 +6,8 @@ that the deprecated function is called. Note that all doctests in the following use the trac ticket number -#13109, which is where this mandatory argument to :func:`deprecation` -was introduced. +:trac:`13109`, which is where this mandatory argument to +:func:`deprecation` was introduced. """ @@ -36,26 +36,34 @@ def _check_trac_number(trac_number): OUTPUT: - This function returns nothing. A ``ValueError`` is raised if the - argument can not be a valid trac number. + This function returns nothing. A ``ValueError`` or ``TypeError`` is + raised if the argument can not be a valid trac number. EXAMPLES:: sage: from sage.misc.superseded import _check_trac_number sage: _check_trac_number(1) + sage: _check_trac_number(0) + Traceback (most recent call last): + ... + ValueError: 0 is not a valid trac issue number sage: _check_trac_number(int(10)) sage: _check_trac_number(long(1000)) - sage: _check_trac_number('1') + sage: _check_trac_number(10.0) + Traceback (most recent call last): + ... + TypeError: 10.0000000000000 is not a valid trac issue number + sage: _check_trac_number('10') Traceback (most recent call last): ... - ValueError: The argument "1" is not a valid trac issue number. + TypeError: '10' is not a valid trac issue number """ - from sage.rings.integer import is_Integer - err = ValueError('The argument "'+str(trac_number)+'" is not a valid trac issue number.') - if not (is_Integer(trac_number) or isinstance(trac_number, (int,long))): - raise err - if trac_number < 0: - raise err + try: + trac_number = trac_number.__index__() + except Exception: + raise TypeError('%r is not a valid trac issue number'%trac_number) + if trac_number <= 0: + raise ValueError('%r is not a valid trac issue number'%trac_number) def deprecation(trac_number, message): r""" @@ -72,15 +80,14 @@ def deprecation(trac_number, message): EXAMPLES:: sage: def foo(): - ... sage.misc.superseded.deprecation(13109, 'the function foo is replaced by bar') + ....: sage.misc.superseded.deprecation(13109, 'the function foo is replaced by bar') sage: foo() doctest:1: DeprecationWarning: the function foo is replaced by bar See http://trac.sagemath.org/13109 for details. """ _check_trac_number(trac_number) - if trac_number is not None: - message += '\n' - message += 'See http://trac.sagemath.org/'+ str(trac_number) + ' for details.' + message += '\n' + message += 'See http://trac.sagemath.org/'+ str(trac_number) + ' for details.' resetwarnings() # Stack level 3 to get the line number of the code which called # the deprecated function which called this function. @@ -138,20 +145,20 @@ def __name__(self): sage: from sage.misc.superseded import deprecated_function_alias sage: class cls(object): - ... def new_meth(self): return 42 - ... old_meth = deprecated_function_alias(13109, new_meth) - ... + ....: def new_meth(self): return 42 + ....: old_meth = deprecated_function_alias(13109, new_meth) + ....: sage: cls().old_meth.__name__ 'old_meth' sage: cython('\n'.join([ - ... r"from sage.misc.superseded import deprecated_function_alias", - ... r"cdef class cython_cls(object):", - ... r" def new_cython_meth(self):", - ... r" return 1", - ... r" old_cython_meth = deprecated_function_alias(13109, new_cython_meth)" - ... ])) - ... + ....: r"from sage.misc.superseded import deprecated_function_alias", + ....: r"cdef class cython_cls(object):", + ....: r" def new_cython_meth(self):", + ....: r" return 1", + ....: r" old_cython_meth = deprecated_function_alias(13109, new_cython_meth)" + ....: ])) + ....: sage: cython_cls().old_cython_meth.__name__ 'old_cython_meth' """ @@ -207,8 +214,8 @@ def __get__(self, inst, cls = None): sage: from sage.misc.superseded import deprecated_function_alias sage: class cls(object): - ... def new_meth(self): return 42 - ... old_meth = deprecated_function_alias(13109, new_meth) + ....: def new_meth(self): return 42 + ....: old_meth = deprecated_function_alias(13109, new_meth) sage: obj = cls() sage: obj.old_meth.instance is obj True @@ -245,8 +252,8 @@ def deprecated_function_alias(trac_number, func): This also works for methods:: sage: class cls(object): - ... def new_meth(self): return 42 - ... old_meth = deprecated_function_alias(13109, new_meth) + ....: def new_meth(self): return 42 + ....: old_meth = deprecated_function_alias(13109, new_meth) sage: cls().old_meth() doctest:...: DeprecationWarning: old_meth is deprecated. Please use new_meth instead. See http://trac.sagemath.org/13109 for details. diff --git a/src/sage/modular/arithgroup/arithgroup_element.pyx b/src/sage/modular/arithgroup/arithgroup_element.pyx index 8c3cf92d9b3..6073c9f5dd8 100644 --- a/src/sage/modular/arithgroup/arithgroup_element.pyx +++ b/src/sage/modular/arithgroup/arithgroup_element.pyx @@ -36,14 +36,14 @@ cdef class ArithmeticSubgroupElement(MultiplicativeGroupElement): INPUT: - - parent - an arithmetic subgroup + - ``parent`` -- an arithmetic subgroup - - x - data defining a 2x2 matrix over ZZ - which lives in parent + - `x` -- data defining a 2x2 matrix over ZZ + which lives in parent - - check - if True, check that parent - is an arithmetic subgroup, and that - x defines a matrix of determinant 1. + - ``check`` -- if True, check that parent is an arithmetic + subgroup, and that `x` defines a matrix of + determinant `1`. We tend not to create elements of arithmetic subgroups that aren't SL2Z, in order to avoid coercion issues (that is, the other arithmetic @@ -363,7 +363,7 @@ cdef class ArithmeticSubgroupElement(MultiplicativeGroupElement): sage: g.acton(Cusp(-31/15)) +Infinity - TESTS:: + TESTS: We cover the remaining case, i.e., infinity mapped to infinity:: diff --git a/src/sage/modular/arithgroup/congroup_pyx.pyx b/src/sage/modular/arithgroup/congroup_pyx.pyx index 7c7a6364f3d..3b2e298707d 100644 --- a/src/sage/modular/arithgroup/congroup_pyx.pyx +++ b/src/sage/modular/arithgroup/congroup_pyx.pyx @@ -305,7 +305,7 @@ def generators_helper(coset_reps, level, Mat2Z): # print [type(lift_to_sl2z(c, d, level)) for c,d in crs] try: reps = [Matrix_integer_2x2(Mat2Z,lift_to_sl2z(c, d, level),False,True) for c,d in crs] - except StandardError: + except Exception: raise ArithmeticError, "Error lifting to SL2Z: level=%s crs=%s" % (level, crs) ans = [] for i from 0 <= i < len(crs): diff --git a/src/sage/modular/modform/element.py b/src/sage/modular/modform/element.py index 31ff4286ec7..2fdc749b3e8 100644 --- a/src/sage/modular/modform/element.py +++ b/src/sage/modular/modform/element.py @@ -249,7 +249,7 @@ def __cmp__(self, other): """ try: self._ensure_is_compatible(other) - except StandardError: + except Exception: return self.parent().__cmp__(other.parent()) if self.element() == other.element(): return 0 @@ -686,7 +686,7 @@ def __eq__(self, other): """ try: self._ensure_is_compatible(other) - except StandardError: + except Exception: return False if isinstance(other, Newform): if self.q_expansion(self.parent().sturm_bound()) == other.q_expansion(other.parent().sturm_bound()): @@ -715,7 +715,7 @@ def __cmp__(self, other): """ try: self._ensure_is_compatible(other) - except StandardError: + except Exception: return self.parent().__cmp__(other.parent()) if isinstance(other, Newform): if self.q_expansion(self.parent().sturm_bound()) == other.q_expansion(other.parent().sturm_bound()): diff --git a/src/sage/modules/vector_double_dense.pyx b/src/sage/modules/vector_double_dense.pyx index a306bb68672..6a51a23776a 100644 --- a/src/sage/modules/vector_double_dense.pyx +++ b/src/sage/modules/vector_double_dense.pyx @@ -741,7 +741,7 @@ cdef class Vector_double_dense(free_module_element.FreeModuleElement): else: try: p = RDF(p) - except StandardError: + except Exception: raise ValueError("vector norm 'p' must be +/- infinity or a real number, not %s" % p) n = numpy.linalg.norm(self._vector_numpy, ord=p) # p = 0 returns integer *count* of non-zero entries diff --git a/src/sage/monoids/string_monoid_element.py b/src/sage/monoids/string_monoid_element.py index be2ec18a804..4a852074bae 100644 --- a/src/sage/monoids/string_monoid_element.py +++ b/src/sage/monoids/string_monoid_element.py @@ -248,7 +248,7 @@ def __getitem__(self, n): """ try: c = self._element_list[n] - except StandardError: + except Exception: raise IndexError("Argument n (= %s) is not a valid index." % n) if not isinstance(c, list): c = [c] diff --git a/src/sage/numerical/optimize.py b/src/sage/numerical/optimize.py index 9b7b83682c7..f566b42def5 100644 --- a/src/sage/numerical/optimize.py +++ b/src/sage/numerical/optimize.py @@ -21,7 +21,8 @@ def find_root(f, a, b, xtol=10e-13, rtol=4.5e-16, maxiter=100, full_output=False """ Numerically find a root of ``f`` on the closed interval `[a,b]` (or `[b,a]`) if possible, where ``f`` is a function in the one variable. - + Note: this function only works in fixed (machine) precision, it is not + possible to get arbitrary precision approximations with it. INPUT: diff --git a/src/sage/plot/all.py b/src/sage/plot/all.py index 6cc64c3aaeb..680bc79afcf 100644 --- a/src/sage/plot/all.py +++ b/src/sage/plot/all.py @@ -23,7 +23,7 @@ from arc import arc -from animate import Animation as animate +from animate import animate from plot3d.tachyon import Tachyon diff --git a/src/sage/plot/animate.py b/src/sage/plot/animate.py index bc79d803872..515698192a2 100644 --- a/src/sage/plot/animate.py +++ b/src/sage/plot/animate.py @@ -1,13 +1,91 @@ -""" +r""" Animated plots +Animations are generated from a list (or other iterable) of graphics +objects. Images are produced by calling the ``save_image`` method on +each input object, and using ImageMagick's ``convert`` program [IM] or +``ffmpeg`` [FF] to generate an animation. The output format is GIF by +default, but can be any of the formats supported by ``convert`` or +``ffmpeg``. + +.. Warning:: + + Note that ImageMagick and FFmpeg are not included with Sage, and + must be installed by the user. On unix systems, type ``which + convert`` at a command prompt to see if ``convert`` (part of the + ImageMagick suite) is installed. If it is, you will be given its + location. Similarly, you can check for ``ffmpeg`` with ``which + ffmpeg``. See [IM] or [FF] for installation instructions. + EXAMPLES: -We plot a circle shooting up to the right:: +The sine function:: + + sage: sines = [plot(c*sin(x), (-2*pi,2*pi), color=Color(c,0,0), ymin=-1,ymax=1) for c in sxrange(0,1,.2)] + sage: a = animate(sines) + sage: a + Animation with 5 frames + sage: a.show() # optional -- ImageMagick + +Animate using ffmpeg instead of ImageMagick:: + + sage: f = sage.misc.temporary_file.tmp_filename(ext='.gif') + sage: a.save(filename=f,use_ffmpeg=True) # optional -- ffmpeg + +An animated :class:`sage.plot.graphics.GraphicsArray` of rotating ellipses:: + + sage: E = animate((graphics_array([[ellipse((0,0),a,b,angle=t,xmin=-3,xmax=3)+circle((0,0),3,color='blue') for a in range(1,3)] for b in range(2,4)]) for t in sxrange(0,pi/4,.15))) + sage: E # animations produced from a generator do not have a known length + Animation with unknown number of frames + sage: E.show() # optional -- ImageMagick + +A simple animation of a circle shooting up to the right:: + + sage: c = animate([circle((i,i), 1-1/(i+1), hue=i/10) for i in srange(0,2,0.2)], + ....: xmin=0,ymin=0,xmax=2,ymax=2,figsize=[2,2]) + sage: c.show() # optional -- ImageMagick + + +Animations of 3d objects:: + + sage: var('s,t') + (s, t) + sage: def sphere_and_plane(x): + ....: return sphere((0,0,0),1,color='red',opacity=.5)+parametric_plot3d([t,x,s],(s,-1,1),(t,-1,1),color='green',opacity=.7) + sage: sp = animate([sphere_and_plane(x) for x in sxrange(-1,1,.3)]) + sage: sp[0] # first frame + sage: sp[-1] # last frame + sage: sp.show() # optional -- ImageMagick + + sage: (x,y,z) = var('x,y,z') + sage: def frame(t): + ....: return implicit_plot3d((x^2 + y^2 + z^2), (x, -2, 2), (y, -2, 2), (z, -2, 2), plot_points=60, contour=[1,3,5], region=lambda x,y,z: x<=t or y>=t or z<=t) + sage: a = animate([frame(t) for t in srange(.01,1.5,.2)]) + sage: a[0] # first frame + sage: a.show() # optional -- ImageMagick + +If the input objects do not have a ``save_image`` method, then the +animation object attempts to make an image by calling its internal +method :meth:`sage.plot.animate.Animation.make_image`. This is +illustrated by the following example:: + + sage: t = var('t') + sage: a = animate((sin(c*pi*t) for c in sxrange(1,2,.2))) + sage: a.show() # optional -- ImageMagick + + +AUTHORS: + +- William Stein +- John Palmieri +- Niles Johnson (2013-12): Expand to animate more graphics objects + +REFERENCES: + +.. [IM] http://www.imagemagick.org + +.. [FF] http://www.ffmpeg.org - sage: a = animate([circle((i,i), 1-1/(i+1), hue=i/10) for i in srange(0,2,0.2)], - ... xmin=0,ymin=0,xmax=2,ymax=2,figsize=[2,2]) - sage: a.show() # optional -- ImageMagick """ ############################################################################ @@ -24,6 +102,20 @@ import sage.misc.misc import sage.misc.viewer + +def animate(frames, **kwds): + r""" + Animate a list of frames by creating a + :class:`sage.plot.animate.Animation` object. + + EXAMPLES:: + + sage: t = var('t') + sage: a = animate((cos(c*pi*t) for c in sxrange(1,2,.2))) + sage: a.show() # optional -- ImageMagick + """ + return Animation(frames, **kwds) + class Animation(SageObject): r""" Return an animation of a sequence of plots of objects. @@ -31,22 +123,21 @@ class Animation(SageObject): INPUT: - - ``v`` - list of Sage objects. These should - preferably be graphics objects, but if they aren't then plot is - called on them. + - ``v`` - iterable of Sage objects. These should preferably be + graphics objects, but if they aren't then :meth:`make_image` is + called on them. - - ``xmin, xmax, ymin, ymax`` - the ranges of the x and - y axes. + - ``xmin, xmax, ymin, ymax`` - the ranges of the x and y axes. - - ``**kwds`` - all additional inputs are passed onto - the rendering command. E.g., use figsize to adjust the resolution - and aspect ratio. + - ``**kwds`` - all additional inputs are passed onto the rendering + command. E.g., use figsize to adjust the resolution and aspect + ratio. EXAMPLES:: sage: a = animate([sin(x + float(k)) for k in srange(0,2*pi,0.3)], - ... xmin=0, xmax=2*pi, figsize=[2,1]) + ....: xmin=0, xmax=2*pi, figsize=[2,1]) sage: a Animation with 21 frames sage: a[:5] @@ -54,7 +145,7 @@ class Animation(SageObject): sage: a.show() # optional -- ImageMagick sage: a[:5].show() # optional -- ImageMagick - The ``show`` function takes arguments to specify the + The :meth:`show` method takes arguments to specify the delay between frames (measured in hundredths of a second, default value 20) and the number of iterations (default value 0, which means to iterate forever). To iterate 4 times with half a second @@ -68,45 +159,48 @@ class Animation(SageObject): sage: L = Graphics() sage: v = [] sage: for i in srange(0,1,step): - ... L += line([(i,i^2),(i+step,(i+step)^2)], rgbcolor=(1,0,0), thickness=2) - ... v.append(L) + ....: L += line([(i,i^2),(i+step,(i+step)^2)], rgbcolor=(1,0,0), thickness=2) + ....: v.append(L) sage: a = animate(v, xmin=0, ymin=0) sage: a.show() # optional -- ImageMagick sage: show(L) - TESTS: This illustrates that ticket #2066 is fixed (setting axes + TESTS: + + This illustrates that :trac:`2066` is fixed (setting axes ranges when an endpoint is 0):: sage: animate([plot(sin, -1,1)], xmin=0, ymin=0)._kwds['xmin'] 0 - We check that Trac #7981 is fixed:: + We check that :trac:`7981` is fixed:: sage: a = animate([plot(sin(x + float(k)), (0, 2*pi), ymin=-5, ymax=5) - ... for k in srange(0,2*pi,0.3)]) + ....: for k in srange(0,2*pi,0.3)]) sage: a.show() # optional -- ImageMagick + + Do not convert input iterator to a list:: + + sage: a = animate((x^p for p in sxrange(1,2,.1))); a + Animation with unknown number of frames + sage: a._frames + 0: + nrows += 1 + return plot.graphics_array(frame_list, nrows, ncols) def gif(self, delay=20, savefile=None, iterations=0, show_path=False, use_ffmpeg=False): @@ -299,11 +485,11 @@ def gif(self, delay=20, savefile=None, iterations=0, show_path=False, Returns an animated gif composed from rendering the graphics objects in self. - This function will only work if either (a) the ImageMagick + This method will only work if either (a) the ImageMagick software suite is installed, i.e., you have the ``convert`` command or (b) ``ffmpeg`` is installed. See - www.imagemagick.org for more about ImageMagic, and see - www.ffmpeg.org for more about ``ffmpeg``. By default, this + [IM] for more about ImageMagick, and see + [FF] for more about ``ffmpeg``. By default, this produces the gif using ``convert`` if it is present. If this can't find ``convert`` or if ``use_ffmpeg`` is True, then it uses ``ffmpeg`` instead. @@ -325,20 +511,20 @@ def gif(self, delay=20, savefile=None, iterations=0, show_path=False, - ``use_ffmpeg`` - boolean (default: False); if True, use 'ffmpeg' by default instead of 'convert'. - If savefile is not specified: in notebook mode, display the + If ``savefile`` is not specified: in notebook mode, display the animation; otherwise, save it to a default file name. EXAMPLES:: sage: a = animate([sin(x + float(k)) for k in srange(0,2*pi,0.7)], - ... xmin=0, xmax=2*pi, figsize=[2,1]) + ....: xmin=0, xmax=2*pi, figsize=[2,1]) sage: dir = tmp_dir() sage: a.gif() # not tested sage: a.gif(savefile=dir + 'my_animation.gif', delay=35, iterations=3) # optional -- ImageMagick sage: a.gif(savefile=dir + 'my_animation.gif', show_path=True) # optional -- ImageMagick Animation saved to .../my_animation.gif. - sage: a.gif(savefile=dir + 'my_animation.gif', show_path=True, use_ffmpeg=True) # optional -- ffmpeg - Animation saved to .../my_animation.gif. + sage: a.gif(savefile=dir + 'my_animation_2.gif', show_path=True, use_ffmpeg=True) # optional -- ffmpeg + Animation saved to .../my_animation_2.gif. .. note:: @@ -350,10 +536,6 @@ def gif(self, delay=20, savefile=None, iterations=0, show_path=False, packages, so please install one of them and try again. See www.imagemagick.org and www.ffmpeg.org for more information. - - AUTHORS: - - - William Stein """ from sage.misc.sage_ostools import have_program have_convert = have_program('convert') @@ -361,7 +543,7 @@ def gif(self, delay=20, savefile=None, iterations=0, show_path=False, if use_ffmpeg or not have_convert: if have_ffmpeg: self.ffmpeg(savefile=savefile, show_path=show_path, - output_format='gif', delay=delay, + output_format='.gif', delay=delay, iterations=iterations) else: if not have_convert: @@ -378,7 +560,7 @@ def gif(self, delay=20, savefile=None, iterations=0, show_path=False, raise OSError, msg else: if not savefile: - savefile = sage.misc.temporary_file.graphics_filename(ext='gif') + savefile = tmp_filename(ext='.gif') if not savefile.endswith('.gif'): savefile += '.gif' savefile = os.path.abspath(savefile) @@ -393,9 +575,9 @@ def gif(self, delay=20, savefile=None, iterations=0, show_path=False, print "Animation saved to file %s." % savefile except (CalledProcessError, OSError): msg = """ -Error: Neither ImageMagick nor ffmpeg appears to be installed. Saving an -animation to a GIF file or displaying an animation requires one of these -packages, so please install one of them and try again. +Error: Cannot generate GIF animation. Verify that convert +(ImageMagick) or ffmpeg is installed, and that the objects passed to +the animate command can be saved in PNG image format. See www.imagemagick.org and www.ffmpeg.org for more information.""" raise OSError, msg @@ -426,7 +608,7 @@ def show(self, delay=20, iterations=0): EXAMPLES:: sage: a = animate([sin(x + float(k)) for k in srange(0,2*pi,0.7)], - ... xmin=0, xmax=2*pi, figsize=[2,1]) + ....: xmin=0, xmax=2*pi, figsize=[2,1]) sage: a.show() # optional -- ImageMagick The preceding will loop the animation forever. If you want to show @@ -477,12 +659,12 @@ def _have_ffmpeg(self): return have_program('ffmpeg') def ffmpeg(self, savefile=None, show_path=False, output_format=None, - ffmpeg_options='', delay=None, iterations=0, verbose=False): - """ + ffmpeg_options='', delay=None, iterations=0, pix_fmt='rgb24'): + r""" Returns a movie showing an animation composed from rendering - the graphics objects in self. + the frames in self. - This function will only work if ffmpeg is installed. See + This method will only work if ffmpeg is installed. See http://www.ffmpeg.org for information about ffmpeg. INPUT: @@ -500,7 +682,7 @@ def ffmpeg(self, savefile=None, show_path=False, output_format=None, suffix to use for the video. This may be 'mpg', 'mpeg', 'avi', 'gif', or any other format that ffmpeg can handle. If this is None and the user specifies ``savefile`` with a - suffix, say 'savefile=animation.avi', try to determine the + suffix, say ``savefile='animation.avi'``, try to determine the format ('avi' in this case) from that file name. If no file is specified or if the suffix cannot be determined, 'mpg' is used. @@ -508,25 +690,30 @@ def ffmpeg(self, savefile=None, show_path=False, output_format=None, - ``ffmpeg_options`` - string (default: ''); this string is passed directly to ffmpeg. - - ``delay`` - integer (default: None) delay in hundredths of a - second between frames; i.e., the framerate is 100/delay. + - ``delay`` - integer (default: None); delay in hundredths of a + second between frames. The framerate is 100/delay. This is not supported for mpeg files: for mpegs, the frame rate is always 25 fps. - ``iterations`` - integer (default: 0); number of iterations of animation. If 0, loop forever. This is only supported - for animated gif output. + for animated gif output and requires ffmpeg version 0.9 or + later. For older versions, set ``iterations=None``. - - ``verbose`` - boolean (default: False); if True, print - messages produced by the ffmpeg command. + - ``pix_fmt`` - string (default: 'rgb24'); used only for gif + output. Different values such as 'rgb8' or 'pal8' may be + necessary depending on how ffmpeg was installed. Set + ``pix_fmt=None`` to disable this option. - If savefile is not specified: in notebook mode, display the - animation; otherwise, save it to a default file name. + If ``savefile`` is not specified: in notebook mode, display + the animation; otherwise, save it to a default file name. Use + :func:`sage.misc.misc.set_verbose` with ``level=1`` to see + additional output. EXAMPLES:: sage: a = animate([sin(x + float(k)) for k in srange(0,2*pi,0.7)], - ... xmin=0, xmax=2*pi, figsize=[2,1]) + ....: xmin=0, xmax=2*pi, figsize=[2,1]) sage: dir = tmp_dir() sage: a.ffmpeg(savefile=dir + 'new.mpg') # optional -- ffmpeg sage: a.ffmpeg(savefile=dir + 'new.avi') # optional -- ffmpeg @@ -543,7 +730,12 @@ def ffmpeg(self, savefile=None, show_path=False, output_format=None, a movie file in any format other than GIF requires this software, so please install it and try again. - See www.ffmpeg.org for more information. + See www.ffmpeg.org for more information. + + + TESTS:: + + sage: a.ffmpeg(output_format='gif',delay=30,iterations=5) # optional -- ffmpeg """ if not self._have_ffmpeg(): msg = """Error: ffmpeg does not appear to be installed. Saving an animation to @@ -551,25 +743,47 @@ def ffmpeg(self, savefile=None, show_path=False, output_format=None, please install it and try again.""" raise OSError, msg else: - if not savefile: + if savefile is None: if output_format is None: - output_format = 'mpg' - savefile = sage.misc.temporary_file.graphics_filename(ext=output_format) + output_format = '.mpg' + else: + if output_format[0] != '.': + output_format = '.'+output_format + savefile = tmp_filename(ext=output_format) else: if output_format is None: suffix = os.path.splitext(savefile)[1] if len(suffix) > 0: - suffix = suffix.lstrip('.') output_format = suffix else: - output_format = 'mpg' - if not savefile.endswith('.' + output_format): - savefile += '.' + output_format + output_format = '.mpg' + if not savefile.endswith(output_format): + savefile += output_format early_options = '' - if output_format == 'gif': - ffmpeg_options += ' -pix_fmt rgb24 -loop_output %s ' % iterations - if delay is not None and output_format != 'mpeg' and output_format != 'mpg': - early_options += ' -r %s -g 3 ' % int(100/delay) + if output_format == '.gif': + # We try to set reasonable options for gif output. + # + # Older versions of ffmpeg (before 0.9, summer 2011) + # use the option -loop_output instead of -loop. + # Setting iterations=None is a way of preventing sage + # from adding the -loop option. A separate + # -loop_output option can be added with the + # ffmpeg_options argument. + if iterations is not None: + loop_cmd = '-loop {0} '.format(iterations) + else: + loop_cmd = '' + # A pix_fmt value is required for some but not all + # ffmpeg installations. Setting pix_fmt=None will + # prevent sage from adding this option, and it may be + # controlled separately through ffmpeg_options. + if pix_fmt is not None: + pix_fmt_cmd = '-pix_fmt {0} '.format(pix_fmt) + else: + pix_fmt_cmd = '' + ffmpeg_options += ' {0}{1}'.format(pix_fmt_cmd,loop_cmd) + if delay is not None and output_format != '.mpeg' and output_format != '.mpg': + early_options += ' -r %s ' % int(100/delay) savefile = os.path.abspath(savefile) pngdir = self.png() pngs = os.path.join(pngdir, "%08d.png") @@ -580,11 +794,13 @@ def ffmpeg(self, savefile=None, show_path=False, output_format=None, cmd = 'cd "%s"; sage-native-execute ffmpeg -y -f image2 %s -i %s %s %s' % (pngdir, early_options, pngs, ffmpeg_options, savefile) from subprocess import check_call, CalledProcessError, PIPE try: - if verbose: - print "Executing %s " % cmd - check_call(cmd, shell=True) + if sage.misc.misc.get_verbose() > 0: + set_stderr = None else: - check_call(cmd, shell=True, stderr=PIPE) + set_stderr = PIPE + sage.misc.misc.verbose("Executing '%s'" % cmd,level=1) + sage.misc.misc.verbose("\n---- ffmpeg output below ----\n") + check_call(cmd, shell=True, stderr=set_stderr) if show_path: print "Animation saved to file %s." % savefile except (CalledProcessError, OSError): @@ -611,7 +827,7 @@ def save(self, filename=None, show_path=False, use_ffmpeg=False): filename ends in '.sobj', save to an sobj file. Otherwise, try to determine the format from the filename extension ('.mpg', '.gif', '.avi', etc.). If the format cannot be - determined, default to gif. + determined, default to GIF. For GIF files, either ffmpeg or the ImageMagick suite must be installed. For other movie formats, ffmpeg must be installed. @@ -620,7 +836,7 @@ def save(self, filename=None, show_path=False, use_ffmpeg=False): EXAMPLES:: sage: a = animate([sin(x + float(k)) for k in srange(0,2*pi,0.7)], - ... xmin=0, xmax=2*pi, figsize=[2,1]) + ....: xmin=0, xmax=2*pi, figsize=[2,1]) sage: dir = tmp_dir() sage: a.save() # not tested sage: a.save(dir + 'wave.gif') # optional -- ImageMagick diff --git a/src/sage/plot/graphics.py b/src/sage/plot/graphics.py index b5f814bd116..549ee2dbd15 100644 --- a/src/sage/plot/graphics.py +++ b/src/sage/plot/graphics.py @@ -101,8 +101,8 @@ class Graphics(SageObject): sage: h=10; c=0.4; p=0.5; sage: G = Graphics() sage: for x in srange(1,h+1): - ... l = [[0,x*sqrt(3)],[-x/2,-x*sqrt(3)/2],[x/2,-x*sqrt(3)/2],[0,x*sqrt(3)]] - ... G+=line(l,color=hue(c + p*(x/h))) + ....: l = [[0,x*sqrt(3)],[-x/2,-x*sqrt(3)/2],[x/2,-x*sqrt(3)/2],[0,x*sqrt(3)]] + ....: G+=line(l,color=hue(c + p*(x/h))) sage: G.show(figsize=[5,5]) We can change the scale of the axes in the graphics before displaying.:: @@ -1598,7 +1598,7 @@ def show(self, **kwds): sage: x, y = var('x, y') sage: p = implicit_plot((y^2-x^2)*(x-1)*(2*x-3)-4*(x^2+y^2-2*x)^2, \ - ... (x,-2,2), (y,-2,2), plot_points=1000) + ....: (x,-2,2), (y,-2,2), plot_points=1000) sage: p.show(gridlines=[[1,0],[-1,0,1]]) Add grid lines at specific positions (using iterators). @@ -1606,7 +1606,7 @@ def show(self, **kwds): :: sage: def maple_leaf(t): - ... return (100/(100+(t-pi/2)^8))*(2-sin(7*t)-cos(30*t)/2) + ....: return (100/(100+(t-pi/2)^8))*(2-sin(7*t)-cos(30*t)/2) sage: p = polar_plot(maple_leaf, -pi/4, 3*pi/2, color="red",plot_points=1000) # long time sage: p.show(gridlines=( [-3,-2.75,..,3], xrange(-1,5,2) )) # long time @@ -1625,7 +1625,7 @@ def show(self, **kwds): sage: b = bar_chart([-3,5,-6,11], color='red') sage: b.show(gridlines=([-1,-0.5,..,4],True), - ... gridlinesstyle=dict(color="blue", linestyle=":")) + ....: gridlinesstyle=dict(color="blue", linestyle=":")) Change the style of the horizontal or vertical grid lines separately. @@ -1634,8 +1634,8 @@ def show(self, **kwds): sage: p = polar_plot(2 + 2*cos(x), 0, 2*pi, color=hue(0.3)) sage: p.show(gridlines=True, - ... hgridlinesstyle=dict(color="orange", linewidth=1.0), - ... vgridlinesstyle=dict(color="blue", linestyle=":")) + ....: hgridlinesstyle=dict(color="orange", linewidth=1.0), + ....: vgridlinesstyle=dict(color="blue", linestyle=":")) Change the style of each grid line individually. @@ -1643,19 +1643,19 @@ def show(self, **kwds): sage: x, y = var('x, y') sage: p = implicit_plot((y^2-x^2)*(x-1)*(2*x-3)-4*(x^2+y^2-2*x)^2, - ... (x,-2,2), (y,-2,2), plot_points=1000) + ....: (x,-2,2), (y,-2,2), plot_points=1000) sage: p.show(gridlines=( - ... [ - ... (1,{"color":"red","linestyle":":"}), - ... (0,{"color":"blue","linestyle":"--"}) - ... ], - ... [ - ... (-1,{"color":"red","linestyle":":"}), - ... (0,{"color":"blue","linestyle":"--"}), - ... (1,{"color":"red","linestyle":":"}), - ... ] - ... ), - ... gridlinesstyle=dict(marker='x',color="black")) + ....: [ + ....: (1,{"color":"red","linestyle":":"}), + ....: (0,{"color":"blue","linestyle":"--"}) + ....: ], + ....: [ + ....: (-1,{"color":"red","linestyle":":"}), + ....: (0,{"color":"blue","linestyle":"--"}), + ....: (1,{"color":"red","linestyle":":"}), + ....: ] + ....: ), + ....: gridlinesstyle=dict(marker='x',color="black")) Grid lines can be added to contour plots. @@ -2596,6 +2596,29 @@ def matplotlib(self, filename=None, return figure + def save_image(self, filename=None, *args, **kwds): + r""" + Save an image representation of self. The image type is + determined by the extension of the filename. For example, + this could be ``.png``, ``.jpg``, ``.gif``, ``.pdf``, + ``.svg``. Currently this is implemented by calling the + :meth:`save` method of self, passing along all arguments and + keywords. + + .. Note:: + + Not all image types are necessarily implemented for all + graphics types. See :meth:`save` for more details. + + EXAMPLES:: + + sage: c = circle((1,1), 1, color='red') + sage: filename = os.path.join(SAGE_TMP, 'test.png') + sage: c.save_image(filename, xmin=-1, xmax=3, ymin=-1, ymax=3) + """ + self.save(filename, *args, **kwds) + + # ALLOWED_EXTENSIONS is the list of recognized formats. # filename argument is written explicitly so that it can be used as a # positional one, which is a very likely usage for this function. @@ -2656,7 +2679,7 @@ def save(self, filename=None, **kwds): ``fig_tight=False``:: sage: c.save(filename, figsize=[8,4], fig_tight=False, - ... xmin=-1, xmax=3, ymin=-1, ymax=3) + ....: xmin=-1, xmax=3, ymin=-1, ymax=3) You can also pass extra options to the plot command instead of this method, e.g. :: @@ -3075,6 +3098,28 @@ def _render(self, filename, dpi=None, figsize=None, axes=None, **args): g.save(filename, dpi=dpi, figure=figure, sub=subplot, verify=do_verify, axes = axes, **args) + def save_image(self, filename=None, *args, **kwds): + r""" + Save an image representation of self. The image type is + determined by the extension of the filename. For example, + this could be ``.png``, ``.jpg``, ``.gif``, ``.pdf``, + ``.svg``. Currently this is implemented by calling the + :meth:`save` method of self, passing along all arguments and + keywords. + + .. Note:: + + Not all image types are necessarily implemented for all + graphics types. See :meth:`save` for more details. + + EXAMPLES:: + + sage: plots = [[plot(m*cos(x + n*pi/4), (x,0, 2*pi)) for n in range(3)] for m in range(1,3)] + sage: G = graphics_array(plots) + sage: G.save_image(tmp_filename()+'.png') + """ + self.save(filename, *args, **kwds) + def save(self, filename=None, dpi=DEFAULT_DPI, figsize=None, axes = None, **args): """ diff --git a/src/sage/plot/line.py b/src/sage/plot/line.py index 6b79c756712..2f436441571 100644 --- a/src/sage/plot/line.py +++ b/src/sage/plot/line.py @@ -454,7 +454,6 @@ def line2d(points, **options): sage: E = EllipticCurve('37a') sage: vals = E.lseries().values_along_line(1-I, 1+10*I, 100) # critical line - *** Warning:...new stack size = ... sage: L = [(z[1].real(), z[1].imag()) for z in vals] sage: line(L, rgbcolor=(3/4,1/2,5/8)) diff --git a/src/sage/plot/matrix_plot.py b/src/sage/plot/matrix_plot.py index 26495af565d..c15f2f7a1d9 100644 --- a/src/sage/plot/matrix_plot.py +++ b/src/sage/plot/matrix_plot.py @@ -465,7 +465,7 @@ def matrix_plot(mat, **options): entries = list(mat._dict().items()) try: data = np.asarray([d for _,d in entries], dtype=float) - except StandardError: + except Exception: raise ValueError, "can not convert entries to floating point numbers" positions = np.asarray([[row for (row,col),_ in entries], [col for (row,col),_ in entries]], dtype=int) diff --git a/src/sage/plot/plot3d/base.pyx b/src/sage/plot/plot3d/base.pyx index a135f3e1886..7b4debeb884 100644 --- a/src/sage/plot/plot3d/base.pyx +++ b/src/sage/plot/plot3d/base.pyx @@ -1227,6 +1227,28 @@ end_scene""" % (render_params.antialiasing, pipes = "2>/dev/null 1>/dev/null &" os.system('%s "%s.%s" %s' % (viewer_app, filename, ext, pipes)) + def save_image(self, filename=None, *args, **kwds): + r""" + Save an image representation of self. The image type is + determined by the extension of the filename. For example, + this could be ``.png``, ``.jpg``, ``.gif``, ``.pdf``, + ``.svg``. Currently this is implemented by calling the + :meth:`save` method of self, passing along all arguments and + keywords. + + .. Note:: + + Not all image types are necessarily implemented for all + graphics types. See :meth:`save` for more details. + + EXAMPLES:: + + sage: f = tmp_filename() + '.png' + sage: G = sphere() + sage: G.save_image(f) + """ + self.save(filename, *args, **kwds) + def save(self, filename, **kwds): """ Save the graphic to an image file (of type: PNG, BMP, GIF, PPM, or TIFF) diff --git a/src/sage/plot/plot3d/implicit_surface.pyx b/src/sage/plot/plot3d/implicit_surface.pyx index d0d70038ddc..714f7585af9 100644 --- a/src/sage/plot/plot3d/implicit_surface.pyx +++ b/src/sage/plot/plot3d/implicit_surface.pyx @@ -963,7 +963,7 @@ cdef class ImplicitSurface(IndexFaceSet): gradient = (orig_f.diff(self.vars[0]), orig_f.diff(self.vars[1]), orig_f.diff(self.vars[2])) - except StandardError: + except Exception: # Would be nice to have more nuanced error handling here. # If anything goes wrong, we'll just use central differencing. diff --git a/src/sage/plot/plot3d/tachyon.py b/src/sage/plot/plot3d/tachyon.py index b52cd81d7b0..db7dfa063be 100644 --- a/src/sage/plot/plot3d/tachyon.py +++ b/src/sage/plot/plot3d/tachyon.py @@ -98,9 +98,8 @@ class Tachyon(SageObject): sage: t.texture('t2', ambient=0.2,diffuse=0.7, specular=0.5, opacity=0.7, color=(0,0,1.0)) sage: k=0 sage: for i in srange(-1,1,0.05): - ... k += 1 - ... t.sphere((i,i^2-0.5,i^3), 0.1, 't%s'%(k%3)) - ... + ....: k += 1 + ....: t.sphere((i,i^2-0.5,i^3), 0.1, 't%s'%(k%3)) sage: t.show() Another twisted cubic, but with a white background, got by putting @@ -122,10 +121,9 @@ class Tachyon(SageObject): sage: k=0 sage: for i in srange(-1,1,0.05): - ... k += 1 - ... t.sphere((i,i^2 - 0.5,i^3), 0.1, 't%s'%(k%3)) - ... t.cylinder((0,0,0), (0,0,1), 0.05,'t1') - ... + ....: k += 1 + ....: t.sphere((i,i^2 - 0.5,i^3), 0.1, 't%s'%(k%3)) + ....: t.cylinder((0,0,0), (0,0,1), 0.05,'t1') sage: t.show() Many random spheres:: @@ -137,9 +135,8 @@ class Tachyon(SageObject): sage: t.texture('t2', ambient=0.2, diffuse=0.7, specular=0.5, opacity=0.7, color=(0,0,1.0)) sage: k=0 sage: for i in range(100): - ... k += 1 - ... t.sphere((random(),random(), random()), random()/10, 't%s'%(k%3)) - ... + ....: k += 1 + ....: t.sphere((random(),random(), random()), random()/10, 't%s'%(k%3)) sage: t.show() Points on an elliptic curve, their height indicated by their height @@ -155,9 +152,8 @@ class Tachyon(SageObject): sage: Q = P sage: n = 100 sage: for i in range(n): # increase 20 for a better plot - ... Q = Q + P - ... t.sphere((Q[1], Q[0], ZZ(i)/n), 0.1, 't%s'%(i%3)) - ... + ....: Q = Q + P + ....: t.sphere((Q[1], Q[0], ZZ(i)/n), 0.1, 't%s'%(i%3)) sage: t.show() A beautiful picture of rational points on a rank 1 elliptic curve. @@ -178,12 +174,10 @@ class Tachyon(SageObject): sage: Q = P sage: n = 100 sage: for i in range(n): - ... Q = Q + P - ... c = i/n + .1 - ... t.texture('r%s'%i,color=(float(i/n),0,0)) - ... t.sphere((Q[0], -Q[1], .01), .04, 'r%s'%i) - ... - ... + ....: Q = Q + P + ....: c = i/n + .1 + ....: t.texture('r%s'%i,color=(float(i/n),0,0)) + ....: t.sphere((Q[0], -Q[1], .01), .04, 'r%s'%i) sage: t.show() # long time, e.g., 10-20 seconds A beautiful spiral. @@ -194,8 +188,7 @@ class Tachyon(SageObject): sage: t.light((0,0,100), 1, (1,1,1)) sage: t.texture('r', ambient=0.1, diffuse=0.9, specular=0.5, opacity=1.0, color=(1,0,0)) sage: for i in srange(0,50,0.1): - ... t.sphere((i/10,sin(i),cos(i)), 0.05, 'r') - ... + ....: t.sphere((i/10,sin(i),cos(i)), 0.05, 'r') sage: t.texture('white', color=(1,1,1), opacity=1, specular=1, diffuse=1) sage: t.plane((0,0,-100), (0,0,-100), 'white') sage: t.show() @@ -253,6 +246,48 @@ def __repr__(self): """ return self.str() + def save_image(self, filename=None, *args, **kwds): + r""" + Save an image representation of self. The image type is + determined by the extension of the filename. For example, + this could be ``.png``, ``.jpg``, ``.gif``, ``.pdf``, + ``.svg``. Currently this is implemented by calling the + :meth:`save` method of self, passing along all arguments and + keywords. + + .. Note:: + + Not all image types are necessarily implemented for all + graphics types. See :meth:`save` for more details. + + EXAMPLES:: + + sage: q = Tachyon() + sage: q.light((1,1,11), 1,(1,1,1)) + sage: q.texture('s') + sage: q.sphere((0,-1,1),1,'s') + sage: tempname = tmp_filename() + sage: q.save_image(tempname) + + TESTS: + + :meth:`save_image` is used for generating animations:: + + sage: def tw_cubic(t): + ....: q = Tachyon() + ....: q.light((1,1,11), 1,(1,1,1)) + ....: q.texture('s') + ....: for i in srange(-1,t,0.05): + ....: q.sphere((i,i^2-0.5,i^3), 0.1, 's') + ....: return q + + sage: a = animate([tw_cubic(t) for t in srange(-1,1,.3)]) + sage: a + Animation with 7 frames + sage: a.show() # optional -- ImageMagick + """ + self.save(filename, *args, **kwds) + def save(self, filename='sage.png', verbose=0, block=True, extra_opts=''): r""" INPUT: diff --git a/src/sage/quadratic_forms/extras.py b/src/sage/quadratic_forms/extras.py index c1ac25f6314..cdaa53647af 100644 --- a/src/sage/quadratic_forms/extras.py +++ b/src/sage/quadratic_forms/extras.py @@ -63,7 +63,7 @@ def is_triangular_number(n): disc_sqrt = ZZ(sqrt(1+8*n)) a = ZZ( (ZZ(-1) + disc_sqrt) / ZZ(2) ) return a - except StandardError: + except Exception: return False diff --git a/src/sage/quadratic_forms/quadratic_form.py b/src/sage/quadratic_forms/quadratic_form.py index 6e40c858ea6..a85824c16a6 100644 --- a/src/sage/quadratic_forms/quadratic_form.py +++ b/src/sage/quadratic_forms/quadratic_form.py @@ -425,7 +425,7 @@ def __init__(self, R, n=None, entries=None, unsafe_initialization=False, number_ ## Verify the size of the matrix is an integer >= 0 try: n = int(n) - except StandardError: + except Exception: raise TypeError, "Oops! The size " + str(n) + " must be an integer." if (n < 0): raise TypeError, "Oops! The size " + str(n) + " must be a non-negative integer." @@ -496,7 +496,7 @@ def list_external_initializations(self): def _pari_(self): """ - Return a pari-formatted Hessian matrix for Q. + Return a PARI-formatted Hessian matrix for Q. EXAMPLES:: @@ -507,6 +507,19 @@ def _pari_(self): """ return self.matrix()._pari_() + def _pari_init_(self): + """ + Return a PARI-formatted Hessian matrix for Q, as string. + + EXAMPLES:: + + sage: Q = QuadraticForm(ZZ, 2, [1,0,5]) + sage: Q._pari_init_() + 'Mat([2,0;0,10])' + + """ + return self.matrix()._pari_init_() + def _repr_(self): """ @@ -627,7 +640,7 @@ def __setitem__(self, ij, coeff): ## Set the entry try: self.__coeffs[i*self.__n - i*(i-1)/2 + j -i] = self.__base_ring(coeff) - except StandardError: + except Exception: raise RuntimeError, "Oops! This coefficient can't be coerced to an element of the base ring for the quadratic form." @@ -755,7 +768,7 @@ def sum_by_coefficients_with(self, right): # """ # try: # c = self.base_ring()(right) -# except StandardError: +# except Exception: # raise TypeError, "Oh no! The multiplier cannot be coerced into the base ring of the quadratic form. =(" # # return QuadraticForm(self.base_ring(), self.dim(), [c * self.__coeffs[i] for i in range(len(self.__coeffs))]) @@ -871,7 +884,7 @@ def __call__(self, v): if len(v) > 0: try: x = self.base_ring()(v[0]) - except StandardError: + except Exception: raise TypeError, "Oops! Your vector is not coercible to the base ring of the quadratic form... =(" ## Attempt to evaluate Q[v] @@ -935,7 +948,7 @@ def _is_even_symmetric_matrix_(self, A, R=None): for i in range(n): for j in range(i, n): x = R(A[i,j]) - except StandardError: + except Exception: return False ## Test that the diagonal is even (if 1/2 isn't in R) @@ -1087,7 +1100,7 @@ def has_integral_Gram_matrix(self): flag = True try: self.Gram_matrix() - except StandardError: + except Exception: flag = False return flag @@ -1159,7 +1172,7 @@ def polynomial(self,names='x'): B = self.base_ring() try: R = PolynomialRing(self.base_ring(),names,n) - except StandardError: + except Exception: raise ValueError, 'Can only create polynomial rings over commutative rings.' V = vector(R.gens()) P = (V*M).dot_product(V) diff --git a/src/sage/quadratic_forms/quadratic_form__automorphisms.py b/src/sage/quadratic_forms/quadratic_form__automorphisms.py index b396883446b..10b0b77f6a8 100644 --- a/src/sage/quadratic_forms/quadratic_form__automorphisms.py +++ b/src/sage/quadratic_forms/quadratic_form__automorphisms.py @@ -2,11 +2,13 @@ Automorphisms of Quadratic Forms """ from sage.interfaces.gp import gp +from sage.libs.pari.all import pari from sage.matrix.constructor import Matrix from sage.rings.integer_ring import ZZ from sage.misc.mrange import mrange from sage.misc.all import cython_lambda +from sage.modules.all import FreeModule from sage.modules.free_module_element import vector from sage.rings.arith import GCD from sage.misc.sage_eval import sage_eval @@ -51,7 +53,7 @@ def basis_of_short_vectors(self, show_lengths=False, safe_flag=True): return deepcopy(self.__basis_of_short_vectors) else: return deepcopy(self.__basis_of_short_vectors) - except StandardError: + except Exception: pass @@ -149,14 +151,19 @@ def basis_of_short_vectors(self, show_lengths=False, safe_flag=True): def short_vector_list_up_to_length(self, len_bound, up_to_sign_flag=False): """ Return a list of lists of short vectors `v`, sorted by length, with - Q(`v`) < len_bound. The list in output `[i]` indexes all vectors of - length `i`. If the up_to_sign_flag is set to True, then only one of - the vectors of the pair `[v, -v]` is listed. + Q(`v`) < len_bound. + + INPUT: - Note: This processes the PARI/GP output to always give elements of type `ZZ`. + - ``len_bound`` -- bound for the length of the vectors. + + - ``up_to_sign_flag`` -- (default: ``False``) if set to True, then + only one of the vectors of the pair `[v, -v]` is listed. OUTPUT: - a list of lists of vectors. + + A list of lists of vectors such that entry `[i]` contains all + vectors of length `i`. EXAMPLES:: @@ -186,12 +193,19 @@ def short_vector_list_up_to_length(self, len_bound, up_to_sign_flag=False): [(0, 1, 0, 0)], [(1, 1, 0, 0), (-1, 1, 0, 0), (2, 0, 0, 0)]] sage: Q = QuadraticForm(matrix(6, [2, 1, 1, 1, -1, -1, 1, 2, 1, 1, -1, -1, 1, 1, 2, 0, -1, -1, 1, 1, 0, 2, 0, -1, -1, -1, -1, 0, 2, 1, -1, -1, -1, -1, 1, 2])) - sage: vs = Q.short_vector_list_up_to_length(40) #long time + sage: vs = Q.short_vector_list_up_to_length(8) + sage: [len(vs[i]) for i in range(len(vs))] + [1, 72, 270, 720, 936, 2160, 2214, 3600] + sage: vs = Q.short_vector_list_up_to_length(30) # long time (28s on sage.math, 2014) + sage: [len(vs[i]) for i in range(len(vs))] # long time + [1, 72, 270, 720, 936, 2160, 2214, 3600, 4590, 6552, 5184, 10800, 9360, 12240, 13500, 17712, 14760, 25920, 19710, 26064, 28080, 36000, 25920, 47520, 37638, 43272, 45900, 59040, 46800, 75600] The cases of ``len_bound < 2`` led to exception or infinite runtime before. :: + sage: Q.short_vector_list_up_to_length(-1) + [] sage: Q.short_vector_list_up_to_length(0) [] sage: Q.short_vector_list_up_to_length(1) @@ -206,67 +220,57 @@ def short_vector_list_up_to_length(self, len_bound, up_to_sign_flag=False): ... ValueError: Quadratic form must be positive definite in order to enumerate short vectors - Sometimes, Pari does not compute short vectors correctly. It returns too long vectors. + Sometimes, PARI does not compute short vectors correctly. It returns too long vectors. :: - sage: mat = matrix(2, [72, 12, 12, 120]) #long time - sage: len_bound = 22953421 #long time - sage: gp_mat = gp.qfminim(str(gp(mat)), 2 * len_bound - 2)[3] #long time - sage: rows = [ map(ZZ, str(gp_mat[i,])[1:-1].split(',')) for i in range(1, gp_mat.matsize()[1] + 1) ] #long time - sage: vec_list = map(vector, zip(*rows)) #long time - sage: eval_v_cython = cython_lambda( ", ".join( "int a{0}".format(i) for i in range(2) ), " + ".join( "{coeff} * a{i} * a{j}".format(coeff = mat[i,j], i = i, j = j) for i in range(2) for j in range(2) ) ) #long time - sage: any( eval_v_cython(*v) == 2 * 22955664 for v in vec_list ) # 22955664 > 22953421 = len_bound #long time - True + sage: Q = QuadraticForm(matrix(2, [72, 12, 12, 120])) + sage: len_bound_pari = 2*22953421 - 2; len_bound_pari + 45906840 + sage: vs = list(Q._pari_().qfminim(len_bound_pari)[2]) # long time (18s on sage.math, 2014) + sage: v = vs[0]; v # long time + [-65, 623]~ + sage: v.Vec() * Q._pari_() * v # long time + 45907800 """ if not self.is_positive_definite() : raise ValueError( "Quadratic form must be positive definite in order to enumerate short vectors" ) - ## Generate a PARI matrix string for the associated Hessian matrix - M_str = str(gp(self.matrix())) + if len_bound <= 0: + return [] + + # Free module in which the vectors live + V = FreeModule(ZZ, self.dim()) + + # Adjust length for PARI. We need to subtract 1 because PARI returns + # returns vectors of length less than or equal to b, but we want + # strictly less. We need to double because the matrix is doubled. + len_bound_pari = 2*(len_bound - 1) - if len_bound <= 0 : - return list() - elif len_bound == 1 : - return [ [(vector([ZZ(0) for _ in range(self.dim())]))] ] - - ## Generate the short vectors - gp_mat = gp.qfminim(M_str, 2*len_bound - 2)[3] - - ## We read all n-th entries at once so that not too many sage[...] variables are - ## used. This is important when to many vectors are returned. - rows = [ map(ZZ, str(gp_mat[i,])[1:-1].split(',')) - for i in range(1, gp_mat.matsize()[1] + 1) ] - vec_list = map(vector, zip(*rows)) - - if len(vec_list) > 500 : - eval_v_cython = cython_lambda( ", ".join( "int a{0}".format(i) for i in range(self.dim()) ), - " + ".join( "{coeff} * a{i} * a{j}".format(coeff = self[i,j], i = i, j = j) - for i in range(self.dim()) for j in range(i, self.dim()) ) ) - eval_v = lambda v: eval_v_cython(*v) - else : - eval_v = self - - ## Sort the vectors into lists by their length + # Call PARI's qfminim() + parilist = self._pari_().qfminim(len_bound_pari)[2].Vec() + + # List of lengths + parilens = pari(r"(M,v) -> vector(#v, i, (v[i]~ * M * v[i])\2)")(self, parilist) + + # Sort the vectors into lists by their length vec_sorted_list = [list() for i in range(len_bound)] - for v in vec_list: - v_evaluated = eval_v(v) - try : - vec_sorted_list[v_evaluated].append(v) + for i in range(len(parilist)): + length = ZZ(parilens[i]) + # PARI can sometimes return longer vectors than requested. + # E.g. : self.matrix() == matrix(2, [72, 12, 12, 120]) + # len_bound = 22953421 + # gives maximal length 22955664 + if length < len_bound: + v = parilist[i] + sagevec = V(list(parilist[i])) + vec_sorted_list[length].append(sagevec) if not up_to_sign_flag : - vec_sorted_list[v_evaluated].append(-v) - except IndexError : - ## We deal with a Pari but, that returns longer vectors that requested. - ## E.g. : self.matrix() == matrix(2, [72, 12, 12, 120]) - ## len_bound = 22953421 - ## gives maximal length 22955664 - pass + vec_sorted_list[length].append(-sagevec) - ## Add the zero vector by hand - zero_vec = vector([ZZ(0) for _ in range(self.dim())]) - vec_sorted_list[0].append(zero_vec) + # Add the zero vector by hand + vec_sorted_list[0].append(V.zero_vector()) - ## Return the sorted list return vec_sorted_list def short_primitive_vector_list_up_to_length(self, len_bound, up_to_sign_flag=False): @@ -469,7 +473,7 @@ def number_of_automorphisms(self, recompute=False): self.__number_of_automorphisms = self.number_of_automorphisms__souvigner() try: self._external_initialization_list.remove('number_of_automorphisms') - except StandardError: + except Exception: pass ## Do nothing if the removal fails, since it might not be in the list (causing an error)! return self.__number_of_automorphisms diff --git a/src/sage/quadratic_forms/quadratic_form__genus.py b/src/sage/quadratic_forms/quadratic_form__genus.py index 6eb0d902136..2caf2f9a325 100644 --- a/src/sage/quadratic_forms/quadratic_form__genus.py +++ b/src/sage/quadratic_forms/quadratic_form__genus.py @@ -60,7 +60,7 @@ def global_genus_symbol(self): ## Return the result try: return Genus(self.Hessian_matrix()) - except StandardError: + except Exception: raise TypeError, "Oops! There is a problem computing the genus symbols for this form." @@ -127,7 +127,7 @@ def local_genus_symbol(self, p): try: M = self.Hessian_matrix() return LocalGenusSymbol(M, p) - except StandardError: + except Exception: raise TypeError, "Oops! There is a problem computing the local genus symbol at the prime " + str(p) + " for this form." diff --git a/src/sage/quadratic_forms/quadratic_form__local_normal_form.py b/src/sage/quadratic_forms/quadratic_form__local_normal_form.py index 48545ab03cd..2d01f704c0d 100644 --- a/src/sage/quadratic_forms/quadratic_form__local_normal_form.py +++ b/src/sage/quadratic_forms/quadratic_form__local_normal_form.py @@ -341,7 +341,7 @@ def jordan_blocks_by_scale_and_unimodular(self, p, safe_flag=True): return copy.deepcopy(self.__jordan_blocks_by_scale_and_unimodular_dict[p]) else: return self.__jordan_blocks_by_scale_and_unimodular_dict[p] - except StandardError: + except Exception: ## Initialize the global dictionary if it doesn't exist if not hasattr(self, '__jordan_blocks_by_scale_and_unimodular_dict'): self.__jordan_blocks_by_scale_and_unimodular_dict = {} diff --git a/src/sage/quadratic_forms/quadratic_form__siegel_product.py b/src/sage/quadratic_forms/quadratic_form__siegel_product.py index dbffd666b32..f37496f0bad 100644 --- a/src/sage/quadratic_forms/quadratic_form__siegel_product.py +++ b/src/sage/quadratic_forms/quadratic_form__siegel_product.py @@ -62,19 +62,19 @@ def siegel_product(self, u): 1 sage: M = 4; len([v for v in mrange([M,M,M,M]) if Q(v) % M == 1]) / M^3 1 - sage: M = 16; len([v for v in mrange([M,M,M,M]) if Q(v) % M == 1]) / M^3 # long time (41s on sage.math, 2011) + sage: M = 16; len([v for v in mrange([M,M,M,M]) if Q(v) % M == 1]) / M^3 # long time (2s on sage.math, 2014) 1 sage: Q.local_density(2,2) 3/2 sage: M = 4; len([v for v in mrange([M,M,M,M]) if Q(v) % M == 2]) / M^3 3/2 - sage: M = 16; len([v for v in mrange([M,M,M,M]) if Q(v) % M == 2]) / M^3 # long time (41s on sage.math, 2011) + sage: M = 16; len([v for v in mrange([M,M,M,M]) if Q(v) % M == 2]) / M^3 # long time (2s on sage.math, 2014) 3/2 TESTS:: - sage: [1] + [Q.siegel_product(ZZ(a)) for a in range(1,11)] == Q.theta_series(11).list() + sage: [1] + [Q.siegel_product(ZZ(a)) for a in range(1,11)] == Q.theta_series(11).list() # long time (2s on sage.math, 2014) True """ ## Protect u (since it fails often if it's an just an int!) diff --git a/src/sage/quadratic_forms/quadratic_form__variable_substitutions.py b/src/sage/quadratic_forms/quadratic_form__variable_substitutions.py index 62c1bff318c..baa3b8d8c2d 100644 --- a/src/sage/quadratic_forms/quadratic_form__variable_substitutions.py +++ b/src/sage/quadratic_forms/quadratic_form__variable_substitutions.py @@ -212,7 +212,7 @@ def scale_by_factor(self, c, change_value_ring_flag=False): # it doesn't work by scoping reasons. Q = self.__class__(R, self.dim(), list2) return Q - except StandardError: + except Exception: if (change_value_ring_flag == False): raise TypeError, "Oops! We could not rescale the lattice in this way and preserve its defining ring." else: diff --git a/src/sage/quadratic_forms/random_quadraticform.py b/src/sage/quadratic_forms/random_quadraticform.py index 2865a6a8380..7c341949d08 100644 --- a/src/sage/quadratic_forms/random_quadraticform.py +++ b/src/sage/quadratic_forms/random_quadraticform.py @@ -109,7 +109,7 @@ def random_quadraticform_with_conditions(R, n, condition_list=[], rand_arg_list= ## Check if condition c is satisfied try: bool_ans = Q.c() - except StandardError: + except Exception: bool_ans = c(Q) ## Create a new quadratic form if a condition fails @@ -204,7 +204,7 @@ def random_ternaryqf_with_conditions(condition_list=[], rand_arg_list=[]): ## Check if condition c is satisfied try: bool_ans = Q.c() - except StandardError: + except Exception: bool_ans = c(Q) ## Create a new quadratic form if a condition fails diff --git a/src/sage/quadratic_forms/special_values.py b/src/sage/quadratic_forms/special_values.py index def2c8dbb3e..2fb86657599 100644 --- a/src/sage/quadratic_forms/special_values.py +++ b/src/sage/quadratic_forms/special_values.py @@ -265,9 +265,9 @@ def quadratic_L_function__numerical(n, d, num_terms=1000): Test for several characters that the result agrees with the exact value, to a given accuracy :: - sage: for d in range(-20,0): - ... if abs(RR(quadratic_L_function__numerical(1, d, 10000) - quadratic_L_function__exact(1, d))) > 0.001: - ... print "Oops! We have a problem at d = ", d, " exact = ", RR(quadratic_L_function__exact(1, d)), " numerical = ", RR(quadratic_L_function__numerical(1, d)) + sage: for d in range(-20,0): # long time (2s on sage.math 2014) + ....: if abs(RR(quadratic_L_function__numerical(1, d, 10000) - quadratic_L_function__exact(1, d))) > 0.001: + ....: print "Oops! We have a problem at d = ", d, " exact = ", RR(quadratic_L_function__exact(1, d)), " numerical = ", RR(quadratic_L_function__numerical(1, d)) """ # Set the correct precision if it is given (for n). if is_RealField(n.parent()): diff --git a/src/sage/quadratic_forms/ternary.pyx b/src/sage/quadratic_forms/ternary.pyx index 14496ebf828..a14e41955bc 100644 --- a/src/sage/quadratic_forms/ternary.pyx +++ b/src/sage/quadratic_forms/ternary.pyx @@ -122,19 +122,19 @@ def _reduced_ternary_form_eisenstein_with_matrix(a1, a2, a3, a23, a13, a12): a23+=a12*m # order 12 - if ((a1>a2) or ((a1==a2) & (abs(a23)>abs(a13)))): + if a1 > a2 or (a1 == a2 and abs(a23) > abs(a13)): M*=matrix(ZZ,3,[0,-1,0,-1,0,0,0,0,-1]) [a1,a2]=[a2,a1] [a13,a23]=[a23,a13] # order 23 - if ((a2>a3) or ((a2==a3) & (abs(a13)>abs(a12)))): + if a2 > a3 or (a2 == a3 and abs(a13) > abs(a12)): M*=matrix(ZZ,3,[-1,0,0,0,0,-1,0,-1,0]) [a2,a3]=[a3,a2] [a13,a12]=[a12,a13] # order 12 - if ((a1>a2) or ((a1==a2) & (abs(a23)>abs(a13)))): + if a1 > a2 or (a1 == a2 and abs(a23) > abs(a13)): M*=matrix(ZZ,3,[0,-1,0,-1,0,0,0,0,-1]) [a1,a2]=[a2,a1] [a13,a23]=[a23,a13] @@ -176,7 +176,7 @@ def _reduced_ternary_form_eisenstein_with_matrix(a1, a2, a3, a23, a13, a12): M*=diagonal_matrix([1,1,-1]) a12=-a12 - loop=(not ((abs(a23)<=a2) & (abs(a13)<=a1) & (abs(a12)<=a1) & (a1+a2+a23+a13+a12>=0))) + loop = not (abs(a23) <= a2 and abs(a13) <= a1 and abs(a12) <= a1 and a1+a2+a23+a13+a12>=0) ################ @@ -185,14 +185,14 @@ def _reduced_ternary_form_eisenstein_with_matrix(a1, a2, a3, a23, a13, a12): # adj 3 - if ((a1+a2+a23+a13+a12==0) & (2*a1+2*a13+a12>0)): + if a1+a2+a23+a13+a12 == 0 and 2*a1+2*a13+a12 > 0: M*=matrix(ZZ,3,[-1,0,1,0,-1,1,0,0,1]) # a3 += a1+a2+a23+a13+a12 a23=-2*a2-a23-a12 a13=-2*a1-a13-a12 # adj 5.12 - if ((a1==-a12) & (a13!=0)): + if a1 == -a12 and a13 != 0: M*=matrix(ZZ,3,[-1,-1,0,0,-1,0,0,0,1]) #a2 += a1+a12 a23=-a23-a13 @@ -200,7 +200,7 @@ def _reduced_ternary_form_eisenstein_with_matrix(a1, a2, a3, a23, a13, a12): a12=-a12 # = 2*a1+a12 # adj 5.13 - if ((a1==-a13) & (a12!=0)): + if a1 == -a13 and a12 != 0: M*=matrix(ZZ,3,[-1,0,-1,0,1,0,0,0,-1]) # a3 += a1+a13 a23=-a23-a12 @@ -208,7 +208,7 @@ def _reduced_ternary_form_eisenstein_with_matrix(a1, a2, a3, a23, a13, a12): a12=-a12 # adj 5.23 - if ((a2==-a23) & (a12!=0)): + if a2 == -a23 and a12 != 0: M*=matrix(ZZ,3,[1,0,0,0,-1,-1,0,0,-1]) # a3 += a2+a23 a23=-a23 # = 2*a2+a23 @@ -216,39 +216,39 @@ def _reduced_ternary_form_eisenstein_with_matrix(a1, a2, a3, a23, a13, a12): a12=-a12 # adj 4.12 - if ((a1==a12) & (a13>2*a23)): + if a1 == a12 and a13 > 2*a23: M*=matrix(ZZ,3,[-1,-1,0,0,1,0,0,0,-1]) # a 2 += a1-a12 a23 = -a23 + a13 # a12 = 2*a1 - a12 # adj 4.13 - if ((a1==a13) & (a12>2*a23)): + if a1 == a13 and a12 > 2*a23: M*=matrix(ZZ,3,[-1,0,-1,0,-1,0,0,0,1]) # a3 += a1-a13 a23 = -a23 + a12 # a13 = 2*a1 - a13 # adj 4.23 - if ((a2==a23) & (a12>2*a13)): + if a2 == a23 and a12 > 2*a13: M*=matrix(ZZ,3,[-1,0,0,0,-1,-1,0,0,1]) # a3 += a2-a23 # a23 = 2*a2 - a23 a13 = -a13 + a12 # order 12 - if (a1==a2) & (abs(a23)>abs(a13)): + if a1 == a2 and abs(a23) > abs(a13): M*=matrix(ZZ,3,[0,-1,0,-1,0,0,0,0,-1]) [a1,a2]=[a2,a1] [a13,a23]=[a23,a13] # order 23 - if (a2==a3) & (abs(a13)>abs(a12)): + if a2 == a3 and abs(a13) > abs(a12): M*=matrix(ZZ,3,[-1,0,0,0,0,-1,0,-1,0]) [a13,a12]=[a12,a13] # order 12 - if (a1==a2) & (abs(a23)>abs(a13)): + if a1 == a2 and abs(a23) > abs(a13): M*=matrix(ZZ,3,[0,-1,0,-1,0,0,0,0,-1]) [a13,a23]=[a23,a13] @@ -309,22 +309,22 @@ def _reduced_ternary_form_eisenstein_without_matrix(a1, a2, a3, a23, a13, a12): a23+=a12*m # order 12 - if ((a1>a2) or ((a1==a2) & (abs(a23)>abs(a13)))): + if a1 > a2 or (a1 == a2 and abs(a23) > abs(a13)): [a1,a2]=[a2,a1] [a13,a23]=[a23,a13] # order 23 - if ((a2>a3) or ((a2==a3) & (abs(a13)>abs(a12)))): + if a2 > a3 or (a2 == a3 and abs(a13) > abs(a12)): [a2,a3]=[a3,a2] [a13,a12]=[a12,a13] # order 12 - if ((a1>a2) or ((a1==a2) & (abs(a23)>abs(a13)))): + if a1 > a2 or (a1 == a2 and abs(a23) > abs(a13)): [a1,a2]=[a2,a1] [a13,a23]=[a23,a13] # signs - if (a23*a13*a12>0): + if a23*a13*a12 > 0: # a23, a13, a12 positive if (a23<0): @@ -354,7 +354,7 @@ def _reduced_ternary_form_eisenstein_without_matrix(a1, a2, a3, a23, a13, a12): if s3: a12=-a12 - loop=(not ((abs(a23)<=a2) & (abs(a13)<=a1) & (abs(a12)<=a1) & (a1+a2+a23+a13+a12>=0))) + loop = not (abs(a23) <= a2 and abs(a13) <= a1 and abs(a12) <= a1 and a1+a2+a23+a13+a12 >= 0) ################ @@ -363,61 +363,61 @@ def _reduced_ternary_form_eisenstein_without_matrix(a1, a2, a3, a23, a13, a12): # adj 3 - if ((a1+a2+a23+a13+a12==0) & (2*a1+2*a13+a12>0)): + if a1+a2+a23+a13+a12 == 0 and 2*a1+2*a13+a12 > 0: # a3 += a1+a2+a23+a13+a12 a23=-2*a2-a23-a12 a13=-2*a1-a13-a12 # adj 5.12 - if ((a1==-a12) & (a13!=0)): + if a1 == -a12 and a13 != 0: #a2 += a1+a12 a23=-a23-a13 a13=-a13 a12=-a12 # = 2*a1+a12 # adj 5.13 - if ((a1==-a13) & (a12!=0)): + if a1 == -a13 and a12 != 0: # a3 += a1+a13 a23=-a23-a12 a13=-a13 # = 2*a1+a13 a12=-a12 # adj 5.23 - if ((a2==-a23) & (a12!=0)): + if a2 == -a23 and a12 != 0: # a3 += a2+a23 a23=-a23 # = 2*a2+a23 a13=-a13-a12 a12=-a12 # adj 4.12 - if ((a1==a12) & (a13>2*a23)): + if a1 == a12 and a13 > 2*a23: # a 2 += a1-a12 a23 = -a23 + a13 # a12 = 2*a1 - a12 # adj 4.13 - if ((a1==a13) & (a12>2*a23)): + if a1 == a13 and a12 > 2*a23: # a3 += a1-a13 a23 = -a23 + a12 # a13 = 2*a1 - a13 # adj 4.23 - if ((a2==a23) & (a12>2*a13)): + if a2 == a23 and a12 > 2*a13: # a3 += a2-a23 # a23 = 2*a2 - a23 a13 = -a13 + a12 # order 12 - if (a1==a2) & (abs(a23)>abs(a13)): + if a1 == a2 and abs(a23) > abs(a13): [a1,a2]=[a2,a1] [a13,a23]=[a23,a13] # order 23 - if (a2==a3) & (abs(a13)>abs(a12)): + if a2 == a3 and abs(a13) > abs(a12): [a13,a12]=[a12,a13] # order 12 - if (a1==a2) & (abs(a23)>abs(a13)): + if a1 == a2 and abs(a23) > abs(a13): [a13,a23]=[a23,a13] return((a1,a2,a3,a23,a13,a12)) @@ -727,44 +727,44 @@ def _find_all_ternary_qf_by_level_disc(long long N, long long d): if (d-r*s*t+a*r*r+b*s*s)%(4*a*b-t**2)==0: c=(d-r*s*t+a*r*r+b*s*s)//(4*a*b-t**2) - if r<=0: - is_reduced=True - if r<-b: - is_reduced=False - elif not ((b<=c) & (0<=a+b+r-s-t)): - is_reduced=False - elif ((a==b) & (abs(r) > abs(s))): - is_reduced=False - elif ((b==c) & (abs(s) > abs(t))): - is_reduced=False - elif ((a+b+r-s-t==0) & (2*a-2*s-t>0)): - is_reduced=False - elif ((a==t) & (s<>0)): - is_reduced=False - elif ((a==s) & (t<>0)): - is_reduced=False - elif ((b==-r) & (t<>0)): - is_reduced=False + if r <= 0: + is_reduced = True + if r < -b: + is_reduced = False + elif not (b <= c and 0 <= a+b+r-s-t): + is_reduced = False + elif a == b and abs(r) > abs(s): + is_reduced = False + elif b == c and abs(s) > abs(t): + is_reduced = False + elif a+b+r-s-t == 0 and 2*a-2*s-t > 0: + is_reduced = False + elif a == t and s != 0: + is_reduced = False + elif a == s and t != 0: + is_reduced = False + elif b == -r and t != 0: + is_reduced = False if is_reduced: m_q=gcd((4*b*c-r**2, 4*a*c-s**2, 4*a*b-t**2, 2*s*t-4*a*r, -2*r*t+4*b*s, -2*r*s+4*c*t)) if m_q==m: l.append((ZZ(a), ZZ(b), ZZ(c), ZZ(r), ZZ(-s), ZZ(-t))) else: is_reduced=True - if not ((b<=c) & (0<=a+b+r+s+t)): - is_reduced=False - elif ((a==b) & (abs(r) > abs(s))): - is_reduced=False - elif ((b==c) & (abs(s) > abs(t))): - is_reduced=False - elif ((a+b+r+s+t==0) & (2*a+2*s+t>0)): - is_reduced=False - elif ((a==t) & (s>2*r)): - is_reduced=False - elif ((a==s) & (t>2*r)): - is_reduced=False - elif ((b==r) & (t>2*s)): - is_reduced=False + if not (b <= c and 0 <= a+b+r+s+t): + is_reduced = False + elif a == b and abs(r) > abs(s): + is_reduced = False + elif b == c and abs(s) > abs(t): + is_reduced = False + elif a+b+r+s+t == 0 and 2*a+2*s+t > 0: + is_reduced = False + elif a == t and s > 2*r: + is_reduced = False + elif a == s and t > 2*r: + is_reduced = False + elif b == r and t > 2*s: + is_reduced = False if is_reduced: m_q=gcd((4*b*c-r**2, 4*a*c-s**2, 4*a*b-t**2, 2*s*t-4*a*r, 2*r*t-4*b*s, 2*r*s-4*c*t)) if m_q==m: @@ -868,44 +868,44 @@ def _find_a_ternary_qf_by_level_disc(long long N, long long d): if (d-r*s*t+a*r*r+b*s*s)%(4*a*b-t**2)==0: c=(d-r*s*t+a*r*r+b*s*s)//(4*a*b-t**2) - if r<=0: - is_reduced=True - if r<-b: - is_reduced=False - elif not ((b<=c) & (0<=a+b+r-s-t)): - is_reduced=False - elif ((a==b) & (abs(r) > abs(s))): - is_reduced=False - elif ((b==c) & (abs(s) > abs(t))): - is_reduced=False - elif ((a+b+r-s-t==0) & (2*a-2*s-t>0)): - is_reduced=False - elif ((a==t) & (s<>0)): - is_reduced=False - elif ((a==s) & (t<>0)): - is_reduced=False - elif ((b==-r) & (t<>0)): - is_reduced=False + if r <= 0: + is_reduced = True + if r < -b: + is_reduced = False + elif not (b <= c and 0 <= a+b+r-s-t): + is_reduced = False + elif a == b and abs(r) > abs(s): + is_reduced = False + elif b == c and abs(s) > abs(t): + is_reduced = False + elif a+b+r-s-t == 0 and 2*a-2*s-t > 0: + is_reduced = False + elif a == t and s != 0: + is_reduced = False + elif a == s and t != 0: + is_reduced = False + elif b == -r and t != 0: + is_reduced = False if is_reduced: m_q=gcd((4*b*c-r**2, 4*a*c-s**2, 4*a*b-t**2, 2*s*t-4*a*r, -2*r*t+4*b*s, -2*r*s+4*c*t)) if m_q==m: return ZZ(a), ZZ(b), ZZ(c), ZZ(r), ZZ(-s), ZZ(-t) else: - is_reduced=True - if not ((b<=c) & (0<=a+b+r+s+t)): - is_reduced=False - elif ((a==b) & (abs(r) > abs(s))): - is_reduced=False - elif ((b==c) & (abs(s) > abs(t))): - is_reduced=False - elif ((a+b+r+s+t==0) & (2*a+2*s+t>0)): - is_reduced=False - elif ((a==t) & (s>2*r)): - is_reduced=False - elif ((a==s) & (t>2*r)): - is_reduced=False - elif ((b==r) & (t>2*s)): - is_reduced=False + is_reduced = True + if not (b <= c and 0 <= a+b+r+s+t): + is_reduced = False + elif a == b and abs(r) > abs(s): + is_reduced = False + elif b == c and abs(s) > abs(t): + is_reduced = False + elif a+b+r+s+t == 0 and 2*a+2*s+t > 0: + is_reduced = False + elif a==t and s > 2*r: + is_reduced = False + elif a == s and t>2*r: + is_reduced = False + elif b == r and t > 2*s: + is_reduced = False if is_reduced: m_q=gcd((4*b*c-r**2, 4*a*c-s**2, 4*a*b-t**2, 2*s*t-4*a*r, 2*r*t-4*b*s, 2*r*s-4*c*t)) if m_q==m: diff --git a/src/sage/quadratic_forms/ternary_qf.py b/src/sage/quadratic_forms/ternary_qf.py index 26df604229d..9548e646aae 100644 --- a/src/sage/quadratic_forms/ternary_qf.py +++ b/src/sage/quadratic_forms/ternary_qf.py @@ -760,43 +760,43 @@ def is_eisenstein_reduced(self): [a,b,c,r,s,t]=[self._a,self._b,self._c,self._r,self._s,self._t] # cond 2 - if not ((r>0) & (t>0) & (s>0)): - if not ((r<=0) & (s<=0) & (t<=0)): + if not (r > 0 and t > 0 and s > 0): + if not (r <= 0 and s <= 0 and t <= 0): return False # cond 1 & 4 - if not ((a<=b<=c) & (0<=a+b+r+s+t)): + if not (a <= b <= c and 0 <= a+b+r+s+t): return False # cond 3 - if not ((a>=abs(s)) & (a>=abs(t)) & (b>=abs(r))): + if not (a >= abs(s) and a >= abs(t) and b >= abs(r)): return False # cond 8 - if ((a==b) & (abs(r)>abs(s))): + if a == b and abs(r) > abs(s): return False - if ((b==c) & (abs(s)>abs(t))): + if b == c and abs(s) > abs(t): return False - if ((a+b+r+s+t==0) & (2*a+2*s+t>0)): + if a+b+r+s+t == 0 and 2*a+2*s+t > 0: return False # cond 6 # r, s, t <= 0 if r<=0: - if ((a==-t) & (s<>0)): + if a == -t and s != 0: return False - if ((a==-s) & (t<>0)): + if a == -s and t != 0: return False - if ((b==-r) & (t<>0)): + if b == -r and t != 0: return False # cond 7 # r, s, t > 0 - if ((a==t) & (s>2*r)): + if a == t and s > 2*r: return False - if ((a==s) & (t>2*r)): + if a == s and t > 2*r: return False - if ((b==r) & (t>2*s)): + if b == r and t > 2*s: return False return True @@ -1477,7 +1477,7 @@ def _automorphisms_reduced_fast(self): (-1, 0, 0, 0, 1, -1, 0, 0, -1)] if self._border(7): - if self._border(8) & self._border(15): + if self._border(8) and self._border(15): if self._border(16): if self._border(9): # borders 7, 8, 9, 15, 16 @@ -1537,7 +1537,7 @@ def _automorphisms_reduced_fast(self): if self._border(8): if self._border(9): - if self._border(10) & self._border(11) & self._border(12): + if self._border(10) and self._border(11) and self._border(12): # borders 8, 9, 10, 11, 12 return [(1, 0, 0, 0, 1, 0, 0, 0, 1), (-1, 0, 0, 0, -1, 0, 0, 0, 1), @@ -1563,7 +1563,7 @@ def _automorphisms_reduced_fast(self): (1, 0, 0, 0, -1, 0, 0, 0, -1), (1, 0, 0, 0, 0, -1, 0, 1, 0), (1, 0, 0, 0, 0, 1, 0, -1, 0)] - elif self._border(13) & self._border(14): + elif self._border(13) and self._border(14): # borders 8, 9, 13, 14 return [(1, 0, 0, 0, 1, 0, 0, 0, 1), (-1, -1, -1, 0, 0, 1, 0, 1, 0), @@ -1598,7 +1598,7 @@ def _automorphisms_reduced_fast(self): (0, 0, 1, 1, 0, 0, 0, 1, 0), (0, 1, 0, 0, 0, 1, 1, 0, 0)] elif self._border(10): - if self._border(11) & self._border(12): + if self._border(11) and self._border(12): # borders 8, 10, 11, 12 return [(1, 0, 0, 0, 1, 0, 0, 0, 1), (-1, 0, 0, 0, -1, 0, 0, 0, 1), @@ -1629,7 +1629,7 @@ def _automorphisms_reduced_fast(self): if self._border(9): if self._border(12): - if self._border(10) & self._border(11): + if self._border(10) and self._border(11): # borders 9, 10, 11, 12 return [(1, 0, 0, 0, 1, 0, 0, 0, 1), (-1, 0, 0, 0, -1, 0, 0, 0, 1), @@ -1674,7 +1674,7 @@ def _automorphisms_reduced_fast(self): (-1, 0, 0, 0, 0, -1, 0, -1, 0)] if self._border(10): - if self._border(11) & self._border(12): + if self._border(11) and self._border(12): # borders 10, 11, 12 return [(1, 0, 0, 0, 1, 0, 0, 0, 1), (-1, 0, 0, 0, -1, 0, 0, 0, 1), @@ -1695,7 +1695,7 @@ def _automorphisms_reduced_fast(self): return [(1, 0, 0, 0, 1, 0, 0, 0, 1), (1, 0, 0, 0, -1, 0, 0, 0, -1)] - if self._border(13) & self._border(14): + if self._border(13) and self._border(14): # border 13, 14 return [(1, 0, 0, 0, 1, 0, 0, 0, 1), (1, 1, 1, 0, -1, 0, 0, 0, -1)] @@ -1722,20 +1722,24 @@ def _automorphisms_reduced_fast(self): def _automorphisms_reduced_slow(self): """ - Return the automorphisms of the reduced ternary quadratic form. It searches over all 3x3 matrices with coefficients -1, 0, 1, determinant 1 and finite order, because Eisenstein reduced forms are Minkowski reduced. See Cassels. + Return the automorphisms of the reduced ternary quadratic form. + It searches over all 3x3 matrices with coefficients -1, 0, 1, + determinant 1 and finite order, because Eisenstein reduced forms + are Minkowski reduced. See Cassels. EXAMPLES:: + sage: Q = TernaryQF([1, 1, 7, 0, 0, 0]) sage: Q.is_eisenstein_reduced() True - sage: auts = Q._automorphisms_reduced_slow() #long time - sage: len(auts) #long time + sage: auts = Q._automorphisms_reduced_slow() # long time (3s on sage.math, 2014) + sage: len(auts) # long time 8 - sage: A = auts[randint(0,7)] #long time - sage: Q(A) == Q #long time + sage: A = auts[randint(0,7)] # long time + sage: Q(A) == Q # long time True sage: Q = TernaryQF([3, 4, 5, 3, 3, 2]) - sage: Q._automorphisms_reduced_slow() #long time + sage: Q._automorphisms_reduced_slow() # long time [ [1 0 0] [0 1 0] @@ -1764,8 +1768,8 @@ def automorphisms(self, slow = True): EXAMPLES:: sage: Q = TernaryQF([1, 1, 7, 0, 0, 0]) - sage: auts = Q.automorphisms() #long time - sage: auts #long time + sage: auts = Q.automorphisms() + sage: auts [ [-1 0 0] [-1 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] @@ -1774,8 +1778,8 @@ def automorphisms(self, slow = True): [ 0 -1 0] [0 1 0] [ 0 0 -1], [0 0 1] ] - sage: False in [Q == Q(A) for A in auts] #long time - False + sage: all(Q == Q(A) for A in auts) + True sage: Q = TernaryQF([3, 4, 5, 3, 3, 2]) sage: Q.automorphisms(slow = False) [ @@ -1908,7 +1912,7 @@ def _number_of_automorphisms_reduced(self): return 2 if self._border(7): - if self._border(8) & self._border(15): + if self._border(8) and self._border(15): if self._border(16): if self._border(9): # borders 7, 8, 9, 15, 16 @@ -1929,17 +1933,17 @@ def _number_of_automorphisms_reduced(self): if self._border(8): if self._border(9): - if self._border(10) & self._border(11) & self._border(12): + if self._border(10) and self._border(11) and self._border(12): # borders 8, 9, 10, 11, 12 return 24 - elif self._border(13) & self._border(14): + elif self._border(13) and self._border(14): # borders 8, 9, 13, 14 return 24 else: # borders 8, 9 return 6 elif self._border(10): - if self._border(11) & self._border(12): + if self._border(11) and self._border(12): # borders 8, 10, 11, 12 return 8 else: @@ -1954,7 +1958,7 @@ def _number_of_automorphisms_reduced(self): if self._border(9): if self._border(12): - if self._border(10) & self._border(11): + if self._border(10) and self._border(11): # borders 9, 10, 11, 12 return 8 else: @@ -1975,7 +1979,7 @@ def _number_of_automorphisms_reduced(self): return 2 if self._border(10): - if self._border(11) & self._border(12): + if self._border(11) and self._border(12): # borders 10, 11, 12 return 4 else: @@ -1990,7 +1994,7 @@ def _number_of_automorphisms_reduced(self): # border 12 return 2 - if self._border(13) & self._border(14): + if self._border(13) and self._border(14): # border 13, 14 return 2 @@ -2025,7 +2029,7 @@ def number_of_automorphisms(self, slow = True): Ternary quadratic form with integer coefficients: [449 33 7] [-14 -112 102] - sage: Q1.number_of_automorphisms() #long time + sage: Q1.number_of_automorphisms() 8 sage: Q = TernaryQF([-19, -7, -6, -12, 20, 23]) sage: Q.is_negative_definite() diff --git a/src/sage/rings/arith.py b/src/sage/rings/arith.py index 63a6b34ecfe..9d4230a996c 100644 --- a/src/sage/rings/arith.py +++ b/src/sage/rings/arith.py @@ -1884,7 +1884,7 @@ def xgcd(a, b): sage: 4*56 + (-5)*44 4 sage: g, a, b = xgcd(5/1, 7/1); g, a, b - (1, 3, -2) + (1, 1/5, 0) sage: a*(5/1) + b*(7/1) == g True sage: x = polygen(QQ) diff --git a/src/sage/rings/complex_mpc.pyx b/src/sage/rings/complex_mpc.pyx index e405368a5ed..13785c994dc 100644 --- a/src/sage/rings/complex_mpc.pyx +++ b/src/sage/rings/complex_mpc.pyx @@ -1269,7 +1269,7 @@ cdef class MPComplexNumber(sage.structure.element.FieldElement): sage: C200(1+i).is_real() False """ - return (mpfr_zero_p(self.value.im) <> 0) + return (mpfr_zero_p(self.value.im) != 0) def is_imaginary(self): """ @@ -1283,7 +1283,7 @@ cdef class MPComplexNumber(sage.structure.element.FieldElement): sage: C200(1+i).is_imaginary() False """ - return (mpfr_zero_p(self.value.re) <> 0) + return (mpfr_zero_p(self.value.re) != 0) def algebraic_dependency(self, n, **kwds): """ @@ -1571,7 +1571,7 @@ cdef class MPComplexNumber(sage.structure.element.FieldElement): else: try: p = (x._parent)(right) - except StandardError: + except Exception: raise ValueError mpc_pow(z.value, x.value, p.value, (x._parent).__rnd) diff --git a/src/sage/rings/complex_number.pyx b/src/sage/rings/complex_number.pyx index 9f0a97cf666..5fb02097125 100644 --- a/src/sage/rings/complex_number.pyx +++ b/src/sage/rings/complex_number.pyx @@ -2249,7 +2249,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): sage: CC(1+i).is_real() False """ - return (mpfr_zero_p(self.__im) <> 0) + return (mpfr_zero_p(self.__im) != 0) def is_imaginary(self): """ @@ -2262,7 +2262,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): sage: CC(1+i).is_imaginary() False """ - return (mpfr_zero_p(self.__re) <> 0) + return (mpfr_zero_p(self.__re) != 0) def zeta(self): """ diff --git a/src/sage/rings/finite_rings/integer_mod.pyx b/src/sage/rings/finite_rings/integer_mod.pyx index ebc2af42c76..a5d3209881d 100644 --- a/src/sage/rings/finite_rings/integer_mod.pyx +++ b/src/sage/rings/finite_rings/integer_mod.pyx @@ -1312,24 +1312,22 @@ cdef class IntegerMod_abstract(FiniteRingElement): TESTS:: sage: for n in range(2,100): # long time - ... K=Integers(n) - ... elist = range(1,min(2*n+2,100)) - ... for e in random_sublist(elist, 5/len(elist)): - ... for a in random_sublist(range(1,n), min((n+2)//2,10)/(n-1)): - ... b = K(a) - ... try: - ... L = b.nth_root(e, all=True) - ... if len(L) > 0: - ... c = b.nth_root(e) - ... except StandardError: - ... L = [-1] - ... M = b._nth_root_naive(e) - ... if sorted(L) != M: - ... print "mod(%s, %s).nth_root(%s,all=True), mod(%s, %s)._nth_root_naive(%s)"%(a,n,e,a,n,e) - ... raise ValueError - ... if len(L) > 0 and (c not in L): - ... print "mod(%s, %s).nth_root(%s), mod(%s, %s).nth_root(%s,all=True)"%(a,n,e,a,n,e) - ... raise ValueError + ....: K=Integers(n) + ....: elist = range(1,min(2*n+2,100)) + ....: for e in random_sublist(elist, 5/len(elist)): + ....: for a in random_sublist(range(1,n), min((n+2)//2,10)/(n-1)): + ....: b = K(a) + ....: try: + ....: L = b.nth_root(e, all=True) + ....: if len(L) > 0: + ....: c = b.nth_root(e) + ....: except Exception: + ....: L = [-1] + ....: M = b._nth_root_naive(e) + ....: if sorted(L) != M: + ....: print "mod(%s, %s).nth_root(%s,all=True), mod(%s, %s)._nth_root_naive(%s)"%(a,n,e,a,n,e) + ....: if len(L) > 0 and (c not in L): + ....: print "mod(%s, %s).nth_root(%s), mod(%s, %s).nth_root(%s,all=True)"%(a,n,e,a,n,e) """ L = [] for a in self.parent(): diff --git a/src/sage/rings/fraction_field_element.pyx b/src/sage/rings/fraction_field_element.pyx index d0dd220e1b7..21255278950 100644 --- a/src/sage/rings/fraction_field_element.pyx +++ b/src/sage/rings/fraction_field_element.pyx @@ -191,7 +191,7 @@ cdef class FractionFieldElement(FieldElement): try: num *= den.inverse_of_unit() den = den.parent().one_element() - except StandardError: + except Exception: pass self.__numerator = num self.__denominator = den diff --git a/src/sage/rings/homset.py b/src/sage/rings/homset.py index 505370dd8dc..f36c464612d 100644 --- a/src/sage/rings/homset.py +++ b/src/sage/rings/homset.py @@ -138,12 +138,12 @@ def _coerce_impl(self, x): try: if isinstance(x, morphism.RingHomomorphism_im_gens) and x.domain().fraction_field().has_coerce_map_from(self.domain()): return morphism.RingHomomorphism_im_gens(self, x.im_gens()) - except StandardError: + except Exception: pass # Case 3: the homomorphism can be extended by coercion try: return x.extend_codomain(self.codomain()).extend_domain(self.domain()) - except StandardError: + except Exception: pass # Last resort, case 4: the homomorphism is induced from the base ring if self.domain()==self.domain().base() or self.codomain()==self.codomain().base(): @@ -151,7 +151,7 @@ def _coerce_impl(self, x): try: x = self.domain().base().Hom(self.codomain().base())(x) return morphism.RingHomomorphism_from_base(self, x) - except StandardError: + except Exception: raise TypeError def __call__(self, im_gens, check=True): @@ -173,7 +173,7 @@ def __call__(self, im_gens, check=True): sage: H == loads(dumps(H)) True """ - if isinstance(im_gens, (morphism.RingHomomorphism_im_gens, morphism.RingHomomorphism_cover, morphism.RingHomomorphism_from_base) ): + if isinstance(im_gens, morphism.RingHomomorphism): return self._coerce_impl(im_gens) try: return morphism.RingHomomorphism_im_gens(self, im_gens, check=check) diff --git a/src/sage/rings/ideal.py b/src/sage/rings/ideal.py index a0663314a2c..8c34becd67a 100644 --- a/src/sage/rings/ideal.py +++ b/src/sage/rings/ideal.py @@ -821,7 +821,7 @@ def is_prime(self): ass = self.associated_primes() except (NotImplementedError, ValueError): raise NotImplementedError - if len(ass) <> 1: + if len(ass) != 1: return False if self == ass[0]: return True diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index 19440f4b43f..e1b50944fde 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -181,7 +181,7 @@ import sage.rings.infinity import sage.libs.pari.pari_instance cdef PariInstance pari = sage.libs.pari.pari_instance.pari -from sage.structure.element import canonical_coercion +from sage.structure.element import canonical_coercion, coerce_binop from sage.misc.superseded import deprecated_function_alias cdef object numpy_long_interface = {'typestr': '=i4' if sizeof(long) == 4 else '=i8' } @@ -2233,7 +2233,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): # upper is *greater* than the answer try: upper = rif_log.upper().ceiling() - except StandardError: + except Exception: # ceiling is probably Infinity # I'm not sure what to do now upper = 0 @@ -5304,100 +5304,120 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): return [z, -z] return z - def _xgcd(self, Integer n, bint minimal=0): + @coerce_binop + def xgcd(self, Integer n): r""" - Computes extended gcd of self and `n`. + Return the extended gcd of this element and ``n``. INPUT: - - ``self`` - integer + - ``n`` -- an integer + + OUTPUT: + + A triple ``(g, s, t)`` such that ``g`` is the non-negative gcd of + ``self`` and ``n``, and ``s`` and ``t`` are cofactors satisfying the + Bezout identity + + .. MATH:: + + g = s \cdot \mathrm{self} + t \cdot n. + + .. NOTE:: + + There is no guarantee that the cofactors will be minimal. If you + need the cofactors to be minimal use :meth:`_xgcd`. Also, using + :meth:`_xgcd` directly might be faster in some cases, see + :trac:`13628`. + + EXAMPLES:: + + sage: 6.xgcd(4) + (2, 1, -1) + + """ + return self._xgcd(n) + + def _xgcd(self, Integer n, bint minimal=0): + r""" + Return the exteded gcd of ``self`` and ``n``. - - ``n`` - integer + INPUT: - - ``minimal`` - boolean (default false), whether to - compute minimal cofactors (see below) + - ``n`` -- an integer + - ``minimal`` -- a boolean (default: ``False``), whether to compute + minimal cofactors (see below) OUTPUT: - A triple (g, s, t), where `g` is the non-negative gcd of self - and `n`, and `s` and `t` are cofactors satisfying the Bezout identity + A triple ``(g, s, t)`` such that ``g`` is the non-negative gcd of + ``self`` and ``n``, and ``s`` and ``t`` are cofactors satisfying the + Bezout identity - .. math:: + .. MATH:: - g = s \cdot \mbox{\rm self} + t \cdot n. + g = s \cdot \mathrm{self} + t \cdot n. - .. note:: + .. NOTE:: - If minimal is False, then there is no guarantee that the returned - cofactors will be minimal in any sense; the only guarantee is that - the Bezout identity will be satisfied (see examples below). + If ``minimal`` is ``False``, then there is no guarantee that the + returned cofactors will be minimal in any sense; the only guarantee + is that the Bezout identity will be satisfied (see examples below). - If minimal is True, the cofactors will satisfy the following - conditions. If either self or `n` are zero, the trivial solution - is returned. If both self and `n` are nonzero, the function returns - the unique solution such that `0 \leq s < |n|/g` (which then must - also satisfy `0 \leq |t| \leq |\mbox{\rm self}|/g`). + If ``minimal`` is ``True``, the cofactors will satisfy the following + conditions. If either ``self`` or ``n`` are zero, the trivial + solution is returned. If both ``self`` and ``n`` are nonzero, the + function returns the unique solution such that `0 \leq s < |n|/g` + (which then must also satisfy + `0 \leq |t| \leq |\mbox{\rm self}|/g`). EXAMPLES:: - sage: Integer(5)._xgcd(7) + sage: 5._xgcd(7) (1, 3, -2) sage: 5*3 + 7*-2 1 - sage: g,s,t = Integer(58526524056)._xgcd(101294172798) + sage: g,s,t = 58526524056._xgcd(101294172798) sage: g 22544886 sage: 58526524056 * s + 101294172798 * t 22544886 - Without minimality guarantees, weird things can happen:: + Try ``minimal`` option with various edge cases:: - sage: Integer(3)._xgcd(21) - (3, 1, 0) - sage: Integer(3)._xgcd(24) - (3, 1, 0) - sage: Integer(3)._xgcd(48) - (3, 1, 0) - - Weirdness disappears with minimal option:: - - sage: Integer(3)._xgcd(21, minimal=True) - (3, 1, 0) - sage: Integer(3)._xgcd(24, minimal=True) - (3, 1, 0) - sage: Integer(3)._xgcd(48, minimal=True) - (3, 1, 0) - sage: Integer(21)._xgcd(3, minimal=True) - (3, 0, 1) - - Try minimal option with various edge cases:: - - sage: Integer(5)._xgcd(0, minimal=True) + sage: 5._xgcd(0, minimal=True) (5, 1, 0) - sage: Integer(-5)._xgcd(0, minimal=True) + sage: (-5)._xgcd(0, minimal=True) (5, -1, 0) - sage: Integer(0)._xgcd(5, minimal=True) + sage: 0._xgcd(5, minimal=True) (5, 0, 1) - sage: Integer(0)._xgcd(-5, minimal=True) + sage: 0._xgcd(-5, minimal=True) (5, 0, -1) - sage: Integer(0)._xgcd(0, minimal=True) + sage: 0._xgcd(0, minimal=True) (0, 1, 0) + Output may differ with and without the ``minimal`` option:: + + sage: 2._xgcd(-2) + (2, 1, 0) + sage: 2._xgcd(-2, minimal=True) + (2, 0, -1) + Exhaustive tests, checking minimality conditions:: sage: for a in srange(-20, 20): - ... for b in srange(-20, 20): - ... if a == 0 or b == 0: continue - ... g, s, t = a._xgcd(b) - ... assert g > 0 - ... assert a % g == 0 and b % g == 0 - ... assert a*s + b*t == g - ... g, s, t = a._xgcd(b, minimal=True) - ... assert g > 0 - ... assert a % g == 0 and b % g == 0 - ... assert a*s + b*t == g - ... assert s >= 0 and s < abs(b)/g - ... assert abs(t) <= abs(a)/g + ....: for b in srange(-20, 20): + ....: if a == 0 or b == 0: continue + ....: g, s, t = a._xgcd(b) + ....: assert g > 0 + ....: assert a % g == 0 and b % g == 0 + ....: assert a*s + b*t == g + ....: g, s, t = a._xgcd(b, minimal=True) + ....: assert g > 0 + ....: assert a % g == 0 and b % g == 0 + ....: assert a*s + b*t == g + ....: assert s >= 0 and s < abs(b)/g + ....: assert abs(t) <= abs(a)/g AUTHORS: diff --git a/src/sage/rings/morphism.pyx b/src/sage/rings/morphism.pyx index 349089f8eab..185d5eb7e91 100644 --- a/src/sage/rings/morphism.pyx +++ b/src/sage/rings/morphism.pyx @@ -1420,15 +1420,15 @@ cdef class RingHomomorphism_from_base(RingHomomorphism): P = self.codomain() try: return P(dict([(a, self.__underlying(b)) for a,b in x.dict().items()])) - except StandardError: + except Exception: pass try: return P([self.__underlying(b) for b in x]) - except StandardError: + except Exception: pass try: return P(self.__underlying(x.numerator()))/P(self.__underlying(x.denominator())) - except StandardError: + except Exception: raise TypeError, "invalid argument %s"%repr(x) cdef class RingHomomorphism_cover(RingHomomorphism): diff --git a/src/sage/rings/number_field/morphism.py b/src/sage/rings/number_field/morphism.py index 07df8a5c988..1055f220229 100644 --- a/src/sage/rings/number_field/morphism.py +++ b/src/sage/rings/number_field/morphism.py @@ -300,7 +300,7 @@ def preimage(self, y): # try to get the cached transformation matrix and vector space isomorphisms if they exist try: M,LtoV,VtoK = self._transformation_data - except StandardError: + except Exception: # get the identifications of K and L with vector spaces over Q V,VtoL,LtoV = self.codomain().absolute_vector_space() V,VtoK,KtoV = self.domain().absolute_vector_space() diff --git a/src/sage/rings/number_field/totallyreal_data.pyx b/src/sage/rings/number_field/totallyreal_data.pyx index 216727bd69e..0804309e7bb 100644 --- a/src/sage/rings/number_field/totallyreal_data.pyx +++ b/src/sage/rings/number_field/totallyreal_data.pyx @@ -525,7 +525,7 @@ cdef class tr_data: # The value of k is the largest index of the coefficients of a which is # currently unknown; e.g., if k == -1, then we can iterate # over polynomials, and if k == n-1, then we have finished iterating. - if a[len(a)-1] <> 1: + if a[len(a)-1] != 1: raise ValueError, "a[len(a)-1](=%s) must be 1 so polynomial is monic"%a[len(a)-1] k = n-len(a) @@ -774,7 +774,7 @@ cdef class tr_data: f = ZZx([self.gnk[(k+1)*n+i] for i in range(n-(k+1)+1)]) # Could just take self.gnk(k+2)*n+i, but this may not be initialized... df = ZZx([i*self.gnk[(k+1)*n+i] for i in range(1,n-(k+1)+1)]) - if gcd(f,df) <> 1: + if gcd(f,df) != 1: if verbose: print " gnk has multiple factor!" maxoutflag = 1 diff --git a/src/sage/rings/number_field/totallyreal_phc.py b/src/sage/rings/number_field/totallyreal_phc.py index bbfa53a30d1..82c5d5c30e5 100644 --- a/src/sage/rings/number_field/totallyreal_phc.py +++ b/src/sage/rings/number_field/totallyreal_phc.py @@ -138,7 +138,7 @@ def __lagrange_bounds_phc(n, m, a, tmpfile=None): f_str = f.read() pos = f_str.find('= real ') crits = [] - while pos <> -1: + while pos != -1: posl = f_str.rfind('xn', 0, pos) f_str_split = f_str[posl:pos].split() crits += [float(f_str_split[2])] diff --git a/src/sage/rings/number_field/totallyreal_rel.py b/src/sage/rings/number_field/totallyreal_rel.py index c5d5993d20a..8d9a4378cea 100644 --- a/src/sage/rings/number_field/totallyreal_rel.py +++ b/src/sage/rings/number_field/totallyreal_rel.py @@ -311,7 +311,7 @@ def __init__(self, F, m, B, a=None): # The value of k is the largest index of the coefficients of a which is # currently unknown; e.g., if k == -1, then we can iterate # over polynomials, and if k == n-1, then we have finished iterating. - if a[len(a)-1] <> 1: + if a[len(a)-1] != 1: raise ValueError, "a[len(a)-1](=%s) must be 1 so polynomial is monic"%a[len(a)-1] raise NotImplementedError, "These have not been checked." @@ -518,7 +518,7 @@ def incr(self, f_out, verbose=False, haltk=0): # the Python routine should be sufficiently fast... f = self.Fx(self.gnk[k+1]) df = self.Fx(self.gnk[k+2]) - if gcd(f,df) <> 1: + if gcd(f,df) != 1: if verbose: print " gnk has multiple factor!" maxoutflag = True @@ -594,9 +594,9 @@ def incr(self, f_out, verbose=False, haltk=0): -sum([self.a[i]*(-2)**i for i in range(1,m+1)])] for a0 in a0s: try: - ind = self.amaxvals[0].remove(a0) - except StandardError: - True + self.amaxvals[0].remove(a0) + except Exception: + pass if verbose: print " amaxvals[k]:", self.amaxvals[k] @@ -725,7 +725,7 @@ def enumerate_totallyreal_fields_rel(F, m, B, a = [], verbose=0, return_seqs=Fal nfF = pari(str(F.defining_polynomial()).replace('x', str(F.primitive_element()) ) ) parit = pari(str(F.primitive_element())) - while f_out[m] <> 0: + while f_out[m] != 0: counts[0] += 1 if verbose: print "==>", f_out, diff --git a/src/sage/rings/polynomial/cyclotomic.pyx b/src/sage/rings/polynomial/cyclotomic.pyx index 583589ba4fa..79eac9a5bd7 100644 --- a/src/sage/rings/polynomial/cyclotomic.pyx +++ b/src/sage/rings/polynomial/cyclotomic.pyx @@ -281,7 +281,7 @@ def cyclotomic_value(n, x): raise ValueError, "n must be positive" try: return x.parent()(pari.polcyclo_eval(n, x._pari_())) - except StandardError: + except Exception: pass # The following is modeled on the implementation in Pari factors = factor(n) diff --git a/src/sage/rings/polynomial/groebner_fan.py b/src/sage/rings/polynomial/groebner_fan.py index 08f1b78e7ae..3d81fa7898c 100644 --- a/src/sage/rings/polynomial/groebner_fan.py +++ b/src/sage/rings/polynomial/groebner_fan.py @@ -1408,7 +1408,7 @@ def _4d_to_3d(self, polyhedral_data): if j>i: try: edges.append([tpoints[i],tpoints[j]]) - except StandardError: + except Exception: print adj print 'tpoints: ' + str(tpoints) print 'fpoints: ' + str(fpoints) @@ -1466,7 +1466,7 @@ def render3d(self, verbose = False): for cone_data in cone_info: try: cone_lines = self._4d_to_3d(cone_data) - except StandardError: + except Exception: print cone_data._rays raise RuntimeError for a_line in cone_lines: diff --git a/src/sage/rings/polynomial/infinite_polynomial_element.py b/src/sage/rings/polynomial/infinite_polynomial_element.py index 30720a7e75f..677675e27f7 100644 --- a/src/sage/rings/polynomial/infinite_polynomial_element.py +++ b/src/sage/rings/polynomial/infinite_polynomial_element.py @@ -335,7 +335,7 @@ def __call__(self, *args, **kwargs): try: from sage.misc.sage_eval import sage_eval return sage_eval(repr(res), self.parent()._gens_dict) - except StandardError: + except Exception: return res def _getAttributeNames(self): @@ -510,7 +510,7 @@ def _add_(self, x): # One may need a new parent for self._p and x._p try: return InfinitePolynomial_sparse(self.parent(),self._p+x._p) - except StandardError: + except Exception: pass ## We can now assume that self._p and x._p actually are polynomials, ## hence, their parent is not simply the underlying ring. @@ -534,7 +534,7 @@ def _mul_(self, x): """ try: return InfinitePolynomial_sparse(self.parent(),self._p*x._p) - except StandardError: + except Exception: pass ## We can now assume that self._p and x._p actually are polynomials, ## hence, their parent is not just the underlying ring. @@ -649,7 +649,7 @@ def _sub_(self, x): """ try: return InfinitePolynomial_sparse(self.parent(),self._p-x._p) - except StandardError: + except Exception: pass ## We can now assume that self._p and x._p actually are polynomials, ## hence, their parent is not just the underlying ring. @@ -1363,11 +1363,11 @@ def __cmp__(self, x): # But, to be on the safe side... try: self._p = self.parent()._P(self._p) - except StandardError: + except Exception: pass try: x._p = x.parent()._P(x._p) - except StandardError: + except Exception: pass return cmp(self._p,x._p) diff --git a/src/sage/rings/polynomial/infinite_polynomial_ring.py b/src/sage/rings/polynomial/infinite_polynomial_ring.py index 33412e45998..bdeac22c343 100644 --- a/src/sage/rings/polynomial/infinite_polynomial_ring.py +++ b/src/sage/rings/polynomial/infinite_polynomial_ring.py @@ -449,7 +449,7 @@ def __getitem__(self, k): try: if len(L)==2: return self._D[L[0]][int(L[1])] - except StandardError: + except Exception: pass raise KeyError, "%s is not a variable name"%k @@ -671,7 +671,7 @@ def __init__(self, R, names, order): try: if not (hasattr(R,'is_ring') and R.is_ring() and hasattr(R,'is_commutative') and R.is_commutative()): raise TypeError - except StandardError: + except Exception: raise TypeError, "The given 'base ring' (= %s) must be a commutative ring"%(R) # now, the input is accepted @@ -853,7 +853,7 @@ def _coerce_map_from_(self, S): # We don't care about the orders. But base ring and generators # of the pushout should remain the same as in self. return (P._names == self._names and P._base == self._base) - except StandardError: + except Exception: return False def _element_constructor_(self, x): @@ -890,7 +890,7 @@ def _element_constructor_(self, x): if isinstance(x, basestring): try: return sage_eval(x, self.gens_dict()) - except StandardError: + except Exception: raise ValueError, "Can't convert %s into an element of %s" % (x, self) if hasattr(x, 'parent') and isinstance(x.parent(), InfinitePolynomialRing_sparse): @@ -913,7 +913,7 @@ def _element_constructor_(self, x): # remark: Conversion to self._P (if applicable) # is done in InfinitePolynomial() return InfinitePolynomial(self, x) - except StandardError: + except Exception: pass # By now, we can assume that x has a parent, because @@ -924,7 +924,7 @@ def _element_constructor_(self, x): if not hasattr(x,'variables'): try: return sage_eval(repr(x), self.gens_dict()) - except StandardError: + except Exception: raise ValueError, "Can't convert %s into an element of %s" % (x, self) # direct conversion will only be used if the underlying polynomials are libsingular. @@ -1014,7 +1014,7 @@ def _element_constructor_(self, x): # Hence, for being on the safe side, we coerce into a pushout ring: x = R(1)*x return InfinitePolynomial(self,x) - except StandardError: + except Exception: # OK, last resort, to be on the safe side try: return sage_eval(repr(x), self._gens_dict) @@ -1069,7 +1069,7 @@ def tensor_with_ring(self, R): # try to find the correct base ring in other ways: try: o = B.one_element()*R.one_element() - except StandardError: + except Exception: raise TypeError, "We can't tensor with "+repr(R) return InfinitePolynomialRing(o.parent(), self._names, self._order, implementation='sparse') @@ -1569,7 +1569,7 @@ def tensor_with_ring(self, R): # try to find the correct base ring in other ways: try: o = B.one_element()*R.one_element() - except StandardError: + except Exception: raise TypeError, "We can't tensor with "+repr(R) return InfinitePolynomialRing(o.parent(), self._names, self._order, implementation='dense') diff --git a/src/sage/rings/polynomial/multi_polynomial_ideal.py b/src/sage/rings/polynomial/multi_polynomial_ideal.py index f24f8447a83..3ce45f46812 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ideal.py +++ b/src/sage/rings/polynomial/multi_polynomial_ideal.py @@ -962,49 +962,43 @@ def plot(self, singular=singular_default): @libsingular_standard_options def complete_primary_decomposition(self, algorithm="sy"): r""" - Return a list of primary ideals and their associated primes such - that the intersection of the primary ideal `Q_i` is - `I` = ``self``. + Return a list of primary ideals such that their intersection + is ``self``, together with the associated prime ideals. - An ideal `Q` is called primary if it is a proper ideal of - the ring `R` and if whenever `ab \in Q` and - `a \not\in Q` then `b^n \in Q` for some - `n \in \ZZ`. + An ideal `Q` is called primary if it is a proper ideal of the + ring `R`, and if whenever `ab \in Q` and `a \not\in Q`, then + `b^n \in Q` for some `n \in \ZZ`. - If `Q` is a primary ideal of the ring `R`, then the - radical ideal `P` of `Q`, i.e. - `P = \{a \in R, a^n \in Q\}` for some - `n \in \ZZ`, is called the - *associated prime* of `Q`. + If `Q` is a primary ideal of the ring `R`, then the radical + ideal `P` of `Q` (i.e. the ideal consisting of all `a \in R` + with a^n \in Q` for some `n \in \ZZ`), is called the + associated prime of `Q`. - If `I` is a proper ideal of the ring `R` then there - exists a decomposition in primary ideals `Q_i` such that + If `I` is a proper ideal of a Noetherian ring `R`, then there + exists a finite collection of primary ideals `Q_i` such that + the following hold: + - the intersection of the `Q_i` is `I`; - - their intersection is `I` - - - none of the `Q_i` contains the intersection of the - rest, and - - - the associated prime ideals of `Q_i` are pairwise - different. + - none of the `Q_i` contains the intersection of the others; - - This method returns these `Q_i` and their associated - primes. + - the associated prime ideals `P_i` of the `Q_i` are pairwise + distinct. INPUT: - - ``algorithm`` - string: + - ``algorithm`` -- string: - - ``'sy'`` - (default) use the shimoyama-yokoyama algorithm + - ``'sy'`` -- (default) use the Shimoyama-Yokoyama + algorithm - - ``'gtz'`` - use the gianni-trager-zacharias algorithm + - ``'gtz'`` -- use the Gianni-Trager-Zacharias algorithm OUTPUT: - - ``list`` - a list of primary ideals and their - associated primes [(primary ideal, associated prime), ...] + - a list of pairs `(Q_i, P_i)`, where the `Q_i` form a primary + decomposition of ``self`` and `P_i` is the associated prime + of `Q_i`. EXAMPLES:: @@ -1042,7 +1036,19 @@ def complete_primary_decomposition(self, algorithm="sy"): .. note:: - See [BW93]_ for an introduction to primary decomposition. + See [BW93]_ for an introduction to primary decomposition. + + TESTS: + + Check that :trac:`15745` is fixed:: + + sage: R.= QQ[] + sage: I = Ideal(R(1)) + sage: I.complete_primary_decomposition() + [] + sage: I.is_prime() + False + """ try: return self.__complete_primary_decomposition[algorithm] @@ -1051,6 +1057,10 @@ def complete_primary_decomposition(self, algorithm="sy"): except KeyError: pass + # Avoid a bug in Singular (see #15745). + if self.is_one(): + return [] + import sage.libs.singular if algorithm == 'sy': @@ -1072,36 +1082,42 @@ def complete_primary_decomposition(self, algorithm="sy"): @require_field def primary_decomposition(self, algorithm='sy'): r""" - Return a list of primary ideals such that their intersection is - `I` = ``self``. + Return a list of primary ideals such that their intersection + is ``self``. - An ideal `Q` is called primary if it is a proper ideal of - the ring `R` and if whenever `ab \in Q` and - `a \not\in Q` then `b^n \in Q` for some - `n \in \ZZ`. + An ideal `Q` is called primary if it is a proper ideal of the + ring `R`, and if whenever `ab \in Q` and `a \not\in Q`, then + `b^n \in Q` for some `n \in \ZZ`. - If `I` is a proper ideal of the ring `R` then there - exists a decomposition in primary ideals `Q_i` such that + If `Q` is a primary ideal of the ring `R`, then the radical + ideal `P` of `Q` (i.e. the ideal consisting of all `a \in R` + with a^n \in Q` for some `n \in \ZZ`), is called the + associated prime of `Q`. + If `I` is a proper ideal of a Noetherian ring `R`, then there + exists a finite collection of primary ideals `Q_i` such that + the following hold: - - their intersection is `I` + - the intersection of the `Q_i` is `I`; - - none of the `Q_i` contains the intersection of the - rest, and + - none of the `Q_i` contains the intersection of the others; - - the associated prime ideals of `Q_i` are pairwise - different. + - the associated prime ideals of the `Q_i` are pairwise + distinct. + INPUT: - This method returns these `Q_i`. + - ``algorithm`` -- string: - INPUT: + - ``'sy'`` -- (default) use the Shimoyama-Yokoyama + algorithm - - ``algorithm`` - string: + - ``'gtz'`` -- use the Gianni-Trager-Zacharias algorithm - - ``'sy'`` - (default) use the shimoyama-yokoyama algorithm + OUTPUT: - - ``'gtz'`` - use the gianni-trager-zacharias algorithm + - a list of primary ideals `Q_i` forming a primary + decomposition of ``self``. EXAMPLES:: @@ -3315,7 +3331,8 @@ def __lt__(self, other): if other_new.groebner_basis.is_in_cache(): r = other_new.groebner_basis() elif len(other_new._gb_by_ordering) != 0: - r = other_new._gb_by_ordering.itervalues().next() + o, r = other_new._gb_by_ordering.iteritems().next() + l = self.change_ring(R.change_ring(order=o)).gens() else: # use easy GB otherwise l = self.change_ring(R.change_ring(order="degrevlex")).gens() r = other_new.change_ring(R.change_ring(order="degrevlex")).groebner_basis() diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index 311bf235a77..d3c84a2d4a3 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -201,10 +201,11 @@ from sage.libs.singular.polynomial cimport ( from sage.libs.singular.ring cimport singular_ring_new, singular_ring_reference, singular_ring_delete # polynomial imports -from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_polydict_domain +from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_polydict, MPolynomialRing_polydict_domain from sage.rings.polynomial.multi_polynomial_element import MPolynomial_polydict from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal from sage.rings.polynomial.polydict import ETuple +from sage.rings.polynomial.polynomial_ring import is_PolynomialRing # base ring imports from sage.rings.finite_rings.finite_field_prime_modn import FiniteField_prime_modn @@ -441,9 +442,58 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_generic): memo[id(self)] = self return self - cdef _coerce_c_impl(self, element): + cpdef _coerce_map_from_(self, other): """ - Coerces elements to this multivariate polynomial ring. + Return True if and only if there exists a coercion map from + ``other`` to ``self``. + + TEST:: + + sage: R. = QQ[] + sage: type(R) + + sage: R.has_coerce_map_from(ZZ['t']) + False + sage: R.coerce_map_from(ZZ['x']) + Conversion map: + From: Univariate Polynomial Ring in x over Integer Ring + To: Multivariate Polynomial Ring in x, y over Rational Field + + """ + base_ring = self.base_ring() + + if isinstance(other, MPolynomialRing_libsingular): + if self is other: + return True + n = other.ngens() + if(other.base_ring is base_ring and self.ngens() >= n and + self.variable_names()[:n] == other.variable_names()): + return True + elif base_ring.has_coerce_map_from(other._mpoly_base_ring(self.variable_names())): + return True + elif isinstance(other, MPolynomialRing_polydict): + if self == other: + return True + elif other.ngens() == 0: + return True + elif base_ring.has_coerce_map_from(other._mpoly_base_ring(self.variable_names())): + return True + elif is_PolynomialRing(other): + if base_ring.has_coerce_map_from(other._mpoly_base_ring(self.variable_names())): + return True + elif base_ring.has_coerce_map_from(other): + return True + + Element = MPolynomial_libsingular + + def _element_constructor_(self, element): + """ + Construct a new element in this polynomial ring by converting + ``element`` into ``self`` if possible. + + INPUT:: + + - ``element`` -- several types are supported, see below EXAMPLES:: @@ -526,117 +576,8 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_generic): sage: R. = GF(127)[] sage: R.coerce(P(5)) 5 - """ - cdef poly *_p - cdef ring *_ring = self._ring - cdef number *_n - cdef poly *mon - cdef int i - - base_ring = self.base_ring() - - if isinstance(element, MPolynomial_libsingular): - n = (element)._parent.ngens() - if element.parent() is self: - return element - elif base_ring is element.base_ring() and \ - self.ngens() >= n and \ - self.variable_names()[:n] == (element)._parent.variable_names(): - if self.term_order() == (element)._parent.term_order(): - _p = prCopyR_NoSort((element)._poly, - (element)._parent_ring, - _ring) - else: - _p = prCopyR((element)._poly, - (element)._parent_ring, _ring) - elif base_ring.has_coerce_map_from(element.parent()._mpoly_base_ring(self.variable_names())): - return self(element._mpoly_dict_recursive(self.variable_names(), base_ring)) - else: - raise TypeError, "parents do not match" - - elif isinstance(element, MPolynomial_polydict): - if (element)._parent == self: - _p = p_ISet(0, _ring) - for (m,c) in element.element().dict().iteritems(): - mon = p_Init(_ring) - p_SetCoeff(mon, sa2si(c, _ring), _ring) - for pos in m.nonzero_positions(): - overflow_check(m[pos], _ring) - p_SetExp(mon, pos+1, m[pos], _ring) - p_Setm(mon, _ring) - _p = p_Add_q(_p, mon, _ring) - elif (element)._parent.ngens() == 0: - # zero variable polynomials - _p = p_NSet(sa2si(base_ring(element[tuple()]), _ring), - _ring) - elif base_ring.has_coerce_map_from(element.parent()._mpoly_base_ring(self.variable_names())): - return self(element._mpoly_dict_recursive(self.variable_names(), base_ring)) - else: - raise TypeError("Parents do not match.") - - elif isinstance(element, polynomial_element.Polynomial): - if base_ring.has_coerce_map_from(element.parent()._mpoly_base_ring(self.variable_names())): - return self(element._mpoly_dict_recursive(self.variable_names(), base_ring)) - else: - raise TypeError("incompatable parents.") - - elif isinstance(element, CommutativeRingElement): - # base ring elements - if element.parent() is base_ring: - # shortcut for GF(p) - if isinstance(base_ring, FiniteField_prime_modn): - _p = p_ISet(int(element) % _ring.ch, _ring) - else: - _n = sa2si(element,_ring) - _p = p_NSet(_n, _ring) - - # also accepting ZZ - elif is_IntegerRing(element.parent()): - if isinstance(base_ring, FiniteField_prime_modn): - _p = p_ISet(int(element),_ring) - else: - _n = sa2si(base_ring(element),_ring) - _p = p_NSet(_n, _ring) - else: - # fall back to base ring - element = base_ring._coerce_c(element) - _n = sa2si(element,_ring) - _p = p_NSet(_n, _ring) - - # Accepting int - elif isinstance(element, int): - if isinstance(base_ring, FiniteField_prime_modn): - _p = p_ISet(int(element) % _ring.ch,_ring) - else: - _n = sa2si(base_ring(element),_ring) - _p = p_NSet(_n, _ring) - - # and longs - elif isinstance(element, long): - if isinstance(base_ring, FiniteField_prime_modn): - element = element % self.base_ring().characteristic() - _p = p_ISet(int(element), _ring) - else: - _n = sa2si(base_ring(element),_ring) - _p = p_NSet(_n, _ring) - else: - raise TypeError, "Cannot coerce element" - - return new_MP(self, _p) - - def __call__(self, element): - """ - Construct a new element in this polynomial ring, i.e. try to - coerce in ``element`` if at all possible. - - INPUT:: - - - ``element`` - several types are supported, see below - EXAMPLES:: - - Call supports all conversions ``_coerce_`` supports, plus: - conversion from strings:: + Conversion from strings:: sage: P. = QQ[] sage: P('x+y + 1/4') @@ -735,8 +676,6 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_generic): ... TypeError: Could not find a mapping of the passed element to this ring. - TESTS:: - Coerce in a polydict where a coefficient reduces to 0 but isn't 0. :: sage: R. = QQ[]; S. = GF(5)[]; S( (5*x*y + x + 17*y)._mpoly_dict_recursive() ) @@ -785,9 +724,16 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_generic): sage: P(a,b) a + Check that :trac:`15746` is fixed:: + + sage: R. = GF(7)[] + sage: R(2^31) + 2 + """ cdef poly *_p, *mon, *El_poly cdef ring *_ring = self._ring + cdef number *_n cdef ring *El_ring cdef long mpos cdef MPolynomial_libsingular Element @@ -797,11 +743,84 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_generic): cdef int e if _ring!=currRing: rChangeCurrRing(_ring) - # try to coerce first - try: - return self._coerce_c_impl(element) - except TypeError: - pass + base_ring = self.base_ring() + + if isinstance(element, MPolynomial_libsingular): + n = (element)._parent.ngens() + if element.parent() is self: + return element + elif(base_ring is element.base_ring() and + self.ngens() >= n and + self.variable_names()[:n] == (element)._parent.variable_names()): + if self.term_order() == (element)._parent.term_order(): + _p = prCopyR_NoSort((element)._poly, + (element)._parent_ring, + _ring) + else: + _p = prCopyR((element)._poly, + (element)._parent_ring, _ring) + return new_MP(self, _p) + elif base_ring.has_coerce_map_from(element.parent()._mpoly_base_ring(self.variable_names())): + return self(element._mpoly_dict_recursive(self.variable_names(), base_ring)) + + elif isinstance(element, MPolynomial_polydict): + if element.parent() == self: + _p = p_ISet(0, _ring) + for (m,c) in element.element().dict().iteritems(): + mon = p_Init(_ring) + p_SetCoeff(mon, sa2si(c, _ring), _ring) + for pos in m.nonzero_positions(): + overflow_check(m[pos], _ring) + p_SetExp(mon, pos+1, m[pos], _ring) + p_Setm(mon, _ring) + _p = p_Add_q(_p, mon, _ring) + return new_MP(self, _p) + elif element.parent().ngens() == 0: + # zero variable polynomials + _p = p_NSet(sa2si(base_ring(element[tuple()]), _ring), + _ring) + return new_MP(self, _p) + elif base_ring.has_coerce_map_from(element.parent()._mpoly_base_ring(self.variable_names())): + return self(element._mpoly_dict_recursive(self.variable_names(), base_ring)) + + elif isinstance(element, polynomial_element.Polynomial): + if base_ring.has_coerce_map_from(element.parent()._mpoly_base_ring(self.variable_names())): + return self(element._mpoly_dict_recursive(self.variable_names(), base_ring)) + + if isinstance(element, CommutativeRingElement): + # base ring elements + if element.parent() is base_ring: + # shortcut for GF(p) + if isinstance(base_ring, FiniteField_prime_modn): + _p = p_ISet(int(element) % _ring.ch, _ring) + else: + _n = sa2si(element,_ring) + _p = p_NSet(_n, _ring) + return new_MP(self, _p) + # also accepting ZZ + elif is_IntegerRing(element.parent()): + if isinstance(base_ring, FiniteField_prime_modn): + _p = p_ISet(int(element),_ring) + else: + _n = sa2si(base_ring(element),_ring) + _p = p_NSet(_n, _ring) + return new_MP(self, _p) + # fall back to base ring + try: + element = base_ring._coerce_c(element) + _n = sa2si(element,_ring) + _p = p_NSet(_n, _ring) + return new_MP(self, _p) + except TypeError: + pass + + elif isinstance(element, int) or isinstance(element, long): + if isinstance(base_ring, FiniteField_prime_modn): + _p = p_ISet(element % _ring.ch, _ring) + else: + _n = sa2si(base_ring(element), _ring) + _p = p_NSet(_n, _ring) + return new_MP(self, _p) if isinstance(element, (SingularElement, sage.libs.pari.gen.gen)): element = str(element) @@ -832,9 +851,9 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_generic): c = si2sa(p_GetCoeff(El_poly, El_ring), El_ring, El_base) try: c = K(c) - except TypeError, msg: + except TypeError: p_Delete(&_p, _ring) - raise TypeError, msg + raise if c: rChangeCurrRing(_ring) mon = p_Init(_ring) @@ -866,9 +885,9 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_generic): try: c = K(c) if not c: continue - except TypeError, msg: + except TypeError: p_Delete(&_p, _ring) - raise TypeError, msg + raise mon = p_Init(_ring) p_SetCoeff(mon, sa2si(c , _ring), _ring) for pos in m.nonzero_positions(): @@ -922,13 +941,13 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_generic): try: c = K(c) if not c: continue - except TypeError, msg: + except TypeError: p_Delete(&_p, _ring) - raise TypeError, msg + raise mon = p_Init(_ring) p_SetCoeff(mon, sa2si(c , _ring), _ring) if len(m) != self.ngens(): - raise TypeError, "tuple key must have same length as ngens" + raise TypeError("tuple key must have same length as ngens") for pos from 0 <= pos < len(m): if m[pos]: overflow_check(m[pos], _ring) @@ -1434,9 +1453,22 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_generic): sage: P == R False """ - return (left)._richcmp(right, op) + return (left)._richcmp_helper(right, op) - cdef int _cmp_c_impl(left, Parent right) except -2: + def _cmp_(left, right): + """ + Compare ``left`` with ``right``. + + TEST:: + + sage: R = QQ['x', 'y']; R + Multivariate Polynomial Ring in x, y over Rational Field + sage: R == R + True + sage: R == QQ['x','z'] + False + + """ if isinstance(right, (MPolynomialRing_libsingular, MPolynomialRing_polydict_domain)): return cmp((left.base_ring(), map(str, left.gens()), left.term_order()), (right.base_ring(), map(str, right.gens()), right.term_order())) @@ -3008,8 +3040,11 @@ cdef class MPolynomial_libsingular(sage.rings.polynomial.multi_polynomial.MPolyn if not p_IsUnit(self._poly, _ring): raise ArithmeticError, "Element is not a unit." - else: - return new_MP(self._parent,pInvers(0,self._poly,NULL)) + + sig_on() + cdef MPolynomial_libsingular r = new_MP(self._parent, pInvers(0, self._poly, NULL)) + sig_off() + return r def is_homogeneous(self): """ diff --git a/src/sage/rings/polynomial/padics/polynomial_padic_capped_relative_dense.py b/src/sage/rings/polynomial/padics/polynomial_padic_capped_relative_dense.py index f03ff90c07a..bb3b6499390 100644 --- a/src/sage/rings/polynomial/padics/polynomial_padic_capped_relative_dense.py +++ b/src/sage/rings/polynomial/padics/polynomial_padic_capped_relative_dense.py @@ -19,6 +19,7 @@ import sage.rings.padics.precision_error as precision_error import sage.rings.fraction_field_element as fraction_field_element import copy +from sage.structure.element import coerce_binop from sage.libs.all import pari, pari_gen from sage.libs.ntl.all import ZZX @@ -957,12 +958,52 @@ def _quo_rem_naive(self, right): #def lcm(self, right): # raise NotImplementedError + @coerce_binop def xgcd(self, right): + """ + Extended gcd of ``self`` and ``other``. + + INPUT: + + - ``other`` -- an element with the same parent as ``self`` + + OUTPUT: + + Polynomials ``g``, ``u``, and ``v`` such that ``g = u*self + v*other`` + + .. WARNING:: + + The computations are performed using the standard Euclidean + algorithm which might produce mathematically incorrect results in + some cases. See :trac:`13439`. + + EXAMPLES:: + + sage: R. = Qp(3,3)[] + sage: f = x + 1 + sage: f.xgcd(f^2) + ((1 + O(3^3))*x + (1 + O(3^3)), (1 + O(3^3)), 0) + + In these examples the results are incorrect, see :trac:`13439`:: + + sage: R. = Qp(3,3)[] + sage: f = 3*x + 7 + sage: g = 5*x + 9 + sage: f.xgcd(f*g) # not tested - currently we get the incorrect result ((O(3^2))*x^2 + (O(3))*x + (1 + O(3^3)), (3^-2 + 2*3^-1 + O(3))*x, (3^-2 + 3^-1 + O(3))) + ((3 + O(3^4))*x + (1 + 2*3 + O(3^3)), (1 + O(3^3)), 0) + + sage: R. = Qp(3)[] + sage: f = 490473657*x + 257392844/729 + sage: g = 225227399/59049*x - 8669753175 + sage: f.xgcd(f*g) # not tested - currently we get the incorrect result ((O(3^18))*x^2 + (O(3^9))*x + (1 + O(3^20)), (3^-5 + 2*3^-1 + 3 + 2*3^2 + 3^4 + 2*3^6 + 3^7 + 3^8 + 2*3^9 + 2*3^11 + 3^13 + O(3^15))*x, (3^5 + 2*3^6 + 2*3^7 + 3^8 + 3^9 + 3^13 + 2*3^14 + 3^17 + 3^18 + 3^20 + 3^21 + 3^23 + 2*3^24 + O(3^25))) + ((3^3 + 3^5 + 2*3^6 + 2*3^7 + 3^8 + 2*3^10 + 2*3^11 + 3^12 + 3^13 + 3^15 + 2*3^16 + 3^18 + O(3^23))*x + (2*3^-6 + 2*3^-5 + 3^-3 + 2*3^-2 + 3^-1 + 2*3 + 2*3^2 + 2*3^3 + 2*3^4 + 3^6 + 2*3^7 + 2*3^8 + 2*3^9 + 2*3^10 + 3^11 + O(3^14)), (1 + O(3^20)), 0) + + """ from sage.misc.stopgap import stopgap stopgap("Extended gcd computations over p-adic fields are performed using the standard Euclidean algorithm which might produce mathematically incorrect results in some cases.", 13439) from sage.rings.polynomial.polynomial_element_generic import Polynomial_generic_field - return Polynomial_generic_field._xgcd.im_func(self,right) + return Polynomial_generic_field.xgcd(self,right) #def discriminant(self): # raise NotImplementedError diff --git a/src/sage/rings/polynomial/pbori.pyx b/src/sage/rings/polynomial/pbori.pyx index 189b94328a3..ed29494e3cd 100644 --- a/src/sage/rings/polynomial/pbori.pyx +++ b/src/sage/rings/polynomial/pbori.pyx @@ -962,10 +962,10 @@ cdef class BooleanPolynomialRing(MPolynomialRing_generic): try: i = int(other) - except StandardError: + except Exception: try: # last chance: try Sage's conversions over GF(2), Trac #13284 return self._coerce_c_impl(self.cover_ring()(other)) - except StandardError: + except Exception: raise TypeError, "cannot convert %s to BooleanPolynomial"%(type(other)) i = i % 2 @@ -4826,7 +4826,7 @@ cdef class MonomialConstruct: if PY_TYPE_CHECK(x, BooleanPolynomial): return result.lm() return result - except StandardError: + except Exception: raise TypeError, "Cannot convert to Boolean Monomial %s"%(str(type(x))) cdef class VariableConstruct: @@ -8171,7 +8171,7 @@ cdef class MonomialFactory: if PY_TYPE_CHECK(arg, BooleanPolynomial): return result.lm() return result - except StandardError: + except Exception: raise TypeError, \ "Cannot %s convert to Boolean Monomial"%(str(type(arg))) diff --git a/src/sage/rings/polynomial/polynomial_element_generic.py b/src/sage/rings/polynomial/polynomial_element_generic.py index 3ee3aec9df3..e8594dc0037 100644 --- a/src/sage/rings/polynomial/polynomial_element_generic.py +++ b/src/sage/rings/polynomial/polynomial_element_generic.py @@ -632,17 +632,32 @@ def quo_rem(self, other): R = R[:R.degree()] - (aaa*B[:B.degree()]).shift(diff_deg) return (Q, R) - def _gcd(self, other): + @coerce_binop + def gcd(self, other): """ - Return the GCD of self and other, as a monic polynomial. + Return the greatest common divisor of this polynomial and ``other``, as + a monic polynomial. + + INPUT: + + - ``other`` -- a polynomial defined over the same ring as ``self`` + + EXAMPLES:: + + sage: R. = QQbar[] + sage: (2*x).gcd(2*x^2) + x + """ - g = EuclideanDomainElement._gcd(self, other) + from sage.categories.euclidean_domains import EuclideanDomains + g = EuclideanDomains().ElementMethods().gcd(self, other) c = g.leading_coefficient() if c.is_unit(): return (1/c)*g return g - def _xgcd(self, other): + @coerce_binop + def xgcd(self, other): r""" Extended gcd of ``self`` and polynomial ``other``. diff --git a/src/sage/rings/polynomial/polynomial_modn_dense_ntl.pyx b/src/sage/rings/polynomial/polynomial_modn_dense_ntl.pyx index 4eb661cef80..649b96fcda8 100644 --- a/src/sage/rings/polynomial/polynomial_modn_dense_ntl.pyx +++ b/src/sage/rings/polynomial/polynomial_modn_dense_ntl.pyx @@ -1750,42 +1750,56 @@ cdef class Polynomial_dense_mod_p(Polynomial_dense_mod_n): @coerce_binop def gcd(self, right): - return self._gcd(right) - - def _gcd(self, right): """ - Return the GCD of self and other, as a monic polynomial. + Return the greatest common divisor of this polynomial and ``other``, as + a monic polynomial. + + INPUT: + + - ``other`` -- a polynomial defined over the same ring as ``self`` + + EXAMPLES:: + + sage: R. = PolynomialRing(GF(3),implementation="NTL") + sage: f,g = x + 2, x^2 - 1 + sage: f.gcd(g) + x + 2 + """ - if not isinstance(right, Polynomial_dense_mod_p): - right = self.parent()(right) - elif self.parent() != right.parent(): - raise TypeError g = self.ntl_ZZ_pX().gcd(right.ntl_ZZ_pX()) return self.parent()(g, construct=True) @coerce_binop - def xgcd(self, right): + def xgcd(self, other): r""" - Return the extended gcd of self and other, i.e., elements `r, s, t` such that + Compute the extended gcd of this element and ``other``. - .. math:: + INPUT: - r = s \cdot self + t \cdot other. + - ``other`` -- an element in the same polynomial ring - """ - # copied from sage.structure.element.PrincipalIdealDomainElement due to lack of mult inheritance - if not PY_TYPE_CHECK(right, Element) or not ((right)._parent is self._parent): - from sage.rings.arith import xgcd - return bin_op(self, right, xgcd) - return self._xgcd(right) + OUTPUT: - def _xgcd(self, right): - """ - Return ``g, u, v`` such that ``g = u*self + v*right``. - """ - r, s, t = self.ntl_ZZ_pX().xgcd(right.ntl_ZZ_pX()) - return self.parent()(r, construct=True), self.parent()(s, construct=True), \ - self.parent()(t, construct=True) + A tuple ``(r,s,t)`` of elements in the polynomial ring such + that ``r = s*self + t*other``. + + EXAMPLES:: + + sage: R. = PolynomialRing(GF(3),implementation='NTL') + sage: x.xgcd(x) + (x, 0, 1) + sage: (x^2 - 1).xgcd(x - 1) + (x + 2, 0, 1) + sage: R.zero().xgcd(R.one()) + (1, 0, 1) + sage: (x^3 - 1).xgcd((x - 1)^2) + (x^2 + x + 1, 0, 1) + sage: ((x - 1)*(x + 1)).xgcd(x*(x - 1)) + (x + 2, 1, 2) + + """ + r, s, t = self.ntl_ZZ_pX().xgcd(other.ntl_ZZ_pX()) + return self.parent()(r, construct=True), self.parent()(s, construct=True), self.parent()(t, construct=True) @coerce_binop def resultant(self, other): diff --git a/src/sage/rings/polynomial/polynomial_quotient_ring.py b/src/sage/rings/polynomial/polynomial_quotient_ring.py index cfb019a5899..51bcfb76bb2 100644 --- a/src/sage/rings/polynomial/polynomial_quotient_ring.py +++ b/src/sage/rings/polynomial/polynomial_quotient_ring.py @@ -265,7 +265,7 @@ class of the category, and store the current class of the quotient sage: first_class == Q.__class__ False sage: [s for s in dir(Q.category().element_class) if not s.startswith('_')] - ['cartesian_product', 'gcd', 'is_idempotent', 'is_one', 'is_unit', 'lcm', 'lift'] + ['cartesian_product', 'gcd', 'is_idempotent', 'is_one', 'is_unit', 'lcm', 'lift', 'xgcd'] As one can see, the elements are now inheriting additional methods: lcm and gcd. Even though ``Q.an_element()`` belongs to the old and not to the new element class, it still inherits diff --git a/src/sage/rings/polynomial/polynomial_ring.py b/src/sage/rings/polynomial/polynomial_ring.py index b185b06a135..70f199101c2 100644 --- a/src/sage/rings/polynomial/polynomial_ring.py +++ b/src/sage/rings/polynomial/polynomial_ring.py @@ -308,6 +308,12 @@ def _element_constructor_(self, x=None, check=True, is_gen = False, construct=Fa Convert ``x`` into this univariate polynomial ring, possibly non-canonically. + Conversion from power series:: + + sage: R. = QQ[] + sage: R(1 + x + x^2 + O(x^3)) + x^2 + x + 1 + Stacked polynomial rings coerce into constants if possible. First, the univariate case:: @@ -410,7 +416,7 @@ def _element_constructor_(self, x=None, check=True, is_gen = False, construct=Fa self._singular_().set_ring() try: return x.sage_poly(self) - except StandardError: + except Exception: raise TypeError, "Unable to coerce singular object" elif isinstance(x , str): try: @@ -435,6 +441,8 @@ def _element_constructor_(self, x=None, check=True, is_gen = False, construct=Fa return self(x.polynomial()) except AttributeError: pass + elif isinstance(x, sage.rings.power_series_ring_element.PowerSeries): + x = x.truncate() return C(self, x, check, is_gen, construct=construct, **kwds) def is_integral_domain(self, proof = True): diff --git a/src/sage/rings/polynomial/symmetric_ideal.py b/src/sage/rings/polynomial/symmetric_ideal.py index db6043cc70c..0a8cc373405 100644 --- a/src/sage/rings/polynomial/symmetric_ideal.py +++ b/src/sage/rings/polynomial/symmetric_ideal.py @@ -247,7 +247,7 @@ def _contains_(self, p): """ try: return self.reduce(p) == 0 - except StandardError: + except Exception: return False def __mul__ (self, other): @@ -953,7 +953,7 @@ def groebner_basis(self, tailreduce=False, reduced=True, algorithm=None, report= try: # working around one libsingular bug and one libsingular oddity DenseIdeal = [CommonR(P._p) if ((CommonR is P._p.parent()) or CommonR.ngens()!=P._p.parent().ngens()) else CommonR(repr(P._p)) for P in OUT.gens()]*CommonR - except StandardError: + except Exception: if report != None: print "working around a libsingular bug" DenseIdeal = [repr(P._p) for P in OUT.gens()]*CommonR diff --git a/src/sage/rings/polynomial/term_order.py b/src/sage/rings/polynomial/term_order.py index 282a1c5d41f..53d3107388e 100644 --- a/src/sage/rings/polynomial/term_order.py +++ b/src/sage/rings/polynomial/term_order.py @@ -653,7 +653,7 @@ def __init__(self, name='lex', n=0, blocks=True, force=False): if not isinstance(name, (tuple,list)): name = name.list() # name may be a matrix name = tuple(name) - except StandardError: + except Exception: raise TypeError, "%s is not a valid term order"%(name,) self._blocks = tuple() @@ -672,7 +672,7 @@ def __init__(self, name='lex', n=0, blocks=True, force=False): if not isinstance(t, TermOrder): try: t = TermOrder(t,force=True) - except StandardError: + except Exception: raise TypeError if t.name() == 'block': blocks = blocks + list(t.blocks()) @@ -1851,7 +1851,7 @@ def __eq__(self, other): if not isinstance(other, TermOrder): try: other = TermOrder(other, force=True) - except StandardError: + except Exception: return False return (self._name == other._name # note that length is not considered. diff --git a/src/sage/rings/polynomial/toy_variety.py b/src/sage/rings/polynomial/toy_variety.py index 44cf520c37c..355f366761e 100644 --- a/src/sage/rings/polynomial/toy_variety.py +++ b/src/sage/rings/polynomial/toy_variety.py @@ -71,7 +71,7 @@ def is_triangular(B): else: try: G = B.gens() - except StandardError: + except Exception: raise TypeError, "is_triangular wants as input an ideal, or a list of polynomials\n" vars = G[0].parent().gens() n = len(G) @@ -263,7 +263,7 @@ def triangular_factorization(B, n=-1): else: try: G = B.gens() - except StandardError: + except Exception: raise TypeError, "triangular_factorization wants as input an ideal, or a list of polynomials\n" # easy cases if len(G)==0: @@ -332,7 +332,7 @@ def elim_pol(B, n=-1): else: try: G = B.gens() - except StandardError: + except Exception: raise TypeError, "elim_pol wants as input an ideal or a list of polynomials" # setup -- main algorithm diff --git a/src/sage/rings/power_series_ring_element.pyx b/src/sage/rings/power_series_ring_element.pyx index fe3ed640916..0357c4caacd 100644 --- a/src/sage/rings/power_series_ring_element.pyx +++ b/src/sage/rings/power_series_ring_element.pyx @@ -313,6 +313,8 @@ cdef class PowerSeries(AlgebraElement): if PY_TYPE_CHECK(right, int): return self.is_zero() + from sage.misc.stopgap import stopgap + stopgap("Warning: Comparison of power series may be wrong if certain coefficients are zero. The padded_list method can be used to give correct comparisons.", 9457) prec = self.common_prec(right) x = self.list() y = right.list() diff --git a/src/sage/rings/rational.pyx b/src/sage/rings/rational.pyx index 39249d9b798..6d113e69344 100644 --- a/src/sage/rings/rational.pyx +++ b/src/sage/rings/rational.pyx @@ -902,28 +902,6 @@ cdef class Rational(sage.structure.element.FieldElement): from sage.rings.arith import gcd, lcm return gcd(nums) / lcm(denoms) -# def gcd_rational(self, other, **kwds): -# """ -# Return a gcd of the rational numbers self and other. -# -# If self = other = 0, this is by convention 0. In all other -# cases it can (mathematically) be any nonzero rational number, -# but for simplicity we choose to always return 1. -# -# EXAMPLES:: -# -# sage: (1/3).gcd_rational(2/1) -# 1 -# sage: (1/1).gcd_rational(0/1) -# 1 -# sage: (0/1).gcd_rational(0/1) -# 0 -# """ -# if self == 0 and other == 0: -# return Rational(0) -# else: -# return Rational(1) - def valuation(self, p): r""" Return the power of ``p`` in the factorization of self. @@ -2394,7 +2372,7 @@ cdef class Rational(sage.structure.element.FieldElement): except AttributeError: try: return type(n)(self)**n - except StandardError: + except Exception: raise TypeError, "exponent (=%s) must be an integer.\nCoerce your numbers to real or complex numbers first."%n except OverflowError: @@ -3145,33 +3123,6 @@ cdef class Rational(sage.structure.element.FieldElement): return Rational(0) return Rational(1) - def _gcd(self, Rational other): - """ - Returns the least common multiple, in the rational numbers, of ``self`` - and ``other``. This function returns either 0 or 1 (as a rational - number). - - INPUT: - - - ``other`` - Rational - - OUTPUT: - - - ``Rational`` - 0 or 1 - - EXAMPLES:: - - sage: (2/3)._gcd(3/5) - 1 - sage: (0/1)._gcd(0/1) - 0 - """ - if mpz_cmp_si(mpq_numref(self.value), 0) == 0 and \ - mpz_cmp_si(mpq_numref(other.value), 0) == 0: - return Rational(0) - return Rational(1) - - def additive_order(self): """ Return the additive order of ``self``. diff --git a/src/sage/rings/real_lazy.pyx b/src/sage/rings/real_lazy.pyx index 6af979af9f1..14b4e3a16db 100644 --- a/src/sage/rings/real_lazy.pyx +++ b/src/sage/rings/real_lazy.pyx @@ -791,7 +791,7 @@ cdef class LazyFieldElement(FieldElement): """ try: return self.eval(complex) - except StandardError: + except Exception: from complex_field import ComplexField return complex(self.eval(ComplexField(53))) diff --git a/src/sage/rings/residue_field.pyx b/src/sage/rings/residue_field.pyx index 991a05ca46e..526d123cc17 100644 --- a/src/sage/rings/residue_field.pyx +++ b/src/sage/rings/residue_field.pyx @@ -53,6 +53,8 @@ TESTS:: sage: K. = CyclotomicField(7) sage: P = K.factor(17)[0][0] sage: ff = K.residue_field(P) + sage: loads(dumps(ff)) is ff + True sage: a = ff(z) sage: parent(a*a) Residue field in zbar of Fractional ideal (17) @@ -70,6 +72,12 @@ Verify that :trac:`15192` has been resolved:: #sage: parent(a*a) #Residue field in a of Principal ideal (t^3 + t + 4) of Univariate Polynomial Ring in t over Finite Field of size 11 +Verify that :trac:`7475` is fixed:: + + sage: K = ZZ.residue_field(2) + sage: loads(dumps(K)) is K + True + Reducing a curve modulo a prime:: sage: K. = NumberField(x^2+23) @@ -901,7 +909,8 @@ cdef class ReductionMap(Map): try: return self._F(self._to_vs(x) * self._PBinv) - except StandardError: pass + except Exception: + pass # Now we do have to work harder...below this point we handle # cases which failed before trac 1951 was fixed. diff --git a/src/sage/schemes/affine/affine_morphism.py b/src/sage/schemes/affine/affine_morphism.py index 384a3a7d485..b807f064a8a 100644 --- a/src/sage/schemes/affine/affine_morphism.py +++ b/src/sage/schemes/affine/affine_morphism.py @@ -219,7 +219,7 @@ def homogenize(self,n,newvar='h'): S=PolynomialRing(A.base_ring(),Vars) try: l=lcm([self[i].denominator() for i in range(N)]) - except StandardError: #no lcm + except Exception: #no lcm l=prod([self[i].denominator() for i in range(N)]) from sage.rings.polynomial.polynomial_ring import PolynomialRing_general diff --git a/src/sage/schemes/affine/affine_rational_point.py b/src/sage/schemes/affine/affine_rational_point.py index 8b49650deb4..a2f73309604 100644 --- a/src/sage/schemes/affine/affine_rational_point.py +++ b/src/sage/schemes/affine/affine_rational_point.py @@ -205,7 +205,7 @@ def enum_affine_finite_field(X): for c in cartesian_product_iterator([F]*n): try: pts.append(X(c)) - except StandardError: + except Exception: pass pts.sort() return pts diff --git a/src/sage/schemes/elliptic_curves/BSD.py b/src/sage/schemes/elliptic_curves/BSD.py index 2866a1aad0f..18db346aee5 100644 --- a/src/sage/schemes/elliptic_curves/BSD.py +++ b/src/sage/schemes/elliptic_curves/BSD.py @@ -449,7 +449,7 @@ def prove_BSD(E, verbosity=0, two_desc='mwrank', proof=None, secs_hi=5, if BSD.curve.j_invariant() in non_max_j_invs: # is this possible for optimal curves? if verbosity > 0: print 'CM by non maximal order: switching curves' - for E in BSD.curve.isogeny_class(use_tuple=False): + for E in BSD.curve.isogeny_class(): if E.j_invariant() not in non_max_j_invs: BSD.curve = E break @@ -659,7 +659,7 @@ def prove_BSD(E, verbosity=0, two_desc='mwrank', proof=None, secs_hi=5, kolyvagin_primes.append(p) # Stein et al. if not BSD.curve.has_cm(): - L = arith.lcm([F.torsion_order() for F in BSD.curve.isogeny_class(use_tuple=False)]) + L = arith.lcm([F.torsion_order() for F in BSD.curve.isogeny_class()]) for p in BSD.primes: if p in kolyvagin_primes or p == 2: continue if L%p != 0: diff --git a/src/sage/schemes/elliptic_curves/ell_field.py b/src/sage/schemes/elliptic_curves/ell_field.py index 716096f07cc..565787ac2e5 100644 --- a/src/sage/schemes/elliptic_curves/ell_field.py +++ b/src/sage/schemes/elliptic_curves/ell_field.py @@ -659,14 +659,14 @@ def descend_to(self, K, f=None): jbase = g.preimage(j) f = g break - except StandardError: + except Exception: pass if f == None: return None else: try: jbase = f.preimage(j) - except StandardError: + except Exception: return None E = EllipticCurve(j=jbase) E2 = EllipticCurve(self.base_field(), [f(a) for a in E.a_invariants()]) @@ -694,7 +694,7 @@ def descend_to(self, K, f=None): if Etwist.is_isomorphic(self): try: Eout = EllipticCurve(K, [f.preimage(a) for a in Etwist.a_invariants()]) - except StandardError: + except Exception: return None else: return Eout diff --git a/src/sage/schemes/elliptic_curves/ell_finite_field.py b/src/sage/schemes/elliptic_curves/ell_finite_field.py index c7d3963e4eb..944e2ab83d0 100644 --- a/src/sage/schemes/elliptic_curves/ell_finite_field.py +++ b/src/sage/schemes/elliptic_curves/ell_finite_field.py @@ -1417,7 +1417,7 @@ def abelian_group(self, debug=False): N=self._order if debug: print "Group order already known to be ",N - except StandardError: + except Exception: if (q<50): if debug: print "Computing group order naively" diff --git a/src/sage/schemes/elliptic_curves/ell_modular_symbols.py b/src/sage/schemes/elliptic_curves/ell_modular_symbols.py index 42d4493541e..7d2a6d3a1bf 100644 --- a/src/sage/schemes/elliptic_curves/ell_modular_symbols.py +++ b/src/sage/schemes/elliptic_curves/ell_modular_symbols.py @@ -465,9 +465,9 @@ def __init__(self, E, sign, normalize="L_ratio"): 8 sage: E = EllipticCurve('15a1') - sage: [C.modular_symbol(use_eclib=True,normalize='L_ratio')(0) for C in E.isogeny_class(use_tuple=False)] + sage: [C.modular_symbol(use_eclib=True,normalize='L_ratio')(0) for C in E.isogeny_class()] [1/4, 1/8, 1/4, 1/2, 1/8, 1/16, 1/2, 1] - sage: [C.modular_symbol(use_eclib=True,normalize='none')(0) for C in E.isogeny_class(use_tuple=False)] + sage: [C.modular_symbol(use_eclib=True,normalize='none')(0) for C in E.isogeny_class()] [1/4, 1/4, 1/4, 1/4, 1/4, 1/4, 1/4, 1/4] Currently, the interface for negative modular symbols in eclib is not yet written:: @@ -609,11 +609,11 @@ def __init__(self, E, sign, normalize="L_ratio"): 1 sage: E = EllipticCurve('15a1') - sage: [C.modular_symbol(use_eclib=False, normalize='L_ratio')(0) for C in E.isogeny_class(use_tuple=False)] + sage: [C.modular_symbol(use_eclib=False, normalize='L_ratio')(0) for C in E.isogeny_class()] [1/4, 1/8, 1/4, 1/2, 1/8, 1/16, 1/2, 1] - sage: [C.modular_symbol(use_eclib=False, normalize='period')(0) for C in E.isogeny_class(use_tuple=False)] + sage: [C.modular_symbol(use_eclib=False, normalize='period')(0) for C in E.isogeny_class()] [1/8, 1/16, 1/8, 1/4, 1/16, 1/32, 1/4, 1/2] - sage: [C.modular_symbol(use_eclib=False, normalize='none')(0) for C in E.isogeny_class(use_tuple=False)] + sage: [C.modular_symbol(use_eclib=False, normalize='none')(0) for C in E.isogeny_class()] [1, 1, 1, 1, 1, 1, 1, 1] """ diff --git a/src/sage/schemes/elliptic_curves/ell_point.py b/src/sage/schemes/elliptic_curves/ell_point.py index 6ad8e0a8701..7158371e7a8 100644 --- a/src/sage/schemes/elliptic_curves/ell_point.py +++ b/src/sage/schemes/elliptic_curves/ell_point.py @@ -3422,7 +3422,7 @@ def discrete_log(self, Q, ord=None): ord = self.order() try: return generic.discrete_log(Q, self, ord, operation='+') - except StandardError: + except Exception: raise ValueError("ECDLog problem has no solution") def order(self): @@ -3494,7 +3494,7 @@ def order(self): plist = M.prime_divisors() E._prime_factors_of_order = plist N = generic.order_from_multiple(self, M, plist, operation='+') - except StandardError: + except Exception: if K.is_prime_field(): M = E.cardinality() # computed and cached plist = M.prime_divisors() diff --git a/src/sage/schemes/elliptic_curves/ell_rational_field.py b/src/sage/schemes/elliptic_curves/ell_rational_field.py index 4d3e011bc98..857061b562f 100644 --- a/src/sage/schemes/elliptic_curves/ell_rational_field.py +++ b/src/sage/schemes/elliptic_curves/ell_rational_field.py @@ -1324,14 +1324,12 @@ def analytic_rank(self, algorithm="pari", leading_coefficient=False): sage: E.analytic_rank(algorithm='pari') 2 sage: E.analytic_rank(algorithm='rubinstein') - *** Warning:...new stack size = ... 2 sage: E.analytic_rank(algorithm='sympow') 2 sage: E.analytic_rank(algorithm='magma') # optional - magma 2 sage: E.analytic_rank(algorithm='all') - *** Warning:...new stack size = ... 2 With the optional parameter leading_coefficient set to ``True``, a @@ -2160,13 +2158,16 @@ def saturation(self, points, verbose=False, max_prime=0, odd_primes_only=False): 113.302910926080 sage: E.saturation([P]) ([(-192128125858676194585718821667542660822323528626273/336995568430319276695106602174283479617040716649 : 70208213492933395764907328787228427430477177498927549075405076353624188436/195630373799784831667835900062564586429333568841391304129067339731164107 : 1)], 1, 113.302910926080) - sage: E.saturation([2*P]) # needs higher precision; long time - After 10 attempts at enlargement, giving up! - ... - ([(1755450733726721618440965414535034458701302721700399/970334851896750960577261378321772998240802013604 : -59636173615502879504846810677646864329901430096139563516090202443694810309127/955833935771565601591243078845907133814963790187832340692216425242529192 : 1)], 2, 113.302910926080) + sage: (Q,), ind, reg = E.saturation([2*P]) # needs higher precision, handled by eclib + sage: 2*Q == 2*P + True + sage: ind + 2 + sage: reg + 113.302910926080 - See #10840. This causes eclib to crash since the curve is - non-minimal at 2:: + See :trac:`10840`. This used to cause eclib to crash since the + curve is non-minimal at 2:: sage: E = EllipticCurve([0,0,0,-13711473216,0]) sage: P = E([-19992,16313472]) @@ -3886,6 +3887,12 @@ def minimal_quadratic_twist(self): database), or the one with minimal `a`-invariant list (otherwise). + .. note:: + + For curves with `j`-invariant 0 or 1728 the curve returned + is the minimal quadratic twist, not necessarily the minimal + twist (which would have conductor 27 or 32 respectively). + EXAMPLES:: sage: E = EllipticCurve('121d1') @@ -3909,20 +3916,35 @@ def minimal_quadratic_twist(self): sage: E.minimal_quadratic_twist() (Elliptic Curve defined by y^2 = x^3 + 4*x over Rational Field, 5) + If the curve has square-free conductor then it is already minimal (see :trac:`14060`):: + + sage: E = cremona_optimal_curves([2*3*5*7*11]).next() + sage: (E, 1) == E.minimal_quadratic_twist() + True + + An example where the minimal quadratic twist is not the + minimal twist (which has conductor 27):: + sage: E = EllipticCurve([0,0,0,0,7]) + sage: E.j_invariant() + 0 + sage: E.minimal_quadratic_twist()[0].conductor() + 5292 """ + if self.conductor().is_squarefree(): + return self, Integer(1) j = self.j_invariant() if j!=0 and j!=1728: # the constructor from j will give the minimal twist Et = constructor.EllipticCurve_from_j(j) else: - if j==0: + if j==0: # divide c6 by largest cube c = -2*self.c6() for p in c.support(): e = c.valuation(p)//3 c /= p**(3*e) E1 = constructor.EllipticCurve([0,0,0,0,c]) - elif j==1728: + elif j==1728: # divide c4 by largest square c = -3*self.c4() for p in c.support(): e = c.valuation(p)//2 @@ -3946,96 +3968,52 @@ def minimal_quadratic_twist(self): ########################################################## # Isogeny class ########################################################## - def isogeny_class(self, algorithm="sage", verbose=False, fill_matrix=True, return_maps=False, order=None, use_tuple=True): + def isogeny_class(self, algorithm="sage", order=None): r""" - Returns all curves over `\QQ` isogenous to this elliptic curve. + Returns the `\QQ`-isogeny class of this elliptic curve. INPUT: - ``algorithm`` - string: one of the following: - - "mwrank" - use the mwrank C++ library - - "database" - use the Cremona database (only works if curve is isomorphic to a curve in the database) - "sage" (default) - use the native Sage implementation. - - ``verbose`` -- bool (default: False): ignored unless - ``algorithm`` == "mwrank", in which case it is passed to the - isogeny class function in mwrank. - - - ``fill_matrix`` -- bool (default: True): See below. - - - ``return_maps`` -- bool (default: False): Ignored unless - ``algorithm`` == "sage"; then if True, also returns a list of - lists indexed by pairs of curves in the class such that the - `(i,j)` entry is the isogeny from curve `i` to curve `j` if - that isogeny has prime degree, else 0. - - ``order`` -- None, string, or list of curves (default: None): If not None then the curves in the class are reordered after being computed. Note that if the order is None then the resulting order will depend on the algorithm. - - if ``order`` is "mwrank", "database", or "sage" then the - reordering is so that the order of curves lines up with - the order produced by that algorithm. + - if ``order`` is "database" or "sage", then the reordering + is so that the order of curves matches the order produced + by that algorithm. - if ``order`` is "lmfdb" then the curves are sorted - lexicographically by a-invariants. + lexicographically by a-invariants, in the LMFDB database. - if ``order`` is a list of curves, then the curves in the class are reordered to be isomorphic with the specified list of curves. - - ``use_tuple`` -- bool (default: True). Controls the output - format: see below. ``use_tuple==True`` is deprecated. - OUTPUT: - If ``use_tuple`` is False, returns a - :class:`sage.schemes.elliptic_curves.isogeny_class.IsogenyClass_EC_Rational` - instance. This object models a list of minimal models (with - containment, index, etc based on isomorphism classes). It - also has methods for computing the isogeny matrix and the list - of isogenies between curves in this class. - - If ``use_tuple`` is True (deprecated), then returns a - tuple (isogeny class, matrix of integers) or (isogeny class, - matrix of integers, matrix of isogenies). The sorted list of - all curves isogenous to self is returned. If ``algorithm`` is - not "database", the isogeny matrix is also returned, otherwise - None is returned as the second return value. When fill_matrix - is True (default) the `(i,j)` entry of the matrix is a - positive integer giving the least degree of a cyclic isogeny - from curve `i` to curve `j` (in particular, the diagonal - entries are all `1`). When fill_matrix is False, the - non-prime entries are replaced by `0` (used in the - ``isogeny_graph()`` function). - - .. note:: - - The curves in the isogeny class are all standard minimal models. - - .. warning:: - - With ``algorithm`` "mwrank", the result is *not* - provably correct, in the sense that when the numbers are - huge isogenies could be missed because of precision - issues. Using ``algorithm`` "sage" avoids this problem, - though is slower. + An instance of the class + :class:`sage.schemes.elliptic_curves.isogeny_class.IsogenyClass_EC_Rational`. + This object models a list of minimal models (with containment, + index, etc based on isomorphism classes). It also has methods + for computing the isogeny matrix and the list of isogenies + between curves in this class. .. note:: - TO DO: when composition of isogenies is implemented, the - optional returned matrix of isogenies should be completed - to include all the isogenies, not just those of prime - degree. + The curves in the isogeny class will all be standard + minimal models. EXAMPLES:: - sage: isocls = EllipticCurve('37b').isogeny_class('mwrank',order="lmfdb",use_tuple=False) + sage: isocls = EllipticCurve('37b').isogeny_class(order="lmfdb") sage: isocls Elliptic curve isogeny class 37b sage: isocls.curves @@ -4049,7 +4027,7 @@ class are reordered to be isomorphic with the specified :: - sage: isocls = EllipticCurve('37b').isogeny_class('database', order="lmfdb", use_tuple=False); isocls.curves + sage: isocls = EllipticCurve('37b').isogeny_class('database', order="lmfdb"); isocls.curves (Elliptic Curve defined by y^2 + y = x^3 + x^2 - 1873*x - 31833 over Rational Field, Elliptic Curve defined by y^2 + y = x^3 + x^2 - 23*x - 50 over Rational Field, Elliptic Curve defined by y^2 + y = x^3 + x^2 - 3*x + 1 over Rational Field) @@ -4057,7 +4035,7 @@ class are reordered to be isomorphic with the specified This is an example of a curve with a `37`-isogeny:: sage: E = EllipticCurve([1,1,1,-8,6]) - sage: isocls = E.isogeny_class(use_tuple=False); isocls + sage: isocls = E.isogeny_class(); isocls Isogeny class of Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 8*x + 6 over Rational Field sage: isocls.matrix() [ 1 37] @@ -4069,7 +4047,7 @@ class are reordered to be isomorphic with the specified This curve had numerous `2`-isogenies:: sage: e=EllipticCurve([1,0,0,-39,90]) - sage: isocls = e.isogeny_class(use_tuple=False); isocls.matrix() + sage: isocls = e.isogeny_class(); isocls.matrix() [1 2 4 4 8 8] [2 1 2 2 4 4] [4 2 1 4 8 8] @@ -4083,24 +4061,19 @@ class are reordered to be isomorphic with the specified :: sage: E = EllipticCurve(j = -262537412640768000) - sage: isocls = E.isogeny_class(algorithm="sage", use_tuple=False); isocls.matrix() + sage: isocls = E.isogeny_class(); isocls.matrix() [ 1 163] [163 1] sage: print "\n".join([repr(C) for C in isocls.curves]) Elliptic Curve defined by y^2 + y = x^3 - 2174420*x + 1234136692 over Rational Field Elliptic Curve defined by y^2 + y = x^3 - 57772164980*x - 5344733777551611 over Rational Field - For large examples, the "mwrank" algorithm may fail to find - some isogenies since it works in fixed precision:: - - sage: E1 = E.quadratic_twist(6584935282) - sage: E1.isogeny_class(algorithm="mwrank", use_tuple=False).matrix() - [1] - Using algorithm="sage" gives another isogeny (even though - results are cached: the cache depends on the algorithm):: + The degrees of isogenies are invariant under twists:: - sage: isocls = E1.isogeny_class(algorithm="sage", use_tuple=False); isocls.matrix() + sage: E = EllipticCurve(j = -262537412640768000) + sage: E1 = E.quadratic_twist(6584935282) + sage: isocls = E1.isogeny_class(); isocls.matrix() [ 1 163] [163 1] sage: E1.conductor() @@ -4109,7 +4082,7 @@ class are reordered to be isomorphic with the specified :: sage: E = EllipticCurve('14a1') - sage: isocls = E.isogeny_class(algorithm="sage", use_tuple=False); isocls.matrix() + sage: isocls = E.isogeny_class(); isocls.matrix() [ 1 2 3 3 6 6] [ 2 1 6 6 3 3] [ 3 6 1 9 2 18] @@ -4141,7 +4114,7 @@ class are reordered to be isomorphic with the specified :: sage: E = EllipticCurve('11a1') - sage: isocls = E.isogeny_class(algorithm="sage", use_tuple=False); isocls.matrix() + sage: isocls = E.isogeny_class(); isocls.matrix() [ 1 5 5] [ 5 1 25] [ 5 25 1] @@ -4158,23 +4131,14 @@ class are reordered to be isomorphic with the specified label = self.__cremona_label[:-1] else: label = None - isoclass = IsogenyClass_EC_Rational(self, algorithm, verbose, label) + + isoclass = IsogenyClass_EC_Rational(self, algorithm, label) self._isoclass[algorithm] = isoclass + if order: isoclass = isoclass.reorder(order) - if use_tuple: - from sage.misc.superseded import deprecation - deprecation(12768, """For elliptic curves E over Q, isogeny_class(use_tuple=False) returns a class -that has methods producing the isogeny graph and list of lists of isogenies. -use_tuple=True (currently default) is deprecated.""") - # After a year or so (in May 2013) we should switch the default to use_tuple=False as the default and deprecate - # the keyword argument - if return_maps: - return isoclass, isoclass.matrix(fill_matrix), isoclass.isogenies() - else: - return isoclass, isoclass.matrix(fill_matrix) - else: - return isoclass + + return isoclass def isogenies_prime_degree(self, l=None): r""" @@ -4328,7 +4292,7 @@ def is_isogenous(self, other, proof=True, maxp=200): if not proof: return True else: - return E2 in E1.isogeny_class(use_tuple=False).curves + return E2 in E1.isogeny_class().curves def isogeny_degree(self, other): """ @@ -4439,7 +4403,7 @@ def isogeny_degree(self, other): if not E1.is_isogenous(E2, proof=False): return Integer(0) - isocls = E1.isogeny_class(use_tuple=False) + isocls = E1.isogeny_class() try: return isocls.matrix(fill=True)[0,isocls.index(E2)] except ValueError: @@ -4552,7 +4516,7 @@ def isogeny_graph(self, order=None): 8 Elliptic Curve defined by y^2 + x*y = x^3 - 130000*x - 18051943 over Rational Field sage: G.plot(edge_labels=True) """ - return self.isogeny_class(algorithm='mwrank', order=order, use_tuple=False).graph() + return self.isogeny_class(order=order).graph() def manin_constant(self): r""" @@ -4600,7 +4564,7 @@ def manin_constant(self): E = self.minimal_model() C = self.optimal_curve() - m = C.isogeny_class(use_tuple=False).matrix() + m = C.isogeny_class().matrix() ma = max(max(x) for x in m) OmC = C.period_lattice().basis() OmE = E.period_lattice().basis() @@ -4639,12 +4603,6 @@ def _shortest_paths(self): curves and corresponding dictionary of shortest isogeny paths from self to each other curve in the isogeny class. - .. warning:: - - The result is *not* provably correct, in the - sense that when the numbers are huge isogenies could be - missed because of precision issues. - OUTPUT: list, dict @@ -4653,8 +4611,8 @@ def _shortest_paths(self): sage: EllipticCurve('11a1')._shortest_paths() ((Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field, - Elliptic Curve defined by y^2 + y = x^3 - x^2 - 7820*x - 263580 over Rational Field, - Elliptic Curve defined by y^2 + y = x^3 - x^2 over Rational Field), + Elliptic Curve defined by y^2 + y = x^3 - x^2 over Rational Field, + Elliptic Curve defined by y^2 + y = x^3 - x^2 - 7820*x - 263580 over Rational Field), {0: 0, 1: 5, 2: 5}) sage: EllipticCurve('11a2')._shortest_paths() ((Elliptic Curve defined by y^2 + y = x^3 - x^2 - 7820*x - 263580 over Rational Field, @@ -4663,7 +4621,7 @@ def _shortest_paths(self): {0: 0, 1: 5, 2: 25}) """ from sage.graphs.graph import Graph - isocls = self.isogeny_class(algorithm='mwrank',use_tuple=False) + isocls = self.isogeny_class() M = isocls.matrix(fill=True).change_ring(rings.RR) # see trac #4889 for nebulous M.list() --> M.entries() change... # Take logs here since shortest path minimizes the *sum* of the weights -- not the product. diff --git a/src/sage/schemes/elliptic_curves/ell_tate_curve.py b/src/sage/schemes/elliptic_curves/ell_tate_curve.py index e6dcef6a3a0..25274c14cbc 100644 --- a/src/sage/schemes/elliptic_curves/ell_tate_curve.py +++ b/src/sage/schemes/elliptic_curves/ell_tate_curve.py @@ -498,7 +498,7 @@ def lift(self,P, prec = 20): yy = t + s * C**2 * P[0] + C**3 * P[1] try: Pq = Eq([xx,yy]) - except StandardError: + except Exception: raise RuntimeError, "Bug : Point %s does not lie on the curve "%[xx,yy] tt = -xx/yy diff --git a/src/sage/schemes/elliptic_curves/gal_reps.py b/src/sage/schemes/elliptic_curves/gal_reps.py index 9f244f967d0..b24d372cd5a 100644 --- a/src/sage/schemes/elliptic_curves/gal_reps.py +++ b/src/sage/schemes/elliptic_curves/gal_reps.py @@ -311,7 +311,7 @@ def is_reducible(self, p): if t: self.__is_reducible[p] = False return False # definitely not reducible - isogeny_matrix = self._E.isogeny_class(use_tuple=False).matrix(fill=True) + isogeny_matrix = self._E.isogeny_class().matrix(fill=True) v = isogeny_matrix.row(0) # first row for a in v: if a != 0 and a % p == 0: @@ -362,7 +362,7 @@ def reducible_primes(self): return self.__reducible_primes except AttributeError: pass - isocls = self._E.isogeny_class(algorithm='sage', use_tuple=False) + isocls = self._E.isogeny_class() X = set(isocls.matrix().list()) R = [p for p in X if arith.is_prime(p)] self.__reducible_primes = R @@ -1081,7 +1081,7 @@ def image_type(self, p): misc.verbose("field of degree %s. try to compute galois group"%(d),2) try: G = K.galois_group() - except StandardError: + except Exception: self.__image_type[p] = "The image is a group of order %s."%d return self.__image_type[p] diff --git a/src/sage/schemes/elliptic_curves/isogeny_class.py b/src/sage/schemes/elliptic_curves/isogeny_class.py index 9dda30d9497..5b259be713b 100644 --- a/src/sage/schemes/elliptic_curves/isogeny_class.py +++ b/src/sage/schemes/elliptic_curves/isogeny_class.py @@ -36,8 +36,8 @@ class IsogenyClass_EC(SageObject): Isogeny class of an elliptic curve. The current implementation chooses a curve from each isomorphism - class in the isogeny class, since over Q there is a unique reduced - minimal model in each isomorphism class. + class in the isogeny class, since over `\QQ` there is a unique + reduced minimal model in each isomorphism class. EXAMPLES:: @@ -45,7 +45,7 @@ class in the isogeny class, since over Q there is a unique reduced """ def __init__(self, E, label=None, empty=False): """ - Over Q we use curves since minimal models exist and there is a canonical choice of one. + Over `\QQ` we use curves since minimal models exist and there is a canonical choice of one. INPUT: @@ -54,7 +54,7 @@ def __init__(self, E, label=None, empty=False): EXAMPLES:: - sage: cls = EllipticCurve('1011b1').isogeny_class(use_tuple=False) + sage: cls = EllipticCurve('1011b1').isogeny_class() sage: print "\n".join([repr(E) for E in cls.curves]) Elliptic Curve defined by y^2 + x*y = x^3 - 8*x - 9 over Rational Field Elliptic Curve defined by y^2 + x*y = x^3 - 23*x + 30 over Rational Field @@ -71,7 +71,7 @@ def __len__(self): EXAMPLES:: sage: E = EllipticCurve('15a') - sage: len(E.isogeny_class(use_tuple=False)) # indirect doctest + sage: len(E.isogeny_class()) # indirect doctest 8 """ return len(self.curves) @@ -83,7 +83,7 @@ def __iter__(self): EXAMPLES:: sage: E = EllipticCurve('15a') - sage: all(C.conductor() == 15 for C in E.isogeny_class(use_tuple=False)) # indirect doctest + sage: all(C.conductor() == 15 for C in E.isogeny_class()) # indirect doctest True """ return iter(self.curves) @@ -95,7 +95,7 @@ def __getitem__(self, i): EXAMPLES:: sage: E = EllipticCurve('990j1') - sage: iso = E.isogeny_class(order="lmfdb",use_tuple=False) # orders lexicographically on a-invariants + sage: iso = E.isogeny_class(order="lmfdb") # orders lexicographically on a-invariants sage: iso[2] == E # indirect doctest True """ @@ -117,7 +117,7 @@ def index(self, C): EXAMPLES:: sage: E = EllipticCurve('990j1') - sage: iso = E.isogeny_class(order="lmfdb", use_tuple=False) # orders lexicographically on a-invariants + sage: iso = E.isogeny_class(order="lmfdb") # orders lexicographically on a-invariants sage: iso.index(E.short_weierstrass_model()) 2 """ @@ -141,7 +141,7 @@ def __cmp__(self, other): sage: E = EllipticCurve('990j1') sage: EE = EllipticCurve('990j4') - sage: E.isogeny_class(use_tuple=False) == EE.isogeny_class(use_tuple=False) # indirect doctest + sage: E.isogeny_class() == EE.isogeny_class() # indirect doctest True """ # This will need updating once we start talking about curves over more general number fields @@ -157,7 +157,7 @@ def __hash__(self): EXAMPLES:: sage: E = EllipticCurve('990j1') - sage: C = E.isogeny_class(use_tuple=False) + sage: C = E.isogeny_class() sage: hash(C) == hash(tuple(sorted([curve.a_invariants() for curve in C.curves]))) # indirect doctest True """ @@ -179,21 +179,21 @@ def _repr_(self): label is used:: sage: E = EllipticCurve('462.f3') - sage: E.isogeny_class(use_tuple=False) # indirect doctest + sage: E.isogeny_class() # indirect doctest Elliptic curve isogeny class 462.f If the curve is constructed from a Cremona label then that label is used:: sage: E = EllipticCurve('990j1') - sage: E.isogeny_class(use_tuple=False) + sage: E.isogeny_class() Elliptic curve isogeny class 990j Otherwise the representation is determined from the first curve in the class:: sage: E = EllipticCurve([1,2,3,4,5]) - sage: E.isogeny_class(use_tuple=False) + sage: E.isogeny_class() Isogeny class of Elliptic Curve defined by y^2 + x*y = x^3 - x^2 + 4*x + 3 over Rational Field """ if self._label: @@ -213,7 +213,7 @@ def __contains__(self, x): EXAMPLES:: - sage: cls = EllipticCurve('15a3').isogeny_class(use_tuple=False) + sage: cls = EllipticCurve('15a3').isogeny_class() sage: E = EllipticCurve('15a7'); E in cls True sage: E.short_weierstrass_model() in cls @@ -237,7 +237,7 @@ def matrix(self, fill=True): EXAMPLES:: - sage: isocls = EllipticCurve('15a3').isogeny_class(use_tuple=False) + sage: isocls = EllipticCurve('15a3').isogeny_class() sage: isocls.matrix() [ 1 2 2 2 4 4 8 8] [ 2 1 4 4 8 8 16 16] @@ -294,7 +294,7 @@ def isogenies(self, fill=False): EXAMPLES:: - sage: isocls = EllipticCurve('15a3').isogeny_class(use_tuple=False) + sage: isocls = EllipticCurve('15a3').isogeny_class() sage: f = isocls.isogenies()[0][1]; f Isogeny of degree 2 from Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 5*x + 2 over Rational Field to Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 80*x + 242 over Rational Field sage: f.domain() == isocls.curves[0] and f.codomain() == isocls.curves[1] @@ -316,7 +316,7 @@ def graph(self): .. note: There are only finitely many possible isogeny graphs for - curves over Q [M78]. This function tries to lay out the graph + curves over `\QQ` [M78]. This function tries to lay out the graph nicely by special casing each isogeny graph. .. note: @@ -326,7 +326,7 @@ def graph(self): EXAMPLES:: - sage: isocls = EllipticCurve('15a3').isogeny_class(use_tuple=False) + sage: isocls = EllipticCurve('15a3').isogeny_class() sage: G = isocls.graph() sage: sorted(G._pos.items()) [(1, [-0.8660254, 0.5]), (2, [-0.8660254, 1.5]), (3, [-1.7320508, 0]), (4, [0, 0]), (5, [0, -1]), (6, [0.8660254, 0.5]), (7, [0.8660254, 1.5]), (8, [1.7320508, 0])] @@ -429,7 +429,7 @@ def reorder(self, order): EXAMPLES:: - sage: isocls = EllipticCurve('15a1').isogeny_class(use_tuple=False) + sage: isocls = EllipticCurve('15a1').isogeny_class() sage: print "\n".join([repr(C) for C in isocls.curves]) Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 10*x - 10 over Rational Field Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 5*x + 2 over Rational Field @@ -456,7 +456,7 @@ def reorder(self, order): if order == "lmfdb": reordered_curves = sorted(self.curves, key = lambda E: E.a_invariants()) else: - reordered_curves = list(self.E.isogeny_class(algorithm=order, use_tuple=False)) + reordered_curves = list(self.E.isogeny_class(algorithm=order)) elif isinstance(order, (list, tuple, IsogenyClass_EC)): reordered_curves = list(order) if len(reordered_curves) != len(self.curves): @@ -499,12 +499,9 @@ def _compute(self): in ``self.curves``, and possibly ``self._mat`` and ``self._maps`` as well, depending on the algorithm. - EXAMPLES:: + .. note: - sage: EllipticCurve('11a1').isogeny_class('mwrank',use_tuple=False).matrix() # indirect doctest - [ 1 5 5] - [ 5 1 25] - [ 5 25 1] + This is currently redundant; it used to be required when mwrank was used. """ pass @@ -516,7 +513,7 @@ def _compute_matrix(self): EXAMPLES:: - sage: EllipticCurve('11a1').isogeny_class('database',use_tuple=False).matrix() # indirect doctest + sage: EllipticCurve('11a1').isogeny_class('database').matrix() # indirect doctest [ 1 5 5] [ 5 1 25] [ 5 25 1] @@ -529,19 +526,17 @@ def _compute_isogenies(self): For algorithms that don't compute the isogenies at first, this function should fill in ``self._maps``. - EXAMPLES:: + .. note: - sage: f = EllipticCurve('11a1').isogeny_class('mwrank',use_tuple=False).isogenies()[0][1] # indirect doctest - sage: f.domain() - Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field + This is currently redundant; it used to be required when mwrank was used. """ pass class IsogenyClass_EC_Rational(IsogenyClass_EC): """ - Isogeny classes for elliptic curves over Q. + Isogeny classes for elliptic curves over `\QQ`. """ - def __init__(self, E, algorithm="sage", verbose=False, label=None, empty=False): + def __init__(self, E, algorithm="sage", label=None, empty=False): """ INPUT: @@ -553,15 +548,9 @@ def __init__(self, E, algorithm="sage", verbose=False, label=None, empty=False): - "sage" -- Use sage's implementation to compute the curves, matrix and isogenies - - "mwrank" -- Use the mwrank C++ library - - "database" -- Use the Cremona database (only works if the curve is in the database) - - ``verbose`` -- boolean (default False). Only relevant for - algorithm="mwrank", controls verbosity of output while - running mwrank. - - ``label`` -- a string, the label of this isogeny class (e.g. '15a' or '37.b'). Used in printing. @@ -569,17 +558,16 @@ def __init__(self, E, algorithm="sage", verbose=False, label=None, empty=False): EXAMPLES:: - sage: isocls = EllipticCurve('389a1').isogeny_class(use_tuple=False); isocls + sage: isocls = EllipticCurve('389a1').isogeny_class(); isocls Elliptic curve isogeny class 389a sage: E = EllipticCurve([0, 0, 0, 0, 1001]) # conductor 108216108 - sage: E.isogeny_class(use_tuple=False, order='database') + sage: E.isogeny_class(order='database') Traceback (most recent call last): ... RuntimeError: unable to to find Elliptic Curve defined by y^2 = x^3 + 1001 over Rational Field in the database sage: TestSuite(isocls).run() """ self._algorithm = algorithm - self._verbose = verbose IsogenyClass_EC.__init__(self, E, label=label, empty=empty) def copy(self): @@ -588,14 +576,14 @@ def copy(self): EXAMPLES:: - sage: isocls = EllipticCurve('389a1').isogeny_class(use_tuple=False) + sage: isocls = EllipticCurve('389a1').isogeny_class() sage: isocls2 = isocls.copy() sage: isocls is isocls2 False sage: isocls == isocls2 True """ - ans = IsogenyClass_EC_Rational(self.E, self._algorithm, self._verbose, self._label, empty=True) + ans = IsogenyClass_EC_Rational(self.E, self._algorithm, self._label, empty=True) # The following isn't needed internally, but it will keep # things from breaking if this is used for something other # than reordering. @@ -611,7 +599,7 @@ def _compute(self): EXAMPLES:: - sage: isocls = EllipticCurve('48a1').isogeny_class('sage',use_tuple=False).copy() + sage: isocls = EllipticCurve('48a1').isogeny_class('sage').copy() sage: isocls._mat sage: isocls._compute(); isocls._mat [0 2 2 2 0 0] @@ -625,15 +613,7 @@ def _compute(self): from sage.schemes.elliptic_curves.ell_curve_isogeny import fill_isogeny_matrix, unfill_isogeny_matrix from sage.matrix.all import MatrixSpace self._maps = None - if algorithm == "mwrank": - try: - E = self.E.mwrank_curve() - except ValueError: - E = self.E.minimal_model().mwrank_curve() - I, A = E.isogeny_class(verbose=self._verbose) - self._mat = MatrixSpace(ZZ, len(A))(A) - self.curves = tuple([constructor.EllipticCurve(ainvs) for ainvs in I]) - elif algorithm == "database": + if algorithm == "database": try: label = self.E.cremona_label(space=False) except RuntimeError: @@ -686,29 +666,26 @@ def _compute_matrix(self): EXAMPLES:: - sage: isocls = EllipticCurve('1225h1').isogeny_class('database',use_tuple=False) + sage: isocls = EllipticCurve('1225h1').isogeny_class('database') sage: isocls._mat sage: isocls._compute_matrix(); isocls._mat [ 0 37] [37 0] """ - try: - self._mat = self.E.isogeny_class(algorithm="mwrank",order=self.curves,use_tuple=False)._mat - except ValueError: # incorrect length because mwrank didn't have enough precision - self._mat = self.E.isogeny_class(algorithm="sage",order=self.curves,use_tuple=False)._mat + self._mat = self.E.isogeny_class(order=self.curves)._mat def _compute_isogenies(self): """ EXAMPLES:: sage: E = EllipticCurve('15a1') - sage: isocls = E.isogeny_class(algorithm='mwrank',use_tuple=False) + sage: isocls = E.isogeny_class() sage: maps = isocls.isogenies() # indirect doctest sage: f = maps[0][1] sage: f.domain() == isocls[0] and f.codomain() == isocls[1] True """ - recomputed = self.E.isogeny_class(algorithm="sage",order=self.curves,use_tuple=False) + recomputed = self.E.isogeny_class(order=self.curves) self._mat = recomputed._mat # The domains and codomains here will be equal, but not the same Python object. self._maps = recomputed._maps diff --git a/src/sage/schemes/elliptic_curves/lseries_ell.py b/src/sage/schemes/elliptic_curves/lseries_ell.py index c32e2893d7e..1f4905d3389 100644 --- a/src/sage/schemes/elliptic_curves/lseries_ell.py +++ b/src/sage/schemes/elliptic_curves/lseries_ell.py @@ -241,11 +241,9 @@ def zeros(self, n): sage: E = EllipticCurve('37a') sage: E.lseries().zeros(2) - *** Warning:...new stack size = ... [0.000000000, 5.00317001] sage: a = E.lseries().zeros(20) # long time - *** Warning:...new stack size = ... sage: point([(1,x) for x in a]) # graph (long time) AUTHOR: @@ -276,7 +274,6 @@ def zeros_in_interval(self, x, y, stepsize): sage: E = EllipticCurve('37a') sage: E.lseries().zeros_in_interval(6, 10, 0.1) # long time - *** Warning:...new stack size = ... [(6.87039122, 0.248922780), (8.01433081, -0.140168533), (9.93309835, -0.129943029)] """ from sage.lfunctions.lcalc import lcalc @@ -304,7 +301,6 @@ def values_along_line(self, s0, s1, number_samples): sage: E = EllipticCurve('37a') sage: E.lseries().values_along_line(1, 0.5 + 20*I, 5) - *** Warning:...new stack size = ... [(0.500000000, ...), (0.400000000 + 4.00000000*I, 3.31920245 - 2.60028054*I), (0.300000000 + 8.00000000*I, -0.886341185 - 0.422640337*I), @@ -339,7 +335,6 @@ def twist_values(self, s, dmin, dmax): sage: E = EllipticCurve('37a') sage: vals = E.lseries().twist_values(1, -12, -4) - *** Warning:...new stack size = ... sage: vals # abs tol 1e-17 [(-11, 1.47824342), (-8, 8.9590946e-18), (-7, 1.85307619), (-4, 2.45138938)] sage: F = E.quadratic_twist(-8) @@ -374,7 +369,6 @@ def twist_zeros(self, n, dmin, dmax): sage: E = EllipticCurve('37a') sage: E.lseries().twist_zeros(3, -4, -3) # long time - *** Warning:...new stack size = ... {-4: [1.60813783, 2.96144840, 3.89751747], -3: [2.06170900, 3.48216881, 4.45853219]} """ from sage.lfunctions.lcalc import lcalc diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index ebbde74ed4a..5ab5cdcab61 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -514,7 +514,7 @@ def _linear_system_as_kernel(self, d, pt, m): raise TypeError('Unable to find a common ring for all elements') try: i = pt.index(1) - except StandardError: + except Exception: raise TypeError('At least one component of pt=%s must be equal ' 'to 1'%pt) pt = pt[:i] + pt[i+1:] diff --git a/src/sage/server/support.py b/src/sage/server/support.py index fccc5d4360e..8a53a7d62a7 100644 --- a/src/sage/server/support.py +++ b/src/sage/server/support.py @@ -272,7 +272,7 @@ def source_code(s, globs, system='sage'): try: try: return obj._sage_src_() - except StandardError: + except Exception: pass newline = "\n\n" # blank line to start new paragraph indent = " " # indent source code to mark it as a code block diff --git a/src/sage/sets/family.py b/src/sage/sets/family.py index ee47f9cc514..2bae01e3672 100644 --- a/src/sage/sets/family.py +++ b/src/sage/sets/family.py @@ -15,7 +15,7 @@ TESTS: -Check for workaround #12482 (shall be run in a fresh session):: +Check for workaround :trac:`12482` (shall be run in a fresh session):: sage: P = Partitions(3) sage: Family(P, lambda x: x).category() # used to return ``enumerated sets`` @@ -40,14 +40,12 @@ from sage.misc.lazy_import import lazy_import from sage.rings.integer import Integer from sage.misc.misc import AttrCallObject -from warnings import warn -name_warn_message = "The keyword name for family has never been used and will be removed shortly. Please update your code." -def Family(indices, function = None, hidden_keys = [], hidden_function = None, lazy = False, name=None): +def Family(indices, function=None, hidden_keys=[], hidden_function=None, lazy=False, name=None): r""" A Family is an associative container which models a family - `(f_i)_{i \in I}`. Then, f[i] returns the element of the family - indexed by i. Whenever available, set and combinatorial class + `(f_i)_{i \in I}`. Then, ``f[i]`` returns the element of the family + indexed by `i`. Whenever available, set and combinatorial class operations (counting, iteration, listing) on the family are induced from those of the index set. @@ -55,11 +53,26 @@ def Family(indices, function = None, hidden_keys = [], hidden_function = None, l usages; Family serves as a factory, and will create instances of the appropriate classes depending on its arguments. + INPUT: + + - ``indices`` -- the indices for the family + - ``function`` -- (optional) the function `f` applied to all visible + indices; the default is the identity function + - ``hidden_keys`` -- (optional) a list of hidden indices that can be + accessed through ``my_family[i]`` + - ``hidden_function`` -- (optional) a function for the hidden indices + - ``lazy`` -- boolean (default: ``False``); whether the family is lazily + created or not; if the indices are infinite, then this is automatically + made ``True`` + - ``name`` -- (optional) the name of the function; only used when the + family is lazily created via a function + EXAMPLES: - In its simplest form, a list l or a tuple by itself is considered as the - family `(l[i]_{i \in I})` where `I` is the range `0\dots,len(l)`. So - Family(l) returns the corresponding family:: + In its simplest form, a list `l = [l_0, l_1, \ldots, l_{\ell}]` or a + tuple by itself is considered as the family `(l_i)_{i \in I}` where + `I` is the set `\{0, \ldots, \ell\}` where `\ell` is ``len(l) - 1``. + So ``Family(l)`` returns the corresponding family:: sage: f = Family([1,2,3]) sage: f @@ -74,10 +87,10 @@ def Family(indices, function = None, hidden_keys = [], hidden_function = None, l sage: f Family (3, 5, 7) - A family can also be constructed from a dictionary t. The resulting - family is very close to t, except that the elements of the family - are the values of t. Here, we define the family `(f_i)_{i \in \{3,4,7\}}` - with f_3='a', f_4='b', and f_7='d':: + A family can also be constructed from a dictionary ``t``. The resulting + family is very close to ``t``, except that the elements of the family + are the values of ``t``. Here, we define the family + `(f_i)_{i \in \{3,4,7\}}` with `f_3 = a`, `f_4 = b`, and `f_7 = d`:: sage: f = Family({3: 'a', 4: 'b', 7: 'd'}) sage: f @@ -181,7 +194,7 @@ def Family(indices, function = None, hidden_keys = [], hidden_function = None, l sage: f == loads(dumps(f)) True - But this one don't:: + But this one does not:: sage: def plus_n(n): return lambda x: x+n sage: f = Family([1,2,3], plus_n(3), lazy=True); f @@ -192,7 +205,7 @@ def Family(indices, function = None, hidden_keys = [], hidden_function = None, l ValueError: Cannot pickle code objects from closures Finally, it can occasionally be useful to add some hidden elements - in a family, which are accessible as f[i], but do not appear in the + in a family, which are accessible as ``f[i]``, but do not appear in the keys or the container operations:: sage: f = Family([3,4,7], lambda i: 2*i, hidden_keys=[2]) @@ -342,19 +355,27 @@ def Family(indices, function = None, hidden_keys = [], hidden_function = None, l sage: f = Family(["c", "a", "b"], lambda x: x+x) sage: list(f) ['cc', 'aa', 'bb'] - """ - if name is not None: - warn(name_warn_message) + TESTS: + + Only the hidden function is applied to the hidden keys:: + + sage: f = lambda x : 2*x + sage: h_f = lambda x:x%2 + sage: F = Family([1,2,3,4],function = f, hidden_keys=[5],hidden_function=h_f) + sage: F[5] + 1 + """ assert(type(hidden_keys) == list) assert(isinstance(lazy, bool)) if hidden_keys == []: if hidden_function is not None: - raise ValueError, "hidden_function keyword only makes sense together with hidden_keys keyword !" - elif function is None: + raise ValueError("hidden_function keyword only makes sense " + "together with hidden_keys keyword !") + if function is None: if lazy: - raise ValueError, "lazy keyword only makes sense together with function keyword !" + raise ValueError("lazy keyword only makes sense together with function keyword !") if isinstance(indices, dict): return FiniteFamily(indices) if isinstance(indices, (list, tuple) ): @@ -367,27 +388,26 @@ def Family(indices, function = None, hidden_keys = [], hidden_function = None, l return EnumeratedFamily(indices) if hasattr(indices, "__iter__"): return TrivialFamily(indices) - elif ( isinstance(indices, (list, tuple, FiniteEnumeratedSet) ) + + raise NotImplementedError + if (isinstance(indices, (list, tuple, FiniteEnumeratedSet) ) and not lazy): return FiniteFamily(dict([(i, function(i)) for i in indices]), keys = indices) - else: - return LazyFamily(indices, function) - else: - if lazy: - raise ValueError, "lazy keyword is incompatible with hidden keys !" - if hidden_function is None: - hidden_function = function - return FiniteFamilyWithHiddenKeys(dict([(i, function(i)) for i in indices]), - hidden_keys, hidden_function) - raise NotImplementedError + return LazyFamily(indices, function, name) + if lazy: + raise ValueError("lazy keyword is incompatible with hidden keys !") + if hidden_function is None: + hidden_function = function + return FiniteFamilyWithHiddenKeys(dict([(i, function(i)) for i in indices]), + hidden_keys, hidden_function) class AbstractFamily(Parent): """ The abstract class for family - Any family belongs to a class which inherits from ``AbstractFamily``. + Any family belongs to a class which inherits from :class:`AbstractFamily`. """ def hidden_keys(self): """ @@ -401,13 +421,13 @@ def hidden_keys(self): """ return [] - def zip(self, f, other, name = None): + def zip(self, f, other, name=None): """ Given two families with same index set `I` (and same hidden keys if relevant), returns the family `( f(self[i], other[i]) )_{i \in I}` - TODO: generalize to any number of families and merge with map? + .. TODO:: generalize to any number of families and merge with map? EXAMPLES:: @@ -419,16 +439,14 @@ def zip(self, f, other, name = None): """ assert(self.keys() == other.keys()) assert(self.hidden_keys() == other.hidden_keys()) - if name is not None: - warn(name_warn_message) - return Family(self.keys(), lambda i: f(self[i],other[i]), hidden_keys = self.hidden_keys()) + return Family(self.keys(), lambda i: f(self[i],other[i]), hidden_keys=self.hidden_keys(), name=name) - def map(self, f, name = None): + def map(self, f, name=None): """ Returns the family `( f(\mathtt{self}[i]) )_{i \in I}`, where `I` is the index set of self. - TODO: good name? + .. TODO:: good name? EXAMPLES:: @@ -437,9 +455,7 @@ def map(self, f, name = None): sage: list(g) ['a1', 'b1', 'd1'] """ - if name is not None: - warn(name_warn_message) - return Family(self.keys(), lambda i: f(self[i]), hidden_keys = self.hidden_keys()) + return Family(self.keys(), lambda i: f(self[i]), hidden_keys=self.hidden_keys(), name=name) # temporary; tested by TestSuite. _an_element_ = EnumeratedSets.ParentMethods._an_element_ @@ -453,7 +469,7 @@ def inverse_family(self): This default implementation is not lazy and therefore will only work with not too big finite families. It is also cached - for the same reason. + for the same reason:: sage: Family({3: 'a', 4: 'b', 7: 'd'}).inverse_family() Finite family {'a': 3, 'b': 4, 'd': 7} @@ -466,13 +482,15 @@ def inverse_family(self): class FiniteFamily(AbstractFamily): r""" - A FiniteFamily is an associative container which models a finite - family `(f_i)_{i \in I}`. Its elements `f_i` are therefore - its values. Instances should be created via the Family factory, - which see for further examples and tests. + A :class:`FiniteFamily` is an associative container which models a finite + family `(f_i)_{i \in I}`. Its elements `f_i` are therefore its + values. Instances should be created via the :func:`Family` factory. See its + documentation for examples and tests. + + EXAMPLES: - EXAMPLES: We define the family `(f_i)_{i \in \{3,4,7\}}` with f_3=a, - f_4=b, and f_7=d:: + We define the family `(f_i)_{i \in \{3,4,7\}}` with `f_3=a`, + `f_4=b`, and `f_7=d`:: sage: from sage.sets.family import FiniteFamily sage: f = FiniteFamily({3: 'a', 4: 'b', 7: 'd'}) @@ -697,13 +715,13 @@ def __setstate__(self, state): class FiniteFamilyWithHiddenKeys(FiniteFamily): r""" - A close variant of FiniteFamily where the family contains some + A close variant of :class:`FiniteFamily` where the family contains some hidden keys whose corresponding values are computed lazily (and - remembered). Instances should be created via the Family factory, - which see for examples and tests. + remembered). Instances should be created via the :func:`Family` factory. + See its documentation for examples and tests. Caveat: Only instances of this class whose functions are compatible - with sage.misc.fpickle can be pickled. + with :mod:`sage.misc.fpickle` can be pickled. """ def __init__(self, dictionary, hidden_keys, hidden_function): """ @@ -800,8 +818,8 @@ class LazyFamily(AbstractFamily): A LazyFamily(I, f) is an associative container which models the (possibly infinite) family `(f(i))_{i \in I}`. - Instances should be created via the Family factory, which see for - examples and tests. + Instances should be created via the :func:`Family` factory. See its + documentation for examples and tests. """ def __init__(self, set, function, name=None): """ @@ -834,12 +852,10 @@ def __init__(self, set, function, name=None): category = EnumeratedSets() Parent.__init__(self, category = category) - if name is not None: - warn(name_warn_message) from copy import copy self.set = copy(set) self.function = function - + self.function_name = name def __eq__(self, other): """ @@ -868,7 +884,7 @@ def _repr_(self): sage: from sage.sets.family import LazyFamily sage: def fun(i): 2*i - sage: f = LazyFamily([3,4,7], fun); f # indirect doctest + sage: f = LazyFamily([3,4,7], fun); f Lazy family (fun(i))_{i in [3, 4, 7]} sage: f = Family(Permutations(3), attrcall("to_lehmer_code"), lazy=True); f @@ -877,14 +893,19 @@ def _repr_(self): sage: f = LazyFamily([3,4,7], lambda i: 2*i); f Lazy family ((i))_{i in [3, 4, 7]} + sage: f = LazyFamily([3,4,7], lambda i: 2*i, name='foo'); f + Lazy family (foo(i))_{i in [3, 4, 7]} + TESTS: Check that a using a class as the function is correctly handled:: - sage: Family(NonNegativeIntegers(), PerfectMatchings) - Lazy family ((i))_{i in Non negative integers} + sage: Family(NonNegativeIntegers(), PerfectMatchings) + Lazy family ((i))_{i in Non negative integers} """ - if isinstance(self.function, type(lambda x:1)): + if self.function_name is not None: + name = self.function_name + "(i)" + elif isinstance(self.function, type(lambda x:1)): name = self.function.__name__ name = name+"(i)" else: @@ -893,7 +914,7 @@ def _repr_(self): name = "i"+name[1:] else: name = name+"(i)" - return "Lazy family (%s)_{i in %s}"%(name,self.set) + return "Lazy family ({})_{{i in {}}}".format(name, self.set) def keys(self): """ @@ -1020,12 +1041,11 @@ def __setstate__(self, d): class TrivialFamily(AbstractFamily): r""" - ``TrivialFamily(c)`` turn the container c into a family indexed by - the set `{0, \dots, len(c)}`. The container `c` can be either a list or a - tuple. + :class:`TrivialFamily` turns a list/tuple `c` into a family indexed by the + set `\{0, \dots, |c|-1\}`. - Instances should be created via the Family factory, which see for - examples and tests. + Instances should be created via the :func:`Family` factory. See its + documentation for examples and tests. """ def __init__(self, enumeration): """ @@ -1154,11 +1174,11 @@ def __setstate__(self, state): class EnumeratedFamily(LazyFamily): r""" - ``EnumeratedFamily(c)`` turn the enumerated set c into a family indexed by - the set `{0,\dots, c.cardinality()}`. + :class:`EnumeratedFamily` turns an enumerated set ``c`` into a family + indexed by the set `\{0,\dots, |c|-1\}`. - Instances should be created via the Family factory, which see for - examples and tests. + Instances should be created via the :func:`Family` factory. See its + documentation for examples and tests. """ def __init__(self, enumset): """ diff --git a/src/sage/sets/totally_ordered_finite_set.py b/src/sage/sets/totally_ordered_finite_set.py index 48cccd53e0a..215edeff6d8 100644 --- a/src/sage/sets/totally_ordered_finite_set.py +++ b/src/sage/sets/totally_ordered_finite_set.py @@ -345,6 +345,6 @@ def le(self, x, y): """ try: return self._elements.index(x) <= self._elements.index(y) - except StandardError: + except Exception: raise ValueError("arguments must be elements of the set") diff --git a/src/sage/structure/category_object.pyx b/src/sage/structure/category_object.pyx index b643034f82a..4764a93499a 100644 --- a/src/sage/structure/category_object.pyx +++ b/src/sage/structure/category_object.pyx @@ -72,7 +72,7 @@ def guess_category(obj): return Algebras(obj._base) else: return Rings() - except StandardError: + except Exception: pass from sage.structure.parent import Parent #if isinstance(obj, Parent): diff --git a/src/sage/structure/coerce.pyx b/src/sage/structure/coerce.pyx index 93a41ed3b1b..5588cc51fec 100644 --- a/src/sage/structure/coerce.pyx +++ b/src/sage/structure/coerce.pyx @@ -679,7 +679,7 @@ cdef class CoercionModel_cache_maps(CoercionModel): pass try: ret = parent_c(~parent.one_element()) - except StandardError: + except Exception: self._record_exception() ret = parent_c(~parent.an_element()) self._division_parents.set(parent, None, None, ret) @@ -965,13 +965,13 @@ cdef class CoercionModel_cache_maps(CoercionModel): if is_Integer(x) and not x and not PY_TYPE_CHECK_EXACT(yp, type): try: return yp(0), y - except StandardError: + except Exception: self._record_exception() if is_Integer(y) and not y and not PY_TYPE_CHECK_EXACT(xp, type): try: return x, xp(0) - except StandardError: + except Exception: self._record_exception() raise TypeError, "no common canonical parent for objects with parents: '%s' and '%s'"%(xp, yp) @@ -1207,7 +1207,7 @@ cdef class CoercionModel_cache_maps(CoercionModel): if coerce_S is None: raise TypeError, "No coercion from %s to pushout %s" % (S, Z) return coerce_R, coerce_S - except StandardError: + except Exception: self._record_exception() return None diff --git a/src/sage/structure/coerce_maps.pyx b/src/sage/structure/coerce_maps.pyx index 5f28ad5f2bc..26c00baee77 100644 --- a/src/sage/structure/coerce_maps.pyx +++ b/src/sage/structure/coerce_maps.pyx @@ -34,7 +34,7 @@ cdef class DefaultConvertMap(Map): cpdef Element _call_(self, x): try: return self._codomain._element_constructor(self._codomain, x) - except StandardError: + except Exception: if print_warnings: print type(self._codomain), self._codomain print type(self._codomain._element_constructor), self._codomain._element_constructor @@ -53,7 +53,7 @@ cdef class DefaultConvertMap(Map): return self._codomain._element_constructor(self._codomain, x, *args) else: return self._codomain._element_constructor(self._codomain, x, *args, **kwds) - except StandardError: + except Exception: if print_warnings: print type(self._codomain), self._codomain print type(self._codomain._element_constructor), self._codomain._element_constructor @@ -75,7 +75,7 @@ cdef class DefaultConvertMap_unique(DefaultConvertMap): cpdef Element _call_(self, x): try: return self._codomain._element_constructor(x) - except StandardError: + except Exception: if print_warnings: print type(self._codomain), self._codomain print type(self._codomain._element_constructor), self._codomain._element_constructor @@ -93,7 +93,7 @@ cdef class DefaultConvertMap_unique(DefaultConvertMap): return self._codomain._element_constructor(x, *args) else: return self._codomain._element_constructor(x, *args, **kwds) - except StandardError: + except Exception: if print_warnings: print type(self._codomain), self._codomain print type(self._codomain._element_constructor), self._codomain._element_constructor @@ -261,7 +261,7 @@ cdef class CallableConvertMap(Map): y = self._func(self._codomain, x) else: y = self._func(x) - except StandardError: + except Exception: if print_warnings: print self._func print self._codomain @@ -297,7 +297,7 @@ cdef class CallableConvertMap(Map): y = self._func(self._codomain, x, *args, **kwds) else: y = self._func(x, *args, **kwds) - except StandardError: + except Exception: if print_warnings: print self._func print self._codomain diff --git a/src/sage/structure/element.pyx b/src/sage/structure/element.pyx index db09203fd11..bd783e53d36 100644 --- a/src/sage/structure/element.pyx +++ b/src/sage/structure/element.pyx @@ -2774,32 +2774,6 @@ cdef class PrincipalIdealDomainElement(DedekindDomainElement): return coercion_model.bin_op(self, right, lcm) return self._lcm(right) - def gcd(self, right): - """ - Returns the gcd of self and right, or 0 if both are 0. - """ - if not PY_TYPE_CHECK(right, Element) or not ((right)._parent is self._parent): - return coercion_model.bin_op(self, right, gcd) - return self._gcd(right) - - def xgcd(self, right): - r""" - Return the extended gcd of self and other, i.e., elements `r, s, t` such that - .. math:: - - r = s \cdot self + t \cdot other. - - .. note:: - - There is no guarantee on minimality of the cofactors. In - the integer case, see documentation for Integer._xgcd() to - obtain minimal cofactors. - """ - if not PY_TYPE_CHECK(right, Element) or not ((right)._parent is self._parent): - return coercion_model.bin_op(self, right, xgcd) - return self._xgcd(right) - - # This is pretty nasty low level stuff. The idea is to speed up construction # of EuclideanDomainElements (in particular Integers) by skipping some tp_new # calls up the inheritance tree. @@ -2816,20 +2790,6 @@ cdef class EuclideanDomainElement(PrincipalIdealDomainElement): def degree(self): raise NotImplementedError - def _gcd(self, other): - """ - Return the greatest common divisor of self and other. - - Algorithm 3.2.1 in Cohen, GTM 138. - """ - A = self - B = other - while not B.is_zero(): - Q, R = A.quo_rem(B) - A = B - B = R - return A - def leading_coefficient(self): raise NotImplementedError @@ -2914,15 +2874,6 @@ cdef class FieldElement(CommutativeRingElement): """ return not not self - def _gcd(self, FieldElement other): - """ - Return the greatest common divisor of self and other. - """ - if self.is_zero() and other.is_zero(): - return self - else: - return self._parent(1) - def _lcm(self, FieldElement other): """ Return the least common multiple of self and other. @@ -2932,16 +2883,6 @@ cdef class FieldElement(CommutativeRingElement): else: return self._parent(1) - def _xgcd(self, FieldElement other): - R = self._parent - if not self.is_zero(): - return R(1), ~self, R(0) - elif not other.is_zero(): - return R(1), R(0), ~self - else: # both are 0 - return self, self, self - - def quo_rem(self, right): r""" Return the quotient and remainder obtained by dividing `self` by @@ -3381,7 +3322,7 @@ cdef generic_power_c(a, nn, one): return a.parent().one() except AttributeError: return type(a)(1) - except StandardError: + except Exception: return 1 #oops, the one sucks else: return one diff --git a/src/sage/structure/factorization.py b/src/sage/structure/factorization.py index 12d4fe6a433..d9f59484b0c 100644 --- a/src/sage/structure/factorization.py +++ b/src/sage/structure/factorization.py @@ -421,7 +421,7 @@ def __cmp__(self, other): return cmp(type(self), type(other)) try: return cmp(self.value(), other.value()) - except StandardError: + except Exception: c = cmp(self.__unit, other.__unit) if c: return c return list.__cmp__(self, other) @@ -584,7 +584,7 @@ def is_commutative(self): """ try: return self.universe().is_commutative() - except StandardError: + except Exception: # This is not the mathematically correct default, but agrees with # history -- we've always assumed factored things commute return True diff --git a/src/sage/structure/parent.pyx b/src/sage/structure/parent.pyx index efa65e9ac31..1b3c81531d3 100644 --- a/src/sage/structure/parent.pyx +++ b/src/sage/structure/parent.pyx @@ -1273,7 +1273,7 @@ cdef class Parent(category_object.CategoryObject): if is_Integer(x) and not x: try: return self(0) - except StandardError: + except Exception: _record_exception() raise TypeError("no canonical coercion from %s to %s" % (parent_c(x), self)) else: @@ -2724,19 +2724,19 @@ cdef class Parent(category_object.CategoryObject): return super(Parent, self)._an_element_() except EmptySetError: raise - except StandardError: + except Exception: _record_exception() pass try: return self.gen(0) - except StandardError: + except Exception: _record_exception() pass try: return self.gen() - except StandardError: + except Exception: _record_exception() pass diff --git a/src/sage/structure/parent_old.pyx b/src/sage/structure/parent_old.pyx index da17817f91f..0290ac32c23 100644 --- a/src/sage/structure/parent_old.pyx +++ b/src/sage/structure/parent_old.pyx @@ -382,12 +382,12 @@ cdef class Parent(parent.Parent): check_old_coerce(self) try: return self.gen(0) - except StandardError: + except Exception: pass try: return self.gen() - except StandardError: + except Exception: pass from sage.rings.infinity import infinity diff --git a/src/sage/structure/sage_object.pyx b/src/sage/structure/sage_object.pyx index c2a30191d84..b585493a186 100644 --- a/src/sage/structure/sage_object.pyx +++ b/src/sage/structure/sage_object.pyx @@ -443,7 +443,7 @@ cdef class SageObject: except NotImplementedError: # It would be best to make sure that this NotImplementedError was triggered by AbstractMethod tester.fail("Not implemented method: %s"%name) - except StandardError: + except Exception: pass def _test_pickling(self, **options): @@ -509,7 +509,7 @@ cdef class SageObject: else: try: s = self._interface_init_(I) - except StandardError: + except Exception: raise NotImplementedError, "coercion of object %s to %s not implemented:\n%s\n%s"%\ (repr(self), I) X = I(s) diff --git a/src/sage/symbolic/constants_c.pxd b/src/sage/symbolic/constants_c.pxd index 26c1c2813a7..99c18da0b80 100644 --- a/src/sage/symbolic/constants_c.pxd +++ b/src/sage/symbolic/constants_c.pxd @@ -1,4 +1,4 @@ -from sage.libs.ginac cimport GConstant +from ginac cimport GConstant cdef class PynacConstant: cdef GConstant* pointer diff --git a/src/sage/symbolic/constants_c.pyx b/src/sage/symbolic/constants_c.pyx index 023bd9d9ac0..6b4174f1f0a 100644 --- a/src/sage/symbolic/constants_c.pyx +++ b/src/sage/symbolic/constants_c.pyx @@ -13,7 +13,7 @@ Wrapper around Pynac's constants from sage.symbolic.expression cimport Expression, new_Expression_from_GEx from sage.symbolic.ring import SR -from sage.libs.ginac cimport * +from ginac cimport * include "sage/ext/stdsage.pxi" cdef extern from "pynac/constant.h": diff --git a/src/sage/symbolic/expression.pxd b/src/sage/symbolic/expression.pxd index 5c17705418a..d2b50bdd898 100644 --- a/src/sage/symbolic/expression.pxd +++ b/src/sage/symbolic/expression.pxd @@ -1,4 +1,4 @@ -from sage.libs.ginac cimport * +from ginac cimport * from sage.structure.element cimport CommutativeRingElement diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index f19195650b3..f8ba06ae1a8 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -550,7 +550,7 @@ cdef class Expression(CommutativeRingElement): # num_columns = MAX_LENGTH ## option of pretty try: s = pretty(sympify(self), use_unicode=False) - except StandardError: + except Exception: s = self return AsciiArt(str(s).splitlines()) @@ -3539,7 +3539,7 @@ cdef class Expression(CommutativeRingElement): else: B=[A[0],SR(A[1])] B.append(Integer(A[len(A)-1])) - except StandardError: + except Exception: raise NotImplementedError, "Wrong arguments passed to taylor. See taylor? for more details." l = self._maxima_().taylor(B) return self.parent()(l) @@ -7775,8 +7775,7 @@ cdef class Expression(CommutativeRingElement): def simplify_full(self): """ Applies simplify_factorial, simplify_trig, simplify_rational, - simplify_radical, simplify_log, and again simplify_rational to - self (in that order). + simplify_log, and again simplify_rational to self (in that order). ALIAS: simplify_full and full_simplify are the same. @@ -9052,11 +9051,11 @@ cdef class Expression(CommutativeRingElement): from sage.symbolic.relation import solve_ineq try: return(solve_ineq(self)) # trying solve_ineq_univar - except StandardError: + except Exception: pass try: return(solve_ineq([self])) # trying solve_ineq_fourier - except StandardError: + except Exception: raise NotImplementedError, "solving only implemented for equalities and few special inequalities, see solve_ineq" ex = self else: @@ -9136,7 +9135,7 @@ cdef class Expression(CommutativeRingElement): s = m.to_poly_solve(x) T = string_to_list_of_solutions(repr(s)) X = [t[0] for t in T] - except StandardError: # if that gives an error, stick with no solutions + except Exception: # if that gives an error, stick with no solutions X = [] for eq in X: @@ -9187,6 +9186,8 @@ cdef class Expression(CommutativeRingElement): """ Numerically find a root of self on the closed interval [a,b] (or [b,a]) if possible, where self is a function in the one variable. + Note: this function only works in fixed (machine) precision, it is not + possible to get arbitrary precision approximations with it. INPUT: @@ -9195,12 +9196,12 @@ cdef class Expression(CommutativeRingElement): - ``var`` - optional variable - ``xtol, rtol`` - the routine converges when a root - is known to lie within xtol of the value return. Should be = 0. The + is known to lie within xtol of the value return. Should be >= 0. The routine modifies this to take into account the relative precision of doubles. - ``maxiter`` - integer; if convergence is not - achieved in maxiter iterations, an error is raised. Must be = 0. + achieved in maxiter iterations, an error is raised. Must be >= 0. - ``full_output`` - bool (default: False), if True, also return object that contains information about convergence. diff --git a/src/sage/symbolic/function.pyx b/src/sage/symbolic/function.pyx index 79254019e87..e3a3446012f 100644 --- a/src/sage/symbolic/function.pyx +++ b/src/sage/symbolic/function.pyx @@ -15,7 +15,7 @@ Support for symbolic functions. include "sage/ext/interrupt.pxi" include "sage/ext/cdefs.pxi" -from sage.libs.ginac cimport * +from ginac cimport * from sage.structure.sage_object cimport SageObject from expression cimport new_Expression_from_GEx, Expression @@ -459,7 +459,7 @@ cdef class Function(SageObject): else: try: nargs[i] = SR.coerce(carg) - except StandardError: + except Exception: raise TypeError, "cannot coerce arguments: %s"%(err) args = nargs else: # coerce == False diff --git a/src/sage/symbolic/getitem.pyx b/src/sage/symbolic/getitem.pyx index ae53b5a4ddf..09b2b825813 100644 --- a/src/sage/symbolic/getitem.pyx +++ b/src/sage/symbolic/getitem.pyx @@ -5,7 +5,7 @@ # version 2 or any later version. The full text of the GPL is available at: # http://www.gnu.org/licenses/ ############################################################################### -from sage.libs.ginac cimport GEx, GEx_construct_ex +from ginac cimport GEx, GEx_construct_ex from sage.symbolic.expression cimport new_Expression_from_GEx cdef inline int normalize_index(object arg, int nops, object err_msg) except -1: diff --git a/src/sage/libs/ginac.pxd b/src/sage/symbolic/ginac.pxd similarity index 100% rename from src/sage/libs/ginac.pxd rename to src/sage/symbolic/ginac.pxd diff --git a/src/c_lib/include/ginac_wrap.h b/src/sage/symbolic/ginac_wrap.h similarity index 100% rename from src/c_lib/include/ginac_wrap.h rename to src/sage/symbolic/ginac_wrap.h diff --git a/src/sage/symbolic/pynac.pyx b/src/sage/symbolic/pynac.pyx index 8bd4613ad07..1549bb170f5 100644 --- a/src/sage/symbolic/pynac.pyx +++ b/src/sage/symbolic/pynac.pyx @@ -19,7 +19,7 @@ include "sage/ext/cdefs.pxi" include "sage/ext/stdsage.pxi" include "sage/ext/python.pxi" -from sage.libs.ginac cimport * +from ginac cimport * # for complex log and log gamma include "sage/gsl/gsl_complex.pxi" @@ -923,10 +923,10 @@ def py_is_integer_for_doctests(x): cdef public bint py_is_even(object x) except +: try: return not(x%2) - except StandardError: + except Exception: try: return not(ZZ(x)%2) - except StandardError: + except Exception: pass return 0 @@ -969,11 +969,11 @@ import sage.rings.arith cdef public bint py_is_prime(object n) except +: try: return n.is_prime() - except StandardError: # yes, I'm doing this on purpose. + except Exception: # yes, I'm doing this on purpose. pass try: return sage.rings.arith.is_prime(n) - except StandardError: + except Exception: pass return False diff --git a/src/sage/symbolic/relation.py b/src/sage/symbolic/relation.py index a3c57698782..860a51884f4 100644 --- a/src/sage/symbolic/relation.py +++ b/src/sage/symbolic/relation.py @@ -382,8 +382,6 @@ def test_relation_maxima(relation): True sage: test_relation_maxima(x!=1) False - sage: test_relation_maxima(x<>1) # alternate syntax for not equal - False sage: forget() sage: assume(x>0) sage: test_relation_maxima(x==0) @@ -441,7 +439,7 @@ def test_relation_maxima(relation): if repr( f() ).strip() == "0": return True break - except StandardError: + except Exception: pass return False @@ -768,7 +766,7 @@ def solve(f, *args, **kwds): try: s = m.solve(variables) - except StandardError: # if Maxima gave an error, try its to_poly_solve + except Exception: # if Maxima gave an error, try its to_poly_solve try: s = m.to_poly_solve(variables) except TypeError, mess: # if that gives an error, raise an error. @@ -780,13 +778,13 @@ def solve(f, *args, **kwds): if len(s)==0: # if Maxima's solve gave no solutions, try its to_poly_solve try: s = m.to_poly_solve(variables) - except StandardError: # if that gives an error, stick with no solutions + except Exception: # if that gives an error, stick with no solutions s = [] if len(s)==0: # if to_poly_solve gave no solutions, try use_grobner try: s = m.to_poly_solve(variables,'use_grobner=true') - except StandardError: # if that gives an error, stick with no solutions + except Exception: # if that gives an error, stick with no solutions s = [] sol_list = string_to_list_of_solutions(repr(s)) diff --git a/src/sage/symbolic/ring.pyx b/src/sage/symbolic/ring.pyx index 0421b837137..2894e489bc5 100644 --- a/src/sage/symbolic/ring.pyx +++ b/src/sage/symbolic/ring.pyx @@ -19,7 +19,7 @@ include "sage/ext/cdefs.pxi" #initialize_ginac() -from sage.libs.ginac cimport * +from ginac cimport * from sage.rings.integer cimport Integer from sage.rings.real_mpfr import RealNumber diff --git a/src/sage/tests/french_book/float_doctest.py b/src/sage/tests/french_book/float_doctest.py index 666542c541f..b4d6afa4c6b 100644 --- a/src/sage/tests/french_book/float_doctest.py +++ b/src/sage/tests/french_book/float_doctest.py @@ -174,7 +174,7 @@ sage: def sumharmo(P): ....: RFP = RealField(P) ....: y = RFP(1.); x = RFP(0.); n = 1 - ....: while x <> y: + ....: while x != y: ....: y = x; x += 1/n; n += 1 ....: return P, n, x diff --git a/src/sage/tests/french_book/programmation_doctest.py b/src/sage/tests/french_book/programmation_doctest.py index bb35e606904..ccb96770210 100644 --- a/src/sage/tests/french_book/programmation_doctest.py +++ b/src/sage/tests/french_book/programmation_doctest.py @@ -132,7 +132,7 @@ Sage example in ./programmation.tex, line 807:: sage: u = 6 ; n = 0 - sage: while u != 1: # test "différent de" <> aussi possible + sage: while u != 1: # test "différent de" ....: if u % 2 == 0: # l'opérateur % donne le reste euclidien ....: u = u//2 # // : quotient de la division euclidienne ....: else: diff --git a/src/sage/version.py b/src/sage/version.py index 562f80d4def..487fbd3fb77 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.1.rc0' -date = '2014-01-25' +version = '6.2.beta1' +date = '2014-02-07'