Ticket #11854: 11854.patch
File 11854.patch, 20.3 KB (added by , 11 years ago) |
---|
-
c_lib/include/convert.h
# HG changeset patch # User Jeroen Demeyer <jdemeyer@cage.ugent.be> # Date 1317728758 -7200 # Node ID 7a69ffa86a2848436e28225813d3f5babd96e83f # Parent aeaa3a623defbcfee3305e6d9fdea55c7d24e8ce Rewrite various conversions to PARI, remove broken functions in convert.h diff --git a/c_lib/include/convert.h b/c_lib/include/convert.h
a b 13 13 #include <stdio.h> 14 14 15 15 void t_INT_to_ZZ ( mpz_t value, GEN g ); 16 17 void ZZ_to_t_INT ( GEN *g, mpz_t value );18 19 16 void t_FRAC_to_QQ ( mpq_t value, GEN g ); 20 21 void QQ_to_t_FRAC ( GEN *g, mpq_t value ); -
c_lib/include/stdsage.h
diff --git a/c_lib/include/stdsage.h b/c_lib/include/stdsage.h
a b 43 43 extern "C" { 44 44 #endif 45 45 46 46 47 /***************************************** 47 For PARI 48 Memory management 48 PARI array element assignment 49 *****************************************/ 50 #define set_gel(x, n, z) (gel(x,n) = z) 51 #define set_gmael(x, i, j, z) (gmael(x,i,j) = z) 52 #define set_gcoeff(x, i, j, z) (gcoeff(x,i,j) = z) 49 53 50 *****************************************/51 52 #define set_gel(x, n, z) (gel(x,n) = z)53 54 54 55 /****************************************** 55 56 Some macros exported for Pyrex in cdefs.pxi -
c_lib/src/convert.c
diff --git a/c_lib/src/convert.c b/c_lib/src/convert.c
a b 37 37 return; 38 38 } 39 39 40 void ZZ_to_t_INT ( GEN *g, mpz_t value )41 {42 long limbs = 0;43 44 limbs = mpz_size( value );45 46 *g = cgetg( limbs+2, t_INT );47 settyp( *g, t_INT );48 setlgefint( *g, limbs+2 );49 setsigne( *g, mpz_sgn(value) );50 51 mpz_export( int_LSW(*g), NULL, -1, sizeof(long), 0, 0, value );52 53 return;54 }55 56 40 57 41 /* 58 42 … … 70 54 t_INT_to_ZZ(mpq_numref(value), numer(g)); 71 55 t_INT_to_ZZ(mpq_denref(value), denom(g)); 72 56 } 73 74 void QQ_to_t_FRAC ( GEN *g, mpq_t value )75 {76 GEN num, den;77 ZZ_to_t_INT(&num, mpq_numref(value));78 ZZ_to_t_INT(&den, mpq_denref(value));79 *g = gdiv(num, den);80 } -
sage/libs/pari/decl.pxi
diff --git a/sage/libs/pari/decl.pxi b/sage/libs/pari/decl.pxi
a b 1573 1573 extern char* diffptr 1574 1574 1575 1575 cdef extern from 'stdsage.h': 1576 GEN set_gel(GEN x, long n, GEN z) # gel(x,n) = z 1576 GEN set_gel(GEN x, long n, GEN z) # gel(x,n) = z 1577 GEN set_gmael(GEN x, long i, long j, GEN z) # gmael(x,i,j) = z 1578 GEN set_gcoeff(GEN x, long i, long j, GEN z) # gcoeff(x,i,j) = z 1577 1579 1578 1580 1579 1581 # Inline functions in separate file -
sage/libs/pari/gen.pxd
diff --git a/sage/libs/pari/gen.pxd b/sage/libs/pari/gen.pxd
a b 25 25 cdef gen new_gen_from_mpz_t(self, mpz_t value) 26 26 cdef inline GEN _new_GEN_from_mpz_t(self, mpz_t value) 27 27 cdef gen new_gen_from_mpq_t(self, mpq_t value) 28 cdef inline GEN _new_GEN_from_mpq_t(self, mpq_t value) 28 29 cdef gen new_gen_from_int(self, int value) 29 30 cdef gen new_t_POL_from_int_star(self, int *vals, int length, long varnum) 30 31 cdef gen new_gen_from_padic(self, long ordp, long relprec, mpz_t prime, mpz_t p_pow, mpz_t unit) … … 36 37 cdef gen new_ref(self, GEN g, gen parent) 37 38 cdef gen _empty_vector(self, long n) 38 39 cdef long get_var(self, v) 39 cdef GEN toGEN(self, x, int i) except NULL 40 cdef GEN integer_matrix_GEN(self, mpz_t** B, Py_ssize_t nr, Py_ssize_t nc) except <GEN>0 41 cdef GEN integer_matrix_permuted_for_hnf_GEN(self, mpz_t** B, Py_ssize_t nr, Py_ssize_t nc) except <GEN>0 42 cdef integer_matrix(self, mpz_t** B, Py_ssize_t nr, Py_ssize_t nc, bint permute_for_hnf) 43 cdef GEN rational_matrix_GEN(self, mpq_t** B, Py_ssize_t nr, Py_ssize_t nc) except <GEN>0 44 cdef rational_matrix(self, mpq_t** B, Py_ssize_t nr, Py_ssize_t nc) 45 46 47 48 40 cdef GEN toGEN(self, x, int i) except NULL 41 cdef GEN _new_GEN_from_mpz_t_matrix(self, mpz_t** B, Py_ssize_t nr, Py_ssize_t nc) 42 cdef GEN _new_GEN_from_mpz_t_matrix_rotate90(self, mpz_t** B, Py_ssize_t nr, Py_ssize_t nc) 43 cdef gen integer_matrix(self, mpz_t** B, Py_ssize_t nr, Py_ssize_t nc, bint permute_for_hnf) 44 cdef GEN _new_GEN_from_mpq_t_matrix(self, mpq_t** B, Py_ssize_t nr, Py_ssize_t nc) 45 cdef gen rational_matrix(self, mpq_t** B, Py_ssize_t nr, Py_ssize_t nc) -
sage/libs/pari/gen.pyx
diff --git a/sage/libs/pari/gen.pyx b/sage/libs/pari/gen.pyx
a b 15 15 - Robert Bradshaw, Jeroen Demeyer, William Stein (2010-08-15): 16 16 Upgrade to PARI 2.4.3 (#9343) 17 17 18 - Jeroen Demeyer (2011-09-27): rewrite various conversion routines 19 (#11611, #11854) 20 21 18 22 EXAMPLES:: 19 23 20 24 sage: pari('5! + 10/x') … … 147 151 148 152 """ 149 153 154 #***************************************************************************** 155 # Copyright (C) 2006,2010 William Stein <wstein@gmail.com> 156 # Copyright (C) ???? Justin Walker 157 # Copyright (C) ???? Gonzalo Tornaria 158 # Copyright (C) 2010 Robert Bradshaw <robertwb@math.washington.edu> 159 # Copyright (C) 2010,2011 Jeroen Demeyer <jdemeyer@cage.ugent.be> 160 # 161 # Distributed under the terms of the GNU General Public License (GPL) 162 # as published by the Free Software Foundation; either version 2 of 163 # the License, or (at your option) any later version. 164 # http://www.gnu.org/licenses/ 165 #***************************************************************************** 166 167 150 168 import sys 151 169 import math 152 170 import types … … 162 180 include 'pari_err.pxi' 163 181 include '../../ext/stdsage.pxi' 164 182 165 cdef extern from "convert.h":166 cdef void ZZ_to_t_INT( GEN *g, mpz_t value )167 cdef void QQ_to_t_FRAC( GEN *g, mpq_t value )168 169 183 # Make sure we don't use mpz_t_offset before initializing it by 170 184 # putting in a value that's likely to provoke a segmentation fault, 171 185 # rather than silently corrupting memory. … … 9014 9028 """ 9015 9029 Create a new gen from a given MPIR-integer ``value``. 9016 9030 9031 EXAMPLES:: 9032 9033 sage: pari(42) # indirect doctest 9034 42 9035 9017 9036 TESTS: 9018 9037 9019 9038 Check that the hash of an integer does not depend on existing … … 9030 9049 return self.new_gen(self._new_GEN_from_mpz_t(value)) 9031 9050 9032 9051 cdef inline GEN _new_GEN_from_mpz_t(self, mpz_t value): 9033 # Create a new PARI GEN from a mpz_t. For internal use only, 9034 # this directly uses the PARI stack. 9035 # One should call sig_on() before and sig_off() after. 9036 9052 r""" 9053 Create a new PARI ``t_INT`` from a ``mpz_t``. 9054 9055 For internal use only; this directly uses the PARI stack. 9056 One should call ``sig_on()`` before and ``sig_off()`` after. 9057 """ 9037 9058 cdef unsigned long limbs = mpz_size(value) 9038 9059 9039 9060 cdef GEN z = cgeti(limbs + 2) … … 9049 9070 9050 9071 cdef gen new_gen_from_mpq_t(self, mpq_t value): 9051 9072 """ 9052 EXAMPLES:: 9053 sage: pari(2/3) # indirect doctest 9054 2/3 9055 """ 9056 cdef GEN z 9057 sig_on() 9058 QQ_to_t_FRAC(&z, value) 9059 return self.new_gen(z) 9073 Create a new gen from a given MPIR-rational ``value``. 9074 9075 EXAMPLES:: 9076 9077 sage: pari(-2/3) 9078 -2/3 9079 sage: pari(QQ(42)) 9080 42 9081 sage: pari(QQ(42)).type() 9082 't_INT' 9083 sage: pari(QQ(1/42)).type() 9084 't_FRAC' 9085 9086 TESTS: 9087 9088 Check that the hash of a rational does not depend on existing 9089 garbage on the stack (#11854):: 9090 9091 sage: foo = pari(2^(32*1024)); # Create large integer to put PARI stack in known state 9092 sage: a5 = pari(5/7); 9093 sage: foo = pari(0xDEADBEEF * (2^(32*1024)-1)//(2^32 - 1)); # Dirty PARI stack 9094 sage: b5 = pari(5/7); 9095 sage: a5.__hash__() == b5.__hash__() 9096 True 9097 """ 9098 sig_on() 9099 return self.new_gen(self._new_GEN_from_mpq_t(value)) 9100 9101 cdef inline GEN _new_GEN_from_mpq_t(self, mpq_t value): 9102 r""" 9103 Create a new PARI ``t_INT`` or ``t_FRAC`` from a ``mpq_t``. 9104 9105 For internal use only; this directly uses the PARI stack. 9106 One should call ``sig_on()`` before and ``sig_off()`` after. 9107 """ 9108 cdef GEN num = self._new_GEN_from_mpz_t(mpq_numref(value)) 9109 if mpz_cmpabs_ui(mpq_denref(value), 1) == 0: 9110 # Denominator is 1, return the numerator (an integer) 9111 return num 9112 cdef GEN denom = self._new_GEN_from_mpz_t(mpq_denref(value)) 9113 return mkfrac(num, denom) 9060 9114 9061 9115 cdef gen new_t_POL_from_int_star(self, int *vals, int length, long varnum): 9062 9116 """ … … 9288 9342 return None 9289 9343 return self.new_gen(g) 9290 9344 9291 cdef GEN integer_matrix_GEN(self, mpz_t** B, Py_ssize_t nr, Py_ssize_t nc) except <GEN>0: 9292 """ 9293 EXAMPLES:: 9294 9295 sage: matrix(ZZ,2,[1..6])._pari_() # indirect doctest 9296 [1, 2, 3; 4, 5, 6] 9297 9298 """ 9299 cdef GEN x, A = gtomat(zeromat(nr, nc)) 9345 cdef GEN _new_GEN_from_mpz_t_matrix(self, mpz_t** B, Py_ssize_t nr, Py_ssize_t nc): 9346 r""" 9347 Create a new PARI ``t_MAT`` with ``nr`` rows and ``nc`` columns 9348 from a ``mpz_t**``. 9349 9350 For internal use only; this directly uses the PARI stack. 9351 One should call ``sig_on()`` before and ``sig_off()`` after. 9352 """ 9353 cdef GEN x 9354 cdef GEN A = zeromatcopy(nr, nc) 9300 9355 cdef Py_ssize_t i, j 9301 9356 for i in range(nr): 9302 9357 for j in range(nc): 9303 ZZ_to_t_INT(&x,B[i][j])9304 (<GEN>(A[j+1]))[i+1] = <long>x9358 x = self._new_GEN_from_mpz_t(B[i][j]) 9359 set_gcoeff(A, i+1, j+1, x) # A[i+1, j+1] = x (using 1-based indexing) 9305 9360 return A 9306 9361 9307 cdef GEN integer_matrix_permuted_for_hnf_GEN(self, mpz_t** B, Py_ssize_t nr, Py_ssize_t nc) except <GEN>0: 9308 cdef GEN x, A = gtomat(zeromat(nc, nr)) 9362 cdef GEN _new_GEN_from_mpz_t_matrix_rotate90(self, mpz_t** B, Py_ssize_t nr, Py_ssize_t nc): 9363 r""" 9364 Create a new PARI ``t_MAT`` with ``nr`` rows and ``nc`` columns 9365 from a ``mpz_t**`` and rotate the matrix 90 degrees 9366 counterclockwise. So the resulting matrix will have ``nc`` rows 9367 and ``nr`` columns. This is useful for computing the Hermite 9368 Normal Form because Sage and PARI use different definitions. 9369 9370 For internal use only; this directly uses the PARI stack. 9371 One should call ``sig_on()`` before and ``sig_off()`` after. 9372 """ 9373 cdef GEN x 9374 cdef GEN A = zeromatcopy(nc, nr) 9309 9375 cdef Py_ssize_t i, j 9310 9376 for i in range(nr): 9311 9377 for j in range(nc): 9312 ZZ_to_t_INT(&x,B[i][nc-j-1])9313 (<GEN>(A[i+1]))[j+1] = <long>x9378 x = self._new_GEN_from_mpz_t(B[i][nc-j-1]) 9379 set_gcoeff(A, j+1, i+1, x) # A[j+1, i+1] = x (using 1-based indexing) 9314 9380 return A 9315 9381 9316 cdef integer_matrix(self, mpz_t** B, Py_ssize_t nr, Py_ssize_t nc, bint permute_for_hnf):9382 cdef gen integer_matrix(self, mpz_t** B, Py_ssize_t nr, Py_ssize_t nc, bint permute_for_hnf): 9317 9383 """ 9318 9384 EXAMPLES:: 9319 9385 … … 9323 9389 sig_on() 9324 9390 cdef GEN g 9325 9391 if permute_for_hnf: 9326 g = self. integer_matrix_permuted_for_hnf_GEN(B, nr, nc)9392 g = self._new_GEN_from_mpz_t_matrix_rotate90(B, nr, nc) 9327 9393 else: 9328 g = self. integer_matrix_GEN(B, nr, nc)9394 g = self._new_GEN_from_mpz_t_matrix(B, nr, nc) 9329 9395 return self.new_gen(g) 9330 9396 9331 cdef GEN rational_matrix_GEN(self, mpq_t** B, Py_ssize_t nr, Py_ssize_t nc) except <GEN>0: 9332 """ 9333 EXAMPLES:: 9334 9335 sage: matrix(QQ,2,[1..6])._pari_() # indirect doctest 9336 [1, 2, 3; 4, 5, 6] 9337 """ 9338 cdef GEN x, A = gtomat(zeromat(nr, nc)) 9397 cdef GEN _new_GEN_from_mpq_t_matrix(self, mpq_t** B, Py_ssize_t nr, Py_ssize_t nc): 9398 cdef GEN x 9399 # Allocate zero matrix 9400 cdef GEN A = zeromatcopy(nr, nc) 9339 9401 cdef Py_ssize_t i, j 9340 9402 for i in range(nr): 9341 9403 for j in range(nc): 9342 QQ_to_t_FRAC(&x,B[i][j])9343 (<GEN>(A[j+1]))[i+1] = <long>x9404 x = self._new_GEN_from_mpq_t(B[i][j]) 9405 set_gcoeff(A, i+1, j+1, x) # A[i+1, j+1] = x (using 1-based indexing) 9344 9406 return A 9345 9407 9346 cdef rational_matrix(self, mpq_t** B, Py_ssize_t nr, Py_ssize_t nc):9408 cdef gen rational_matrix(self, mpq_t** B, Py_ssize_t nr, Py_ssize_t nc): 9347 9409 """ 9348 9410 EXAMPLES:: 9349 9411 … … 9351 9413 [1, 2, 3; 4, 5, 6] 9352 9414 """ 9353 9415 sig_on() 9354 cdef GEN g = self. rational_matrix_GEN(B, nr, nc)9416 cdef GEN g = self._new_GEN_from_mpq_t_matrix(B, nr, nc) 9355 9417 return self.new_gen(g) 9356 9418 9357 9419 cdef _coerce_c_impl(self, x): -
sage/libs/pari/misc.h
diff --git a/sage/libs/pari/misc.h b/sage/libs/pari/misc.h
a b 1 1 /***************************************** 2 For PARI 2 PARI misc macros and functions 3 *****************************************/ 4 #ifndef SAGE_LIBS_PARI_MISC_H 5 #define SAGE_LIBS_PARI_MISC_H 3 6 4 *****************************************/5 7 #include <pari/pari.h> 6 8 #include "interrupt.h" 7 9 8 #define set_gel(x, n, z) gel(x,n)=z;9 10 11 /***************************************** 12 Interrupts and PARI exception handling 13 *****************************************/ 10 14 #define _pari_sig_on() sig_on(); _pari_catch; 11 15 #define _pari_sig_str(s) sig_str(s); _pari_catch; 12 16 #define _pari_sig_off() _pari_endcatch; sig_off(); 13 17 18 14 19 inline int strcmp_to_cmp(int f) { 15 20 if (f > 0) { 16 21 return 1; … … 108 113 } 109 114 return 0; 110 115 } 116 117 #endif /* SAGE_LIBS_PARI_MISC_H */ -
sage/matrix/matrix_integer_dense.pxd
diff --git a/sage/matrix/matrix_integer_dense.pxd b/sage/matrix/matrix_integer_dense.pxd
a b 40 40 cdef void four_dim_det(mpz_t, mpz_t *) 41 41 42 42 ################################################################ 43 # fast conversion to parion the stack43 # fast conversion to PARI on the stack 44 44 ################################################################ 45 cdef GEN pari_GEN(Matrix_integer_dense B)45 cdef inline GEN pari_GEN(Matrix_integer_dense B) -
sage/matrix/matrix_integer_dense.pyx
diff --git a/sage/matrix/matrix_integer_dense.pyx b/sage/matrix/matrix_integer_dense.pyx
a b 75 75 long rank(GEN x) 76 76 77 77 cdef extern from "convert.h": 78 void ZZ_to_t_INT ( GEN *g, mpz_t value )79 78 cdef void t_INT_to_ZZ( mpz_t value, long *g ) 80 79 81 80 ######################################################### … … 4812 4811 [0 0 0] 4813 4812 """ 4814 4813 cdef PariInstance P = sage.libs.pari.gen.pari 4815 cdef GEN x, A = gtomat(zeromat(self._ncols, self._nrows)) 4816 cdef Py_ssize_t i, j 4817 # We make the matrix A got from self by reversing the order of 4818 # the columns and transposing. This is needed since PARI's 4819 # hnf does column operations instead of row operations. 4820 for i in range(self._nrows): 4821 for j in range(self._ncols): 4822 ZZ_to_t_INT(&x, self._matrix[i][self._ncols-j-1]) 4823 (<GEN>(A[i+1]))[j+1] = <long>x 4824 4825 # Actually compute the HNF using PARI. 4814 cdef GEN A 4826 4815 sig_on() 4816 A = P._new_GEN_from_mpz_t_matrix_rotate90(self._matrix, self._nrows, self._ncols) 4827 4817 cdef GEN H = mathnf0(A, flag) 4828 4818 B = self.extract_hnf_from_pari_matrix(H, flag, include_zero_rows) 4829 P.clear_stack() 4819 P.clear_stack() # This calls sig_off() 4830 4820 return B 4831 4821 4832 4822 … … 4873 4863 t_INT_to_ZZ(B._matrix[j][self._ncols-i-1], gcoeff(H, i+1, H_nc-j)) 4874 4864 return B 4875 4865 4876 cdef GEN pari_GEN(Matrix_integer_dense B):4877 """4866 cdef inline GEN pari_GEN(Matrix_integer_dense B): 4867 r""" 4878 4868 Create the PARI GEN object on the stack defined by the integer 4879 4869 matrix B. This is used internally by the function for conversion 4880 4870 of matrices to PARI. 4881 4882 EXAMPLES:: 4883 4884 sage: matrix(ZZ,1,[1..4])._pari_() # implicit doctest 4885 Mat([1, 2, 3, 4]) 4871 4872 For internal use only; this directly uses the PARI stack. 4873 One should call ``sig_on()`` before and ``sig_off()`` after. 4886 4874 """ 4887 cdef GEN x, A = gtomat(zeromat(B._nrows, B._ncols)) 4888 cdef Py_ssize_t i, j 4889 for i in range(B._nrows): 4890 for j in range(B._ncols): 4891 ZZ_to_t_INT(&x, B._matrix[i][j]) 4892 (<GEN>(A[j+1]))[i+1] = <long>x 4875 cdef PariInstance P = sage.libs.pari.gen.pari 4876 cdef GEN A 4877 A = P._new_GEN_from_mpz_t_matrix(B._matrix, B._nrows, B._ncols) 4893 4878 return A 4894 4879 4895 4880 -
sage/matrix/matrix_rational_dense.pxd
diff --git a/sage/matrix/matrix_rational_dense.pxd b/sage/matrix/matrix_rational_dense.pxd
a b 28 28 # fast conversion to pari on the stack 29 29 ################################################################ 30 30 ctypedef long* GEN 31 cdef GEN pari_GEN(Matrix_rational_dense B)31 cdef inline GEN pari_GEN(Matrix_rational_dense B) -
sage/matrix/matrix_rational_dense.pyx
diff --git a/sage/matrix/matrix_rational_dense.pyx b/sage/matrix/matrix_rational_dense.pyx
a b 96 96 97 97 cdef extern from "convert.h": 98 98 void t_FRAC_to_QQ ( mpq_t value, GEN g ) 99 void QQ_to_t_FRAC ( GEN *g, mpq_t value )100 99 101 100 ######################################################### 102 101 … … 2728 2727 t_FRAC_to_QQ(B._matrix[i][j], gcoeff(d, i+1, j+1)) 2729 2728 return B 2730 2729 2731 cdef GEN pari_GEN(Matrix_rational_dense B): 2730 cdef inline GEN pari_GEN(Matrix_rational_dense B): 2731 r""" 2732 Create the PARI GEN object on the stack defined by the rational 2733 matrix B. This is used internally by the function for conversion 2734 of matrices to PARI. 2735 2736 For internal use only; this directly uses the PARI stack. 2737 One should call ``sig_on()`` before and ``sig_off()`` after. 2732 2738 """ 2733 EXAMPLES:: 2734 2735 sage: matrix(QQ,2,3,[1..6])._rank_pari() # indirect doctest 2736 2 2737 """ 2738 cdef GEN x, A = gtomat(zeromat(B._nrows, B._ncols)) 2739 cdef Py_ssize_t i, j 2740 for i in range(B._nrows): 2741 for j in range(B._ncols): 2742 QQ_to_t_FRAC(&x, B._matrix[i][j]) 2743 (<GEN>(A[j+1]))[i+1] = <long>x 2739 cdef PariInstance P = sage.libs.pari.gen.pari 2740 cdef GEN A 2741 A = P._new_GEN_from_mpq_t_matrix(B._matrix, B._nrows, B._ncols) 2744 2742 return A 2745 2743 -
sage/rings/fast_arith.pyx
diff --git a/sage/rings/fast_arith.pyx b/sage/rings/fast_arith.pyx
a b 53 53 from sage.libs.pari.gen cimport gen as pari_gen 54 54 from sage.rings.integer cimport Integer 55 55 56 cdef extern from "convert.h":57 cdef void t_INT_to_ZZ(mpz_t value, long *g)58 59 56 cpdef prime_range(start, stop=None, algorithm="pari_primes", bint py_ints=False): 60 57 r""" 61 58 List of all primes between start and stop-1, inclusive. If the -
sage/rings/number_field/number_field_ideal.py
diff --git a/sage/rings/number_field/number_field_ideal.py b/sage/rings/number_field/number_field_ideal.py
a b 201 201 EXAMPLES:: 202 202 203 203 sage: NumberField(x^2 + 1, 'a').ideal(7).__hash__() 204 - 288230376151711715# 64-bit205 - 67108835# 32-bit204 -9223372036854775779 # 64-bit 205 -2147483619 # 32-bit 206 206 """ 207 try: return self._hash 208 # At some point in the future (e.g., for relative extensions), we'll likely 209 # have to consider other hashes, like the following. 210 #except AttributeError: self._hash = hash(self.gens()) 211 except AttributeError: self._hash = self.pari_hnf().__hash__() 207 try: 208 return self._hash 209 except AttributeError: 210 # At some point in the future (e.g., for relative extensions), 211 # we'll likely have to consider other hashes. 212 self._hash = self.pari_hnf().__hash__() 212 213 return self._hash 213 214 214 215 def _latex_(self): -
sage/rings/rational.pyx
diff --git a/sage/rings/rational.pyx b/sage/rings/rational.pyx
a b 85 85 86 86 cdef extern from "convert.h": 87 87 ctypedef long* GEN 88 void QQ_to_t_FRAC (GEN *g, mpq_t value)89 88 void t_FRAC_to_QQ ( mpq_t value, GEN g ) 90 89 void t_INT_to_ZZ ( mpz_t value, GEN g ) 91 90