diff --git a/README.txt b/README.txt index 0463ff52866..116ae89d089 100644 --- a/README.txt +++ b/README.txt @@ -64,7 +64,7 @@ QUICK INSTRUCTIONS TO BUILD FROM SOURCE The following steps briefly outline the process of building Sage from source. More detailed instructions, including how to build faster on -multicore machines are contained later in this README and in the +multicore machines, are contained later in this README and in the Installation Guide: http://www.sagemath.org/doc/installation diff --git a/VERSION.txt b/VERSION.txt index a7d31073eb0..07626bddbf0 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -Sage version 6.4.rc0, released 2014-10-30 +Sage version 6.4, released 2014-11-14 diff --git a/build/install b/build/install index 54198ecac65..abe04d7bb9e 100755 --- a/build/install +++ b/build/install @@ -129,7 +129,7 @@ else # https://groups.google.com/forum/?fromgroups#!topic/sage-devel/KCeFqQ_w2FE echo >&2 "Installing GCC because you have $CXX version $GCCVERSION, which is quite old." need_to_install_gcc=yes;; - 4.4*|4.5*) + 4.4.*|4.5.*) # GCC 4.4.x and GCC 4.5.x fail to compile PARI/GP on ia64: # * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46044 if [ x`uname -m` = xia64 ]; then @@ -137,22 +137,16 @@ else echo >&2 "gcc <= 4.5 fails to compile PARI/GP on ia64." need_to_install_gcc=yes fi;; - 4.6.[01]) - # Also install GCC if we have version 4.6.0 or 4.6.1, which is + 4.6.*) + # Also install GCC if we have version 4.6.* which is # known to give trouble within Sage: # * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48702 # * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48774 + # * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52061 + # * https://groups.google.com/d/msg/sage-release/xgmJ3nAcUOY/jH8OZjftYRsJ echo >&2 "Installing GCC because you have $CXX version $GCCVERSION." - echo >&2 "gcc-4.6.0 and gcc-4.6.1 have known bugs affecting Sage." + echo >&2 "gcc-4.6.* has known bugs affecting Sage." need_to_install_gcc=yes;; - 4.6*) - # GCC 4.6.x doesn't compile ECL on Cygwin: - # * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52061 - if uname | grep CYGWIN >/dev/null; then - echo >&2 "Installing GCC because you have $CXX version $GCCVERSION on Cygwin." - echo >&2 "gcc-4.6.x fails to compile ECL on Cygwin." - need_to_install_gcc=yes - fi;; 4.7.0) # GCC 4.7.0 is very broken on ia64, see # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48496 diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index ab6065ec371..5aa4105af3b 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,4 +1,4 @@ tarball=configure-VERSION.tar.gz -sha1=f36dcb6fc8c54f740a1ac320d8431ab3c4dfb0cc -md5=b0ca65bc85b94ba59aa45b7d2266bd1f -cksum=1249053991 +sha1=3d31c6b8f81341adaf05d841fe7002529ba86d43 +md5=4e5a65be3826adbbaf4dc811ee124e08 +cksum=1057167572 diff --git a/build/pkgs/configure/package-version.txt b/build/pkgs/configure/package-version.txt index 82cced27d7b..fb1e7bc8699 100644 --- a/build/pkgs/configure/package-version.txt +++ b/build/pkgs/configure/package-version.txt @@ -1 +1 @@ -51 +54 diff --git a/build/pkgs/gcc/checksums.ini b/build/pkgs/gcc/checksums.ini index ff7019ba7d9..f7b2abfc65c 100644 --- a/build/pkgs/gcc/checksums.ini +++ b/build/pkgs/gcc/checksums.ini @@ -1,4 +1,4 @@ tarball=gcc-VERSION.tar.bz2 -sha1=3f303f403053f0ce79530dae832811ecef91197e -md5=fddf71348546af523353bd43d34919c1 -cksum=1055529215 +sha1=79dbcb09f44232822460d80b033c962c0237c6d8 +md5=4df8ee253b7f3863ad0b86359cd39c43 +cksum=2698546200 diff --git a/build/pkgs/gcc/package-version.txt b/build/pkgs/gcc/package-version.txt index aef17f13d11..dad10c76dbf 100644 --- a/build/pkgs/gcc/package-version.txt +++ b/build/pkgs/gcc/package-version.txt @@ -1 +1 @@ -4.9.1.p0 +4.9.2 diff --git a/build/pkgs/gcc/patches/min_version_10_10.patch b/build/pkgs/gcc/patches/min_version_10_10.patch deleted file mode 100644 index 1ff8a423957..00000000000 --- a/build/pkgs/gcc/patches/min_version_10_10.patch +++ /dev/null @@ -1,54 +0,0 @@ -Taken from https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61407#c16 - ---- a/gcc/config/darwin-c.c.orig -+++ b/gcc/config/darwin-c.c -@@ -572,20 +572,31 @@ find_subframework_header (cpp_reader *pfile, const char *header, cpp_dir **dirp) - - /* Return the value of darwin_macosx_version_min suitable for the - __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ macro, -- so '10.4.2' becomes 1040. The lowest digit is always zero. -- Print a warning if the version number can't be understood. */ -+ so '10.4.2' becomes 1040 and '10.10.0' becomes 101000. The lowest -+ digit is always zero. Print a warning if the version number -+ can't be understood. */ - static const char * - version_as_macro (void) - { -- static char result[] = "1000"; -+ static char result[7] = "1000"; -+ int minorDigitIdx; - - if (strncmp (darwin_macosx_version_min, "10.", 3) != 0) - goto fail; - if (! ISDIGIT (darwin_macosx_version_min[3])) - goto fail; -- result[2] = darwin_macosx_version_min[3]; -- if (darwin_macosx_version_min[4] != '\0' -- && darwin_macosx_version_min[4] != '.') -+ -+ minorDigitIdx = 3; -+ result[2] = darwin_macosx_version_min[minorDigitIdx++]; -+ if (ISDIGIT(darwin_macosx_version_min[minorDigitIdx])) { -+ /* Starting with 10.10 numeration for mactro changed */ -+ result[3] = darwin_macosx_version_min[minorDigitIdx++]; -+ result[4] = '0'; -+ result[5] = '0'; -+ result[6] = '\0'; -+ } -+ if (darwin_macosx_version_min[minorDigitIdx] != '\0' -+ && darwin_macosx_version_min[minorDigitIdx] != '.') - goto fail; - - return result; ---- a/gcc/config/darwin-driver.c.orig -+++ b/gcc/config/darwin-driver.c -@@ -57,7 +57,7 @@ darwin_find_version_from_kernel (char *new_flag) - version_p = osversion + 1; - if (ISDIGIT (*version_p)) - major_vers = major_vers * 10 + (*version_p++ - '0'); -- if (major_vers > 4 + 9) -+ if (major_vers > 4 + 10) - goto parse_failed; - if (*version_p++ != '.') - goto parse_failed; - diff --git a/build/pkgs/gcc/spkg-install b/build/pkgs/gcc/spkg-install index 3128aa68267..54ec8a5914a 100755 --- a/build/pkgs/gcc/spkg-install +++ b/build/pkgs/gcc/spkg-install @@ -81,6 +81,11 @@ if { uname -sr | grep 'Darwin 14\.' ;} &>/dev/null; then fi fi +# On OSX: isl/cloog libraries are almost certainly from Homebrew and won't work +if [ "$UNAME" = "Darwin" ]; then + GCC_CONFIGURE="--without-isl --without-cloog $GCC_CONFIGURE" +fi + # Let GCC build on Raspberry Pi using hard floats. if [ `uname -m` = "armv6l" ]; then GCC_CONFIGURE="--with-arch=armv6 --with-fpu=vfp --with-float=hard $GCC_CONFIGURE" diff --git a/build/pkgs/openssl/checksums.ini b/build/pkgs/openssl/checksums.ini index bdded2bab89..7ab811e3d70 100644 --- a/build/pkgs/openssl/checksums.ini +++ b/build/pkgs/openssl/checksums.ini @@ -1,4 +1,4 @@ tarball=openssl-VERSION.tar.gz -sha1=b2239599c8bf8f7fc48590a55205c26abe560bf8 -md5=8d6d684a9430d5cc98a62a5d8fbda8cf -cksum=3773835410 +sha1=cff86857507624f0ad42d922bb6f77c4f1c2b819 +md5=f7175c9cd3c39bb1907ac8bba9df8ed3 +cksum=490651201 diff --git a/build/pkgs/openssl/package-version.txt b/build/pkgs/openssl/package-version.txt index 36beb0f0e4e..9753fcecf96 100644 --- a/build/pkgs/openssl/package-version.txt +++ b/build/pkgs/openssl/package-version.txt @@ -1 +1 @@ -1.0.1h +1.0.1j diff --git a/build/pkgs/pkgconf/SPKG.txt b/build/pkgs/pkgconf/SPKG.txt index dd194b0214e..c6a225879dc 100644 --- a/build/pkgs/pkgconf/SPKG.txt +++ b/build/pkgs/pkgconf/SPKG.txt @@ -24,3 +24,6 @@ https://github.com/pkgconf/pkgconf == Special Update/Build Instructions == * install.patch: Use install script from AC_PROG_INSTALL + +Pkgconf is used in bzip2, so we must not use the bzip2-compressed +tarball. diff --git a/build/pkgs/pkgconf/checksums.ini b/build/pkgs/pkgconf/checksums.ini index be8a24c0949..3359977c65d 100644 --- a/build/pkgs/pkgconf/checksums.ini +++ b/build/pkgs/pkgconf/checksums.ini @@ -1,4 +1,4 @@ -tarball=pkgconf-VERSION.tar.bz2 -sha1=2d353227f5dfbcaa2c0f48f045f828dac2abcff0 -md5=88f34448e9c5c20b23c328824043a239 -cksum=997423134 +tarball=pkgconf-VERSION.tar.gz +sha1=9943ba508c3293cd3afb5187f633104f8305af42 +md5=56837bbee89a542ffe7012b4a52caf5b +cksum=320066684 diff --git a/build/pkgs/pkgconf/package-version.txt b/build/pkgs/pkgconf/package-version.txt index a602fc9e283..c81aa44afbf 100644 --- a/build/pkgs/pkgconf/package-version.txt +++ b/build/pkgs/pkgconf/package-version.txt @@ -1 +1 @@ -0.9.4 +0.9.7 diff --git a/build/pkgs/pkgconf/patches/install.patch b/build/pkgs/pkgconf/patches/install.patch deleted file mode 100644 index b659812df29..00000000000 --- a/build/pkgs/pkgconf/patches/install.patch +++ /dev/null @@ -1,27 +0,0 @@ -diff --git a/Makefile.in b/Makefile.in -index 7a1f42a..101044e 100644 ---- a/Makefile.in -+++ b/Makefile.in -@@ -11,6 +11,7 @@ system_libdir = @SYSTEM_LIBDIR@ - pkgconfigdir = @PKGCONFIGDIR@ - - CC = @CC@ -+INSTALL = @INSTALL@ - PROG = pkgconf@EXEEXT@ - SRCS = main.c cache.c pkg.c bsdstubs.c getopt_long.c fragment.c argvsplit.c fileio.c tuple.c dependency.c queue.c - OBJS = ${SRCS:.c=.o} -@@ -30,11 +31,11 @@ clean: - - install: - mkdir -p $(DESTDIR)$(bindir) -- install -c -m755 $(PROG) $(DESTDIR)$(bindir)/$(PROG) -+ @INSTALL_PROGRAM@ $(PROG) $(DESTDIR)$(bindir)/$(PROG) - mkdir -p $(DESTDIR)$(datarootdir)/aclocal -- install -c -m644 $(srcdir)/pkg.m4 $(DESTDIR)$(datarootdir)/aclocal/pkg.m4 -+ @INSTALL_DATA@ $(srcdir)/pkg.m4 $(DESTDIR)$(datarootdir)/aclocal/pkg.m4 - mkdir -p $(DESTDIR)$(MANDIR) -- install -c -m644 $(srcdir)/pkgconf.1 $(DESTDIR)$(MANDIR)/pkgconf.1 -+ @INSTALL_DATA@ $(srcdir)/pkgconf.1 $(DESTDIR)$(MANDIR)/pkgconf.1 - - check: $(PROG) - $(SHELL) tests/run.sh ./$(PROG) diff --git a/build/pkgs/ppl/SPKG.txt b/build/pkgs/ppl/SPKG.txt index ec8c3fc1d6b..b95f2ac3095 100644 --- a/build/pkgs/ppl/SPKG.txt +++ b/build/pkgs/ppl/SPKG.txt @@ -42,7 +42,7 @@ Enea Zaffanella (University of Parma) == Special Update/Build Instructions == -Patches: - +=== Patches === * ptrdiff_t-ppl-1.1.patch: Fixes to compile with gcc 4.9; C++ name lookup issue. +* weak.patch: disable use of weak symbols on Cygwin64. diff --git a/build/pkgs/ppl/patches/weak.patch b/build/pkgs/ppl/patches/weak.patch new file mode 100644 index 00000000000..60d27d8576b --- /dev/null +++ b/build/pkgs/ppl/patches/weak.patch @@ -0,0 +1,24 @@ +diff -druN ppl-1.1.orig/src/assert.hh ppl-1.1/src/assert.hh +--- ppl-1.1.orig/src/assert.hh 2013-10-28 13:38:33.000000000 +0100 ++++ ppl-1.1/src/assert.hh 2014-04-08 11:40:48.924491100 +0200 +@@ -98,7 +98,7 @@ + + namespace Parma_Polyhedra_Library { + +-#if PPL_CXX_SUPPORTS_ATTRIBUTE_WEAK ++#if PPL_CXX_SUPPORTS_ATTRIBUTE_WEAK && ! (defined(__CYGWIN__) && defined(__x86_64__)) + #define PPL_WEAK_NORETURN __attribute__((weak, noreturn)) + #else + #define PPL_WEAK_NORETURN __attribute__((noreturn)) +diff -druN ppl-1.1.orig/src/ppl.hh.dist ppl-1.1/src/ppl.hh.dist +--- ppl-1.1.orig/src/ppl.hh.dist 2013-10-28 13:47:20.000000000 +0100 ++++ ppl-1.1/src/ppl.hh.dist 2014-04-08 11:01:13.361991100 +0200 +@@ -1739,7 +1739,7 @@ + + namespace Parma_Polyhedra_Library { + +-#if PPL_CXX_SUPPORTS_ATTRIBUTE_WEAK ++#if PPL_CXX_SUPPORTS_ATTRIBUTE_WEAK && ! (defined(__CYGWIN__) && defined(__x86_64__)) + #define PPL_WEAK_NORETURN __attribute__((weak, noreturn)) + #else + #define PPL_WEAK_NORETURN __attribute__((noreturn)) diff --git a/build/pkgs/sagenb/checksums.ini b/build/pkgs/sagenb/checksums.ini index 3bc135655e3..50952b45f7e 100644 --- a/build/pkgs/sagenb/checksums.ini +++ b/build/pkgs/sagenb/checksums.ini @@ -1,4 +1,4 @@ tarball=sagenb-VERSION.tar -sha1=a6e39573251fcdbb02f7a851041d49b7fb286395 -md5=75665520800ebc0addadb67e274bf9eb -cksum=404833031 +sha1=5f731ed387351cd1d1d130769ca309764cd2ecd9 +md5=eb4fd89c8c907171a098fa6f06891bd8 +cksum=3318210891 diff --git a/build/pkgs/sagenb/package-version.txt b/build/pkgs/sagenb/package-version.txt index d9df1bbc0c7..af88ba82486 100644 --- a/build/pkgs/sagenb/package-version.txt +++ b/build/pkgs/sagenb/package-version.txt @@ -1 +1 @@ -0.11.0 +0.11.1 diff --git a/build/pkgs/setuptools/package-version.txt b/build/pkgs/setuptools/package-version.txt index d70c8f8d89f..41320c41189 100644 --- a/build/pkgs/setuptools/package-version.txt +++ b/build/pkgs/setuptools/package-version.txt @@ -1 +1 @@ -3.6 +3.6.p0 diff --git a/build/pkgs/setuptools/patches/easy_install_lock.patch b/build/pkgs/setuptools/patches/easy_install_lock.patch index cf4f4c2e160..0acc44aff37 100644 --- a/build/pkgs/setuptools/patches/easy_install_lock.patch +++ b/build/pkgs/setuptools/patches/easy_install_lock.patch @@ -1,58 +1,31 @@ -diff -ur setuptools-2.0.1-orig/setuptools/command/easy_install.py setuptools-2.0.1/setuptools/command/easy_install.py ---- setuptools-2.0.1-orig/setuptools/command/easy_install.py 2013-12-13 17:31:51.000000000 +0100 -+++ setuptools-2.0.1/setuptools/command/easy_install.py 2014-02-28 20:03:44.805017754 +0100 -@@ -26,6 +26,7 @@ - import warnings - import site - import struct -+import fcntl - from glob import glob - from distutils import log, dir_util - -@@ -1432,12 +1433,14 @@ - for path in yield_lines(self.paths): +diff -ru src/setuptools/command/easy_install.py b/setuptools/command/easy_install.py +--- src/setuptools/command/easy_install.py 2014-10-31 14:42:35.779973945 +0100 ++++ b/setuptools/command/easy_install.py 2014-10-31 15:07:53.067034724 +0100 +@@ -1446,6 +1446,11 @@ list(map(self.add, find_distributions(path, True))) -- def _load(self): -- self.paths = [] -+ def _load(self, lock=True, paths=[]): -+ self.paths = list(paths) + def _load(self): ++ # Lock self.filename until save() is called ++ import fcntl ++ self.lock = open(self.filename, 'a') ++ fcntl.flock(self.lock, fcntl.LOCK_EX) ++ + self.paths = [] saw_import = False seen = dict.fromkeys(self.sitedirs) - if os.path.isfile(self.filename): - f = open(self.filename,'rt') -+ if lock: -+ fcntl.flock(f, fcntl.LOCK_SH) - for line in f: - if line.startswith('import'): - saw_import = True -@@ -1465,10 +1468,12 @@ - +@@ -1479,6 +1484,7 @@ def save(self): """Write changed .pth file back to disk""" -- if not self.dirty: -- return -+ lock = open(self.filename, 'a') -+ fcntl.flock(lock, fcntl.LOCK_EX) -+ self._load(lock=False, paths=self.paths) - -- data = '\n'.join(map(self.make_relative,self.paths)) -+ relative_paths = set(map(self.make_relative,self.paths)) -+ data = '\n'.join(relative_paths) - if data: - log.debug("Saving %s", self.filename) - data = ( -@@ -1486,11 +1491,12 @@ - f.write(data) - f.close() + if not self.dirty: ++ self.lock.close() + return -- elif os.path.exists(self.filename): -+ else: - log.debug("Deleting empty %s", self.filename) + data = '\n'.join(map(self.make_relative,self.paths)) +@@ -1504,6 +1510,7 @@ os.unlink(self.filename) self.dirty = False -+ lock.close() ++ self.lock.close() def add(self, dist): """Add `dist` to the distribution map""" diff --git a/build/pkgs/setuptools/spkg-install b/build/pkgs/setuptools/spkg-install index 6f7e9aa0bb4..87588a7fb69 100755 --- a/build/pkgs/setuptools/spkg-install +++ b/build/pkgs/setuptools/spkg-install @@ -18,6 +18,7 @@ cd src # Apply patches. See SPKG.txt for information about what each patch # does. 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'" diff --git a/src/bin/sage b/src/bin/sage index 44b183ea9e7..ca077604578 100755 --- a/src/bin/sage +++ b/src/bin/sage @@ -18,13 +18,13 @@ usage() { echo " -gp [...] -- run Sage's PARI/GP calculator with given arguments" echo " -h, -? -- print this help message" echo " -i [packages] -- install the given Sage packages" + echo " -pip [...] -- invoke pip, the Python package manager" echo " -inotebook [...] -- start the *insecure* Sage notebook (deprecated)" echo " -maxima [...] -- run Sage's Maxima with given arguments" echo " -mwrank [...] -- run Sage's mwrank with given arguments" echo " --notebook=[...] -- start the Sage notebook (valid options are" echo " 'default', 'sagenb', and 'ipython')" echo " -n, --notebook -- shortcut for --notebook=default" - echo " -notebook-ipy [...] -- start the Sage IPython notebook" echo " -optional -- list all optional packages that can be installed" echo " -python [...] -- run the Python interpreter" echo " -R [...] -- run Sage's R with given arguments" @@ -73,12 +73,14 @@ usage_advanced() { echo "Running the notebook:" echo " --notebook=[...] -- start the Sage notebook (valid options are" echo " 'default', 'sagenb', and 'ipython'). See the output" - echo " 'of sage --notebook --help for more details" + echo " of sage --notebook --help for more details and" + echo " examples of how to pass optional arguments" echo " -bn, -build-and-notebook [...] -- build the Sage library then start" echo " the Sage notebook" echo " -inotebook [...] -- start the *insecure* Sage notebook (deprecated)" - echo " -n, -notebook [...] -- start the Sage notebook (options are the same" - echo " as for the notebook command in Sage)" + echo " -n, -notebook [...] -- start the default Sage notebook (options are the" + echo " same as for the notebook command in Sage). See the" + echo " output of sage -n -h for more details" echo #### 1.......................26..................................................78 @@ -127,6 +129,7 @@ usage_advanced() { echo " -info [packages] -- print the SPKG.txt of the given packages" echo " -optional -- list all optional packages that can be installed" echo " -standard -- list all standard packages that can be installed" + echo " -installed -- list all installed packages" #echo " -update -- download latest non-optional Sage packages (do not build them)" #echo " -update-build -- build and install all downloaded non-optional Sage packages" echo " -upgrade [version] -- download, build and install the given version. Here," @@ -445,6 +448,15 @@ if [ "$1" = '-scons' -o "$1" = '--scons' ]; then exec scons "$@" fi +if [ "$1" = '-pip' -o "$1" = '--pip' ]; then + if [ ! -x "$SAGE_LOCAL/bin/pip" ]; then + echo "Pip is not installed. Run \"sage -i pip\" to install it." + exit 1 + fi + shift + exec pip "$@" +fi + if [ "$1" = '-python' -o "$1" = '--python' ]; then shift exec python "$@" @@ -782,15 +794,19 @@ install() { } if [ "$1" = '-optional' -o "$1" = "--optional" ]; then - exec sage-list-optional + exec sage-list-packages optional fi if [ "$1" = '-experimental' -o "$1" = "--experimental" ]; then - exec sage-list-experimental + exec sage-list-packages experimental fi if [ "$1" = '-standard' -o "$1" = "--standard" ]; then - exec sage-list-standard + exec sage-list-packages standard +fi + +if [ "$1" = '-installed' -o "$1" = "--installed" ]; then + exec sage-list-packages installed fi if [ "$1" = '-i' ]; then diff --git a/src/bin/sage-banner b/src/bin/sage-banner index e6d251ce2ed..fa39e69b60b 100644 --- a/src/bin/sage-banner +++ b/src/bin/sage-banner @@ -1,8 +1,5 @@ ┌────────────────────────────────────────────────────────────────────┐ -│ Sage Version 6.4.rc0, Release Date: 2014-10-30 │ +│ Sage Version 6.4, Release Date: 2014-11-14 │ │ Type "notebook()" for the browser-based notebook interface. │ │ Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ -┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ -┃ Warning: this is a prerelease version, and it may be unstable. ┃ -┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ diff --git a/src/bin/sage-list-experimental b/src/bin/sage-list-experimental index 094d62df0c4..b6a5760f939 100755 --- a/src/bin/sage-list-experimental +++ b/src/bin/sage-list-experimental @@ -1,3 +1,5 @@ #!/usr/bin/env bash -sage-list-packages experimental - +echo "DEPRECATION WARNING: this script is deprecated" >&2 +echo "do:" >&2 +echo " $ sage-list-packages experimental" >&2 +exec sage-list-packages experimental diff --git a/src/bin/sage-list-optional b/src/bin/sage-list-optional index 527b6024a02..3fd911e4ea6 100755 --- a/src/bin/sage-list-optional +++ b/src/bin/sage-list-optional @@ -1,3 +1,5 @@ #!/usr/bin/env bash -sage-list-packages optional - +echo "DEPRECATION WARNING: this script is deprecated" >&2 +echo "do:" >&2 +echo " $ sage-list-packages optional" >&2 +exec sage-list-packages optional diff --git a/src/bin/sage-list-packages b/src/bin/sage-list-packages index 328c7c0e5de..0afbdd96488 100755 --- a/src/bin/sage-list-packages +++ b/src/bin/sage-list-packages @@ -1,49 +1,69 @@ #!/usr/bin/env python -import os, sys, urllib, urllib2, urlparse +# script to list the Sage packages +# called with one argument which meight be either "installed" or "standard" or +# "optional" or "experimental". + +import os, sys if not os.environ.has_key("SAGE_ROOT"): - raise RuntimeError, "The environment variable SAGE_ROOT must be set." + raise RuntimeError("The environment variable SAGE_ROOT must be set.") SAGE_SPKG_INST=os.environ.get("SAGE_SPKG_INST", os.path.join(os.environ["SAGE_ROOT"],'spkg','installed')) - if not os.environ.has_key("SAGE_SERVER"): sys.stderr.write("The environment variable SAGE_SERVER must be set.\n") sys.exit(1) +def get_remote_package_list(category): + r""" + Return the list of packages + + INPUT: + + - ``category`` -- can be either "standard", "optional" or "experimental". + """ + import urllib, urllib2, urlparse + + PKG_SERVER = urlparse.urljoin(os.environ['SAGE_SERVER'],'packages') + print "Using Sage Server %s"%PKG_SERVER + + url_path = os.path.join('packages', category, 'list') + url = urlparse.urljoin(PKG_SERVER, urllib.pathname2url(url_path)) + + try: + pkg_list_file = urllib2.urlopen(url) + except (OSError, IOError) as msg: + print msg + print "\n\n" + print "*"*80 + print "\n\n" + print "Error contacting %s. Try using an alternative server."%url + print "For example, from the bash prompt try typing\n" + print " export SAGE_SERVER=http://sage.scipy.org/sage/\n" + print "then try again." + print "\n\n" + print "*"*80 + print "\n\n" + sys.exit(1) + + result = [line.strip() for line in pkg_list_file.readlines()] + pkg_list_file.close() + return result + try: category = sys.argv[1] except IndexError: sys.stderr.write("Usage: %s .\n" % sys.argv[0]) sys.exit(1) - -PKG_SERVER = urlparse.urljoin(os.environ['SAGE_SERVER'],'packages') -print "Using Sage Server %s"%PKG_SERVER - -url_path = os.path.join('packages', category, 'list') -url = urlparse.urljoin(PKG_SERVER, urllib.pathname2url(url_path)) - try: installed = set(os.listdir(SAGE_SPKG_INST)) except OSError: installed = set([]) -try: - pkg_list_file = urllib2.urlopen(url) -except (OSError, IOError), msg: - print msg - print "\n\n" - print "*"*80 - print "\n\n" - print "Error contacting %s. Try using an alternative server."%url - print "For example, from the bash prompt try typing\n" - print " export SAGE_SERVER=http://sage.scipy.org/sage/\n" - print "then try again." - print "\n\n" - print "*"*80 - print "\n\n" - sys.exit(1) +if category == 'installed': + print '\n'.join(installed) + sys.exit(0) def split_pkgname(name): try: @@ -57,8 +77,7 @@ def split_pkgname(name): installed_version = dict([ split_pkgname(pkg) for pkg in installed ]) -available_version = dict([ split_pkgname(pkg.rstrip()) - for pkg in pkg_list_file.readlines() ]) +available_version = dict([ split_pkgname(pkg) for pkg in get_remote_package_list(category)]) print "\n%s packages:\n" % (category[0].upper() + category[1:]) @@ -77,4 +96,3 @@ for pkg_name in sorted(available_version.keys()): print "\nType 'sage -i package_name' to download and install a package." -pkg_list_file.close() diff --git a/src/bin/sage-list-standard b/src/bin/sage-list-standard index d56b33f2d38..a8bbd66af46 100755 --- a/src/bin/sage-list-standard +++ b/src/bin/sage-list-standard @@ -1,3 +1,5 @@ #!/usr/bin/env bash +echo "DEPRECATION WARNING: this script is deprecated" >&2 +echo "do:" >&2 +echo " $ sage-list-packages standard" >&2 sage-list-packages standard - diff --git a/src/bin/sage-notebook b/src/bin/sage-notebook index 1cc33fac1cf..b892f612d0e 100755 --- a/src/bin/sage-notebook +++ b/src/bin/sage-notebook @@ -37,11 +37,17 @@ class NotebookSageNB(object): if '=' in x: key, value = x.split('=', 2) logger.debug('keyword argument %s = %s', key, value) - value = ast.literal_eval(value) + try: + value = ast.literal_eval(value) + except StandardError: + logger.debug('cannot evaluate, treat as string') kwds[key] = value else: logger.debug('positional argument %s', x) - value = ast.literal_eval(x) + try: + value = ast.literal_eval(x) + except StandardError: + logger.debug('cannot evaluate, treat as string') args.append(value) return tuple(args), kwds @@ -79,6 +85,24 @@ show this help message and exit. Can be combined with "--notebook=[...]" to see notebook-specific options """ +epilog = \ +""" +EXAMPLES: + +* Run default notebook on port 1234. Note that the first argument + after "-n" will be interpreted as notebook name unless you stop + processing with "--": + + sage -n default port=1234 + sage -n -- port=1234 # equivalent + sage -n port=1234 # ERROR: invalid notebook name + +* Run IPython notebook in custom directory: + + sage --notebook=ipython --notebook-dir=/home/foo/bar +""" + + notebook_launcher = { 'default': NotebookSageNB, # change this to change the default 'sagenb': NotebookSageNB, @@ -95,7 +119,10 @@ def make_parser(): Any arguments that are not parsed here are supposed to be handled by the notebook implementation. """ - parser = argparse.ArgumentParser(description=description, add_help=False) + parser = argparse.ArgumentParser( + description=description, epilog=epilog, + formatter_class=argparse.RawDescriptionHelpFormatter, + add_help=False) parser.add_argument('-h', '--help', dest='option_help', action='store_true', default=False, @@ -120,6 +147,8 @@ def make_parser(): if __name__ == '__main__': parser = make_parser() args, unknown = parser.parse_known_args(sys.argv[1:]) + if len(unknown) > 0 and unknown[0] == '--': + unknown = unknown[1:] if args.log is not None: import logging level = getattr(logging, args.log.upper()) diff --git a/src/bin/sage-version.sh b/src/bin/sage-version.sh index 3789a6796ad..bd7c51935e0 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.4.rc0' -SAGE_RELEASE_DATE='2014-10-30' +SAGE_VERSION='6.4' +SAGE_RELEASE_DATE='2014-11-14' diff --git a/src/doc/de/tutorial/tour_linalg.rst b/src/doc/de/tutorial/tour_linalg.rst index e04f7e0d5fd..f1bd249d874 100644 --- a/src/doc/de/tutorial/tour_linalg.rst +++ b/src/doc/de/tutorial/tour_linalg.rst @@ -117,7 +117,7 @@ alle der folgenden Berechnungen unterstützen:: sage: ARDF.eigenvalues() # rel tol 8e-16 [-0.09317121994613098, 4.293171219946131] sage: ACDF = matrix(CDF, [[1.2, I], [2, 3]]) - sage: ACDF.eigenvectors_right() # rel tol 2e-15 + sage: ACDF.eigenvectors_right() # rel tol 3e-15 [(0.8818456983293743 - 0.8209140653434135*I, [(0.7505608183809549, -0.616145932704589 + 0.2387941530333261*I)], 1), (3.3181543016706256 + 0.8209140653434133*I, [(0.14559469829270957 + 0.3756690858502104*I, 0.9152458258662108)], 1)] diff --git a/src/doc/en/developer/index.rst b/src/doc/en/developer/index.rst index 86822997fbc..707cbddcf71 100644 --- a/src/doc/en/developer/index.rst +++ b/src/doc/en/developer/index.rst @@ -10,6 +10,8 @@ Sage at some point. You could: * Find bugs or typos * Fix a bug * Implement a new function +* Contribute a useful tutorial for a mathematical topic +* Translate an existing document to a new language * Create a new class, create a fast new C library, etc. This document describes how to write programs using Sage, how to modify @@ -17,39 +19,60 @@ and extend the core Sage libraries, and how to modify Sage's documentation. We also discuss how to share your new and modified code with other Sage users around the globe. -All development takes place on or via `the Sage Trac server -`_, -including bug reports, fixes, new functionality, and discussions about -approaches to particular tickets. Once you start writing code for Sage, -you will want to carefully read the -:ref:`conventions and guidelines ` we use. - -Depending on your previous knowledge, there are several places you can -start learning about the source code revision control process. - -- First, although it is possible to try out bugfixes and explore the - code without having a developer account, it is best to :ref:`acquire a - Trac account ` first, then :ref:`configure git - ` for use with Trac. -- An overview of the Sage development process, assuming you have ``git`` - installed and know the basics of how to use it, is in the :ref:`concise - development guide `. -- More advanced :ref:`tricks and tips ` for - ``git`` are linked below. -- For those unfamiliar with revision control, please start by reading - about :ref:`collaborative development with Git-Trac `, - which provides some easier interface with git and Trac, both for newbies - and power users. -- Alternately, one can do certain amounts of Sage development without - having git installed, by using Sage's own internal installation of git - and the :ref:`Sage dev scripts `. This is mainly - intended as a bridge to full use of git once one becomes more comfortable - with the system. - -Finally, if you've never worked on software before, don't forget you -will need the `prerequisites to compile -`_ -in order to make your changes in the source code work. +It is not necessary to memorize this entire guide to begin working on +Sage, but careful reading of different sections now will be well worth +the effort in seamless contributions later. There are four main things +to be aware of. + +- All development takes place on or via `the Sage Trac server + `_, including bug reports, fixes, + new functionality, and discussions about approaches to particular tickets. + If you don't have an account on it, read about how to :ref:`acquire a + Trac account `. This is recommended even if you + only want to report bugs or request new functionality, not necessarily + to help make changes to Sage. + +- Next, if you've never worked on software before, you will want to read + about the `prerequisites to compile + `_ + from the installation guide. This will allow you to + make your changes in the source code work. Pay close attention + to any system-specific requirements. + +- Once you start writing code for Sage, you will want to carefully read the + :ref:`conventions and guidelines ` we use. + (Looking at newer files and functionality within Sage is another way to + get a sense for the the general style, but refer here for details.) + + - There is an entire section on how to modify or add to the various + :ref:`manuals and tutorials `, + including localizing to other languages. + +- Finally, in order to share changes with the Sage community, you will + need to learn some basics of the source code revision control process. + There are several places to start, depending upon your previous knowledge. + + - Don't forget to :ref:`acquire a Trac account `. + - First, you will need to :ref:`install the 'git' revision control + software ` if you don't already have it. + - Then you will need to go through a short process to :ref:`configure git + ` for use with Trac. + - Assuming you have ``git`` installed and know the basics of how to use it, + the next step is the overview of the Sage development flow in the + :ref:`concise development guide `. + + - (More advanced :ref:`tricks and tips ` for + ``git`` are linked below.) + + - For those unfamiliar with ``git`` or revision control, please start by + reading about :ref:`collaborative development with Git-Trac `, + which provides some easier interface with git and Trac, both for newbies + and power users. + - Alternately, one can do certain amounts of Sage development without + having ``git`` installed, by using Sage's own internal installation of ``git`` + and the :ref:`Sage dev scripts `. This is mainly + intended as a bridge to full use of git once one becomes more comfortable + with the system. No matter where you start, good luck and welcome to Sage development! @@ -111,18 +134,41 @@ When ``git trac`` is not enough. Writing Code for Sage ===================== +Basics of Writing and Testing Sage Code +--------------------------------------- + .. toctree:: :maxdepth: 3 coding_basics + doctesting + +Contributing to Manuals and Tutorials +------------------------------------- + +.. toctree:: + :maxdepth: 3 + + sage_manuals + +Sage Coding Details +------------------- + +.. toctree:: + :maxdepth: 3 + coding_in_python coding_in_cython coding_in_other + +Packaging Third-Party Code +-------------------------- + +.. toctree:: + :maxdepth: 3 + packaging packaging_old_spkgs - doctesting - sage_manuals - Sage Notebook Developer Guide ============================= @@ -142,5 +188,3 @@ Indices and tables This work is licensed under a `Creative Commons Attribution-Share Alike 3.0 License `_. - - diff --git a/src/doc/en/faq/faq-usage.rst b/src/doc/en/faq/faq-usage.rst index 94ebacce9c6..736451fa5aa 100644 --- a/src/doc/en/faq/faq-usage.rst +++ b/src/doc/en/faq/faq-usage.rst @@ -564,26 +564,31 @@ where it says:: The show command for plotting 3-D objects does not work. """""""""""""""""""""""""""""""""""""""""""""""""""""""" -Since Sage 2.9.2, we have switched to using -`Jmol `_, -a Java applet, for 3-D plotting. There are several possibilities for -the cause of the malfunction. You do not have Java installed at all or -the Java installed is an older GNU based alternative Java -implementation, which causes some yet to determine problem. A solution -to both issues is to either install Sun's Java SDK or to update the -GNU based Java implementation. As of January 2008 Debian's Java in -testing works, but stable does have problems. - -If you are running a brand new (as of April 2008) Ubuntu 8.04, they -ship the Java Plugin by IcedTea. This is basically a good idea, but a -bit too early since it is broken. Either wait for an update or -uninstall the IcedTea Plugin and install the "SUN Java 6 -Plugin". Later, switch back to IcedTea, since it is based on OpenJDK 7 -(or SUNs Java 7) which is the next Java version. You can check for the -used plugin in Firefox 3 by typing "about:plugins" into the URL -bar. Read more about this issue at -`launchpad `_. - +The default live 3-D plotting for Sage 6.4+ uses +`Jmol/JSmol `_ +for viewing. From the command line the Jmol Java application is used, +and for in browser viewing either pure javascript or a Java applet +is used. By default in browsers pure javascript is used to avoid +the problems with some browsers that do not support java applet +plugins (namely Chrome). On each browser worksheet there is a +checkbox which must be checked before a 3-D plot is generated if +the user wants to use the Java applet (the applet is a little faster +with complex plots). + +The most likely reason for a malfunction is that you do not have +a Java Run Time Environment (JRE) installed or you have one older than +version 1.7. If things work from the command line another possibility +is that your browser does not have the proper plugin to support Java +applets (at present, 2014, plugins do not work with most versions of +Chrome). Make sure you have installed either the IcedTea browser +plugin (for linux see your package manager), see: +`IcedTea `_, +or the Oracle Java plugin see: +`Java `_. + +If you are using a Sage server over the web and even javascript rendering +does not work, you may have a problem with your browser's javascript +engine or have it turned off. May I use Sage tools in a commercial environment? """"""""""""""""""""""""""""""""""""""""""""""""" diff --git a/src/doc/en/installation/source.rst b/src/doc/en/installation/source.rst index 827704f90ec..33d7651765f 100644 --- a/src/doc/en/installation/source.rst +++ b/src/doc/en/installation/source.rst @@ -9,12 +9,13 @@ Install from Source Code More familiarity with computers may be required to build Sage from the `source code `_. -If you do have all the pre-requisite tools, the process should be completely +If you do have all the :ref:`pre-requisite tools `, +the process should be completely painless, basically consisting in extracting the source tarball and typing -``make``. -It can take your computer a while to build Sage from the source code, +``make``. It can take your computer a while to build Sage from the source code, although the procedure is fully automated and should need no human intervention. + Building Sage from the source code has the major advantage that your install will be optimised for your particular computer and should therefore offer better performance and compatibility than a binary install. @@ -48,20 +49,31 @@ you can find details about `ports `_ to other operating systems or processors which may be taking place. +.. _section-prereqs: + Prerequisites ------------- General requirements ~~~~~~~~~~~~~~~~~~~~ -Your computer comes with at least 5 GB of free disk space running one of the +This section details the technical prerequisites needed on all platforms. See +also the `System-specific requirements`_ below. + +Disk space and memory +^^^^^^^^^^^^^^^^^^^^^ + +Your computer comes with at least 6 GB of free disk space running one of the supported versions of an operating system listed at http://wiki.sagemath.org/SupportedPlatforms. It is recommended to have at least 2 GB of RAM, but you might get away with less (be sure to have some swap space in this case). +Command-line tools +^^^^^^^^^^^^^^^^^^ + In addition to standard `POSIX `_ utilities -and a `bash `_-compatible shell, +and the `bash `_ shell, the following standard command-line development tools must be installed on your computer: @@ -78,29 +90,37 @@ computer: - **ar** and **ranlib**: can be obtained as part of GNU binutils. - **tar**: GNU tar version 1.17 or later, or BSD tar. +Fortran and compiler suites +########################### + Sage also needs a Fortran compiler. The only configuration currently supported is matching versions of the C, C++ and Fortran compilers from the `GNU Compiler Collection (GCC) `_. Therefore, if you plan on using your own GCC compilers, then make sure that their versions match. + Alternatively, Sage includes a GCC package, so that C, C++ and Fortran compilers will be built when the build system detects that it is needed, e.g., non-GCC compilers, or versions of the GCC compilers known to miscompile some components of Sage, or simply a missing Fortran compiler. -Whatsoever, you always need at least a C/C++ compiler to build the GCC package and -its prerequisites before the compilers it provides can be used. +In any case, you always need at least a C/C++ compiler to build the GCC +package and its prerequisites before the compilers it provides can be used. + Note that you can always override this behavior through the environment variable :envvar:`SAGE_INSTALL_GCC`, see :ref:`section_compilers` and :ref:`section_envvar`. +Other notes +^^^^^^^^^^^ + Although some of Sage is written in `Python `_, you do not need Python pre-installed on your computer, since the Sage installation includes virtually everything you need. -After extracting the Sage tarball, the subdirectory :file:`spkg` contains the -source distributions for everything on which Sage depends. +After extracting the Sage tarball, the subdirectory :file:`upstream` +contains the source distributions for everything on which Sage depends. We emphasize that all of this software is included with Sage, so you do not have to worry about trying to download and install any one of these packages (such as Python, for example) yourself. @@ -112,11 +132,14 @@ and inform you of any that are missing, or have unsuitable versions. System-specific requirements ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +On Mac OS X, there are various developer tools needed which may require +some registration on Apple's developer site; see :ref:`section_macprereqs`. + On recent Debian or Ubuntu systems, the **dpkg-dev** package is needed for `multiarch `_ support. On Cygwin, the **lapack** and **liblapack-devel** packages are required to -provide ATLAS support as the ATLAS spkg is not built by default. +provide ATLAS support as the Sage package for ATLAS is not built by default. Installing prerequisites ~~~~~~~~~~~~~~~~~~~~~~~~ @@ -134,6 +157,9 @@ on the command line. If it gives an error (or returns nothing), then either ``perl`` is not installed, or it is installed but not in your `PATH `_. +Linux prerequisite installation +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + On Linux systems (e.g., Ubuntu, Redhat, etc), ``ar`` and ``ranlib`` are in the `binutils `_ package. The other programs are usually located in packages with their respective names. @@ -155,26 +181,47 @@ On other Linux systems, you might use `yum `_, or other package managers. +.. _section_macprereqs: + +Mac OS X prerequisite installation +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + On OS X systems, you need a recent version of -`Command Line Tools `_. +`Command Line Tools `_. It provides all the above requirements. -You can download it for free at -http://developer.apple.com/downloads/index.action?=command%20line%20tools -provided you registered for a free Apple Developer account at -http://developer.apple.com/register/. -Alternatively, if you have already installed -`Xcode `_ + +If you have already installed `Xcode `_ (which at the time of writing is freely available in the Mac App Store, or through http://developer.apple.com/downloads/ provided you registered for an Apple Developer account), you can install the command line tools from -there: with OS X Mavericks, run the command ``xcode-select --install`` -from a Terminal window and click "Install" in the pop-up dialog -box. Using OS X Mountain Lion or earlier, run Xcode, open its "Downloads" -preference pane and install the command line -tools from there. -On pre-Lion OS X systems, the command line tools are not available as a -separate download and you have to install the full-blown Xcode supporting your -system version. +there as well. + +- With OS X Mavericks or Yosemite, run the command + ``xcode-select --install`` from a Terminal window and click "Install" + in the pop-up dialog box. + +- Using OS X Mountain Lion or earlier, run Xcode, open its "Downloads" + preference pane and install the command line tools from there. + +- On pre-Lion OS X systems, the command line tools are not available as a + separate download and you have to install the full-blown Xcode supporting your + system version. + +If you have not installed `Xcode `_ +you can get these tools as a relatively small download, but it does require +a registration. + +- First, you will need to register as an Apple Developer at + http://developer.apple.com/register/. + +- Having done so, you should be able to download it for free at + http://developer.apple.com/downloads/index.action?=command%20line%20tools + +- Alternately, https://developer.apple.com/opensource/ should have a link + to Command Line Tools. + +Other platforms +^^^^^^^^^^^^^^^ On Solaris, you would use ``pkgadd`` and on OpenSolaris ``ipf`` to install the necessary software. @@ -290,7 +337,7 @@ you need to follow specific installation steps described in Although all necessary components are provided through Sage optional packages, i.e. you can install a local version of `OpenSSL `_ -by using Sage's **openssl** spkg and running ``sage -i openssl`` as suggested +by using Sage's **openssl** package and running ``sage -i openssl`` as suggested in :ref:`section_notebook_ssl` (this requires an Internet connection), you might prefer to install OpenSSL and the OpenSSL development headers globally on your system. @@ -1323,4 +1370,4 @@ would be appropriate if you have a Core i3/5/7 processor with AVX support. -**This page was last updated in May 2014 (Sage 6.2).** +**This page was last updated in October 2014 (Sage 6.4).** diff --git a/src/doc/en/reference/index.rst b/src/doc/en/reference/index.rst index 662a07944fe..bf6c7aeae25 100644 --- a/src/doc/en/reference/index.rst +++ b/src/doc/en/reference/index.rst @@ -29,7 +29,7 @@ Combinatorics, Discrete Mathematics * :doc:`Graph Theory ` * :doc:`Matroid Theory ` * :doc:`Discrete Dynamics ` -* :doc:`Quviers ` +* :doc:`Quivers ` Structures, Coercion, Categories -------------------------------- diff --git a/src/doc/en/thematic_tutorials/index.rst b/src/doc/en/thematic_tutorials/index.rst index 583d55ec2c8..d43fd917957 100644 --- a/src/doc/en/thematic_tutorials/index.rst +++ b/src/doc/en/thematic_tutorials/index.rst @@ -65,6 +65,11 @@ Coding Theory .. Monoids, Groups, representation Theory .. -------------------------------------- +Geometry +======== + +* :ref:`polytutorial` + Combinatorics ============= diff --git a/src/doc/en/thematic_tutorials/linear_programming.rst b/src/doc/en/thematic_tutorials/linear_programming.rst index 03b77e6ff25..186b4401239 100644 --- a/src/doc/en/thematic_tutorials/linear_programming.rst +++ b/src/doc/en/thematic_tutorials/linear_programming.rst @@ -77,13 +77,13 @@ solvers. Let us ask Sage to solve the following LP: .. MATH:: - \text{Max: } & x + y - 3z\\ + \text{Max: } & x + y + 3z\\ \text{Such that: } & x + 2y \leq 4\\ \text{} & 5z - y \leq 8\\ \text{} & x,y,z \geq 0\\ To achieve it, we need to define a corresponding ``MILP`` object, along with 3 -variables ``x,y`` and ``z``:: +variables ``x``, ``y`` and ``z``:: sage: p = MixedIntegerLinearProgram() sage: v = p.new_variable(real=True, nonnegative=True) @@ -116,7 +116,7 @@ the objective function sage: round(p.solve(), 2) 8.8 -We can read the optimal assignation found by the solver for `x, y` and +We can read the optimal assignation found by the solver for `x`, `y` and `z` through the ``get_values`` method .. link @@ -134,9 +134,9 @@ We can read the optimal assignation found by the solver for `x, y` and Variables ^^^^^^^^^ -In the previous example, we obtained variables through ``v['x'], v['y']`` and -``v['z']``. This being said, larger LP/MILP will require us to associate a LP -variable to many Sage objects, which can be integers, strings, or even the +In the previous example, we obtained variables through ``v['x']``, ``v['y']`` +and ``v['z']``. This being said, larger LP/MILP will require us to associate a +LP variable to many Sage objects, which can be integers, strings, or even the vertices and edges of a graph. For example: .. link diff --git a/src/doc/en/thematic_tutorials/polytutorial.rst b/src/doc/en/thematic_tutorials/polytutorial.rst new file mode 100644 index 00000000000..c731c10278a --- /dev/null +++ b/src/doc/en/thematic_tutorials/polytutorial.rst @@ -0,0 +1,387 @@ +.. -*- coding: utf-8 -*- + +.. linkall + +.. _polytutorial: + +A Brief Introduction to Polytopes in Sage +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. MODULEAUTHOR:: sarah-marie belcastro + +If you already know some convex geometry *a la* Grünbaum or +Brøndsted, then you may have itched to get your hands dirty with some +polytope calculations. Here is a mini\-guide to doing just that. + +Basics +"""""" + +First, let's define a polytope as the convex hull of a set of points, +i.e. given :math:`S` we compute :math:`P={\rm conv}(S)`: + + +:: + + sage: P1 = Polyhedron(vertices = [[-5,2], [4,4], [3,0], [1,0], [2,-4], [-3,-1], [-5,-3]]) + sage: P1 + A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 4 vertices + +.. end of output + +Notice that Sage tells you the dimension of the polytope as well as the +dimension of the ambient space. + +Of course, you want to know what this object looks like: + + +:: + + sage: show(P1) + Graphics object consisting of 6 graphics primitives + +.. end of output + +Even in only 2 dimensions, it's a pain to figure out what the supporting +hyperplanes are. Luckily Sage will take care of that for us. + + +:: + + sage: for q in P1.Hrepresentation(): + ....: print q + An inequality (-4, 1) x + 12 >= 0 + An inequality (1, 7) x + 26 >= 0 + An inequality (1, 0) x + 5 >= 0 + An inequality (2, -9) x + 28 >= 0 + +.. end of output + +That notation is not immediately parseable, because seriously, +those do not look like equations of lines (or of halfspaces, which is +really what they are). + +``(-4, 1) x + 12 >= 0`` really means :math:`(-4, 1)\cdot\vec{x} + 12 \geq 0`. + +So... if you want to define a polytope via inequalities, you have to +translate each inequality into a vector. For example, +:math:`(-4, 1)\cdot\vec{x} + 12 \geq 0` becomes (12, \-4, 1). + + +:: + + sage: altP1 = Polyhedron(ieqs=[(12, -4, 1), (26, 1, 7),(5,1,0), (28, 2, -9)]) + sage: show(altP1) + Graphics object consisting of 6 graphics primitives + +.. end of output + +Other information you might want to pull out of Sage about a polytope is the +vertex list, which can be done in two ways: + + +:: + + sage: for q in P1.Vrepresentation(): + ....: print q + A vertex at (-5, -3) + A vertex at (-5, 2) + A vertex at (4, 4) + A vertex at (2, -4) + +.. end of output + +:: + + sage: P1.vertices() + (A vertex at (-5, -3), A vertex at (-5, 2), A vertex at (4, 4), A vertex at (2, -4)) + +.. end of output + +Polar duals +""""""""""" + +Surely you want to compute the polar dual: + + +:: + + sage: P1dual = P1.polar() + sage: P1dual + A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 4 vertices + +.. end of output + +Check it out\-\-\-we started with an integer\-lattice polytope and dualized +to a rational\-lattice polytope. Let's look at that. + + + + +:: + + sage: show(P1dual) + Graphics object consisting of 6 graphics primitives + + +.. end of output + +:: + + sage: show(P1)+show(P1dual) + Graphics object consisting of 12 graphics primitives + + +.. end of output + +Oh, yeah, unless the polytope is unit\-sphere\-sized, the dual will be a +very different size. Let's rescale. + + +:: + + sage: show((1/4)*P1)+show(4*P1dual) + Graphics object consisting of 12 graphics primitives + +.. end of output + +If you think that looks a little bit shady, you're correct. Here is an +example that makes the issue a bit clearer. + + +:: + + sage: P2 = Polyhedron(vertices = [[-5,0], [-1,1], [-2,0], [1,0], [-2,-1], [-3,-1], [-5,-1]]) + sage: P2 + A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 5 vertices + sage: P2dual = P2.polar(); P2dual + A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 5 vertices + sage: show(P2)+show(P2dual) + Graphics object consisting of 14 graphics primitives + +.. end of output + +That is clearly not computing what we think of as the polar dual. But look +at this... + + +:: + + sage: show(P2)+show(-1*P2dual) + Graphics object consisting of 14 graphics primitives + +.. end of output + +Here is what's going on. + +If a polytope ``P`` is in `\ZZ`, then... + +(1) ...the dual is inverted in some way, which is vertically for polygons. + +(2) ...the dual is taken of P itself. + +(3) ...if the origin is not in P, then an error is returned. + +However, if a polytope is *not* in `\ZZ`, for example if it's in `\QQ` or +``RDF``, then... + +(1') ...the dual is not inverted. + +(2') ...the dual is taken of P\-translated\-so\-barycenter\-is\-at\-origin. + +Keep all of this in mind as you take polar duals. + + + +Polytope Constructions +"""""""""""""""""""""" + +Minkowski sums! Now with two syntaxes! + + +:: + + sage: P1+P2 + A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 8 vertices + +.. end of output + +:: + + sage: P1.Minkowski_sum(P2) + A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 8 vertices + +.. end of output + +Okay, fine. We should have some 3\-dimensional examples, at least. +(Note that in order to display polytopes effectively you'll need +visualization software such as Javaview and Jmol installed.) + + +:: + + sage: P3 = Polyhedron(vertices=[(0,0,0), (0,0,1/2), (0,1/2,0), (1/2,0,0), (3/4,1/5,3/2)]); P3 + A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 5 vertices + sage: P4 = Polyhedron(vertices=[(-1,1,0),(1,1,0),(-1,0,1), (1,0,1),(0,-1,1),(0,1,1)]); P4 + A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 6 vertices + sage: show(P3)+show(P4) + Graphics3d Object + +.. end of output + +:: + + sage: show(P3+P4) + Graphics3d Object + +.. end of output + +We can also find the intersection of two polytopes... and this too has two +syntaxes! + + +:: + + sage: int12 = P1.intersection(P2*.5); show(int12) + Graphics object consisting of 7 graphics primitives + +.. end of output + +:: + + sage: int34 = P3 & P4; show(int34) + Graphics3d Object + +.. end of output + +Should one wish to translate, one can. + + +:: + + sage: transP2 = P2.translation([2,1]) + sage: show(P2)+show(transP2) + Graphics object consisting of 14 graphics primitives + +.. end of output + +Then of course we can take prisms, pyramids, and bipyramids of polytopes... + + +:: + + sage: show(P2.prism()) + Graphics3d Object + +.. end of output + +:: + + sage: show(P1.pyramid()) + Graphics3d Object + +.. end of output + +:: + + sage: show(P2dual.bipyramid()) + Graphics3d Object + +.. end of output + +Okay, fine. Yes, Sage has some kinds of polytopes built in. +If you type ``polytopes.`` and then press ``TAB`` after the period, you'll get a +list of pre\-built polytopes. + + +:: + + sage: P5 = polytopes.n_cube(5) + sage: P6 = polytopes.cross_polytope(3) + sage: P7 = polytopes.n_simplex(7) + + +.. end of output + +Let's look at a 4\-dimensional polytope. + + +:: + + sage: P8 = polytopes.n_cube(4) + sage: P8.show() + Graphics3d Object + +.. end of output + +We can see it from a different perspective: + + +:: + + sage: P8.schlegel_projection([2,5,11,17]).plot() + Graphics3d Object + +.. end of output + +Queries to polytopes +"""""""""""""""""""" + +Once you've constructed some polytope, you can ask Sage questions about it. + + +:: + + sage: P1.contains([1,0]) + True + +.. end of output + +:: + + sage: P1.interior_contains([3,0]) + False + +.. end of output + +:: + + sage: P3.contains([1,0,0]) + False + +.. end of output + +Face information can be useful. + + +:: + + sage: int34.f_vector() + (1, 8, 12, 6, 1) + +.. end of output + +Well, geometric information might be *more* helpful... +Here we are told which of the vertices form each 2\-face: + + +:: + + sage: int34.faces(2) + (<1,3,4>, <0,1,3,5>, <0,1,2,4,6>, <2,3,4,5,7>, <2,6,7>, <0,5,6,7>) + +.. end of output + +Yeah, that isn't so useful as it is. Let's figure out the vertex and +hyperplane representations of the first face in the list. + + +:: + + sage: first2faceofint34 = P3.faces(2)[0] + sage: first2faceofint34.ambient_Hrepresentation(); first2faceofint34.vertices() + (An inequality (1, 0, 0) x + 0 >= 0,) + (A vertex at (0, 0, 0), A vertex at (0, 0, 1/2), A vertex at (0, 1/2, 0)) + +.. end of output + +If you want more... :ref:`sage.geometry.polyhedron.base` is the first place you want to go. diff --git a/src/doc/en/thematic_tutorials/toctree.rst b/src/doc/en/thematic_tutorials/toctree.rst index a6c0e37b95d..6d43d89fe69 100644 --- a/src/doc/en/thematic_tutorials/toctree.rst +++ b/src/doc/en/thematic_tutorials/toctree.rst @@ -13,6 +13,7 @@ Thematic tutorial document tree linear_programming numtheory_rsa coding_theory + polytutorial tutorial-programming-python tutorial-comprehensions tutorial-objects-and-classes diff --git a/src/doc/en/tutorial/tour_linalg.rst b/src/doc/en/tutorial/tour_linalg.rst index 04df8532337..aa66b484628 100644 --- a/src/doc/en/tutorial/tour_linalg.rst +++ b/src/doc/en/tutorial/tour_linalg.rst @@ -114,7 +114,7 @@ respectively, which do not support these computations for all the cases:: sage: ARDF.eigenvalues() # rel tol 8e-16 [-0.09317121994613098, 4.293171219946131] sage: ACDF = matrix(CDF, [[1.2, I], [2, 3]]) - sage: ACDF.eigenvectors_right() # rel tol 2e-15 + sage: ACDF.eigenvectors_right() # rel tol 3e-15 [(0.8818456983293743 - 0.8209140653434135*I, [(0.7505608183809549, -0.616145932704589 + 0.2387941530333261*I)], 1), (3.3181543016706256 + 0.8209140653434133*I, [(0.14559469829270957 + 0.3756690858502104*I, 0.9152458258662108)], 1)] diff --git a/src/doc/fr/tutorial/tour_linalg.rst b/src/doc/fr/tutorial/tour_linalg.rst index 0b896ed139a..19a6e0dee63 100644 --- a/src/doc/fr/tutorial/tour_linalg.rst +++ b/src/doc/fr/tutorial/tour_linalg.rst @@ -115,7 +115,7 @@ ce ne sont pas ``RDF`` ou ``CDF`` qui sont utilisés par défaut, mais ``RR`` et sage: ARDF.eigenvalues() # rel tol 8e-16 [-0.09317121994613098, 4.293171219946131] sage: ACDF = matrix(CDF, [[1.2, I], [2, 3]]) - sage: ACDF.eigenvectors_right() # rel tol 2e-15 + sage: ACDF.eigenvectors_right() # rel tol 3e-15 [(0.8818456983293743 - 0.8209140653434135*I, [(0.7505608183809549, -0.616145932704589 + 0.2387941530333261*I)], 1), (3.3181543016706256 + 0.8209140653434133*I, [(0.14559469829270957 + 0.3756690858502104*I, 0.9152458258662108)], 1)] diff --git a/src/doc/ru/tutorial/tour_linalg.rst b/src/doc/ru/tutorial/tour_linalg.rst index 359f4b3626e..f77d7241bbd 100644 --- a/src/doc/ru/tutorial/tour_linalg.rst +++ b/src/doc/ru/tutorial/tour_linalg.rst @@ -109,7 +109,7 @@ Sage может находить собственное число и собст sage: ARDF.eigenvalues() # rel tol 8e-16 [-0.09317121994613098, 4.293171219946131] sage: ACDF = matrix(CDF, [[1.2, I], [2, 3]]) - sage: ACDF.eigenvectors_right() # rel tol 2e-15 + sage: ACDF.eigenvectors_right() # rel tol 3e-15 [(0.8818456983293743 - 0.8209140653434135*I, [(0.7505608183809549, -0.616145932704589 + 0.2387941530333261*I)], 1), (3.3181543016706256 + 0.8209140653434133*I, [(0.14559469829270957 + 0.3756690858502104*I, 0.9152458258662108)], 1)] diff --git a/src/module_list.py b/src/module_list.py index c254bf97c16..cc33b3c86fd 100755 --- a/src/module_list.py +++ b/src/module_list.py @@ -712,6 +712,10 @@ def uname_specific(name, value, alternative): extra_compile_args=["-DFPLLL_V3_COMPAT"], depends = [SAGE_INC + "/fplll/fplll.h"] + flint_depends), + Extension('sage.libs.gmp.rational_reconstruction', + sources = ['sage/libs/gmp/rational_reconstruction.pyx'], + libraries = ['gmp']), + Extension('sage.libs.linbox.linbox', sources = ['sage/libs/linbox/linbox.pyx'], # For this to work on cygwin, linboxsage *must* be @@ -730,8 +734,6 @@ def uname_specific(name, value, alternative): extra_compile_args=["-O3", "-ffast-math"], language = 'c++'), - - Extension('sage.libs.libecm', sources = ['sage/libs/libecm.pyx'], libraries = ['ecm', 'gmp'], diff --git a/src/sage/combinat/binary_recurrence_sequences.py b/src/sage/combinat/binary_recurrence_sequences.py index 20dcb051667..29e28b613a7 100644 --- a/src/sage/combinat/binary_recurrence_sequences.py +++ b/src/sage/combinat/binary_recurrence_sequences.py @@ -362,7 +362,7 @@ def is_arithmetic(self): #Test if u_1-u_0 = u_2-u_1 = u_3-u_2 - return bool(self(1) - self(0) == self(2) - self(1) == self(3) - self(2)) + return bool(self(1) - self(0) == self(2) - self(1) == self(3) - self(2)) def period(self, m): @@ -792,10 +792,10 @@ def _prime_powers(N): [65537] """ - - output = sorted([i**j for i,j in N.factor()]) + output = sorted([i ** j for i, j in N.factor()]) return output + #This function finds the largest prime power divisor of an integer N def _largest_ppower_divisor(N): @@ -1036,7 +1036,7 @@ def _is_p_power_mod(a,p,N): #If q = p and ee = 1, then everything is a pth power p by Fermat's little theorem. - elif ee > 1: + elif ee > 1: #We use the strong statement of Hensel's lemma, which implies that if p is odd #and aa is a pth power mod p^2, then aa is a pth power mod any higher power of p diff --git a/src/sage/combinat/cluster_algebra_quiver/mutation_type.py b/src/sage/combinat/cluster_algebra_quiver/mutation_type.py index 104351fdac2..a322a630f40 100644 --- a/src/sage/combinat/cluster_algebra_quiver/mutation_type.py +++ b/src/sage/combinat/cluster_algebra_quiver/mutation_type.py @@ -960,11 +960,11 @@ def _connected_mutation_type_AAtildeD(dg, ret_conn_vert=False): # test that there is no triple-edge or higher multiplicity and that there is at most one double-edge. if dg.has_multiple_edges(): multiple_edges = dg.multiple_edges(labels=False) - if len( multiple_edges ) > 2: + if len(multiple_edges) > 2: return _false_return(14) - elif len( multiple_edges ) == 2: + elif len(multiple_edges) == 2: # we think of the double-edge as a long_cycle, an unoriented 2-cycle. - long_cycle = [ multiple_edges, ['A',n-1,1] ] + long_cycle = [multiple_edges, ['A', n - 1, 1]] # creating a dictionary of in-, out- and total degrees dict_in_out = {} diff --git a/src/sage/combinat/cluster_algebra_quiver/quiver.py b/src/sage/combinat/cluster_algebra_quiver/quiver.py index 38ce9ca9450..f0f3a948b79 100644 --- a/src/sage/combinat/cluster_algebra_quiver/quiver.py +++ b/src/sage/combinat/cluster_algebra_quiver/quiver.py @@ -1381,13 +1381,14 @@ def mutation_class_iter( self, depth=infinity, show_depth=False, return_paths=Fa elif data_type == "digraph": next_element = data[0] elif data_type == "dig6": - next_element = data[0] + next_element = data[0] elif data_type == "path": - next_element = data[1] + next_element = data[1] else: - raise ValueError("The parameter for data_type was not recognized.") + raise ValueError("The parameter for data_type was " + "not recognized.") if return_paths: - yield ( next_element, data[1] ) + yield (next_element, data[1]) else: yield next_element diff --git a/src/sage/combinat/combinat.py b/src/sage/combinat/combinat.py index db8b608d261..ca5200cedd3 100644 --- a/src/sage/combinat/combinat.py +++ b/src/sage/combinat/combinat.py @@ -1637,7 +1637,7 @@ def __rank_from_iterator(self, obj): r += 1 raise ValueError - rank = __rank_from_iterator + rank = __rank_from_iterator def __first_from_iterator(self): """ @@ -2549,10 +2549,11 @@ def bell_polynomial(n, k): power_factorial_product *= factorial(part)**count coefficient = factorial(n) / (factorial_product * power_factorial_product) - result += coefficient * prod([vars[i-1] for i in p]) + result += coefficient * prod([vars[i - 1] for i in p]) return result + def fibonacci_sequence(start, stop=None, algorithm=None): r""" Return an iterator over the Fibonacci sequence, for all fibonacci diff --git a/src/sage/combinat/designs/covering_design.py b/src/sage/combinat/designs/covering_design.py index db1bec0f030..11caedcbb8c 100644 --- a/src/sage/combinat/designs/covering_design.py +++ b/src/sage/combinat/designs/covering_design.py @@ -222,14 +222,17 @@ def __repr__(self): Lower bound: 7 Method: Projective Plane """ - repr = '(%d,%d,%d)-covering design of size %d\n'%(self.__v,self.__k,self.__t,self.__size) - repr += 'Lower bound: %d\n'%(self.__low_bd) + repr = '(%d,%d,%d)-covering design of size %d\n' % (self.__v, + self.__k, + self.__t, + self.__size) + repr += 'Lower bound: %d\n' % (self.__low_bd) if self.__creator != '': - repr += 'Created by: %s\n'%(self.__creator) + repr += 'Created by: %s\n' % (self.__creator) if self.__method != '': - repr += 'Method: %s\n'%(self.__method) + repr += 'Method: %s\n' % (self.__method) if self.__timestamp != '': - repr += 'Submitted on: %s\n'%(self.__timestamp) + repr += 'Submitted on: %s\n' % (self.__timestamp) return repr diff --git a/src/sage/combinat/designs/orthogonal_arrays.py b/src/sage/combinat/designs/orthogonal_arrays.py index adf7375bf5c..2f6f20449d4 100644 --- a/src/sage/combinat/designs/orthogonal_arrays.py +++ b/src/sage/combinat/designs/orthogonal_arrays.py @@ -609,7 +609,8 @@ def wilson_construction(OA,k,r,m,u,check=True,explain_construction=False): if OA is None: master_design = orthogonal_array(k+n_trunc,r,check=False) matrix = [range(r)]*k - for ((_,uu),) in u: + for uu in u: + uu = sum(x[1] for x in uu) matrix.append(range(uu)+[None]*(r-uu)) master_design = OA_relabel(master_design, k+n_trunc, r, matrix=matrix) else: diff --git a/src/sage/combinat/designs/orthogonal_arrays_build_recursive.py b/src/sage/combinat/designs/orthogonal_arrays_build_recursive.py index b36d6aba619..32ca93f8599 100644 --- a/src/sage/combinat/designs/orthogonal_arrays_build_recursive.py +++ b/src/sage/combinat/designs/orthogonal_arrays_build_recursive.py @@ -26,7 +26,6 @@ :func:`thwart_lemma_4_1` | Returns an `OA(k,nm+4(n-2))`. :func:`three_factor_product` | Returns an `OA(k+1,n_1n_2n_3)`. :func:`brouwer_separable_design` | Returns a `OA(k,t(q^2+q+1)+x)` using Brouwer's result on separable designs. - :func:`brouwer_van_rees_with_one_truncated_column` | Return an `OA(k,rm+\sum_{1\leq i\leq c} u_i)` using the Brouwer-van Rees construction with one truncated column. Functions --------- @@ -1762,42 +1761,3 @@ def brouwer_separable_design(k,t,q,x,check=False,verbose=False,explain_construct if check: assert is_orthogonal_array(OA,k,N,2,1) return OA - -def brouwer_van_rees_with_one_truncated_column(k,r,m,u): - r""" - Return an `OA(k,rm+\sum_{1\leq i\leq c} u_i)` using the - Brouwer-van Rees construction with one truncated column. - - Let `n=rm+\sum_{1\leq i\leq c}` such that `c\leq r`. The - generalization of Wilson's construction found by Brouwer and van - Rees (with one truncated column) ensures that an `OA(k,n)` exists - if the following designs exist: `OA(k+1,r)`, `OA(k,m)`, - `OA(k,\sum_{1\leq i\leq c} u_i)`, `OA(k,m+x_1)-OA(k,x_1)`, ..., - `OA(k,m+x_c)-OA(k,x_c)`. - - For more information, see the documentation of - :func:`~sage.combinat.designs.orthogonal_arrays.wilson_construction`. - - INPUT: - - - ``k,r,m`` (integers) - - - ``u`` (list of integers of length `\leq r`). - - .. SEEALSO:: - - :func:`~sage.combinat.designs.orthogonal_arrays_find_recursive.find_brouwer_van_rees_with_one_truncated_column` - - EXAMPLE:: - - sage: from sage.combinat.designs.orthogonal_arrays_build_recursive import brouwer_van_rees_with_one_truncated_column - sage: from sage.combinat.designs.orthogonal_arrays import is_orthogonal_array - sage: OA = brouwer_van_rees_with_one_truncated_column(5, 7, 7, (2, 2)) - sage: is_orthogonal_array(OA,5,53) - True - """ - OA = orthogonal_array(k+1,r) - c = len(u) - OA = [[x if (i v1._len or step > v2._len: - raise IndexError, "list index out of range" + raise IndexError("list index out of range") for i in range(step): if v1._list[i] != v2._list[i]: diff --git a/src/sage/combinat/expnums.pyx b/src/sage/combinat/expnums.pyx index 3a038e0bcb6..cf0b1a033cf 100644 --- a/src/sage/combinat/expnums.pyx +++ b/src/sage/combinat/expnums.pyx @@ -85,7 +85,8 @@ def expnums(int n, int aa): cdef mpz_t *bell bell = sage_malloc(sizeof(mpz_t) * (n+1)) if bell == NULL: - raise MemoryError, "out of memory allocating temporary storage in expnums" + raise MemoryError("out of memory allocating temporary " + "storage in expnums") cdef mpz_t a mpz_init_set_si(a, aa) mpz_init_set_si(bell[1], aa) diff --git a/src/sage/combinat/finite_state_machine.py b/src/sage/combinat/finite_state_machine.py index 44a021d472f..754864fab88 100644 --- a/src/sage/combinat/finite_state_machine.py +++ b/src/sage/combinat/finite_state_machine.py @@ -3465,9 +3465,9 @@ def __call__(self, *args, **kwargs): if is_FiniteStateMachine(args[0]): return self.composition(*args, **kwargs) if hasattr(args[0], '__iter__'): - if not kwargs.has_key('full_output'): + if not 'full_output' in kwargs: kwargs['full_output'] = False - if not kwargs.has_key('list_of_outputs'): + if not 'list_of_outputs' in kwargs: kwargs['list_of_outputs'] = False return self.process(*args, **kwargs) raise TypeError("Do not know what to do with that arguments.") @@ -11903,13 +11903,13 @@ def _push_branch_(self, state, tape_cache, outputs): (True, 3, 'i:)'), (True, 3, 'l:)'), (True, 3, 'n:)')] """ - if self._current_.has_key(tape_cache.position): + if tape_cache.position in self._current_: states = self._current_[tape_cache.position] else: states = self._current_[tape_cache.position] = {} heapq.heappush(self._current_positions_, tape_cache.position) - if states.has_key(state): + if state in states: existing_tape_cache, existing_outputs = states[state] existing_outputs.extend(outputs) existing_outputs = [t for t, _ in diff --git a/src/sage/combinat/k_tableau.py b/src/sage/combinat/k_tableau.py index 5e15541891d..d4f29b0114d 100644 --- a/src/sage/combinat/k_tableau.py +++ b/src/sage/combinat/k_tableau.py @@ -1866,8 +1866,8 @@ def __classcall_private__(cls, t, k, inner_shape = []): return t W = WeylGroup(['A', k, 1], prefix='s') w = cls.straighten_input(t, k) - weight = tuple(w[i].length() for i in range(len(w)-1,-1,-1)) - inner_shape = Core(inner_shape, k+1) + weight = tuple(w[i].length() for i in range(len(w) - 1, -1, -1)) + inner_shape = Core(inner_shape, k + 1) outer_shape = (W.prod(w)*W(inner_shape.to_grassmannian())).affine_grassmannian_to_core() return WeakTableaux_factorized_permutation(k, [outer_shape, inner_shape], weight)(w) @@ -1987,9 +1987,10 @@ def check(self): ... ValueError: The weight of the parent does not agree with the weight of the tableau! """ - weight = tuple(self[i].length() for i in range(len(self)-1,-1,-1)) + weight = tuple(self[i].length() for i in range(len(self) - 1, -1, -1)) if not self.parent()._weight == weight: - raise ValueError("The weight of the parent does not agree with the weight of the tableau!") + raise ValueError("The weight of the parent does not agree " + "with the weight of the tableau!") W = self[0].parent() outer = (W.prod(self)*W((self._inner_shape).to_grassmannian())).affine_grassmannian_to_core() if self.parent()._outer_shape != outer: @@ -2273,7 +2274,7 @@ def __init__(self, parent, T): """ INPUT: - - ``parent`` - an instance of ``StrongTableaux`` + - ``parent`` -- an instance of ``StrongTableaux`` - ``T`` -- standard marked strong (possibly skew) `k`-tableau or a semistandard marked strong (possibly skew) `k`-tableau with inner cells represented by ``None`` @@ -2389,7 +2390,7 @@ def __classcall_private__(cls, T, k, weight=None): if weight is not None and tuple(weight)!=count_marks: raise ValueError("Weight = %s and tableau = %s do not agree"%(weight, T)) tijseq = StrongTableaux.marked_CST_to_transposition_sequence(T, k) - if len(tijseq) 12: - raise ValueError, "Cowardly refusing to enumerate the permutations on more than 12 letters." + raise ValueError("Cowardly refusing to enumerate the permutations " + "on more than 12 letters.") m = n-1 N = n @@ -157,14 +158,16 @@ def permutation_iterator_transposition_list(int n): c = sage_malloc(2*n*sizeof(int)) if c is NULL: - raise MemoryError, "Failed to allocate memory in permutation_iterator_transposition_list" + raise MemoryError("Failed to allocate memory in " + "permutation_iterator_transposition_list") o = c + n try: T = PyList_New(N-1) except Exception: sage_free(c) - raise MemoryError, "Failed to allocate memory in permutation_iterator_transposition_list" + raise MemoryError("Failed to allocate memory in " + "permutation_iterator_transposition_list") reset_swap(n,c,o) for m in range(N-1): diff --git a/src/sage/combinat/ribbon_tableau.py b/src/sage/combinat/ribbon_tableau.py index 9549c8e3629..0623a9330cb 100644 --- a/src/sage/combinat/ribbon_tableau.py +++ b/src/sage/combinat/ribbon_tableau.py @@ -474,7 +474,8 @@ def insertion_tableau(skp, perm, evaluation, tableau, length): tableau[-(k+1)] += [0]* ( skp[0][k] - partc[k] - len(tableau[-(k+1)])) ## We construct a tableau from the southwest corner to the northeast one - tableau = [[0]*(skp[0][k] - partc[k]) for k in reversed(range(len(tableau), len(skp[0])))] + tableau + tableau = [[0] * (skp[0][k] - partc[k]) + for k in reversed(range(len(tableau), len(skp[0])))] + tableau tableau = SkewTableaux().from_expr([skp[1], tableau]).conjugate() tableau = tableau.to_expr()[1] @@ -625,7 +626,8 @@ def spin_rec(t, nexts, current, part, weight, length): #compute the contribution of the ribbons added at #the current node for perms in [current[i][1] for i in range(len(current))]: - perm = [partp[i] + len(partp)-(i+1)-perms[i] for i in range(len(partp))] + perm = [partp[i] + len(partp) - (i + 1) - perms[i] + for i in range(len(partp))] perm.reverse() perm = Word(perm).standard_permutation() tmp.append( (weight[-1]*(length-1)-perm.number_of_inversions()) ) diff --git a/src/sage/combinat/root_system/non_symmetric_macdonald_polynomials.py b/src/sage/combinat/root_system/non_symmetric_macdonald_polynomials.py index 58ded993349..a74b01bce25 100644 --- a/src/sage/combinat/root_system/non_symmetric_macdonald_polynomials.py +++ b/src/sage/combinat/root_system/non_symmetric_macdonald_polynomials.py @@ -1806,7 +1806,7 @@ def symmetric_macdonald_polynomial(self, mu): """ if self.cartan_type().classical() != mu.parent().cartan_type() or not mu.is_dominant(): - raise ValueError, "%s must be a dominant weight for the classical subrootsystem of %s"%(mu,self.cartan_type()) + raise ValueError("%s must be a dominant weight for the classical subrootsystem of %s" % (mu, self.cartan_type())) v = self._q1 KL0 = self.KL0() s = KL0.zero() diff --git a/src/sage/combinat/root_system/root_lattice_realizations.py b/src/sage/combinat/root_system/root_lattice_realizations.py index 11eafe1db8c..7322f1757a9 100644 --- a/src/sage/combinat/root_system/root_lattice_realizations.py +++ b/src/sage/combinat/root_system/root_lattice_realizations.py @@ -714,10 +714,12 @@ def nonparabolic_positive_roots(self, index_set = None): """ if not self.cartan_type().is_finite(): - raise NotImplementedError, "Only implemented for finite Cartan type" + raise NotImplementedError("Only implemented for " + "finite Cartan type") if index_set is None: return [] - return [x for x in self.positive_roots() if not x in self.positive_roots(index_set)] + return [x for x in self.positive_roots() + if not x in self.positive_roots(index_set)] @cached_method def nonparabolic_positive_root_sum(self, index_set=None): diff --git a/src/sage/combinat/skew_tableau.py b/src/sage/combinat/skew_tableau.py index 92dea634abc..cf9da182024 100644 --- a/src/sage/combinat/skew_tableau.py +++ b/src/sage/combinat/skew_tableau.py @@ -1062,7 +1062,7 @@ def to_ribbon(self): if not self.is_ribbon(): raise ValueError("self must be a ribbon") from sage.combinat.ribbon_shaped_tableau import RibbonShapedTableau - r = [ [i for i in row if i is not None] for row in self] + r = [[i for i in row if i is not None] for row in self] return RibbonShapedTableau(r) def filling(self): @@ -1075,7 +1075,7 @@ def filling(self): sage: t.filling() [[1], [2, 3]] """ - return [ [i for i in row if i is not None] for row in self ] + return [[i for i in row if i is not None] for row in self] def cells_by_content(self, c): """ diff --git a/src/sage/combinat/symmetric_group_algebra.py b/src/sage/combinat/symmetric_group_algebra.py index f6165084224..33f1b8a00d7 100644 --- a/src/sage/combinat/symmetric_group_algebra.py +++ b/src/sage/combinat/symmetric_group_algebra.py @@ -1502,14 +1502,14 @@ def epsilon_ik(itab, ktab, star=0): if kt == it: res = epsilon(itab) elif (it, kt) in epsilon_ik_cache: - res = epsilon_ik_cache[(it,kt)] + res = epsilon_ik_cache[(it, kt)] else: eik = e_ik(it, kt, star) QSn = eik.parent() mul = QSn.right_action_product - epsilon_ik_cache[(it,kt)] = mul(mul(epsilon(it, star+1), eik), - epsilon(kt, star+1)) * (1/kappa(it.shape())) - res = epsilon_ik_cache[(it,kt)] + epsilon_ik_cache[(it, kt)] = mul(mul(epsilon(it, star+1), eik), + epsilon(kt, star+1)) * (1/kappa(it.shape())) + res = epsilon_ik_cache[(it, kt)] return res @@ -1543,11 +1543,11 @@ def epsilon(tab, star=0): res = epsilon_cache[t] else: if t.size() == 2: - epsilon_cache[t] = e(t)*(1 / kappa(t.shape())) - res = epsilon_cache[t] + epsilon_cache[t] = e(t) * (1 / kappa(t.shape())) + res = epsilon_cache[t] elif t == Tableau([[1]]): epsilon_cache[t] = e(t) - res = epsilon_cache[t] + res = epsilon_cache[t] else: et = e(t) QSn = et.parent() diff --git a/src/sage/combinat/words/word_datatypes.pyx b/src/sage/combinat/words/word_datatypes.pyx index 1e2f771dca4..86730d3b1c5 100644 --- a/src/sage/combinat/words/word_datatypes.pyx +++ b/src/sage/combinat/words/word_datatypes.pyx @@ -709,7 +709,7 @@ cdef class WordDatatype_str(WordDatatype): elif isinstance(sep, WordDatatype_str): sep = sep._data else: - raise ValueError, "the separator must be a string." + raise ValueError("the separator must be a string.") if maxsplit is None: return map(self._parent, self._data.split(sep)) @@ -760,8 +760,7 @@ cdef class WordDatatype_str(WordDatatype): return map(self._parent, self._data.partition(sep)) elif isinstance(sep, WordDatatype_str): return map(self._parent, self._data.partition(sep._data)) - else: - raise ValueError, "the separator must be a string." + raise ValueError("the separator must be a string.") def is_suffix(self, other): r""" diff --git a/src/sage/crypto/mq/sbox.py b/src/sage/crypto/mq/sbox.py index c668832166f..8706fbe6ef8 100644 --- a/src/sage/crypto/mq/sbox.py +++ b/src/sage/crypto/mq/sbox.py @@ -6,7 +6,7 @@ from sage.matrix.constructor import Matrix from sage.misc.misc_c import prod as mul from sage.modules.free_module_element import vector -from sage.rings.finite_rings.element_ext_pari import is_FiniteFieldElement +from sage.rings.finite_rings.element_base import is_FiniteFieldElement from sage.rings.finite_rings.constructor import FiniteField as GF from sage.rings.ideal import FieldIdeal, Ideal from sage.rings.integer_ring import ZZ diff --git a/src/sage/ext/fast_callable.pyx b/src/sage/ext/fast_callable.pyx index da15b3d5ecb..9fd44e3f33e 100644 --- a/src/sage/ext/fast_callable.pyx +++ b/src/sage/ext/fast_callable.pyx @@ -1788,7 +1788,7 @@ cpdef generate_code(Expression expr, InstructionStream stream): sage: fc = fast_callable(etb(x)^expo, domain=RDF) sage: fc.op_list() [('load_arg', 0), ('py_call', (^4294967296), 1), 'return'] - sage: fc(base) + sage: fc(base) # rel tol 1e-15 1.0000009536747712 sage: RDF(base)^expo 1.0000009536747712 diff --git a/src/sage/ext/gmp.pxi b/src/sage/ext/gmp.pxi index 9a3e9f34886..d71f3f609a6 100644 --- a/src/sage/ext/gmp.pxi +++ b/src/sage/ext/gmp.pxi @@ -45,68 +45,3 @@ cdef object mpz_to_str(mpz_t x): sig_unblock() sig_off() return t - -cdef int mpq_rational_reconstruction(mpq_t answer, mpz_t a, mpz_t m) except -1: - """ - Set answer to the unique mpq is a modulo m such that ... - - We assume that answer has been mpq_init'd. - If the rational reconstruction doesn't exist, - raises a ValueError - """ -## #debug -## cdef char* s -## s = mpz_get_str(NULL, 10, a) -## t = str(s) -## print 'a = ', t -## s = mpz_get_str(NULL, 10, m) -## t = str(s) -## print 'm = ', t -## #debug - sig_on() - mpz_mod(a, a, m) # a = a % m - if mpz_sgn(a) == 0 or mpz_sgn(m) == 0: # a or m is zero - mpq_set_si(answer, 0, 1) # return 0 - sig_off() - return 0 - if mpz_sgn(m) < 0: # m negative - mpz_neg(m, m) # replace m by -m - if mpz_sgn(a) < 0: # a negative - mpz_sub(a, m, a) # replace a by m - a - if mpz_cmp_si(a, 1) == 0: # if a is 1 - mpq_set_si(answer, 1, 1) - sig_off() - return 0 - - mpz_set(u, m) # u = m - mpz_set(v, a) # v = a - mpz_set_si(u0,1); mpz_set_si(u1,0); mpz_set(u2,u) - mpz_set_si(v0,0); mpz_set_si(v1,1); mpz_set(v2,v) - mpz_fdiv_q_ui(m2, m, 2) - while 1: - mpz_mul(ssqr, v2, v2) - if mpz_cmp(ssqr, m2) <= 0: - break - mpz_fdiv_q(q, u2, v2) # q = floor of u2/v2 - mpz_mul(x, q, v0); mpz_sub(t0, u0, x) # t0 = u0-q*v0 - mpz_mul(x, q, v1); mpz_sub(t1, u1, x) # t0 = u1-q*v1 - mpz_mul(x, q, v2); mpz_sub(t2, u2, x) # t0 = u2-q*v2 - mpz_set(u0,v0); mpz_set(u1,v1); mpz_set(u2,v2) # permute - mpz_set(v0,t0); mpz_set(v1,t1); mpz_set(v2,t2) - - mpz_abs(x, v1) - mpz_set(y, v2) - if mpz_sgn(v1)<0: - mpz_neg(y, y) - mpz_mul(ssqr, x, x) - mpz_gcd(q, x, y) - if mpz_cmp(ssqr, m2) <= 0 and mpz_cmp_si(q, 1) == 0: - # return y/x - mpq_set_z(answer, y) - mpq_set_z(tmp, x) - mpq_div(answer, answer, tmp) - sig_off() - return 0 - - sig_off() - raise ValueError, "Rational reconstruction of %s (mod %s) does not exist."%(mpz_to_str(a),mpz_to_str(m)) diff --git a/src/sage/functions/bessel.py b/src/sage/functions/bessel.py index a5c1b93b74b..891930e77ac 100644 --- a/src/sage/functions/bessel.py +++ b/src/sage/functions/bessel.py @@ -722,7 +722,7 @@ class Function_Bessel_K(BuiltinFunction): sage: f = bessel_K(2, x) sage: f.diff(x) - 1/2*bessel_K(3, x) + 1/2*bessel_K(1, x) + -1/2*bessel_K(3, x) - 1/2*bessel_K(1, x) sage: bessel_K(1/2, x) bessel_K(1/2, x) @@ -842,7 +842,7 @@ def _derivative_(self, n, x, diff_param): sage: f(x) = bessel_K(10, x) sage: derivative(f, x) - x |--> 1/2*bessel_K(11, x) + 1/2*bessel_K(9, x) + x |--> -1/2*bessel_K(11, x) - 1/2*bessel_K(9, x) sage: nu = var('nu') sage: bessel_K(nu, x).diff(nu) Traceback (most recent call last): @@ -850,7 +850,7 @@ def _derivative_(self, n, x, diff_param): NotImplementedError: derivative with respect to order """ if diff_param == 1: - return (bessel_K(n - 1, x) + bessel_K(n + 1, x)) / Integer(2) + return -(bessel_K(n - 1, x) + bessel_K(n + 1, x)) / Integer(2) else: raise NotImplementedError('derivative with respect to order') diff --git a/src/sage/geometry/polyhedron/plot.py b/src/sage/geometry/polyhedron/plot.py index f7032549d85..baed522eb18 100644 --- a/src/sage/geometry/polyhedron/plot.py +++ b/src/sage/geometry/polyhedron/plot.py @@ -710,6 +710,18 @@ def _init_dimension(self): pass def show(self, *args, **kwds): + """ + Deprecated method to show the projection as a graphics + object. Use ``Projection.plot()`` instead. + + EXAMPLE:: + + sage: P8 = polytopes.n_cube(4) + sage: P8.schlegel_projection([2,5,11,17]).show() + doctest:...: DeprecationWarning: use Projection.plot instead + See http://trac.sagemath.org/16625 for details. + Graphics3d Object + """ from sage.misc.superseded import deprecation deprecation(16625, 'use Projection.plot instead') return self.plot(*args, **kwds) diff --git a/src/sage/groups/matrix_gps/group_element.py b/src/sage/groups/matrix_gps/group_element.py index cfd9e370724..1b9a3d01810 100644 --- a/src/sage/groups/matrix_gps/group_element.py +++ b/src/sage/groups/matrix_gps/group_element.py @@ -99,7 +99,6 @@ def is_MatrixGroupElement(x): return isinstance(x, MatrixGroupElement_base) - class MatrixGroupElement_base(MultiplicativeGroupElement): """ Base class for elements of matrix groups. @@ -107,10 +106,10 @@ class MatrixGroupElement_base(MultiplicativeGroupElement): You should use one of the two subclasses: * :class:`MatrixGroupElement_sage` implements the group - mulitplication using Sage matrices. + multiplication using Sage matrices. * :class:`MatrixGroupElement_gap` implements the group - mulitplication using libGAP matrices. + multiplication using libGAP matrices. The base class only assumes that derived classes implement :meth:`matrix`. diff --git a/src/sage/groups/misc_gps/misc_groups_catalog.py b/src/sage/groups/misc_gps/misc_groups_catalog.py index 01ca357151a..307336fd382 100644 --- a/src/sage/groups/misc_gps/misc_groups_catalog.py +++ b/src/sage/groups/misc_gps/misc_groups_catalog.py @@ -13,7 +13,7 @@ # docstring of groups/groups_catalog.py from sage.groups.additive_abelian.additive_abelian_group import AdditiveAbelianGroup as AdditiveAbelian -from sage.groups.abelian_gps.abelian_group import AbelianGroup as MulitplicativeAbelian +from sage.groups.abelian_gps.abelian_group import AbelianGroup as MultiplicativeAbelian from sage.rings.finite_rings.integer_mod_ring import IntegerModRing as AdditiveCyclic from sage.groups.free_group import FreeGroup as Free from sage.groups.braid import BraidGroup as Braid diff --git a/src/sage/gsl/probability_distribution.pyx b/src/sage/gsl/probability_distribution.pyx index 5b0efea6f50..e809503d8ec 100644 --- a/src/sage/gsl/probability_distribution.pyx +++ b/src/sage/gsl/probability_distribution.pyx @@ -43,7 +43,8 @@ include 'sage/ext/stdsage.pxi' include 'gsl.pxi' #cimport sage.rings.real_double #import sage.rings.real_double -import random, sys +import sage.misc.prandom as random +import sys import integration from sage.modules.free_module_element import vector @@ -116,9 +117,18 @@ cdef class ProbabilityDistribution: sage: P = [0.3, 0.4, 0.3] sage: X = GeneralDiscreteDistribution(P) sage: h, b = X.generate_histogram_data(bins = 10) - sage: h # random - [1.5249999999999995, 0.0, 0.0, 0.0, 0.0, 1.8649999999999995, 0.0, 0.0, 0.0, 1.6099999999999994] - sage: b # random + sage: h + [1.6299999999999999, + 0.0, + 0.0, + 0.0, + 0.0, + 1.9049999999999985, + 0.0, + 0.0, + 0.0, + 1.4650000000000003] + sage: b [0.0, 0.20000000000000001, 0.40000000000000002, 0.60000000000000009, 0.80000000000000004, 1.0, 1.2000000000000002, 1.4000000000000001, 1.6000000000000001, 1.8, 2.0] """ @@ -175,11 +185,11 @@ cdef class SphericalDistribution(ProbabilityDistribution): EXAMPLES:: sage: T = SphericalDistribution() - sage: T.get_random_element() # random - (-0.872578667429, -0.29632873418, -0.388324285164) + sage: T.get_random_element() # rel tol 1e-14 + (-0.2922296724828204, -0.9563459345927822, 0.0020668595602153454) sage: T = SphericalDistribution(dimension = 4, rng = 'luxury') - sage: T.get_random_element() # random - (-0.196597969334, -0.536955365418, -0.672242159448, -0.470232552109) + sage: T.get_random_element() # rel tol 1e-14 + (-0.0363300434761631, 0.6459885817544098, 0.24825817345598158, 0.7209346430129753) TESTS: @@ -202,8 +212,8 @@ cdef class SphericalDistribution(ProbabilityDistribution): EXAMPLES:: sage: T = SphericalDistribution() - sage: T.get_random_element() # random - (-0.872578667429, -0.29632873418, -0.388324285164) + sage: T.get_random_element() # rel tol 1e-14 + (-0.2922296724828204, -0.9563459345927822, 0.0020668595602153454) TESTS: @@ -226,10 +236,8 @@ cdef class SphericalDistribution(ProbabilityDistribution): self.set_random_number_generator(rng) self.r = gsl_rng_alloc(self.T) if seed is None: - self.seed = random.randint(1, sys.maxsize) - else: - self.seed = seed - self.set_seed(self.seed) + seed = random.randint(1, 2**31) + self.set_seed(seed) self.dimension = dimension self.vec = sage_malloc(self.dimension*(sizeof(double))) @@ -328,8 +336,8 @@ cdef class RealDistribution(ProbabilityDistribution): sage: a = 0 sage: b = 2 sage: T = RealDistribution('uniform', [a, b]) - sage: T.get_random_element() # random - 0.416921074037 + sage: T.get_random_element() + 0.8175557665526867 sage: T.distribution_function(0) 0.5 sage: T.cum_distribution_function(1) @@ -342,8 +350,8 @@ cdef class RealDistribution(ProbabilityDistribution): sage: sigma = 1 sage: T = RealDistribution('gaussian', sigma) - sage: T.get_random_element() # random - 0.818610064197 + sage: T.get_random_element() + -0.5860943109756299 sage: T.distribution_function(0) 0.3989422804014327 sage: T.cum_distribution_function(1) @@ -355,8 +363,8 @@ cdef class RealDistribution(ProbabilityDistribution): sage: sigma = 3 sage: T = RealDistribution('rayleigh', sigma) - sage: T.get_random_element() # random - 1.65471291529 + sage: T.get_random_element() + 5.748307572643492 sage: T.distribution_function(0) 0.0 sage: T.cum_distribution_function(1) @@ -370,8 +378,8 @@ cdef class RealDistribution(ProbabilityDistribution): sage: zeta = 0 sage: sigma = 1 sage: T = RealDistribution('lognormal', [zeta, sigma]) - sage: T.get_random_element() # random - 1.23541716538 + sage: T.get_random_element() + 0.3876433713532701 sage: T.distribution_function(0) 0.0 sage: T.cum_distribution_function(1) @@ -384,8 +392,8 @@ cdef class RealDistribution(ProbabilityDistribution): sage: a = 1 sage: b = 1 sage: T = RealDistribution('pareto', [a, b]) - sage: T.get_random_element() # random - 1.16429443511 + sage: T.get_random_element() + 10.418714048916407 sage: T.distribution_function(0) 0.0 sage: T.cum_distribution_function(1) @@ -397,9 +405,9 @@ cdef class RealDistribution(ProbabilityDistribution): sage: nu = 1 sage: T = RealDistribution('t', nu) - sage: T.get_random_element() # random - -0.994514581164 - sage: T.distribution_function(0) + sage: T.get_random_element() # rel tol 1e-15 + -8.404911172800615 + sage: T.distribution_function(0) # rel tol 1e-15 0.3183098861837906 sage: T.cum_distribution_function(1) # rel tol 1e-15 0.75 @@ -410,8 +418,8 @@ cdef class RealDistribution(ProbabilityDistribution): sage: nu1 = 9; nu2 = 17 sage: F = RealDistribution('F', [nu1,nu2]) - sage: F.get_random_element() # random - 1.65211335491 + sage: F.get_random_element() # rel tol 1e-14 + 1.239233786115256 sage: F.distribution_function(1) # rel tol 1e-14 0.6695025505192798 sage: F.cum_distribution_function(3.68) # rel tol 1e-14 @@ -423,8 +431,8 @@ cdef class RealDistribution(ProbabilityDistribution): sage: nu = 1 sage: T = RealDistribution('chisquared', nu) - sage: T.get_random_element() # random - 0.103230507883 + sage: T.get_random_element() + 0.4603367753992381 sage: T.distribution_function(0) +infinity sage: T.cum_distribution_function(1) # rel tol 1e-14 @@ -438,8 +446,8 @@ cdef class RealDistribution(ProbabilityDistribution): sage: a = 1 sage: b = 2.5 sage: T = RealDistribution('exppow', [a, b]) - sage: T.get_random_element() # random - 0.570108609774 + sage: T.get_random_element() + 0.16442075306686463 sage: T.distribution_function(0) # rel tol 1e-14 0.5635302489930136 sage: T.cum_distribution_function(1) # rel tol 1e-14 @@ -450,8 +458,8 @@ cdef class RealDistribution(ProbabilityDistribution): sage: a = 2 sage: b = 2 sage: T = RealDistribution('beta', [a, b]) - sage: T.get_random_element() # random - 0.518139435862 + sage: T.get_random_element() # rel tol 1e-14 + 0.7110581877139808 sage: T.distribution_function(0) 0.0 sage: T.cum_distribution_function(1) @@ -462,8 +470,8 @@ cdef class RealDistribution(ProbabilityDistribution): sage: a = 1 sage: b = 1 sage: T = RealDistribution('weibull', [a, b]) - sage: T.get_random_element() # random - 1.86974582214 + sage: T.get_random_element() + 1.1867854542468694 sage: T.distribution_function(0) 1.0 sage: T.cum_distribution_function(1) @@ -536,10 +544,8 @@ cdef class RealDistribution(ProbabilityDistribution): self.set_random_number_generator(rng) self.r = gsl_rng_alloc(self.T) if seed is None: - self.seed = random.randint(1, sys.maxsize) - else: - self.seed = seed - self.set_seed(self.seed) + seed = random.randint(1, 2**31) + self.set_seed(seed) self.name = " " self.set_distribution(type, parameters) @@ -949,8 +955,8 @@ cdef class GeneralDiscreteDistribution(ProbabilityDistribution): sage: P = [0.3, 0.4, 0.3] sage: X = GeneralDiscreteDistribution(P) - sage: X.get_random_element() # random - 2 + sage: X.get_random_element() + 1 Checking the distribution of samples:: @@ -960,8 +966,9 @@ cdef class GeneralDiscreteDistribution(ProbabilityDistribution): sage: nr_samples = 10000 sage: for _ in range(nr_samples): ... counts[X.get_random_element()] += 1 - sage: [1.0*x/nr_samples for x in counts] # random - [0.295400000000000, 0.400200000000000, 0.304400000000000] + sage: [1.0*x/nr_samples for x in counts] + [0.304200000000000, 0.397300000000000, 0.298500000000000] + The distribution probabilities will automatically be normalised:: @@ -1029,10 +1036,8 @@ cdef class GeneralDiscreteDistribution(ProbabilityDistribution): self.set_random_number_generator(rng) self.r = gsl_rng_alloc(self.T) if seed is None: - self.seed = random.randint(1, sys.maxsize) - else: - self.seed = seed - self.set_seed(self.seed) + seed = random.randint(1, 2**31) + self.set_seed(seed) cdef int n n = len(P) @@ -1059,7 +1064,7 @@ cdef class GeneralDiscreteDistribution(ProbabilityDistribution): sage: X = GeneralDiscreteDistribution([0.3, 0.4, 0.3]) sage: X.set_seed(1) - sage: X.get_random_element() # random + sage: X.get_random_element() 1 """ @@ -1100,8 +1105,8 @@ cdef class GeneralDiscreteDistribution(ProbabilityDistribution): sage: P = [0.3, 0.4, 0.3] sage: X = GeneralDiscreteDistribution(P) - sage: [X.get_random_element() for _ in range(10)] # random - [1, 0, 1, 1, 2, 0, 0, 2, 2, 0] + sage: [X.get_random_element() for _ in range(10)] + [1, 0, 1, 1, 0, 1, 1, 1, 1, 1] sage: isinstance(X.get_random_element(), sage.rings.integer.Integer) True diff --git a/src/sage/interfaces/jmoldata.py b/src/sage/interfaces/jmoldata.py index 321f38e8b6c..7154448f499 100644 --- a/src/sage/interfaces/jmoldata.py +++ b/src/sage/interfaces/jmoldata.py @@ -64,7 +64,7 @@ def is_jvm_available(self): return False import re - java_version = re.search("version.*[1][.][567]", version) + java_version = re.search("version.*[1][.][78]", version) return java_version is not None def export_image(self, diff --git a/src/sage/libs/gmp/rational_reconstruction.pxd b/src/sage/libs/gmp/rational_reconstruction.pxd new file mode 100644 index 00000000000..d8d24ec5b6c --- /dev/null +++ b/src/sage/libs/gmp/rational_reconstruction.pxd @@ -0,0 +1,3 @@ +from types cimport mpz_t, mpq_t + +cdef int mpq_rational_reconstruction(mpq_t answer, mpz_t a, mpz_t m) except -1 diff --git a/src/sage/libs/gmp/rational_reconstruction.pyx b/src/sage/libs/gmp/rational_reconstruction.pyx new file mode 100644 index 00000000000..36a55cf26a7 --- /dev/null +++ b/src/sage/libs/gmp/rational_reconstruction.pyx @@ -0,0 +1,114 @@ +""" +Rational reconstruction + +This file is a Cython implementation of rational reconstruction, using +direct MPIR calls. + +AUTHORS: + +- ??? (2006 or before) + +- Jeroen Demeyer (2014-10-20): move this function from ``gmp.pxi``, + simplify and fix some bugs, see :trac:`17180` +""" +#***************************************************************************** +# Copyright (C) 2006 ??? +# Copyright (C) 2014 Jeroen Demeyer +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# http://www.gnu.org/licenses/ +#***************************************************************************** + +include 'sage/ext/interrupt.pxi' + +from mpz cimport * +from mpq cimport * + + +cdef int mpq_rational_reconstruction(mpq_t answer, mpz_t a, mpz_t m) except -1: + """ + Set ``answer`` to a rational number which is `a` modulo `m` and + such that the numerator and denominator of the result is bounded by + sqrt(m/2). + + If `m` is zero, raise ``ZeroDivisionError``. If the rational + reconstruction does not exist, raise ``ValueError``. + + We assume that ``mpq_init`` has been called on ``answer``. + + For examples, see the ``rational_reconstruction`` method of + :class:`Integer`. + + TESTS:: + + sage: q = -113/355 + sage: for p in range(2*355^2, 3*355^2): # long time + ....: if is_prime(p): + ....: assert Mod(q, p).rational_reconstruction() == q + """ + cdef mpz_t bound + cdef mpz_t u1 + cdef mpz_t u2 + cdef mpz_t v1 + cdef mpz_t v2 + cdef mpz_t q + + if mpz_sgn(m) == 0: + raise ZeroDivisionError("rational reconstruction with zero modulus") + + sig_on() + mpz_init(bound) + mpz_init_set_ui(u1, 0) + mpz_init_set_ui(v1, 1) + mpz_init(u2) + mpz_init(v2) + mpz_init(q) + + try: + mpz_abs(u2, m) # u2 = |m| + mpz_mod(v2, a, u2) # v2 = a % m + mpz_fdiv_q_2exp(bound, u2, 1) + mpz_sqrtrem(bound, q, bound) # bound = floor(sqrt(|m|/2)) + + # Initialization: u1 = 0; v1 = 1 + while True: + if mpz_cmpabs(v2, bound) <= 0: + break + mpz_fdiv_q(q, u2, v2) # q = floor(u2/v2) + mpz_submul(u1, q, v1) # tmp1 = u1 - q*v1 (store tmp1 in u1) + mpz_submul(u2, q, v2) # tmp2 = u2 - q*v2 (store tmp2 in u2) + mpz_swap(u1, v1) # u1 = v1; v1 = tmp1 + mpz_swap(u2, v2) # u2 = v2; v2 = tmp2 + + # The answer is v2/v1, but check the conditions first + if mpz_cmpabs(v1, bound) <= 0: + mpz_gcd(q, v1, v2) + if mpz_cmp_ui(q, 1) == 0: + # Set answer to v2/v1 with correct sign + if mpz_sgn(v1) >= 0: + mpz_set(mpq_numref(answer), v2) + mpz_set(mpq_denref(answer), v1) + else: + mpz_neg(mpq_numref(answer), v2) + mpz_neg(mpq_denref(answer), v1) + sig_off() + return 0 + + sig_off() + # Earlier versions used to put a string representation of + # the input here. We don't do this, since some low-level code + # needs to catch and handle this exception so the string + # handling is just a waste of time. The actual user-facing + # methods could catch ValueError and raise a better exception + # instead. + raise ValueError("rational reconstruction does not exist") + finally: + mpz_clear(bound) + mpz_clear(u1) + mpz_clear(v1) + mpz_clear(u2) + mpz_clear(v2) + mpz_clear(q) diff --git a/src/sage/libs/linkages/padics/API.pxi b/src/sage/libs/linkages/padics/API.pxi index 9ed1531a28b..5b84dbb2b96 100644 --- a/src/sage/libs/linkages/padics/API.pxi +++ b/src/sage/libs/linkages/padics/API.pxi @@ -23,7 +23,7 @@ file gives the function signatures. - :meth:`cvaluation` -- return the maximum power of the uniformizer dividing this element. - :meth:`cisunit` -- returns whether this element has valuation zero -- :meth:`cshift` -- mulitplies by a power of the uniformizer +- :meth:`cshift` -- multiplies by a power of the uniformizer - :meth:`cshift_notrunc` -- multiplies by a power of the uniformizer, assuming no truncation - :meth:`csub` -- subtraction @@ -248,7 +248,7 @@ cdef inline bint cisunit(celement a, PowComputer_class prime_pow) except -1: cdef inline int cshift(celement out, celement a, long n, long prec, PowComputer_class prime_pow, bint reduce_afterward) except -1: """ - Mulitplies by a power of the uniformizer. + Multiplies by a power of the uniformizer. INPUT: @@ -265,7 +265,7 @@ cdef inline int cshift(celement out, celement a, long n, long prec, PowComputer_ cdef inline int cshift_notrunc(celement out, celement a, long n, long prec, PowComputer_class prime_pow) except -1: """ - Mulitplies by a power of the uniformizer, assuming that the + Multiplies by a power of the uniformizer, assuming that the valuation of a is at least -n. INPUT: diff --git a/src/sage/libs/linkages/padics/mpz.pxi b/src/sage/libs/linkages/padics/mpz.pxi index 749b62902b7..7dc3518aa93 100644 --- a/src/sage/libs/linkages/padics/mpz.pxi +++ b/src/sage/libs/linkages/padics/mpz.pxi @@ -18,12 +18,12 @@ AUTHORS: include "sage/ext/stdsage.pxi" include "sage/ext/interrupt.pxi" -include "sage/ext/gmp.pxi" from cpython.list cimport * cdef extern from "mpz_pylong.h": cdef long mpz_pythonhash(mpz_t src) +from sage.libs.gmp.rational_reconstruction cimport mpq_rational_reconstruction from sage.rings.integer cimport Integer from sage.rings.rational cimport Rational from sage.rings.padics.padic_generic_element cimport pAdicGenericElement @@ -224,7 +224,7 @@ cdef inline bint cisunit(mpz_t a, PowComputer_class prime_pow) except -1: cdef inline int cshift(mpz_t out, mpz_t a, long n, long prec, PowComputer_class prime_pow, bint reduce_afterward) except -1: """ - Mulitplies by a power of the uniformizer. + Multiplies by a power of the uniformizer. INPUT: @@ -250,7 +250,7 @@ cdef inline int cshift(mpz_t out, mpz_t a, long n, long prec, PowComputer_class cdef inline int cshift_notrunc(mpz_t out, mpz_t a, long n, long prec, PowComputer_class prime_pow) except -1: """ - Mulitplies by a power of the uniformizer, assuming that the + Multiplies by a power of the uniformizer, assuming that the valuation of a is at least -n. INPUT: diff --git a/src/sage/libs/ntl/ntl_GF2X.pyx b/src/sage/libs/ntl/ntl_GF2X.pyx index 8449c7738fe..68a49323ef4 100644 --- a/src/sage/libs/ntl/ntl_GF2X.pyx +++ b/src/sage/libs/ntl/ntl_GF2X.pyx @@ -119,8 +119,6 @@ cdef class ntl_GF2X: sage: ntl.GF2X(f) [1 0 1 0 0 1] """ - - from sage.rings.finite_rings.element_ext_pari import FiniteField_ext_pariElement from sage.rings.finite_rings.element_givaro import FiniteField_givaroElement from sage.rings.finite_rings.element_ntl_gf2e import FiniteField_ntl_gf2eElement from sage.rings.finite_rings.finite_field_base import FiniteField @@ -147,10 +145,6 @@ cdef class ntl_GF2X: elif PY_TYPE_CHECK(x, FiniteField): if x.characteristic() == 2: x= list(x.modulus()) - elif PY_TYPE_CHECK(x, FiniteField_ext_pariElement): - if x.parent().characteristic() == 2: - x=x._pari_().centerlift().centerlift().subst('a',2).int_unsafe() - x="0x"+hex(x)[2:][::-1] elif PY_TYPE_CHECK(x, FiniteField_givaroElement): x = "0x"+hex(x.integer_representation())[2:][::-1] elif PY_TYPE_CHECK(x, FiniteField_ntl_gf2eElement): diff --git a/src/sage/matrix/constructor.py b/src/sage/matrix/constructor.py index 159f8a368d5..552a22f6b59 100644 --- a/src/sage/matrix/constructor.py +++ b/src/sage/matrix/constructor.py @@ -3228,12 +3228,12 @@ def random_echelonizable_matrix(parent, rank, upper_bound=None, max_tries=100): sage: from sage.matrix.constructor import random_echelonizable_matrix sage: matrix_space = sage.matrix.matrix_space.MatrixSpace(QQ, 5, 6) - sage: A=random_echelonizable_matrix(matrix_space, rank=4, upper_bound=40); A # random - [ 1 -1 1 -3 -4 6] - [ 5 -4 0 8 4 19] - [ -3 3 -2 4 7 -16] - [ -4 5 -7 26 31 -31] - [ 2 -3 4 -11 -14 17] + sage: A=random_echelonizable_matrix(matrix_space, rank=4, upper_bound=40); A + [ 3 4 12 39 18 22] + [ -1 -3 -9 -27 -16 -19] + [ 1 3 10 31 18 21] + [ -1 0 0 -2 2 2] + [ 0 1 2 8 4 5] sage: A.rank() 4 sage: max(map(abs,A.list()))<40 @@ -3243,13 +3243,13 @@ def random_echelonizable_matrix(parent, rank, upper_bound=None, max_tries=100): An example with default settings (i.e. no entry size control). :: - sage: C=random_matrix(QQ, 6, 7, algorithm='echelonizable', rank=5); C # random - [ 1 0 5 -2 -26 -16 0] - [ -3 1 -19 6 97 61 1] - [ 0 4 -15 -1 71 50 3] - [ 2 4 -9 0 39 25 8] - [ 2 2 3 -3 -18 -9 3] - [ -3 -4 -2 14 14 -6 4] + sage: C=random_matrix(QQ, 6, 7, algorithm='echelonizable', rank=5); C + [ 1 -5 -8 16 6 65 30] + [ 3 -14 -22 42 17 178 84] + [ -5 24 39 -79 -31 -320 -148] + [ 4 -15 -26 55 27 224 106] + [ -1 0 -6 29 8 65 17] + [ 3 -20 -32 72 14 250 107] sage: C.rank() 5 sage: C.rref()==C.rref().change_ring(ZZ) @@ -3257,36 +3257,36 @@ def random_echelonizable_matrix(parent, rank, upper_bound=None, max_tries=100): A matrix without size control may have very large entry sizes. :: - sage: D=random_matrix(ZZ, 7, 8, algorithm='echelonizable', rank=6); D # random - [ 9 -53 -255 45 -1519 4043 9819 3324] - [ 3 -14 -64 8 -369 972 2350 810] - [ 2 -14 -65 9 -377 1000 2420 829] - [ 4 -24 -116 21 -693 1846 4485 1516] - [ -3 14 68 -16 426 -1134 -2767 -919] - [ -5 21 92 -13 548 -1432 -3466 -1183] - [ 1 -9 -42 7 -254 670 1624 547] + sage: D=random_matrix(ZZ, 7, 8, algorithm='echelonizable', rank=6); D + [ 1 2 8 -35 -178 -673 -284 778] + [ 4 9 37 -163 -827 -3128 -1324 3624] + [ 5 6 21 -88 -454 -1712 -708 1951] + [ -4 -5 -22 97 491 1854 779 -2140] + [ 4 4 13 -55 -283 -1066 -436 1206] + [ 4 11 43 -194 -982 -3714 -1576 4310] + [ -1 -2 -13 59 294 1113 481 -1312] Matrices can be generated over any exact ring. :: sage: F.=GF(2^3) - sage: B=random_matrix(F, 4, 5, algorithm='echelonizable', rank=4, upper_bound=None); B # random - [ a + 1 a^2 + a + 1 a^2 0 1] - [ 1 a a + 1 a^2 a^2 + a] - [ a a^2 a^2 + a + 1 a + 1 1] - [ 1 0 a^2 + a + 1 0 a^2 + 1] + sage: B=random_matrix(F, 4, 5, algorithm='echelonizable', rank=4, upper_bound=None); B + [ 1 a + 1 0 a^2 + a + 1 1] + [ a a^2 + a + 1 a^2 + 1 a^2 + a 0] + [ a^2 + a 1 1 a^2 + a a + 1] + [a^2 + a + 1 a^2 + a + 1 a^2 0 a^2 + a] sage: B.rank() 4 Square matrices over ZZ or QQ with full rank are always unimodular. :: - sage: E=random_matrix(QQ, 7, 7, algorithm='echelonizable', rank=7); E # random - [ 1 -1 5 12 -24 -41 47] - [ 0 1 -1 3 0 -11 40] - [ 1 -1 6 6 -19 -20 -11] - [ -2 1 -10 -12 35 44 -4] - [ 3 -1 9 7 -35 -40 -18] - [ 0 0 0 -4 4 13 -32] - [ 3 -3 11 6 -33 -31 -35] + sage: E=random_matrix(QQ, 7, 7, algorithm='echelonizable', rank=7); E + [ 1 1 7 -29 139 206 413] + [ -2 -1 -10 41 -197 -292 -584] + [ 2 5 27 -113 541 803 1618] + [ 4 0 14 -55 268 399 798] + [ 3 1 8 -32 152 218 412] + [ -3 -2 -18 70 -343 -506 -1001] + [ 1 -2 -1 1 -2 9 52] sage: det(E) 1 @@ -3446,13 +3446,13 @@ def random_subspaces_matrix(parent, rank=None): sage: from sage.matrix.constructor import random_subspaces_matrix sage: matrix_space = sage.matrix.matrix_space.MatrixSpace(QQ, 6, 8) - sage: B=random_subspaces_matrix(matrix_space, rank=3); B # random - [ 113 339 -46 218 -243 641 -269 -306] - [ -33 -99 13 -63 69 -185 77 90] - [ 35 105 -14 67 -74 197 -82 -95] - [ -18 -54 7 -34 37 -100 41 49] - [ -26 -78 10 -49 53 -144 59 71] - [ -8 -24 3 -15 16 -44 18 22] + sage: B=random_subspaces_matrix(matrix_space, rank=3); B + [ -15 -4 83 35 -24 47 -74 50] + [ -16 -7 94 34 -25 38 -75 50] + [ 89 34 -513 -196 141 -235 426 -285] + [ 17 6 -97 -38 27 -47 82 -55] + [ 7 3 -41 -15 11 -17 33 -22] + [ -5 -2 29 11 -8 13 -24 16] sage: B.rank() 3 sage: B.nullity() @@ -3464,13 +3464,13 @@ def random_subspaces_matrix(parent, rank=None): sage: B_expanded=B.augment(identity_matrix(6)).rref() sage: all([x in ZZ for x in B_expanded.list()]) True - sage: B_expanded # random - [ 1 3 0 0 1 1 3 -2 0 0 -3 0 -9 16] - [ 0 0 1 0 3 -2 -1 -3 0 0 2 0 11 -27] - [ 0 0 0 1 -1 2 -3 -1 0 0 2 0 7 -14] - [ 0 0 0 0 0 0 0 0 1 0 -5 0 -3 2] - [ 0 0 0 0 0 0 0 0 0 1 1 0 1 -3] - [ 0 0 0 0 0 0 0 0 0 0 0 1 -1 1] + sage: B_expanded + [ 1 0 -5 0 -1 1 0 -1 0 0 0 3 10 24] + [ 0 1 -2 0 1 2 1 0 0 0 0 -2 -3 -11] + [ 0 0 0 1 -1 2 -2 1 0 0 0 1 4 9] + [ 0 0 0 0 0 0 0 0 1 0 0 2 -2 1] + [ 0 0 0 0 0 0 0 0 0 1 0 0 3 1] + [ 0 0 0 0 0 0 0 0 0 0 1 -3 -4 2] Check that we fixed Trac #10543 (echelon forms should be immutable):: @@ -3480,24 +3480,24 @@ def random_subspaces_matrix(parent, rank=None): We want to modify B_expanded, so replace it with a copy:: sage: B_expanded = copy(B_expanded) - sage: B_expanded.subdivide(B.nrows()-B.nullity(),B.ncols());B_expanded # random - [ 1 3 0 0 1 1 3 -2| 0 0 -3 0 -9 16] - [ 0 0 1 0 3 -2 -1 -3| 0 0 2 0 11 -27] - [ 0 0 0 1 -1 2 -3 -1| 0 0 2 0 7 -14] + sage: B_expanded.subdivide(B.nrows()-B.nullity(),B.ncols());B_expanded + [ 1 0 -5 0 -1 1 0 -1| 0 0 0 3 10 24] + [ 0 1 -2 0 1 2 1 0| 0 0 0 -2 -3 -11] + [ 0 0 0 1 -1 2 -2 1| 0 0 0 1 4 9] [-------------------------------+-----------------------] - [ 0 0 0 0 0 0 0 0| 1 0 -5 0 -3 2] - [ 0 0 0 0 0 0 0 0| 0 1 1 0 1 -3] - [ 0 0 0 0 0 0 0 0| 0 0 0 1 -1 1] + [ 0 0 0 0 0 0 0 0| 1 0 0 2 -2 1] + [ 0 0 0 0 0 0 0 0| 0 1 0 0 3 1] + [ 0 0 0 0 0 0 0 0| 0 0 1 -3 -4 2] sage: C=B_expanded.subdivision(0,0) - sage: C # random - [ 1 3 0 0 1 1 3 -2] - [ 0 0 1 0 3 -2 -1 -3] - [ 0 0 0 1 -1 2 -3 -1] + sage: C + [ 1 0 -5 0 -1 1 0 -1] + [ 0 1 -2 0 1 2 1 0] + [ 0 0 0 1 -1 2 -2 1] sage: L=B_expanded.subdivision(1,1) - sage: L # random - [ 1 0 -5 0 -3 2] - [ 0 1 1 0 1 -3] - [ 0 0 0 1 -1 1] + sage: L + [ 1 0 0 2 -2 1] + [ 0 1 0 0 3 1] + [ 0 0 1 -3 -4 2] sage: B.right_kernel()==C.right_kernel() True sage: B.row_space()==C.row_space() @@ -3509,25 +3509,25 @@ def random_subspaces_matrix(parent, rank=None): A matrix to show that the null space of the L matrix is the column space of the starting matrix. :: - sage: A=random_matrix(QQ, 5, 7, algorithm='subspaces', rank=None); A # random - [-31 12 -9 -27 21 2 -15] - [105 -24 6 103 -30 -34 79] - [ 29 -9 5 26 -14 -5 17] - [233 -55 16 228 -71 -73 173] - [-42 10 -3 -41 13 13 -31] + sage: A=random_matrix(QQ, 5, 7, algorithm='subspaces', rank=None); A + [ -63 13 -71 29 -163 150 -268] + [ 24 -5 27 -11 62 -57 102] + [ 14 -3 16 -7 37 -34 60] + [ -4 1 -4 1 -9 8 -16] + [ 9 -2 10 -4 23 -21 38] sage: (A.nrows(), A.ncols()) (5, 7) sage: all([x in ZZ for x in A.list()]) True - sage: A.nullity() # random - 1 + sage: A.nullity() + 2 sage: A_expanded=A.augment(identity_matrix(5)).rref() - sage: A_expanded # random - [ 1 0 0 0 0 1 0 0 3 7 25 151] - [ 0 1 0 0 1 2 1 0 5 21 84 493] - [ 0 0 1 0 -1 2 0 0 2 13 53 308] - [ 0 0 0 1 0 -1 1 0 -2 -3 -9 -57] - [ 0 0 0 0 0 0 0 1 -3 1 1 -2] + sage: A_expanded + [ 1 0 0 2 -1 1 2 0 2 0 -4 -7] + [ 0 1 0 1 -1 0 0 0 4 0 -3 -12] + [ 0 0 1 -2 3 -3 2 0 -1 0 3 4] + [ 0 0 0 0 0 0 0 1 3 0 0 -1] + [ 0 0 0 0 0 0 0 0 0 1 -1 -2] sage: all([x in ZZ for x in A_expanded.list()]) True sage: C=A_expanded.submatrix(0,0,A.nrows()-A.nullity(),A.ncols()) @@ -3648,25 +3648,25 @@ def random_unimodular_matrix(parent, upper_bound=None, max_tries=100): sage: from sage.matrix.constructor import random_unimodular_matrix sage: matrix_space = sage.matrix.matrix_space.MatrixSpace(QQ, 5) - sage: A=random_unimodular_matrix(matrix_space); A # random - [ -8 31 85 148 -419] - [ 2 -9 -25 -45 127] - [ -1 10 30 65 -176] - [ -3 12 33 58 -164] - [ 5 -21 -59 -109 304] + sage: A=random_unimodular_matrix(matrix_space); A + [ 0 3 8 -30 -30] + [ 0 1 4 -18 -13] + [ -1 0 0 3 0] + [ 4 16 71 -334 -222] + [ -1 -1 -9 50 24] sage: det(A) 1 A matrix size 6 with entries no larger than 50. :: - sage: B=random_matrix(ZZ, 7, algorithm='unimodular', upper_bound=50);B # random - [ -1 0 3 1 -2 2 9] - [ 1 2 -5 0 14 19 -49] - [ -3 -2 12 5 -6 -4 24] - [ 1 2 -9 -3 3 4 -7] - [ -2 -1 7 2 -8 -5 31] - [ 2 2 -6 -3 8 16 -32] - [ 1 2 -9 -2 5 6 -12] + sage: B=random_matrix(ZZ, 7, algorithm='unimodular', upper_bound=50);B + [-14 17 14 -31 43 24 46] + [ -5 6 5 -11 15 9 18] + [ -2 5 3 -7 15 -3 -16] + [ 1 -2 -3 4 -3 -7 -21] + [ -1 4 1 -4 14 -10 -37] + [ 3 -3 -1 6 -12 4 25] + [ 4 -4 -2 7 -13 -2 1] sage: det(B) 1 @@ -3674,10 +3674,10 @@ def random_unimodular_matrix(parent, upper_bound=None, max_tries=100): sage: y = var('y') sage: K=NumberField(y^2-2*y-2,'y') - sage: C=random_matrix(K, 3, algorithm='unimodular');C # random - [ 2*y - 33 681*y - 787 31*y - 37] - [ y + 6 -155*y + 83 -7*y + 4] - [ -y 24*y + 51 y + 3] + sage: C=random_matrix(K, 3, algorithm='unimodular');C + [ -5*y + 11 10*y - 30 -695*y + 2366] + [ 5 5*y - 9 -535*y + 588] + [ y - 1 3*y - 1 -35*y - 273] sage: det(C) 1 @@ -3756,51 +3756,51 @@ def random_diagonalizable_matrix(parent,eigenvalues=None,dimensions=None): sage: from sage.matrix.constructor import random_diagonalizable_matrix sage: matrix_space = sage.matrix.matrix_space.MatrixSpace(QQ, 5) - sage: A=random_diagonalizable_matrix(matrix_space); A # random - [ 10 18 8 4 -18] - [ 20 10 8 4 -16] - [-60 -54 -22 -12 18] - [-60 -54 -24 -6 6] - [-20 -18 -8 -4 8] - sage: A.eigenvalues() # random - [10,6,2,-8,-10] - sage: S=A.right_eigenmatrix()[1]; S # random - [ 1 1 1 1 0] - [ 1 1 1 0 1] - [-3 -3 -4 -3 -3] - [-3 -4 -3 -3 -3] - [-1 -1 -1 -1 -1] - sage: S_inverse=S.inverse(); S_inverse # random - [ 1 1 1 1 -5] - [ 0 0 0 -1 3] - [ 0 0 -1 0 3] - [ 0 -1 0 0 -1] - [-1 0 0 0 -1] - sage: S_inverse*A*S # random - [ 10 0 0 0 0] - [ 0 6 0 0 0] - [ 0 0 2 0 0] - [ 0 0 0 -8 0] - [ 0 0 0 0 -10] + sage: A=random_diagonalizable_matrix(matrix_space); A + [ 90 -80 56 -448 -588] + [ 60 0 28 -324 -204] + [ 60 -72 32 -264 -432] + [ 30 -16 16 -152 -156] + [ -10 -8 -4 60 8] + sage: sorted(A.eigenvalues()) + [-10, -8, -4, 0, 0] + sage: S=A.right_eigenmatrix()[1]; S + [ 1 1 1 1 0] + [ 1/2 0 2/3 0 1] + [ 4/7 9/10 2/3 6/7 -3/7] + [ 2/7 1/5 1/3 3/14 1/7] + [-1/14 1/10 -1/9 1/14 -2/7] + sage: S_inverse=S.inverse(); S_inverse + [ 0 0 -14 42 42] + [ 0 10 0 -10 30] + [ -9 0 0 36 18] + [ 10 -10 14 -68 -90] + [ 6 1 7 -45 -33] + sage: S_inverse*A*S + [ -4 0 0 0 0] + [ 0 -8 0 0 0] + [ 0 0 -10 0 0] + [ 0 0 0 0 0] + [ 0 0 0 0 0] A diagonalizable matrix with eigenvalues and dimensions designated, with a check that if eigenvectors were calculated by hand entries would all be integers. :: - sage: B=random_matrix(QQ, 6, algorithm='diagonalizable', eigenvalues=[-12,4,6],dimensions=[2,3,1]); B # random - [ -52 32 240 -464 -96 -520] - [ 6 4 -48 72 36 90] - [ 46 -32 -108 296 -12 274] - [ 24 -16 -64 164 0 152] - [ 18 -16 0 72 -48 30] - [ 2 0 -16 24 12 34] + sage: B=random_matrix(QQ, 6, algorithm='diagonalizable', eigenvalues=[-12,4,6],dimensions=[2,3,1]); B + [ 2 -64 16 206 56 -142] + [ 14 -28 -64 46 40 -14] + [ -4 -16 4 44 32 -28] + [ 6 0 -32 -22 8 26] + [ 0 -16 0 48 20 -32] + [ 2 0 -16 -14 8 18] sage: all([x in ZZ for x in (B-(-12*identity_matrix(6))).rref().list()]) True sage: all([x in ZZ for x in (B-(4*identity_matrix(6))).rref().list()]) True sage: all([x in ZZ for x in (B-(6*identity_matrix(6))).rref().list()]) True - sage: S=B.right_eigenmatrix()[1]; S_inverse=S.inverse(); S_inverse*B*S # random + sage: S=B.right_eigenmatrix()[1]; S_inverse=S.inverse(); S_inverse*B*S [ 6 0 0 0 0 0] [ 0 -12 0 0 0 0] [ 0 0 -12 0 0 0] diff --git a/src/sage/matrix/matrix_double_dense.pyx b/src/sage/matrix/matrix_double_dense.pyx index caf3e5f7722..bbc8cdfd8bf 100644 --- a/src/sage/matrix/matrix_double_dense.pyx +++ b/src/sage/matrix/matrix_double_dense.pyx @@ -84,7 +84,7 @@ cdef class Matrix_double_dense(matrix_dense.Matrix_dense): sage: m**2 [ 7.0 10.0] [15.0 22.0] - sage: m^(-1) + sage: m^(-1) # rel tol 1e-15 [-1.9999999999999996 0.9999999999999998] [ 1.4999999999999998 -0.4999999999999999] """ @@ -1009,11 +1009,11 @@ cdef class Matrix_double_dense(matrix_dense.Matrix_dense): sage: A.condition() > 1.6e16 or A.condition() True - sage: A.singular_values(eps=None) # abs tol 5e-16 + sage: A.singular_values(eps=None) # abs tol 7e-16 [1.7953720595619975, 0.38027524595503703, 0.04473854875218107, 0.0037223122378911614, 0.0002330890890217751, 1.116335748323284e-05, 4.082376110397296e-07, 1.1228610675717613e-08, 2.2519645713496478e-10, 3.1113486853814003e-12, 2.6500422260778388e-14, 9.87312834948426e-17] - sage: A.singular_values(eps='auto') # abs tol 5e-16 + sage: A.singular_values(eps='auto') # abs tol 7e-16 [1.7953720595619975, 0.38027524595503703, 0.04473854875218107, 0.0037223122378911614, 0.0002330890890217751, 1.116335748323284e-05, 4.082376110397296e-07, 1.1228610675717613e-08, 2.2519645713496478e-10, 3.1113486853814003e-12, 2.6500422260778388e-14, 0.0] - sage: A.singular_values(eps=1e-4) # abs tol 5e-16 + sage: A.singular_values(eps=1e-4) # abs tol 7e-16 [1.7953720595619975, 0.38027524595503703, 0.04473854875218107, 0.0037223122378911614, 0.0002330890890217751, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] With Sage's "verbose" facility, you can compactly see the cutoff @@ -3840,7 +3840,7 @@ cdef class Matrix_double_dense(matrix_dense.Matrix_dense): [51.968956198705044 74.73656456700327] [112.10484685050491 164.07380304920997] sage: A = matrix(CDF, 2, [1,2+I,3*I,4]) - sage: A.exp(algorithm='eig') # tol 2e-14 + sage: A.exp(algorithm='eig') # tol 3e-14 [-19.614602953804923 + 12.51774384676257*I 3.7949636449582016 + 28.883799306580997*I] [-32.38358098092227 + 21.884235957898433*I 2.2696330040935084 + 44.90132482768484*I] """ diff --git a/src/sage/matrix/matrix_integer_dense.pyx b/src/sage/matrix/matrix_integer_dense.pyx index 9ad8987d058..0cc61a967b7 100644 --- a/src/sage/matrix/matrix_integer_dense.pyx +++ b/src/sage/matrix/matrix_integer_dense.pyx @@ -3090,7 +3090,7 @@ cdef class Matrix_integer_dense(matrix_dense.Matrix_dense): # dense or sparse sage: A.rational_reconstruction(11) Traceback (most recent call last): ... - ValueError: Rational reconstruction of 4 (mod 11) does not exist. + ValueError: rational reconstruction does not exist We throw in a denominator and reduce the matrix modulo 389 - it does rationally reconstruct. @@ -3103,7 +3103,7 @@ cdef class Matrix_integer_dense(matrix_dense.Matrix_dense): # dense or sparse TEST: - Check that ticket #9345 is fixed:: + Check that trac:`9345` is fixed:: sage: A = random_matrix(ZZ, 3, 3) sage: A.rational_reconstruction(0) diff --git a/src/sage/matrix/matrix_rational_dense.pyx b/src/sage/matrix/matrix_rational_dense.pyx index 13986227bf6..ba57369f829 100644 --- a/src/sage/matrix/matrix_rational_dense.pyx +++ b/src/sage/matrix/matrix_rational_dense.pyx @@ -53,9 +53,9 @@ from sage.modules.vector_rational_dense cimport Vector_rational_dense include "sage/ext/interrupt.pxi" include "sage/ext/stdsage.pxi" include "sage/ext/random.pxi" -include "sage/ext/gmp.pxi" from sage.libs.gmp.types cimport mpq_t +from sage.libs.gmp.rational_reconstruction cimport mpq_rational_reconstruction from sage.libs.flint.fmpz cimport * from sage.libs.flint.fmpz_mat cimport * cimport sage.structure.element diff --git a/src/sage/matrix/matrix_real_double_dense.pyx b/src/sage/matrix/matrix_real_double_dense.pyx index e964810d936..2b5b1264322 100644 --- a/src/sage/matrix/matrix_real_double_dense.pyx +++ b/src/sage/matrix/matrix_real_double_dense.pyx @@ -58,7 +58,7 @@ cdef class Matrix_real_double_dense(matrix_double_dense.Matrix_double_dense): sage: m**2 [ 7.0 10.0] [15.0 22.0] - sage: n = m^(-1); n + sage: n = m^(-1); n # rel tol 1e-15 [-1.9999999999999996 0.9999999999999998] [ 1.4999999999999998 -0.4999999999999999] diff --git a/src/sage/matrix/misc.pyx b/src/sage/matrix/misc.pyx index 54720b54001..8454b165bc2 100644 --- a/src/sage/matrix/misc.pyx +++ b/src/sage/matrix/misc.pyx @@ -16,6 +16,7 @@ include 'sage/ext/stdsage.pxi' from sage.ext.mod_int cimport * from sage.libs.mpfr cimport * +from sage.libs.gmp.rational_reconstruction cimport mpq_rational_reconstruction include 'sage/modules/binary_search.pxi' include 'sage/modules/vector_integer_sparse_h.pxi' diff --git a/src/sage/modules/vector_rational_sparse_c.pxi b/src/sage/modules/vector_rational_sparse_c.pxi index 483974fae2f..c9979400133 100644 --- a/src/sage/modules/vector_rational_sparse_c.pxi +++ b/src/sage/modules/vector_rational_sparse_c.pxi @@ -10,7 +10,6 @@ include 'vector_rational_sparse_h.pxi' include "sage/ext/cdefs.pxi" -include "sage/ext/gmp.pxi" include "sage/ext/stdsage.pxi" diff --git a/src/sage/plot/plot3d/base.pxd b/src/sage/plot/plot3d/base.pxd index c0bfccfb60b..0b7619ddd44 100644 --- a/src/sage/plot/plot3d/base.pxd +++ b/src/sage/plot/plot3d/base.pxd @@ -5,7 +5,7 @@ cdef class Graphics3d(SageObject): cdef public object texture cdef object _aspect_ratio cdef object _frame_aspect_ratio - cdef public object _extra_kwds + cdef public dict _extra_kwds cdef class PrimitiveObject(Graphics3d): pass diff --git a/src/sage/plot/plot3d/base.pyx b/src/sage/plot/plot3d/base.pyx index 27053f3b155..4f33fc52062 100644 --- a/src/sage/plot/plot3d/base.pyx +++ b/src/sage/plot/plot3d/base.pyx @@ -69,6 +69,18 @@ cdef class Graphics3d(SageObject): .. automethod:: _graphics_ .. automethod:: __add__ """ + def __cinit__(self): + """ + The Cython constructor + + EXAMPLES:: + + sage: gfx = sage.plot.plot3d.base.Graphics3d() + sage: gfx._extra_kwds + {} + """ + self._extra_kwds = dict() + def _repr_(self): """ Return a string representation. @@ -108,16 +120,35 @@ cdef class Graphics3d(SageObject): """ from sage.structure.graphics_file import ( Mime, graphics_from_save, GraphicsFile) - if (mime_types is None) or (Mime.JMOL in mime_types): - # default to jmol + ### First, figure out the best graphics format + can_view_jmol = (mime_types is None) or (Mime.JMOL in mime_types) + viewer = self._extra_kwds.get('viewer', None) + # make sure viewer is one of the supported options + if viewer not in [None, 'jmol', 'tachyon']: + import warnings + warnings.warn('viewer={0} is not supported'.format(viewer)) + viewer = None + # select suitable default + if viewer is None: + viewer = 'jmol' + # fall back to 2d image if necessary + if viewer == 'jmol' and not can_view_jmol: + viewer = 'tachyon' + ### Second, return the corresponding graphics file + if viewer == 'jmol': filename = tmp_filename( ext=os.path.extsep + Mime.extension(Mime.JMOL)) self.save(filename) return GraphicsFile(filename, Mime.JMOL) - preference = [Mime.PNG, Mime.JPG] - return graphics_from_save(self.save, preference, - allowed_mime_types=mime_types, - figsize=figsize, dpi=dpi) + elif viewer == 'tachyon': + preference = [Mime.PNG, Mime.JPG] + figsize = self._extra_kwds.get('figsize', figsize) + dpi = self._extra_kwds.get('dpi', dpi) + return graphics_from_save(self.save, preference, + allowed_mime_types=mime_types, + figsize=figsize, dpi=dpi) + else: + assert False # unreachable def __str__(self): """ @@ -1011,8 +1042,7 @@ end_scene""" % (render_params.antialiasing, """ opts = {} opts.update(SHOW_DEFAULTS) - if self._extra_kwds is not None: - opts.update(self._extra_kwds) + opts.update(self._extra_kwds) opts.update(kwds) # Remove all of the keys that are viewing options, since the remaining @@ -1409,7 +1439,7 @@ class Graphics3dGroup(Graphics3d): self.all = list(all) self.frame_aspect_ratio(optimal_aspect_ratios([a.frame_aspect_ratio() for a in all])) self.aspect_ratio(optimal_aspect_ratios([a.aspect_ratio() for a in all])) - self._set_extra_kwds(optimal_extra_kwds([a._extra_kwds for a in all if a._extra_kwds is not None])) + self._set_extra_kwds(optimal_extra_kwds([a._extra_kwds for a in all])) def __add__(self, other): """ diff --git a/src/sage/rings/arith.py b/src/sage/rings/arith.py index 8a576e66f27..8fb9f76d114 100644 --- a/src/sage/rings/arith.py +++ b/src/sage/rings/arith.py @@ -2145,15 +2145,14 @@ def rational_reconstruction(a, m, algorithm='fast'): INPUT: - - ``a`` - an integer + - ``a`` -- an integer - - ``m`` - a modulus + - ``m`` -- a modulus - - ``algorithm`` - (default: 'fast') + - ``algorithm`` -- (default: 'fast') - - ``'fast'`` - a fast compiled implementation - - - ``'python'`` - a slow pure python implementation + - ``'fast'`` - a fast implementation using direct MPIR calls + in Cython. OUTPUT: @@ -2192,95 +2191,37 @@ def rational_reconstruction(a, m, algorithm='fast'): sage: rational_reconstruction(400,1000) Traceback (most recent call last): ... - ValueError: Rational reconstruction of 400 (mod 1000) does not exist. + ArithmeticError: rational reconstruction of 400 (mod 1000) does not exist :: - sage: rational_reconstruction(3,292393, algorithm='python') + sage: rational_reconstruction(3, 292393) 3 sage: a = Integers(292393)(45/97); a 204977 - sage: rational_reconstruction(a,292393, algorithm='python') - 45/97 - sage: a = Integers(292393)(45/97); a - 204977 - sage: rational_reconstruction(a,292393, algorithm='fast') + sage: rational_reconstruction(a, 292393, algorithm='fast') 45/97 - sage: rational_reconstruction(293048,292393, algorithm='fast') - Traceback (most recent call last): - ... - ValueError: Rational reconstruction of 655 (mod 292393) does not exist. - sage: rational_reconstruction(293048,292393, algorithm='python') + sage: rational_reconstruction(293048, 292393) Traceback (most recent call last): ... - ValueError: Rational reconstruction of 655 (mod 292393) does not exist. - - TESTS: - - Check that ticket #9345 is fixed:: - - sage: rational_reconstruction(1, 0) + ArithmeticError: rational reconstruction of 655 (mod 292393) does not exist + sage: rational_reconstruction(0, 0) Traceback (most recent call last): ... - ZeroDivisionError: The modulus cannot be zero - sage: rational_reconstruction(randint(-10^6, 10^6), 0) + ZeroDivisionError: rational reconstruction with zero modulus + sage: rational_reconstruction(0, 1, algorithm="foobar") Traceback (most recent call last): ... - ZeroDivisionError: The modulus cannot be zero + ValueError: unknown algorithm 'foobar' """ if algorithm == 'fast': return ZZ(a).rational_reconstruction(m) elif algorithm == 'python': - return _rational_reconstruction_python(a,m) + from sage.misc.superseded import deprecation + deprecation(17180, 'The %r algorithm for rational_reconstruction is deprecated' % algorithm) + return ZZ(a).rational_reconstruction(m) else: - raise ValueError("unknown algorithm") - -def _rational_reconstruction_python(a,m): - """ - Internal fallback function for rational_reconstruction; see - documentation of that function for details. - - INPUT: - - - ``a`` - an integer - - - ``m`` - a modulus - - EXAMPLES:: - - sage: from sage.rings.arith import _rational_reconstruction_python - sage: _rational_reconstruction_python(20,31) - -2/3 - sage: _rational_reconstruction_python(11323,100000) - 119/53 - """ - a = int(a); m = int(m) - a %= m - if a == 0 or m==0: - return ZZ(0)/ZZ(1) - if m < 0: - m = -m - if a < 0: - a = m-a - if a == 1: - return ZZ(1)/ZZ(1) - u = m - v = a - bnd = math.sqrt(m/2) - U = (1,0,u) - V = (0,1,v) - while abs(V[2]) > bnd: - q = U[2]/V[2] # floor is implicit - T = (U[0]-q*V[0], U[1]-q*V[1], U[2]-q*V[2]) - U = V - V = T - x = abs(V[1]) - y = V[2] - if V[1] < 0: - y *= -1 - if x <= bnd and GCD(x,y) == 1: - return ZZ(y) / ZZ(x) - raise ValueError("Rational reconstruction of %s (mod %s) does not exist."%(a,m)) + raise ValueError("unknown algorithm %r" % algorithm) def mqrr_rational_reconstruction(u, m, T): r""" diff --git a/src/sage/rings/finite_rings/constructor.py b/src/sage/rings/finite_rings/constructor.py index f658573a145..83103aa1d73 100644 --- a/src/sage/rings/finite_rings/constructor.py +++ b/src/sage/rings/finite_rings/constructor.py @@ -25,7 +25,7 @@ represent the field (``sage.rings.finite_rings.finite_field_ntl_gf2e.FiniteField_ntl_gf2e``). In all other case the PARI C library is used -(``sage.rings.finite_rings.finite_field_ext_pari.FiniteField_ext_pari``). +(``sage.rings.finite_rings.finite_field_pari_ffelt.FiniteField_pari_ffelt``). However, this distinction is internal only and the user usually does not have to worry about it because consistency across all @@ -625,6 +625,9 @@ def create_object(self, version, key, **kwds): K = FiniteField_pari_ffelt(p, modulus, name) elif (impl == 'pari_mod' or impl == 'pari'): # for unpickling old pickles + # This implementation is deprecated, a warning will + # be given when this field is created. + # See http://trac.sagemath.org/ticket/17297 from finite_field_ext_pari import FiniteField_ext_pari K = FiniteField_ext_pari(order, name, modulus) else: diff --git a/src/sage/rings/finite_rings/element_base.pyx b/src/sage/rings/finite_rings/element_base.pyx index 775b4c5a0dd..b8337de1176 100644 --- a/src/sage/rings/finite_rings/element_base.pyx +++ b/src/sage/rings/finite_rings/element_base.pyx @@ -18,7 +18,7 @@ def is_FiniteFieldElement(x): EXAMPLE:: - sage: from sage.rings.finite_rings.element_ext_pari import is_FiniteFieldElement + sage: from sage.rings.finite_rings.element_base import is_FiniteFieldElement sage: is_FiniteFieldElement(1) False sage: is_FiniteFieldElement(IntegerRing()) @@ -61,7 +61,7 @@ cdef class FiniteRingElement(CommutativeRingElement): n = n % (q-1) if n == 0: if all: return [] - else: raise ValueError, "no nth root" + else: raise ValueError("no nth root") gcd, alpha, beta = n.xgcd(q-1) # gcd = alpha*n + beta*(q-1), so 1/n = alpha/gcd (mod q-1) if gcd == 1: return [self**alpha] if all else self**alpha @@ -69,7 +69,7 @@ cdef class FiniteRingElement(CommutativeRingElement): q1overn = (q-1)//n if self**q1overn != 1: if all: return [] - else: raise ValueError, "no nth root" + else: raise ValueError("no nth root") self = self**alpha if cunningham: from sage.rings.factorint import factor_cunningham @@ -98,7 +98,7 @@ cdef class FiniteRingElement(CommutativeRingElement): else: return self else: - raise ValueError, "unknown algorithm" + raise ValueError("unknown algorithm") cdef class FinitePolyExtElement(FiniteRingElement): """ @@ -483,8 +483,6 @@ cdef class FinitePolyExtElement(FiniteRingElement): ... ArithmeticError: Multiplicative order of 0 not defined. """ - import sage.rings.arith - if self.is_zero(): raise ArithmeticError("Multiplicative order of 0 not defined.") n = self._parent.order() - 1 @@ -517,6 +515,94 @@ cdef class FinitePolyExtElement(FiniteRingElement): return Integer(1) return self.parent().characteristic() + def is_square(self): + """ + Returns ``True`` if and only if this element is a perfect square. + + EXAMPLES:: + + sage: k. = FiniteField(9, impl='givaro', modulus='primitive') + sage: a.is_square() + False + sage: (a**2).is_square() + True + sage: k. = FiniteField(4, impl='ntl', modulus='primitive') + sage: (a**2).is_square() + True + sage: k. = FiniteField(17^5, impl='pari_ffelt', modulus='primitive') + sage: a.is_square() + False + sage: (a**2).is_square() + True + + :: + + sage: k(0).is_square() + True + """ + K = self.parent() + if K.characteristic() == 2: + return True + n = K.order() - 1 + a = self**(n // 2) + return a == 1 or a == 0 + + def square_root(self, extend=False, all=False): + """ + The square root function. + + INPUT: + + + - ``extend`` -- bool (default: ``True``); if ``True``, return a + square root in an extension ring, if necessary. Otherwise, raise a + ValueError if the root is not in the base ring. + + .. WARNING:: + + This option is not implemented! + + - ``all`` - bool (default: ``False``); if ``True``, return all + square roots of ``self``, instead of just one. + + .. WARNING:: + + The ``'extend'`` option is not implemented (yet). + + EXAMPLES:: + + sage: F = FiniteField(7^2, 'a') + sage: F(2).square_root() + 4 + sage: F(3).square_root() + 2*a + 6 + sage: F(3).square_root()**2 + 3 + sage: F(4).square_root() + 2 + sage: K = FiniteField(7^3, 'alpha', impl='pari_ffelt') + sage: K(3).square_root() + Traceback (most recent call last): + ... + ValueError: must be a perfect square. + """ + try: + return self.nth_root(2, extend=extend, all=all) + except ValueError: + raise ValueError("must be a perfect square.") + + def sqrt(self, extend=False, all = False): + """ + See :meth:square_root(). + + EXAMPLES:: + + sage: k. = GF(3^17) + sage: (a^3 - a - 1).sqrt() + a^16 + 2*a^15 + a^13 + 2*a^12 + a^10 + 2*a^9 + 2*a^8 + a^7 + a^6 + 2*a^5 + a^4 + 2*a^2 + 2*a + 2 + """ + return self.square_root(extend=extend, all=all) + def nth_root(self, n, extend = False, all = False, algorithm=None, cunningham=False): r""" Returns an `n`\th root of ``self``. diff --git a/src/sage/rings/finite_rings/element_ext_pari.py b/src/sage/rings/finite_rings/element_ext_pari.py index 95140e88f76..633af6b86a0 100644 --- a/src/sage/rings/finite_rings/element_ext_pari.py +++ b/src/sage/rings/finite_rings/element_ext_pari.py @@ -1,5 +1,5 @@ """ -Elements of Finite Fields +Finite field elements implemented via PARI's POLMOD type (deprecated) EXAMPLES:: @@ -16,6 +16,8 @@ sage: f = conway_polynomial(2,63) sage: K. = GF(2**63, name='a', modulus=f, impl='pari_mod') + doctest:...: DeprecationWarning: The "pari_mod" finite field implementation is deprecated + See http://trac.sagemath.org/17297 for details. sage: n = f.degree() sage: m = 3; sage: e = (2^n - 1) / (2^m - 1) @@ -29,10 +31,8 @@ import operator import sage.structure.element as element -import sage.rings.arith as arith import sage.rings.integer_ring as integer_ring from sage.rings.integer import Integer -import sage.rings.rational as rational from sage.libs.pari.all import pari, pari_gen from sage.rings.finite_rings.element_base import FinitePolyExtElement import sage.rings.field_element as field_element @@ -337,133 +337,6 @@ def polynomial(self): """ return self.parent().polynomial_ring()(self.__value.lift()) - def is_square(self): - """ - Returns ``True`` if and only if this element is a perfect square. - - EXAMPLES:: - - sage: k. = FiniteField(9, impl='pari_mod') - sage: a.is_square() - False - sage: (a^2).is_square() - True - sage: k. = FiniteField(4, impl='pari_mod') - sage: (a^2).is_square() - True - sage: k. = FiniteField(17^5, impl='pari_mod') - sage: (a^2).is_square() - True - sage: a.is_square() - False - - :: - - sage: k(0).is_square() - True - """ - K = self.parent() - if K.characteristic() == 2: - return True - n = K.order() - 1 - a = self**(n // 2) - return a == 1 or a == 0 - - def square_root(self, extend=False, all=False): - """ - The square root function. - - INPUT: - - - - ``extend`` -- bool (default: ``True``); if ``True``, return a - square root in an extension ring, if necessary. Otherwise, raise a - ValueError if the root is not in the base ring. - - .. WARNING:: - - This option is not implemented! - - - ``all`` - bool (default: ``False``); if ``True``, return all - square roots of ``self``, instead of just one. - - .. WARNING:: - - The ``'extend'`` option is not implemented (yet). - - EXAMPLES:: - - sage: F = FiniteField(7^2, 'a', impl='pari_mod') - sage: F(2).square_root() - 4 - sage: F(3).square_root() - 2*a + 6 - sage: F(3).square_root()**2 - 3 - sage: F(4).square_root() - 5 - sage: K = FiniteField(7^3, 'alpha', impl='pari_mod') - sage: K(3).square_root() - Traceback (most recent call last): - ... - ValueError: must be a perfect square. - """ - if extend: - raise NotImplementedError - R = self.parent()['x'] - f = R([-self, 0, 1]) - g = f.factor() - if len(g) == 2 or g[0][1] == 2: - if all: - return [-g[0][0][0], g[0][0][0]] - else: - return -g[0][0][0] - if all: - return [] - else: - raise ValueError("must be a perfect square.") - - def sqrt(self, extend=False, all = False): - """ - See :meth:square_root(). - - EXAMPLES:: - - sage: k. = GF(3^17, impl='pari_mod') - sage: (a^3 - a - 1).sqrt() - a^16 + 2*a^15 + a^13 + 2*a^12 + a^10 + 2*a^9 + 2*a^8 + a^7 + a^6 + 2*a^5 + a^4 + 2*a^2 + 2*a + 2 - """ - return self.square_root(extend=extend, all=all) - - def multiplicative_order(self): - r""" - Returns the *multiplicative* order of this element, which must be - nonzero. - - EXAMPLES:: - - sage: k. = FiniteField(5^3, impl='pari_mod', modulus='conway') - sage: a.multiplicative_order() - 124 - sage: a**124 - 1 - """ - try: - return self.__multiplicative_order - except AttributeError: - if self.is_zero(): - raise ArithmeticError("Multiplicative order of 0 not defined.") - n = self.parent().order() - 1 - order = 1 - for p, e in arith.factor(n): - # Determine the power of p that divides the order. - a = self**(n//(p**e)) - while a != 1: - order *= p - a = a**p - self.__multiplicative_order = order - return order - def __copy__(self): """ Return a copy of this element. diff --git a/src/sage/rings/finite_rings/element_givaro.pyx b/src/sage/rings/finite_rings/element_givaro.pyx index 9756cabb740..6d68261aa37 100644 --- a/src/sage/rings/finite_rings/element_givaro.pyx +++ b/src/sage/rings/finite_rings/element_givaro.pyx @@ -65,7 +65,6 @@ from sage.structure.sage_object cimport SageObject import operator import sage.rings.arith import constructor as finite_field -import finite_field_ext_pari import sage.interfaces.gap from sage.libs.pari.all import pari diff --git a/src/sage/rings/finite_rings/element_ntl_gf2e.pyx b/src/sage/rings/finite_rings/element_ntl_gf2e.pyx index e8a59853d78..0b855299923 100644 --- a/src/sage/rings/finite_rings/element_ntl_gf2e.pyx +++ b/src/sage/rings/finite_rings/element_ntl_gf2e.pyx @@ -281,9 +281,6 @@ cdef class Cache_ntl_gf2e(SageObject): sage: K. = GF(2^19, impl="ntl") sage: a^20 a^6 + a^3 + a^2 + a - sage: L. = GF(2^19, impl="pari_mod") - sage: K(b^20) - a^6 + a^3 + a^2 + a sage: M. = GF(2^19, impl="pari_ffelt") sage: K(c^20) a^6 + a^3 + a^2 + a diff --git a/src/sage/rings/finite_rings/finite_field_base.pyx b/src/sage/rings/finite_rings/finite_field_base.pyx index 3f23e7c8c92..aea0c97759c 100644 --- a/src/sage/rings/finite_rings/finite_field_base.pyx +++ b/src/sage/rings/finite_rings/finite_field_base.pyx @@ -36,6 +36,9 @@ from sage.structure.parent cimport Parent from sage.misc.cachefunc import cached_method from sage.misc.prandom import randrange +# Copied from sage.misc.fast_methods, used in __hash__() below. +cdef int SIZEOF_VOID_P_SHIFT = 8*sizeof(void *) - 4 + cdef class FiniteFieldIterator: r""" An iterator over a finite field. This should only be used when the field @@ -51,12 +54,15 @@ cdef class FiniteFieldIterator: EXAMPLES:: - sage: k = iter(FiniteField(9, 'a', impl='pari_mod')) # indirect doctest + sage: k = iter(FiniteField(9, 'a', impl='pari_ffelt')) # indirect doctest + sage: isinstance(k, sage.rings.finite_rings.finite_field_base.FiniteFieldIterator) + True + sage: k = iter(FiniteField(16, 'a', impl='ntl')) # indirect doctest sage: isinstance(k, sage.rings.finite_rings.finite_field_base.FiniteFieldIterator) True """ self.parent = parent - self.iter =iter(self.parent.vector_space()) + self.iter = iter(self.parent.vector_space()) def __next__(self): r""" @@ -64,7 +70,7 @@ cdef class FiniteFieldIterator: EXAMPLE:: - sage: k = iter(FiniteField(9, 'a', impl='pari_mod')) + sage: k = iter(FiniteField(9, 'a', impl='pari_ffelt')) sage: k.next() # indirect doctest 0 """ @@ -81,8 +87,8 @@ cdef class FiniteFieldIterator: [0, a, a^2, a^3, 2*a^2 + 3*a + 4, 2*a^3 + 3*a^2 + 4*a, 3*a^3 + a^2 + 6*a + 1] sage: K. = GF(5^9) sage: for x in K: - ... if x == a+3: break - ... print x + ....: if x == a+3: break + ....: print x 0 1 2 @@ -120,6 +126,71 @@ cdef class FiniteField(Field): category = FiniteFields() Field.__init__(self, base, names, normalize, category) + # The methods __hash__ and __richcmp__ below were copied from + # sage.misc.fast_methods.WithEqualityById; we cannot inherit from + # this since Cython does not support multiple inheritance. + + def __hash__(self): + """ + The hash provided by this class coincides with that of ````. + + TESTS:: + + sage: F. = FiniteField(2^3) + sage: hash(F) == hash(F) + True + sage: hash(F) == object.__hash__(F) + True + + """ + # This is the default hash function in Python's object.c: + cdef long x + cdef size_t y = self + y = (y >> 4) | (y << SIZEOF_VOID_P_SHIFT) + x = y + if x==-1: + x = -2 + return x + + def __richcmp__(self, other, int m): + """ + Compare ``self`` with ``other``. + + Finite fields compare equal if and only if they are identical. + In particular, they are not equal unless they have the same + cardinality, modulus, variable name and implementation. + + EXAMPLES:: + + sage: x = polygen(GF(3)) + sage: F = FiniteField(3^2, 'c', modulus=x^2+1) + sage: F == F + True + sage: F == FiniteField(3^3, 'c') + False + sage: F == FiniteField(3^2, 'c', modulus=x^2+x+2) + False + sage: F == FiniteField(3^2, 'd') + False + sage: F == FiniteField(3^2, 'c', impl='pari_ffelt') + False + """ + if self is other: + if m == 2: # == + return True + elif m == 3: # != + return False + else: + # <= or >= or NotImplemented + return m==1 or m==5 or NotImplemented + else: + if m == 2: + return False + elif m == 3: + return True + else: + return NotImplemented + def is_perfect(self): r""" Return whether this field is perfect, i.e., every element has a `p`-th @@ -272,38 +343,6 @@ cdef class FiniteField(Field): sib.cache(self, v, name) return v - def _cmp_(left, Parent right): - """ - Compares this finite field with other. - - .. WARNING:: - - The notation of equality of finite fields in Sage is - currently not stable, i.e., it may change in a future version. - - EXAMPLES:: - - sage: FiniteField(3**2, 'c') == FiniteField(3**3, 'c') # indirect doctest - False - sage: FiniteField(3**2, 'c') == FiniteField(3**2, 'c') - True - - The variable name is (currently) relevant for comparison of finite - fields:: - - sage: FiniteField(3**2, 'c') == FiniteField(3**2, 'd') - False - """ - if not PY_TYPE_CHECK(right, FiniteField): - return cmp(type(left), type(right)) - c = cmp(left.characteristic(), right.characteristic()) - if c: return c - c = cmp(left.degree(), right.degree()) - if c: return c - # TODO comparing the polynomials themselves would recursively call - # this cmp... - return cmp(str(left.polynomial()), str(right.polynomial())) - def __iter__(self): """ Return an iterator over the elements of this finite field. This generic @@ -313,7 +352,7 @@ cdef class FiniteField(Field): EXAMPLES:: - sage: k = FiniteField(8, 'a', impl='pari_mod') + sage: k = FiniteField(8, 'a', impl='pari_ffelt') sage: i = iter(k); i # indirect doctest sage: i.next() @@ -814,8 +853,6 @@ cdef class FiniteField(Field): x sage: GF(13^2, 'a', impl="givaro", modulus=x^2+2).modulus() x^2 + 2 - sage: GF(13^2, 'a', impl="pari_mod", modulus=x^2+2).modulus() - x^2 + 2 sage: GF(13^2, 'a', impl="pari_ffelt", modulus=x^2+2).modulus() x^2 + 2 """ @@ -852,7 +889,7 @@ cdef class FiniteField(Field): EXAMPLES:: - sage: k. = FiniteField(9, impl='pari_mod') + sage: k. = FiniteField(9) sage: k.polynomial('x') x^2 + 2*x + 2 sage: k.polynomial() @@ -972,18 +1009,6 @@ cdef class FiniteField(Field): self.__vector_space = V return V - def __hash__(self): - r""" - Return a hash of this finite field. - - EXAMPLES:: - - sage: hash(GF(17)) - -1709973406 # 32-bit - 9088054599082082 # 64-bit - """ - return hash("GF") + hash(self.order()) - cpdef _coerce_map_from_(self, R): r""" Canonical coercion to ``self``. diff --git a/src/sage/rings/finite_rings/finite_field_ext_pari.py b/src/sage/rings/finite_rings/finite_field_ext_pari.py index e3b014c2a78..f62f3933332 100644 --- a/src/sage/rings/finite_rings/finite_field_ext_pari.py +++ b/src/sage/rings/finite_rings/finite_field_ext_pari.py @@ -1,5 +1,5 @@ """ -Finite Extension Fields implemented via PARI. +Finite Extension Fields implemented via PARI POLMODs (deprecated). AUTHORS: @@ -43,9 +43,8 @@ class FiniteField_ext_pari(FiniteField_generic): - ``q`` -- integer, size of the finite field, not prime - - ``name`` -- variable used for printing element of the finite - field. Also, two finite fields are considered equal if they - have the same variable name, and not otherwise. + - ``name`` -- variable name used for printing elements of the + finite field - ``modulus`` -- an irreducible polynomial to construct this field. @@ -58,6 +57,8 @@ class FiniteField_ext_pari(FiniteField_generic): sage: P. = PolynomialRing(GF(3)) sage: from sage.rings.finite_rings.finite_field_ext_pari import FiniteField_ext_pari sage: k = FiniteField_ext_pari(9, 'a', modulus=(x^2 + 2*x + 2)) + doctest:...: DeprecationWarning: The "pari_mod" finite field implementation is deprecated + See http://trac.sagemath.org/17297 for details. sage: k Finite Field in a of size 3^2 sage: k.is_field() @@ -136,6 +137,8 @@ class FiniteField_ext_pari(FiniteField_generic): sage: loads(K.dumps()) == K True sage: K = FiniteField(7^10, 'b', impl='pari_mod') + doctest:...: DeprecationWarning: The "pari_mod" finite field implementation is deprecated + See http://trac.sagemath.org/17297 for details. sage: loads(K.dumps()) == K True sage: K = FiniteField(7^10, 'a', impl='pari_mod') @@ -169,6 +172,9 @@ def __init__(self, q, name, modulus=None): sage: k = FiniteField(9, 'a', impl='pari_mod'); k Finite Field in a of size 3^2 """ + from sage.misc.superseded import deprecation + deprecation(17297, 'The "pari_mod" finite field implementation is deprecated') + if element_ext_pari.dynamic_FiniteField_ext_pariElement is None: element_ext_pari._late_import() from constructor import FiniteField as GF q = integer.Integer(q) @@ -258,36 +264,6 @@ def __reduce__(self): """ return self._factory_data[0].reduce_data(self) - def __cmp__(self, other): - """ - Compare ``self`` to ``other``. - - EXAMPLES:: - - sage: k = GF(7^20, 'a', impl='pari_mod') - sage: k == loads(dumps(k)) - True - """ - if not isinstance(other, FiniteField_ext_pari): - return cmp(type(self), type(other)) - return cmp((self.__order, self.variable_name(), self._modulus), (other.__order, other.variable_name(), other._modulus)) - - def __richcmp__(left, right, op): - r""" - Compare ``left`` with ``right``. - - EXAMPLE:: - - sage: k. = GF(2^17, impl='pari_mod') - sage: j. = GF(2^18, impl='pari_mod') - sage: k == j - False - - sage: GF(2^17, 'a', impl='pari_mod') == copy(GF(2^17, 'a', impl='pari_mod')) - True - """ - return left._richcmp_helper(right, op) - def _pari_one(self): r""" The PARI object ``Mod(1,p)``. This is implementation specific @@ -571,20 +547,3 @@ def order(self): 1024 """ return self.__order - - def __hash__(self): - """ - Return the hash of this field. - - EXAMPLES:: - - sage: {GF(9, 'a', impl='pari_mod'): 1} # indirect doctest - {Finite Field in a of size 3^2: 1} - sage: {GF(9, 'b', impl='pari_mod'): 1} # indirect doctest - {Finite Field in b of size 3^2: 1} - """ - try: - return self.__hash - except AttributeError: - self.__hash = hash((self.__order, self.variable_name(), self._modulus)) - return self.__hash diff --git a/src/sage/rings/finite_rings/finite_field_givaro.py b/src/sage/rings/finite_rings/finite_field_givaro.py index 58e4c672934..68e4b7620ce 100644 --- a/src/sage/rings/finite_rings/finite_field_givaro.py +++ b/src/sage/rings/finite_rings/finite_field_givaro.py @@ -352,9 +352,6 @@ def _element_constructor_(self, e): sage: K. = GF(3^10, impl="givaro") sage: a^20 2*a^9 + 2*a^8 + a^7 + 2*a^5 + 2*a^4 + 2*a^3 + 1 - sage: L. = GF(3^10, impl="pari_mod") - sage: K(b^20) - 2*a^9 + 2*a^8 + a^7 + 2*a^5 + 2*a^4 + 2*a^3 + 1 sage: M. = GF(3^10, impl="pari_ffelt") sage: K(c^20) 2*a^9 + 2*a^8 + a^7 + 2*a^5 + 2*a^4 + 2*a^3 + 1 @@ -516,25 +513,6 @@ def fetch_int(self, n): """ return self._cache.fetch_int(n) - def __hash__(self): - """ - The hash of a Givaro finite field is a hash over it's - characteristic polynomial and the string 'givaro'. - - EXAMPLES:: - - sage: {GF(3^4, 'a'):1} # indirect doctest - {Finite Field in a of size 3^4: 1} - """ - try: - return self._hash - except AttributeError: - if self.degree() > 1: - self._hash = hash((self.characteristic(), self.polynomial(), self.variable_name(), "givaro")) - else: - self._hash = hash((self.characteristic(), self.variable_name(), "givaro")) - return self._hash - def _pari_modulus(self): """ Return the modulus of ``self`` in a format for PARI. @@ -547,21 +525,6 @@ def _pari_modulus(self): f = pari(str(self.modulus())) return f.subst('x', 'a') * pari("Mod(1,%s)"%self.characteristic()) - def _finite_field_ext_pari_(self): # todo -- cache - """ - Return a :class:`FiniteField_ext_pari` isomorphic to ``self`` with - the same defining polynomial. - - EXAMPLES:: - - sage: GF(3^4,'z')._finite_field_ext_pari_() - Finite Field in z of size 3^4 - """ - f = self.polynomial() - import finite_field_ext_pari - return finite_field_ext_pari.FiniteField_ext_pari(self.order(), - self.variable_name(), f) - def __iter__(self): """ Finite fields may be iterated over. diff --git a/src/sage/rings/finite_rings/finite_field_ntl_gf2e.py b/src/sage/rings/finite_rings/finite_field_ntl_gf2e.py index b035630e604..47b08c5ce44 100644 --- a/src/sage/rings/finite_rings/finite_field_ntl_gf2e.py +++ b/src/sage/rings/finite_rings/finite_field_ntl_gf2e.py @@ -27,7 +27,6 @@ from sage.rings.finite_rings.finite_field_base import FiniteField from sage.libs.pari.all import pari -from finite_field_ext_pari import FiniteField_ext_pari from sage.rings.integer_ring import ZZ from sage.rings.integer import Integer @@ -126,7 +125,7 @@ def __init__(self, q, names="a", modulus=None, repr="poly"): sage: k2. = GF(2^17) sage: k1 == k2 False - sage: k3 = k1._finite_field_ext_pari_() + sage: k3. = GF(2^16, impl="pari_ffelt") sage: k1 == k3 False @@ -319,44 +318,6 @@ def fetch_int(self, number): """ return self._cache.fetch_int(number) - def _finite_field_ext_pari_(self): - """ - Return a :class:`FiniteField_ext_pari` isomorphic to ``self`` with - the same defining polynomial. - - .. NOTE:: - - This method will vanish eventually because that implementation of - finite fields will be deprecated. - - EXAMPLES:: - - sage: k. = GF(2^20) - sage: kP = k._finite_field_ext_pari_() - sage: kP - Finite Field in a of size 2^20 - sage: type(kP) - - """ - f = self.polynomial() - return FiniteField_ext_pari(self.order(), self.variable_name(), f) - - def __hash__(self): - """ - Return the hash value of ``self``. - - EXAMPLES:: - - sage: k1. = GF(2^16) - sage: {k1:1} # indirect doctest - {Finite Field in a of size 2^16: 1} - """ - try: - return self._hash - except AttributeError: - self._hash = hash((self.characteristic(),self.polynomial(),self.variable_name(),"ntl_gf2e")) - return self._hash - def _pari_modulus(self): """ Return PARI object which is equivalent to the diff --git a/src/sage/rings/finite_rings/finite_field_pari_ffelt.py b/src/sage/rings/finite_rings/finite_field_pari_ffelt.py index 3db52ae9819..286ce0d4caf 100644 --- a/src/sage/rings/finite_rings/finite_field_pari_ffelt.py +++ b/src/sage/rings/finite_rings/finite_field_pari_ffelt.py @@ -44,14 +44,11 @@ class FiniteField_pari_ffelt(FiniteField): .. NOTE:: - - Direct construction of FiniteField_pari_ffelt objects - requires specifying a characteristic and a modulus. - To construct a finite field by specifying a cardinality and - an algorithm for finding an irreducible polynomial, use the - FiniteField constructor with ``impl='pari_ffelt'``. - - - Two finite fields are considered equal if and only if they - have the same cardinality, variable name, and modulus. + Direct construction of :class:`FiniteField_pari_ffelt` objects + requires specifying a characteristic and a modulus. To + construct a finite field by specifying a cardinality and an + algorithm for finding an irreducible polynomial, use the + ``FiniteField`` constructor with ``impl='pari_ffelt'``. EXAMPLES: @@ -130,23 +127,6 @@ def __init__(self, p, modulus, name=None): Element = FiniteFieldElement_pari_ffelt - def __hash__(self): - """ - Return the hash of this field. - - EXAMPLE:: - - sage: {GF(9, 'a', impl='pari_ffelt'): 1} # indirect doctest - {Finite Field in a of size 3^2: 1} - sage: {GF(9, 'b', impl='pari_ffelt'): 1} # indirect doctest - {Finite Field in b of size 3^2: 1} - """ - try: - return self.__hash - except AttributeError: - self.__hash = hash((self.cardinality(), self.variable_name(), self._modulus)) - return self.__hash - def __reduce__(self): """ For pickling. @@ -161,43 +141,6 @@ def __reduce__(self): """ return self._factory_data[0].reduce_data(self) - def __cmp__(self, other): - """ - Compare ``self`` to ``other``. - - EXAMPLES:: - - sage: k = FiniteField(7^20, 'a', impl='pari_ffelt') - sage: k == k - True - sage: k2 = FiniteField(7^20, 'a', impl='pari_ffelt') - sage: k2 == k - True - sage: kb = FiniteField(7^20, 'b', impl='pari_ffelt') - sage: kb == k - False - """ - if not isinstance(other, FiniteField_pari_ffelt): - return cmp(type(self), type(other)) - return cmp((self.cardinality(), self.variable_name(), self._modulus), - (other.cardinality(), other.variable_name(), other._modulus)) - - def __richcmp__(left, right, op): - """ - Compare ``left`` with ``right``. - - EXAMPLE:: - - sage: k = FiniteField(2^17, 'a', impl='pari_ffelt') - sage: j = FiniteField(2^18, 'b', impl='pari_ffelt') - sage: k == j - False - - sage: k == copy(k) - True - """ - return left._richcmp_helper(right, op) - def gen(self, n=0): """ Return a generator of ``self`` over its prime field, which is a diff --git a/src/sage/rings/finite_rings/finite_field_prime_modn.py b/src/sage/rings/finite_rings/finite_field_prime_modn.py index b88b6cd5f6b..235a767ab43 100644 --- a/src/sage/rings/finite_rings/finite_field_prime_modn.py +++ b/src/sage/rings/finite_rings/finite_field_prime_modn.py @@ -92,52 +92,6 @@ def __reduce__(self): """ return self._factory_data[0].reduce_data(self) - def __cmp__(self, other): - r""" - Compare ``self`` with ``other``. - - Two finite prime fields are considered equal if and only if - their characteristics and moduli are equal. - - EXAMPLES:: - - sage: K = FiniteField(3) - sage: copy(K) == K - True - sage: x = polygen(GF(5)) - sage: GF(5) == GF(7) - False - sage: GF(5, modulus=x-2) == GF(5) - False - """ - if self is other: - return 0 - if not isinstance(other, FiniteField_prime_modn): - return cmp(type(self), type(other)) - c = cmp(self.__char, other.__char) - if c: return c - # Shortcut: if neither field has a _modulus attribute, they - # are equal - if not hasattr(self, "_modulus") and not hasattr(other, "_modulus"): - return 0 - return cmp(self.modulus(), other.modulus()) - - def __richcmp__(left, right, op): - r""" - Compare ``self`` with ``right``. - - EXAMPLES:: - - sage: k = GF(2) - sage: j = GF(3) - sage: k == j - False - - sage: GF(2) == copy(GF(2)) - True - """ - return left._richcmp_helper(right, op) - def _coerce_map_from_(self, S): """ This is called implicitly by arithmetic methods. diff --git a/src/sage/rings/finite_rings/integer_mod.pyx b/src/sage/rings/finite_rings/integer_mod.pyx index a7779d473fc..9abeaf8a384 100644 --- a/src/sage/rings/finite_rings/integer_mod.pyx +++ b/src/sage/rings/finite_rings/integer_mod.pyx @@ -1366,6 +1366,9 @@ cdef class IntegerMod_abstract(FiniteRingElement): def rational_reconstruction(self): """ + Use rational reconstruction to try to find a lift of this element to + the rational numbers. + EXAMPLES:: sage: R = IntegerModRing(97) @@ -1374,6 +1377,15 @@ cdef class IntegerMod_abstract(FiniteRingElement): 33 sage: a.rational_reconstruction() 2/3 + + This method is also inherited by prime finite fields elements:: + + sage: k = GF(97) + sage: a = k(RationalField()('2/3')) + sage: a + 33 + sage: a.rational_reconstruction() + 2/3 """ return self.lift().rational_reconstruction(self.modulus()) diff --git a/src/sage/rings/finite_rings/residue_field.pyx b/src/sage/rings/finite_rings/residue_field.pyx index 4f7b17ce0dc..8263c14f900 100644 --- a/src/sage/rings/finite_rings/residue_field.pyx +++ b/src/sage/rings/finite_rings/residue_field.pyx @@ -1617,7 +1617,7 @@ class ResidueFiniteField_pari_ffelt(ResidueField_generic, FiniteField_pari_ffelt EXAMPLES:: - We create an ext_pari residue field:: + We create a residue field with implementation ``pari_ffelt``:: sage: K. = NumberField(x^3-7) sage: P = K.ideal(923478923).factor()[0][0] diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index d13f742ddd3..e82d49888fd 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -150,6 +150,8 @@ from libc.stdint cimport uint64_t include "sage/ext/python_debug.pxi" include "../structure/coerce.pxi" # for parent_c include "sage/libs/pari/decl.pxi" +from sage.rings.rational cimport Rational +from sage.libs.gmp.rational_reconstruction cimport mpq_rational_reconstruction cdef extern from "limits.h": long LONG_MAX @@ -3081,6 +3083,16 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): modulo m and whose numerator and denominator is bounded by sqrt(m/2). + INPUT: + + - ``self`` -- Integer + + - ``m`` -- Integer + + OUTPUT: + + - a :class:`Rational` + EXAMPLES:: sage: (3/7)%100 @@ -3088,22 +3100,27 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: (29).rational_reconstruction(100) 3/7 - TEST: + TESTS: - Check that ticket #9345 is fixed:: + Check that trac:`9345` is fixed:: - sage: ZZ(1).rational_reconstruction(0) + sage: 0.rational_reconstruction(0) Traceback (most recent call last): ... - ZeroDivisionError: The modulus cannot be zero - sage: m = ZZ.random_element(-10^6,10^6) - sage: m.rational_reconstruction(0) + ZeroDivisionError: rational reconstruction with zero modulus + sage: ZZ.random_element(-10^6, 10^6).rational_reconstruction(0) Traceback (most recent call last): ... - ZeroDivisionError: The modulus cannot be zero + ZeroDivisionError: rational reconstruction with zero modulus """ - import rational - return rational.pyrex_rational_reconstruction(self, m) + cdef Integer a + cdef Rational x = PY_NEW(Rational) + try: + mpq_rational_reconstruction(x.value, self.value, m.value) + except ValueError: + a = self % m + raise ArithmeticError("rational reconstruction of %s (mod %s) does not exist" % (a, m)) + return x def powermodm_ui(self, exp, mod): r""" @@ -5998,16 +6015,16 @@ cpdef LCM_list(v): def GCD_list(v): r""" - Return the GCD of a list v of integers. Elements of v are converted - to Sage integers if they aren't already. - - This function is used, e.g., by rings/arith.py + Return the greatest common divisor of a list of integers. INPUT: - - ``v`` - list or tuple + - ``v`` -- list or tuple - OUTPUT: integer + Elements of `v` are converted to Sage integers. An empty list has + GCD zero. + + This function is used, for example, by ``rings/arith.py``. EXAMPLES:: @@ -6017,7 +6034,7 @@ def GCD_list(v): sage: type(w) - Check that the bug reported in trac #3118 has been fixed:: + Check that the bug reported in :trac:`3118` has been fixed:: sage: sage.rings.integer.GCD_list([2,2,3]) 1 @@ -6030,6 +6047,11 @@ def GCD_list(v): 3 sage: type(w) + + Check that the GCD of the empty list is zero (:trac:`17257`):: + + sage: GCD_list([]) + 0 """ cdef int i, n = len(v) cdef Integer z = PY_NEW(Integer) @@ -6041,7 +6063,7 @@ def GCD_list(v): v[i] = Integer(v[i]) if n == 0: - return one + return zero elif n == 1: return v[0].abs() diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index 9eb4ec2ca97..159a1e44f1c 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -3076,7 +3076,7 @@ cdef class Polynomial(CommutativeAlgebraElement): sage: R. = CDF[] sage: f = (x^2 + 2*R(I))^3 sage: F = f.factor() - sage: F # abs tol 1e-5 + sage: F # abs tol 3e-5 (x - 1.0000138879287663 + 1.0000013435286879*I) * (x - 0.9999942196864997 + 0.9999873009803959*I) * (x - 0.9999918923847313 + 1.0000113554909125*I) * (x + 0.9999908759550227 - 1.0000069659624138*I) * (x + 0.9999985293216753 - 0.9999886153831807*I) * (x + 1.0000105947233 - 1.0000044186544053*I) sage: [f(t[0][0]).abs() for t in F] # abs tol 1e-13 [1.979365054e-14, 1.97936298566e-14, 1.97936990747e-14, 3.6812407475e-14, 3.65211563729e-14, 3.65220890052e-14] diff --git a/src/sage/rings/rational.pyx b/src/sage/rings/rational.pyx index 4f494248a86..a387396ab26 100644 --- a/src/sage/rings/rational.pyx +++ b/src/sage/rings/rational.pyx @@ -42,7 +42,6 @@ TESTS:: include "sage/ext/interrupt.pxi" # ctrl-c interrupt block support -include "sage/ext/gmp.pxi" include "sage/ext/stdsage.pxi" include "sage/ext/python.pxi" include "sage/libs/pari/decl.pxi" @@ -65,6 +64,7 @@ from sage.libs.pari.gen cimport gen as pari_gen from sage.libs.pari.pari_instance cimport PariInstance from integer_ring import ZZ +from sage.libs.gmp.rational_reconstruction cimport mpq_rational_reconstruction from sage.structure.element cimport Element, RingElement, ModuleElement from sage.structure.element import bin_op @@ -3650,47 +3650,6 @@ cdef double mpq_get_d_nearest(mpq_t x) except? -648555075988944.5: return ldexp(d, shift) -def pyrex_rational_reconstruction(integer.Integer a, integer.Integer m): - """ - Find the rational reconstruction of ``a mod m``, if it exists. - - INPUT: - - - ``a`` - Integer - - - ``m`` - Integer - - OUTPUT: - - - ``x`` - rings.rational.Rational - - EXAMPLES:: - - sage: Integers(100)(2/3) - 34 - sage: sage.rings.rational.pyrex_rational_reconstruction(34, 100) - 2/3 - - TEST: - - Check that ticket #9345 is fixed:: - - sage: sage.rings.rational.pyrex_rational_reconstruction(0,0) - Traceback (most recent call last): - ... - ZeroDivisionError: The modulus cannot be zero - sage: sage.rings.rational.pyrex_rational_reconstruction(ZZ.random_element(-10^6, 10^6), 0) - Traceback (most recent call last): - ... - ZeroDivisionError: The modulus cannot be zero - """ - if not m.__nonzero__(): - raise ZeroDivisionError("The modulus cannot be zero") - cdef Rational x - x = PY_NEW(Rational) - mpq_rational_reconstruction(x.value, a.value, m.value) - return x - def make_rational(s): """ Make a rational number from ``s`` (a string in base 32) diff --git a/src/sage/schemes/elliptic_curves/ell_rational_field.py b/src/sage/schemes/elliptic_curves/ell_rational_field.py index 4e8a3d65a83..f2928b6cbe0 100644 --- a/src/sage/schemes/elliptic_curves/ell_rational_field.py +++ b/src/sage/schemes/elliptic_curves/ell_rational_field.py @@ -158,10 +158,10 @@ def __init__(self, ainvs, **kwds): When constructing a curve from the large database using a label, we must be careful that the copied generators have the - right curve (see #10999: the following used not to work when + right curve (see :trac:`10999`: the following used not to work when the large database was installed):: - sage: E=EllipticCurve('389a1') + sage: E = EllipticCurve('389a1') sage: [P.curve() is E for P in E.gens()] [True, True] @@ -1456,7 +1456,7 @@ def simon_two_descent(self, verbose=0, lim1=5, lim3=50, limtriv=3, sage: r, s, G = E.simon_two_descent(); r,s (8, 8) - Example from :trac: `10832`:: + Example from :trac:`10832`:: sage: E = EllipticCurve([1,0,0,-6664,86543]) sage: E.simon_two_descent() @@ -1478,7 +1478,7 @@ def simon_two_descent(self, verbose=0, lim1=5, lim3=50, limtriv=3, sage: E.gens() # uses mwrank [(4311692542083/48594841 : -13035144436525227/338754636611 : 1)] - Example for :trac: `5153`:: + Example for :trac:`5153`:: sage: E = EllipticCurve([3,0]) sage: E.simon_two_descent() @@ -2769,7 +2769,7 @@ def tamagawa_exponent(self, p): sage: E.tamagawa_exponent(5) 2 - See #4715:: + See :trac:`4715`:: sage: E=EllipticCurve('117a3') sage: E.tamagawa_exponent(13) @@ -4654,7 +4654,7 @@ def manin_constant(self): sage: EllipticCurve('11a3').change_weierstrass_model([1/35,0,0,0]).manin_constant() 5 - Rather complicated examples (see #12080) :: + Rather complicated examples (see :trac:`12080`) :: sage: [ EllipticCurve('27a%s'%i).manin_constant() for i in [1,2,3,4]] [1, 1, 3, 3] @@ -5217,19 +5217,20 @@ def mod5family(self): def tate_curve(self, p): r""" - Creates the Tate Curve over the `p`-adics associated to - this elliptic curves. + Create the Tate curve over the `p`-adics associated to + this elliptic curve. - This Tate curve a `p`-adic curve with split multiplicative + This Tate curve is a `p`-adic curve with split multiplicative reduction of the form `y^2+xy=x^3+s_4 x+s_6` which is isomorphic to the given curve over the algebraic closure of `\QQ_p`. Its points over `\QQ_p` are isomorphic to `\QQ_p^{\times}/q^{\ZZ}` - for a certain parameter `q\in\ZZ_p`. + for a certain parameter `q \in \ZZ_p`. INPUT: - p - a prime where the curve has multiplicative reduction. + - `p` -- a prime where the curve has split multiplicative + reduction EXAMPLES:: @@ -5268,7 +5269,7 @@ def tate_curve(self, p): except KeyError: pass - Eq = ell_tate_curve.TateCurve(self,p) + Eq = ell_tate_curve.TateCurve(self, p) self._tate_curve[p] = Eq return Eq @@ -5489,7 +5490,7 @@ def integral_points(self, mw_base='auto', both_signs=False, verbose=False): TESTS: - The bug reported on trac #4525 is now fixed:: + The bug reported on :trac:`4525` is now fixed:: sage: EllipticCurve('91b1').integral_points() [(-1 : 3 : 1), (1 : 0 : 1), (3 : 4 : 1)] @@ -5499,19 +5500,19 @@ def integral_points(self, mw_base='auto', both_signs=False, verbose=False): sage: [len(e.integral_points(both_signs=False)) for e in cremona_curves([11..100])] # long time (15s on sage.math, 2011) [2, 0, 2, 3, 2, 1, 3, 0, 2, 4, 2, 4, 3, 0, 0, 1, 2, 1, 2, 0, 2, 1, 0, 1, 3, 3, 1, 1, 4, 2, 3, 2, 0, 0, 5, 3, 2, 2, 1, 1, 1, 0, 1, 3, 0, 1, 0, 1, 1, 3, 6, 1, 2, 2, 2, 0, 0, 2, 3, 1, 2, 2, 1, 1, 0, 3, 2, 1, 0, 1, 0, 1, 3, 3, 1, 1, 5, 1, 0, 1, 1, 0, 1, 2, 0, 2, 0, 1, 1, 3, 1, 2, 2, 4, 4, 2, 1, 0, 0, 5, 1, 0, 1, 2, 0, 2, 2, 0, 0, 0, 1, 0, 3, 1, 5, 1, 2, 4, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 0, 0, 1, 0, 1, 1, 4, 1, 0, 1, 1, 0, 4, 2, 0, 1, 1, 2, 3, 1, 1, 1, 1, 6, 2, 1, 1, 0, 2, 0, 6, 2, 0, 4, 2, 2, 0, 0, 1, 2, 0, 2, 1, 0, 3, 1, 2, 1, 4, 6, 3, 2, 1, 0, 2, 2, 0, 0, 5, 4, 1, 0, 0, 1, 0, 2, 2, 0, 0, 2, 3, 1, 3, 1, 1, 0, 1, 0, 0, 1, 2, 2, 0, 2, 0, 0, 1, 2, 0, 0, 4, 1, 0, 1, 1, 0, 1, 2, 0, 1, 4, 3, 1, 2, 2, 1, 1, 1, 1, 6, 3, 3, 3, 3, 1, 1, 1, 1, 1, 0, 7, 3, 0, 1, 3, 2, 1, 0, 3, 2, 1, 0, 2, 2, 6, 0, 0, 6, 2, 2, 3, 3, 5, 5, 1, 0, 6, 1, 0, 3, 1, 1, 2, 3, 1, 2, 1, 1, 0, 1, 0, 1, 0, 5, 5, 2, 2, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1] - The bug reported at #4897 is now fixed:: + The bug reported at :trac:`4897` is now fixed:: sage: [P[0] for P in EllipticCurve([0,0,0,-468,2592]).integral_points()] [-24, -18, -14, -6, -3, 4, 6, 18, 21, 24, 36, 46, 102, 168, 186, 381, 1476, 2034, 67246] .. note:: - This function uses the algorithm given in [Co1]. + This function uses the algorithm given in [Co1]_. REFERENCES: - - [Co1] Cohen H., Number Theory Vol I: Tools and Diophantine - Equations GTM 239, Springer 2007 + .. [Co1] H. Cohen, Number Theory, Vol. I: Tools and + Diophantine Equations. GTM 239, Springer, 2007. AUTHORS: diff --git a/src/sage/schemes/toric/chow_group.py b/src/sage/schemes/toric/chow_group.py index a52a44d9647..8fb0b487080 100644 --- a/src/sage/schemes/toric/chow_group.py +++ b/src/sage/schemes/toric/chow_group.py @@ -1053,7 +1053,7 @@ def relation_gens(self): Return the Chow cycles equivalent to zero. For each `d-k-1`-dimensional cone `\rho \in \Sigma^{(d-k-1)}`, - the relations in `A_k(X)`, that is the cycles equvalent to + the relations in `A_k(X)`, that is the cycles equivalent to zero, are generated by .. MATH:: diff --git a/src/sage/sets/recursively_enumerated_set.pyx b/src/sage/sets/recursively_enumerated_set.pyx index df9afe068bb..7c56ae07eea 100644 --- a/src/sage/sets/recursively_enumerated_set.pyx +++ b/src/sage/sets/recursively_enumerated_set.pyx @@ -137,7 +137,7 @@ graded, it may have other structure like not containing oriented cycle but this does not help for enumeration. In this example, the seed is 0 and the successor function is either ``+2`` -or ``+3``. This is the set of non negative linear combinaisons of 2 and 3:: +or ``+3``. This is the set of non negative linear combinations of 2 and 3:: sage: succ = lambda a:[a+2,a+3] sage: C = RecursivelyEnumeratedSet([0], succ) diff --git a/src/sage/structure/sage_object.pyx b/src/sage/structure/sage_object.pyx index 12c1d8ffa8e..1836e95dd41 100644 --- a/src/sage/structure/sage_object.pyx +++ b/src/sage/structure/sage_object.pyx @@ -1415,8 +1415,8 @@ def unpickle_all(dir = None, debug=False, run_test_suite=False): :: sage: sage.structure.sage_object.unpickle_all() # (4s on sage.math, 2011) - doctest:... DeprecationWarning: This class is replaced by Matrix_modn_dense_float/Matrix_modn_dense_double. - See http://trac.sagemath.org/4260 for details. + doctest:... DeprecationWarning: ... + See http://trac.sagemath.org/... for details. Successfully unpickled ... objects. Failed to unpickle 0 objects. diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index 3f3618c3d4e..986b8619394 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -8098,7 +8098,7 @@ cdef class Expression(CommutativeRingElement): Simplify an expression containing hypergeometric functions. INPUT: - + - ``algorithm`` -- (default: ``'maxima'``) the algorithm to use for for simplification. Implemented are ``'maxima'``, which uses Maxima's ``hgfred`` function, and ``'sage'``, which uses an algorithm @@ -9440,6 +9440,15 @@ cdef class Expression(CommutativeRingElement): ... TypeError: (1, 2) are not valid variables. + :trac:`17128`: fixed:: + + sage: var('x,y') + (x, y) + sage: f = x+y + sage: sol = f.solve([x, y], solution_dict=True) + sage: sol[0].get(x) + sol[0].get(y) + 0 + :trac:`16651` fixed:: sage: (x^7-x-1).solve(x, to_poly_solve=True) # abs tol 1e-6 @@ -9574,7 +9583,11 @@ cdef class Expression(CommutativeRingElement): continue if solution_dict: - X = [dict([[sol.left(), sol.right()]]) for sol in X] + if isinstance(x, (list, tuple)): + X = [{sol.left():sol.right() for sol in b} for b in X] + else: + X = [dict([[sol.left(),sol.right()]]) for sol in X] + if multiplicities: return X, ret_multiplicities else: @@ -10022,40 +10035,40 @@ cdef class Expression(CommutativeRingElement): zeta(5) .. WARNING:: - + This function only works with symbolic expressions. To sum any other objects like list elements or function return values, please use python summation, see http://docs.python.org/library/functions.html#sum In particular, this does not work:: - + sage: n = var('n') sage: list=[1,2,3,4,5] sage: sum(list[n],n,0,3) Traceback (most recent call last): ... TypeError: unable to convert x (=n) to an integer - + Use python ``sum()`` instead:: - + sage: sum(list[n] for n in range(4)) 10 - + Also, only a limited number of functions are recognized in symbolic sums:: - + sage: sum(valuation(n,2),n,1,5) Traceback (most recent call last): ... AttributeError: 'sage.symbolic.expression.Expression' object has no attribute 'valuation' - + Again, use python ``sum()``:: - + sage: sum(valuation(n+1,2) for n in range(5)) 3 - + (now back to the Sage ``sum`` examples) - + A well known binomial identity:: sage: assume(n>=0) diff --git a/src/sage/tests/french_book/linsolve_doctest.py b/src/sage/tests/french_book/linsolve_doctest.py index d6d9722bae5..03ab1fe62ed 100644 --- a/src/sage/tests/french_book/linsolve_doctest.py +++ b/src/sage/tests/french_book/linsolve_doctest.py @@ -48,7 +48,7 @@ sage: A = matrix(RDF, [[-1,2],[3,4]]) sage: b = vector(RDF, [2,3]) - sage: x = A\b; x # rel tol 1e-15 + sage: x = A\b; x # rel tol 3e-15 (-0.20000000000000018, 0.9000000000000001) Sage example in ./linsolve.tex, line 512:: @@ -94,7 +94,7 @@ sage: R1 = R[0:3,0:3] sage: b1 = transpose(Q)*b sage: c = b1[0:3] - sage: R1.solve_right(c) # rel tol 1e-14 + sage: R1.solve_right(c) # rel tol 2e-14 (-1.499999999999999, -0.49999999999999867, 2.7499999999999973) Sage example in ./linsolve.tex, line 834:: diff --git a/src/sage/tests/french_book/numbertheory.py b/src/sage/tests/french_book/numbertheory.py index 1a5a5b29baf..c23082c47e7 100644 --- a/src/sage/tests/french_book/numbertheory.py +++ b/src/sage/tests/french_book/numbertheory.py @@ -54,7 +54,7 @@ sage: rational_reconstruction(409,1000) Traceback (most recent call last): ... -ValueError: Rational reconstruction of 409 (mod 1000) does not exist. +ArithmeticError: rational reconstruction of 409 (mod 1000) does not exist sage: def harmonic(n): ... return sum([1/x for x in range(1,n+1)]) sage: def harmonic_mod(n,m): diff --git a/src/sage/version.py b/src/sage/version.py index 2e7f7005607..97406a58801 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.4.rc0' -date = '2014-10-30' +version = '6.4' +date = '2014-11-14' diff --git a/src/setup.py b/src/setup.py index a69926e27a9..f55d9e74df9 100644 --- a/src/setup.py +++ b/src/setup.py @@ -64,7 +64,7 @@ # compiler flag -Og is used. See also # * http://trac.sagemath.org/sage_trac/ticket/14460 # * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56982 -if subprocess.call("""$CC --version | grep -i 'gcc.* 4[.][89]' >/dev/null """, shell=True) == 0: +if subprocess.call("""$CC --version | grep -i 'gcc.* 4[.]8' >/dev/null """, shell=True) == 0: extra_compile_args.append('-fno-tree-dominator-opts') # Generate interpreters