Ticket #1952: mpolynomial_ideal_refactor.patch
| File mpolynomial_ideal_refactor.patch, 38.1 kB (added by malb, 5 months ago) |
|---|
-
a/sage/crypto/mq/mpolynomialsystem.py
old new 645 645 sage: P = F.ring() 646 646 sage: I = F.ideal() 647 647 sage: I.elimination_ideal(P('s000*s001*s002*s003*w100*w101*w102*w103*x100*x101*x102*x103')) 648 Ideal (k002 + (a^2)*k003 + 1, (a^3)*k001 + (a^3 + a^2)*k003 + 649 (a^3 + a + 1), k000 + (a^3 + a^2 + a)*k003 + (a^3 + a^2 + a), 650 (a^2)*k103 + (a^2 + a)*k003 + (a^2 + a + 1), (a^3)*k102 + 651 (a^3 + 1)*k003 + (a^2), (a^3)*k101 + (a^3)*k003 + (a^2 + 1), 652 (a^3)*k100 + (a^2 + a)*k003 + (a^2 + 1), k003^2 + 653 (a^3 + a^2 + a)*k003 + (a^3 + a^2 + a)) of Multivariate 654 Polynomial Ring in k100, k101, k102, k103, x100, x101, x102, 655 x103, w100, w101, w102, w103, s000, s001, s002, s003, 656 k000, k001, k002, k003 over Finite Field in a of size 2^4 648 Ideal (k002 + (a^2)*k003 + 1, 649 k001 + (a^3)*k003 + (a + 1), 650 k000 + (a^3 + a^2 + a)*k003 + (a^3 + a^2 + a), 651 k103 + (a^3)*k003 + (a^2 + 1), 652 k102 + (a^3 + a^2 + a)*k003 + (a^3 + 1), 653 k101 + k003 + (a^2 + a), 654 k100 + (a^2)*k003 + (a^2 + a), 655 k003^2 + (a^3 + a^2 + a)*k003 + (a^3 + a^2 + a)) 656 of Multivariate Polynomial Ring in k100, k101, k102, k103, 657 x100, x101, x102, x103, w100, w101, w102, w103, s000, 658 s001, s002, s003, k000, k001, k002, k003 over Finite Field 659 in a of size 2^4 660 657 661 """ 658 662 return self._ring.ideal(self.gens()) 659 663 -
a/sage/rings/polynomial/multi_polynomial_ideal.py
old new 13 13 -- William Stein 14 14 -- Kiran S. Kedlaya (2006-02-12): added Macaulay2 analogues of 15 15 some \Singular features 16 -- Martin Albrecht 16 -- Martin Albrecht <malb@informatik.uni-bremen> (2008,2007): 17 refactoring, many Singular related functions 17 18 18 19 EXAMPLES: 19 20 … … 121 122 122 123 #***************************************************************************** 123 124 # 124 # SAGE: System for Algebra and Geometry Experimentation125 # Sage 125 126 # 126 127 # Copyright (C) 2005 William Stein <wstein@gmail.com> 128 # Copyright (C) 2008 Martin Albrecht <malb@informatik.uni-bremen.de> 127 129 # 128 130 # Distributed under the terms of the GNU General Public License (GPL) 129 131 # … … 138 140 #***************************************************************************** 139 141 from __future__ import with_statement 140 142 141 from sage.rings.ideal import Ideal_generic142 143 from sage.interfaces.all import singular as singular_default 143 144 from sage.interfaces.all import macaulay2 as macaulay2_default 144 singular = singular_default 145 146 from sage.rings.ideal import Ideal_generic 145 147 from sage.rings.integer import Integer 146 148 from sage.structure.sequence import Sequence 149 150 from sage.misc.cachefunc import CachedFunction 151 from sage.misc.misc import prod 147 152 from sage.misc.sage_eval import sage_eval 148 from sage.misc.misc import prod 153 149 154 import sage.rings.integer_ring 150 155 import sage.rings.polynomial.toy_buchberger as toy_buchberger 151 156 152 def is_MPolynomialIdeal(x):153 r"""154 Return \code{True} if the provided argument \var{x} is an ideal in155 the multivariate polynomial ring.157 class RedSBContext: 158 """ 159 Within this context all \Singular Groebner basis calculations are 160 reduced automatically. 156 161 157 INPUT: 158 x -- an arbitrary object 159 160 EXAMPLE: 161 sage: P.<x,y,z> = PolynomialRing(QQ) 162 sage: I = [x + 2*y + 2*z - 1, x^2 + 2*y^2 + 2*z^2 - x, 2*x*y + 2*y*z - y] 163 164 \SAGE distinguishes between a list of generators for an ideal and 165 the ideal itself. This distinction is inconsisten with \Singular 166 but matches \Magma's behavior. 167 168 sage: is_MPolynomialIdeal(I) 169 False 170 171 sage: I = Ideal(I) 172 sage: is_MPolynomialIdeal(I) 173 True 162 AUTHOR: 163 -- Martin Albrecht 174 164 """ 175 return isinstance(x, MPolynomialIdeal)176 177 class MPolynomialIdeal_magma_repr:178 def _magma_(self, magma=None):179 r"""180 Returns a \MAGMA ideal matching this ideal if the base ring is181 coercable to \MAGMA and \MAGMA is available.182 183 INPUT:184 magma -- \MAGMA instance or None (default instance)185 (default: None)186 187 EXAMPLES:188 sage: R.<a,b,c,d,e,f,g,h,i,j> = PolynomialRing(GF(127),10)189 sage: I = sage.rings.ideal.Cyclic(R,4)190 sage: I._magma_() #optional MAGMA191 Ideal of Polynomial ring of rank 10 over GF(127)192 Graded Reverse Lexicographical Order193 Variables: a, b, c, d, e, f, g, h, i, j194 Basis:195 [196 a + b + c + d,197 a*b + b*c + a*d + c*d,198 a*b*c + a*b*d + a*c*d + b*c*d,199 a*b*c*d + 126200 ]201 """202 if magma == None:203 import sage.interfaces.magma204 magma = sage.interfaces.magma.magma205 return magma.ideal(self.gens())206 207 def _magma_groebner_basis(self, magma=None):208 r"""209 Computes a Groebner Basis for self using \MAGMA if available.210 211 INPUT:212 magma -- \MAGMA instance or None (default instance)213 (default: None)214 EXAMPLES:215 sage: R.<a,b,c,d,e,f,g,h,i,j> = PolynomialRing(GF(127),10)216 sage: I = sage.rings.ideal.Cyclic(R,6)217 sage: gb = I.groebner_basis('magma:GroebnerBasis') #optional MAGMA, indirect doctest218 sage: len(gb) #optional MAGMA219 45220 """221 try:222 return self.__magma_groebner_basis223 except AttributeError:224 pass225 R = self.ring()226 mgb = self._magma_(magma=magma).GroebnerBasis()227 mgb = [str(mgb[i+1]) for i in range(len(mgb))]228 if R.base_ring().degree() > 1:229 a = str(R.base_ring().gen())230 mgb = [e.replace("$.1",a) for e in mgb]231 B = Sequence([R(e) for e in mgb], R, check=False, immutable=True)232 self.__magma_groebner_basis = B233 return B234 235 class RedSBContext:236 165 def __init__(self, singular=singular_default): 237 166 r""" 238 167 Within this context all \Singular Groebner basis calculations … … 291 220 7*b+210*c^3-79*c^2+3*c, 292 221 7*a-420*c^3+158*c^2+8*c-7 293 222 """ 294 self.o = s ingular.option("get")223 self.o = self.singular.option("get") 295 224 self.singular.option("redSB") 296 225 297 226 def __exit__(self, typ, value, tb): … … 327 256 wrapper.__doc__=func.__doc__ 328 257 return wrapper 329 258 259 class cached(CachedFunction): 260 r""" 261 Specialised \code{CachedFunction} for the application in 262 multivariate polynomial ideals. 263 264 AUTHOR: 265 -- Martin Albrecht 266 """ 267 def __call__(self, *args, **kwds): 268 """ 269 EXAMPLES: 270 sage: P = PolynomialRing(GF(32003),4,'x') 271 sage: I = sage.rings.ideal.Katsura(P) 272 sage: I.groebner_basis.clear_cache() 273 sage: gb = I.groebner_basis() # indirect doctest 274 sage: I.groebner_basis.cache 275 {(Multivariate Polynomial Ring in x0, x1, x2, x3 over Finite Field of size 32003, 276 (x0 + 2*x1 + 2*x2 + 2*x3 - 1, 277 x1^2 + 2*x0*x2 + 2*x1*x3 - x2, 278 2*x0*x1 + 2*x1*x2 + 2*x2*x3 - x1, 279 x0^2 + 2*x1^2 + 2*x2^2 + 2*x3^2 - x0), 280 (), 281 ()): 282 [x0 + 2*x1 + 2*x2 + 2*x3 - 1, 283 x2^2 + 2*x1*x3 - 13711*x2*x3 - 4568*x3^2 - 4572*x1 + 13715*x2 - 9145*x3, 284 x1*x2 - 2*x1*x3 - 9147*x2*x3 - 13719*x3^2 + 2286*x1 + 9144*x2 + 4573*x3, 285 x1^2 + 2*x1*x3 + 4573*x2*x3 - 9142*x3^2 - 9144*x1 - 4572*x2 + 13715*x3, 286 x2*x3^2 + 3557*x3^3 - 1778*x1*x3 - 3161*x2*x3 + 5926*x3^2 - 10075*x1 - 6124*x2 + 11853*x3, x1*x3^2 - 10668*x3^3 - 3556*x1*x3 - 10075*x2*x3 + 3556*x3^2 - 889*x1 - 11853*x2, 287 x3^4 + 12535*x3^3 + 7471*x1*x3 + 6188*x2*x3 + 10117*x3^2 + 10521*x1 + 11393*x2 + 11829*x3]} 288 """ 289 from sage.rings.polynomial.multi_polynomial_ring_generic import is_MPolynomialRing 290 k = self.gen_key(*args, **kwds) 291 if self.cache.has_key(k) and "nocache" not in kwds: 292 return self.cache[k] 293 294 w = self.f(self.instance, *args, **kwds) 295 if is_MPolynomialRing(self.instance.ring()): 296 self.cache[k] = w 297 return w 298 299 def clear_cache(self): 300 """ 301 Clear the cache. 302 303 EXAMPLE: 304 sage: P = PolynomialRing(GF(32003),4,'x') 305 sage: I = sage.rings.ideal.Katsura(P) 306 sage: I.groebner_basis.clear_cache() 307 sage: I.groebner_basis.cache 308 {} 309 sage: gb = I.groebner_basis() # indirect doctest 310 sage: len(I.groebner_basis.cache) 311 1 312 sage: I.groebner_basis.clear_cache() 313 sage: len(I.groebner_basis.cache) 314 0 315 """ 316 self.cache = {} 317 318 def gen_key(self, *args, **kwds): 319 """ 320 Generate a key to the cache. 321 322 EXAMPLE: 323 sage: P = PolynomialRing(GF(32003),4,'x') 324 sage: I = sage.rings.ideal.Katsura(P) 325 sage: I.groebner_basis.gen_key() 326 (Multivariate Polynomial Ring in x0, x1, x2, x3 over Finite Field of size 32003, 327 (x0 + 2*x1 + 2*x2 + 2*x3 - 1, 328 x1^2 + 2*x0*x2 + 2*x1*x3 - x2, 329 2*x0*x1 + 2*x1*x2 + 2*x2*x3 - x1, 330 x0^2 + 2*x1^2 + 2*x2^2 + 2*x3^2 - x0), 331 (), 332 ()) 333 """ 334 r = (self.instance.ring(), tuple(sorted(self.instance.gens())), args, tuple(kwds.iteritems())) 335 return r 336 337 def is_in_cache(self, *args, **kwds): 338 """ 339 Check whether key is already in cache. 340 341 EXAMPLE: 342 sage: P = PolynomialRing(GF(32003),3,'x') 343 sage: I = sage.rings.ideal.Katsura(P) 344 sage: I.groebner_basis.is_in_cache() 345 False 346 sage: gb = I.groebner_basis() 347 sage: I.groebner_basis.is_in_cache() 348 True 349 """ 350 return self.gen_key(*args, **kwds) in self.cache 351 352 def is_MPolynomialIdeal(x): 353 r""" 354 Return \code{True} if the provided argument \var{x} is an ideal in 355 the multivariate polynomial ring. 356 357 INPUT: 358 x -- an arbitrary object 359 360 EXAMPLE: 361 sage: P.<x,y,z> = PolynomialRing(QQ) 362 sage: I = [x + 2*y + 2*z - 1, x^2 + 2*y^2 + 2*z^2 - x, 2*x*y + 2*y*z - y] 363 364 \SAGE distinguishes between a list of generators for an ideal and 365 the ideal itself. This distinction is inconsisten with \Singular 366 but matches \Magma's behavior. 367 368 sage: is_MPolynomialIdeal(I) 369 False 370 371 sage: I = Ideal(I) 372 sage: is_MPolynomialIdeal(I) 373 True 374 """ 375 return isinstance(x, MPolynomialIdeal) 376 377 class MPolynomialIdeal_magma_repr: 378 def _magma_(self, magma=None): 379 r""" 380 Returns a \MAGMA ideal matching this ideal if the base ring is 381 coercable to \MAGMA and \MAGMA is available. 382 383 INPUT: 384 magma -- \MAGMA instance or None (default instance) 385 (default: None) 386 387 EXAMPLES: 388 sage: R.<a,b,c,d,e,f,g,h,i,j> = PolynomialRing(GF(127),10) 389 sage: I = sage.rings.ideal.Cyclic(R,4) 390 sage: I._magma_() #optional MAGMA 391 Ideal of Polynomial ring of rank 10 over GF(127) 392 Graded Reverse Lexicographical Order 393 Variables: a, b, c, d, e, f, g, h, i, j 394 Basis: 395 [ 396 a + b + c + d, 397 a*b + b*c + a*d + c*d, 398 a*b*c + a*b*d + a*c*d + b*c*d, 399 a*b*c*d + 126 400 ] 401 """ 402 if magma == None: 403 import sage.interfaces.magma 404 magma = sage.interfaces.magma.magma 405 return magma.ideal(self.gens()) 406 407 def _groebner_basis_magma(self, magma=None): 408 r""" 409 Computes a Groebner Basis for self using \MAGMA if available. 410 411 INPUT: 412 magma -- \MAGMA instance or None (default instance) 413 (default: None) 414 EXAMPLES: 415 sage: R.<a,b,c,d,e,f,g,h,i,j> = PolynomialRing(GF(127),10) 416 sage: I = sage.rings.ideal.Cyclic(R,6) 417 sage: gb = I.groebner_basis('magma:GroebnerBasis') #optional MAGMA, indirect doctest 418 sage: len(gb) #optional MAGMA 419 45 420 """ 421 R = self.ring() 422 mgb = self._magma_(magma=magma).GroebnerBasis() 423 mgb = [str(mgb[i+1]) for i in range(len(mgb))] 424 if R.base_ring().degree() > 1: 425 a = str(R.base_ring().gen()) 426 mgb = [e.replace("$.1",a) for e in mgb] 427 B = Sequence([R(e) for e in mgb], R, check=False, immutable=True) 428 return B 429 330 430 class MPolynomialIdeal_singular_repr: 331 """431 r""" 332 432 An ideal in a multivariate polynomial ring, which has an 333 433 underlying \Singular ring associated to it. 334 434 """ 335 def __cmp__(self, other): 336 """ 337 EXAMPLE: 338 sage: R = PolynomialRing(QQ,'x,y,z') 339 sage: I = R.ideal() 340 sage: I == R.ideal() 341 True 342 343 sage: R = PolynomialRing(QQ, names=[]) 344 sage: R.ideal(0) == R.ideal(0) 345 True 346 347 sage: R, (x,y) = PolynomialRing(QQ, 2, 'xy').objgens() 348 sage: I = (x^3 + y, y)*R 349 sage: J = (x^3 + y, y, y*x^3 + y^2)*R 350 sage: I == J 351 True 352 """ 353 l = self.groebner_basis() 354 r = other.groebner_basis() 355 return cmp(r,l) 356 357 def _singular_(self, singular=None): 435 def _singular_(self, singular=singular_default): 358 436 r""" 359 437 Return \Singular ideal corresponding to this ideal. 360 438 … … 366 444 x^3+y, 367 445 y 368 446 """ 369 if singular is None:370 singular = singular_default371 447 try: 372 448 self.ring()._singular_(singular).set_ring() 373 449 I = self.__singular … … 412 488 g = f.reduce(self.groebner_basis()) 413 489 return g.is_zero() 414 490 415 def plot(self ):491 def plot(self, singular=singular_default): 416 492 """ 417 493 If you somehow manage to install surf, perhaps you can use 418 494 this function to implicitly plot the real zero locus of this … … 628 704 """ 629 705 return [P for _,P in self.complete_primary_decomposition(algorithm)] 630 706 631 def triangular_decomposition(self, algorithm=None ):707 def triangular_decomposition(self, algorithm=None, singular=singular_default): 632 708 r""" 633 709 Decompose zero-dimensional ideal \code{self} into triangular sets. 634 710 … … 766 842 767 843 return T 768 844 769 def dimension(self ):845 def dimension(self, singular=singular_default): 770 846 """ 771 847 The dimension of the ring modulo this ideal. 772 848 … … 784 860 try: 785 861 return self.__dimension 786 862 except AttributeError: 787 v = list(self.groebner_basis()) 788 if len(v) == 0: 789 v = [0] 790 self.__dimension = Integer(singular(v,"ideal").dim()) 863 v = self._groebner_basis_singular_raw() 864 self.__dimension = Integer(v.dim()) 791 865 return self.__dimension 792 866 793 867 def vector_space_dimension(self): … … 817 891 return vdim 818 892 819 893 @redSB 820 def _groebner_basis_ using_singular(self, algorithm="groebner", *args, **kwds):894 def _groebner_basis_singular(self, algorithm="groebner", *args, **kwds): 821 895 r""" 822 896 Return the reduced Groebner basis of this ideal. If the Groebner 823 897 basis for this ideal has been calculated before the cached … … 852 926 + a*c*d + b*c*d, a*b*c*d - 1) of Multivariate Polynomial 853 927 Ring in a, b, c, d over Rational Field 854 928 855 sage: I._groebner_basis_ using_singular()929 sage: I._groebner_basis_singular() 856 930 [c^2*d^6 - c^2*d^2 - d^4 + 1, c^3*d^2 + c^2*d^3 - c - d, 857 931 b*d^4 - b + d^5 - d, b*c - b*d + c^2*d^4 + c*d - 2*d^2, 858 932 b^2 + 2*b*d + d^2, a + b + c + d] … … 863 937 method and the user usually doesn't need to bother with this 864 938 one. 865 939 """ 940 R = self.ring() 941 S = self._groebner_basis_singular_raw(algorithm=algorithm, *args, **kwds) 942 S = Sequence([R(S[i+1]) for i in range(len(S))], R, check=False, immutable=True) 943 return S 944 945 def _groebner_basis_singular_raw(self, algorithm="groebner", singular=singular_default, *args, **kwds): 946 r""" 947 Return a Grobner basis in \Singular format. 948 949 EXAMPLE: 950 sage: R.<a,b,c,d> = PolynomialRing(QQ, 4, order='lex') 951 sage: I = sage.rings.ideal.Cyclic(R,4) 952 sage: I._groebner_basis_singular() # indirect doctest 953 [c^2*d^6 - c^2*d^2 - d^4 + 1, c^3*d^2 + c^2*d^3 - c - d, 954 b*d^4 - b + d^5 - d, b*c - b*d + c^2*d^4 + c*d - 2*d^2, 955 b^2 + 2*b*d + d^2, a + b + c + d] 956 """ 866 957 try: 867 return self.__g roebner_basis958 return self.__gb_singular 868 959 except AttributeError: 960 pass 961 # singular options are preserved by @redSB so we don't 962 # need to do that here too 963 for o,v in kwds.iteritems(): 964 if v: 965 singular.option(o) 966 else: 967 singular.option("no"+o) 869 968 870 # singular options are preserved by @redSB so we don't 871 # need to do that here too 872 for o,v in kwds.iteritems(): 873 if v: 874 singular.option(o) 875 else: 876 singular.option("no"+o) 969 if algorithm=="groebner": 970 S = self._singular_().groebner() 971 elif algorithm=="std": 972 S = self._singular_().std() 973 elif algorithm=="slimgb": 974 S = self._singular_().slimgb() 975 elif algorithm=="stdhilb": 976 S = self._singular_().stdhilb() 977 elif algorithm=="stdfglm": 978 S = self._singular_().stdfglm() 979 else: 980 raise TypeError, "algorithm '%s' unknown"%algorithm 981 self.__gb_singular = S 982 return S 877 983 878 if algorithm=="groebner": 879 S = self._singular_().groebner() 880 elif algorithm=="std": 881 S = self._singular_().std() 882 elif algorithm=="slimgb": 883 S = self._singular_().slimgb() 884 elif algorithm=="stdhilb": 885 S = self._singular_().stdhilb() 886 elif algorithm=="stdfglm": 887 S = self._singular_().stdfglm() 888 else: 889 raise TypeError, "algorithm '%s' unknown"%algorithm 890 R = self.ring() 891 self.__singular_groebner_basis = S #remember this 892 self.__groebner_basis = Sequence([R(S[i+1]) for i in range(len(S))], R, 893 check=False, immutable=True) 894 return self.__groebner_basis 895 896 def _groebner_basis_using_libsingular(self, algorithm="std"): 984 def _groebner_basis_libsingular(self, algorithm="std"): 897 985 r""" 898 986 Return the reduced Groebner basis of this ideal. If the Groebner 899 987 basis for this ideal has been calculated before the cached … … 920 1008 + a*c*d + b*c*d, a*b*c*d - 1) of Multivariate Polynomial 921 1009 Ring in a, b, c, d over Rational Field 922 1010 923 sage: I._groebner_basis_ using_libsingular()1011 sage: I._groebner_basis_libsingular() 924 1012 [c^2*d^6 - c^2*d^2 - d^4 + 1, c^3*d^2 + c^2*d^3 - c - d, 925 1013 b*d^4 - b + d^5 - d, b*c - b*d + c^2*d^4 + c*d - 2*d^2, 926 1014 b^2 + 2*b*d + d^2, a + b + c + d] … … 929 1017 """ 930 1018 from sage.rings.polynomial.multi_polynomial_ideal_libsingular import std_libsingular, slimgb_libsingular 931 1019 932 try: 933 return self.__groebner_basis 934 except AttributeError: 935 if algorithm=="std": 936 S = std_libsingular(self) 937 elif algorithm=="slimgb": 938 S = slimgb_libsingular(self) 939 else: 940 raise TypeError, "algorithm '%s' unknown"%algorithm 941 self.__groebner_basis = S 942 return self.__groebner_basis 1020 if algorithm=="std": 1021 S = std_libsingular(self) 1022 elif algorithm=="slimgb": 1023 S = slimgb_libsingular(self) 1024 else: 1025 raise TypeError, "algorithm '%s' unknown"%algorithm 1026 return S 943 1027 944 1028 def genus(self): 945 1029 """ … … 1064 1148 return S.ideal(r) 1065 1149 1066 1150 @redSB 1067 def integral_closure(self, p=0, r=True ):1151 def integral_closure(self, p=0, r=True, singular=singular_default): 1068 1152 r""" 1069 1153 Let $I$ = \code{self}. 1070 1154 … … 1097 1181 ret = Sequence([ R(f) for f in Is.normalI(p,int(r))[1] ], R, 1098 1182 check=False, immutable=True) 1099 1183 return ret 1100 1101 1102 1184 1103 1185 def syzygy_module(self): 1104 1186 r""" … … 1174 1256 ret = Sequence( ret, R, check=False, immutable=True) 1175 1257 return ret 1176 1258 1177 def basis_is_groebner(self ):1259 def basis_is_groebner(self, singular=singular_default): 1178 1260 r""" 1179 1261 Returns \code{True} if the generators of \code{self} 1180 1262 (\code{self.gens()}) form a Groebner basis. … … 1205 1287 result. So we may acutally use reduce to determine if self is 1206 1288 a Groebner basis. 1207 1289 """ 1208 s ingular = self._singular_().parent()1290 self.ring()._singular_().set_ring() 1209 1291 1210 1292 F = singular( self.gens(), "module" ) 1211 1293 LTF = singular( [f.lt() for f in self.gens()] , "module" ) … … 1220 1302 return True 1221 1303 1222 1304 @redSB 1223 def transformed_basis(self, algorithm="gwalk", other_ring=None):1305 def transformed_basis(self, algorithm="gwalk", other_ring=None, singular=singular_default): 1224 1306 r""" 1225 1307 Returns a lex or \var{other_ring} Groebner Basis for this 1226 1308 ideal. … … 1273 1355 if self.basis_is_groebner(): 1274 1356 Is = self._singular_() 1275 1357 else: 1276 Is = self._ singular_().groebner()1358 Is = self._groebner_basis_singular_raw() 1277 1359 1278 1360 R = self.ring() 1279 1361 … … 1322 1404 if not isinstance(variables, (list,tuple)): 1323 1405 variables = (variables,) 1324 1406 1325 try: 1326 Is = self.__singular_groebner_basis 1327 except AttributeError: 1328 Is = self._singular_() 1329 1407 Is = self._groebner_basis_singular_raw() 1330 1408 R = self.ring() 1331 1409 return MPolynomialIdeal(R, [f.sage_poly(R) for f in Is.eliminate( prod(variables) ) ] ) 1332 1410 … … 1542 1620 fp = ZZ(len(hp)-1).factorial() 1543 1621 return sum([ZZ(hp[i+1])*t**i for i in xrange(len(hp))])/fp 1544 1622 1545 def hilbert_series(self ):1623 def hilbert_series(self, singular=singular_default): 1546 1624 r""" 1547 1625 Return the Hilbert series of this ideal. 1548 1626 … … 1584 1662 sage: I # optional 1585 1663 Ideal (x*y - z^2, y^2 - w^2) of Multivariate Polynomial Ring in x, y, z, w over Integer Ring 1586 1664 """ 1587 #def __init__(self, ring, gens, coerce=True):1588 # MPolynomialIdeal.__init__(self, ring, gens, coerce=coerce)1589 1590 1665 def _macaulay2_(self, macaulay2=None): 1591 1666 """ 1592 1667 Return Macaulay2 ideal corresponding to this ideal. … … 1613 1688 self.__macaulay2[macaulay2] = z 1614 1689 return z 1615 1690 1616 def _ macaulay2_groebner_basis(self):1691 def _groebner_basis_macaulay2(self): 1617 1692 r""" 1618 Return the Groebner basis for this ideal, computed using Macaulay2. 1693 Return the Groebner basis for this ideal, computed using 1694 Macaulay2. 1619 1695 1620 1696 ALGORITHM: Computed using Macaulay2. A big advantage of 1621 1697 Macaulay2 is that it can compute Groebner basis of ideals in … … 1637 1713 sage: I.groebner_basis() # optional -- requires macaulay2 1638 1714 [361, y^2, x^3] 1639 1715 """ 1640 try: 1641 return self.__groebner_basis 1642 except AttributeError: 1643 I = self._macaulay2_() 1644 G = str(I.gb().generators().external_string()).replace('\n','') 1645 i = G.rfind('{{') 1646 j = G.rfind('}}') 1647 G = G[i+2:j].split(',') 1648 L = self.ring().gens_dict() 1649 B = [sage_eval(f, L) for f in G] 1650 B = Sequence(B, self.ring(), check=False) 1651 B.sort() 1652 B.set_immutable() 1653 self.__groebner_basis = B 1654 return B 1716 I = self._macaulay2_() 1717 G = str(I.gb().generators().external_string()).replace('\n','') 1718 i = G.rfind('{{') 1719 j = G.rfind('}}') 1720 G = G[i+2:j].split(',') 1721 L = self.ring().gens_dict() 1722 B = [sage_eval(f, L) for f in G] 1723 B = Sequence(B, self.ring(), check=False) 1724 B.sort() 1725 B.set_immutable() 1726 return B 1655 1727 1656 1728 def _reduce_using_macaulay2(self, f): 1657 1729 """ … … 1690 1762 Ideal (x0^2, x1^3) of Multivariate Polynomial Ring in x0, x1 over Finite Field of size 3 1691 1763 """ 1692 1764 Ideal_generic.__init__(self, ring, gens, coerce=coerce) 1765 1766 def __cmp__(self, other): 1767 """ 1768 EXAMPLE: 1769 sage: R = PolynomialRing(QQ,'x,y,z') 1770 sage: I = R.ideal() 1771 sage: I == R.ideal() 1772 True 1773 1774 sage: R = PolynomialRing(QQ, names=[]) 1775 sage: R.ideal(0) == R.ideal(0) 1776 True 1777 1778 sage: R, (x,y) = PolynomialRing(QQ, 2, 'xy').objgens() 1779 sage: I = (x^3 + y, y)*R 1780 sage: J = (x^3 + y, y, y*x^3 + y^2)*R 1781 sage: I == J 1782 True 1783 1784 sage: R = PolynomialRing(QQ, 'x,y,z', order='degrevlex') 1785 sage: S = PolynomialRing(QQ, 'x,y,z', order='invlex') 1786 sage: I = R.ideal([R.0,R.1]) 1787 sage: J = S.ideal([S.0,S.1]) 1788 sage: I == J 1789 True 1790 sage: cmp(I,J) 1791 0 1792 sage: I.__cmp__(J) 1793 0 1794 """ 1795 # first check the type 1796 if not isinstance(other, MPolynomialIdeal): 1797 return 1 1798 1799 # the ideals may be defined w.r.t. to different term orders 1800 # but are still the same. 1801 R = self.ring() 1802 S = other.ring() 1803 if R is not S: # rings are unique 1804 if type(R) == type(S) and (R.base_ring() == S.base_ring()) and (R.ngens() == S.ngens()): 1805 other = other.change_ring(R) 1806 else: 1807 return cmp((type(R), R.base_ring(), R.ngens()), (type(S), S.base_ring(), S.ngens())) 1808 1809 # now, check whether the GBs are cached already 1810 if self.groebner_basis.is_in_cache() and other.groebner_basis.is_in_cache(): 1811 l = self.groebner_basis() 1812 r = other.groebner_basis() 1813 else: # use easy GB otherwise 1814 try: 1815 l = self.change_ring(R.change_ring(order="degrevlex")).groebner_basis() 1816 r = other.change_ring(R.change_ring(order="degrevlex")).groebner_basis() 1817 except AttributeError: # e.g. quotient rings 1818 l = self.groebner_basis() 1819 r = other.groebner_basis() 1820 return cmp(l,r) 1693 1821 1694 1822 def groebner_fan(self, is_groebner_basis=False, symmetry=None, verbose=False): 1695 1823 r""" … … 1717 1845 return groebner_fan.GroebnerFan(self, is_groebner_basis=is_groebner_basis, 1718 1846 symmetry=symmetry, verbose=verbose) 1719 1847 1720 def groebner_basis(self, algorithm=None, *args, **kwds): 1848 @cached 1849 def groebner_basis(self, algorithm='', *args, **kwds): 1721 1850 r""" 1722 1851 Return the reduced Groebner basis of this ideal. A Groeber basis 1723 1852 $g_1,...,g_n$ for an ideal $I$ is a basis such that $<LT(g_i)> … … 1739 1868 1740 1869 ALGORITHMS: 1741 1870 \begin{description} 1742 \item[ None] autoselect (default)1871 \item[''] autoselect (default) 1743 1872 \item['singular:groebner'] \Singular's \code{groebner} command 1744 1873 \item['singular:std'] \Singular's \code{std} command 1745 1874 \item['singular:stdhilb'] \Singular's \code{stdhib} command … … 1752 1881 \item['macaulay2:gb'] Macaulay2's \code{gb} command (if available) 1753 1882 \item['magma:GroebnerBasis'] \MAGMA's \code{Groebnerbasis} command (if available) 1754 1883 \end{description} 1884 1885 If only a system is given -- e.g. 'magma' -- the default 1886 algorithm is chosen for that system. 1755 1887 1756 1888 NOTE: The \Singular and lib\Singular versions of the 1757 1889 respective algorithms are identically, but the former calls an … … 1831 1963 available), or toy implementation. 1832 1964 1833 1965 """ 1834 if algorithm is None: 1966 if algorithm.lower() == "magma": 1967 algorithm = "magma:GroebnerBasis" 1968 elif algorithm.lower() == "singular": 1969 algorithm = "singular:groebner" 1970 elif algorithm.lower() == "macaulay2": 1971 algorithm = "macaulay2:gb" 1972 elif algorithm.lower() == "toy": 1973 algorithm = "toy:buchberger2" 1974 1975 if algorithm is '': 1835 1976 if self.ring().base_ring() == sage.rings.integer_ring.ZZ: 1836 gb = self._ macaulay2_groebner_basis()1977 gb = self._groebner_basis_macaulay2() 1837 1978 else: 1838 1979 try: 1839 gb = self._groebner_basis_ using_singular("groebner", *args, **kwds)1980 gb = self._groebner_basis_singular("groebner", *args, **kwds) 1840 1981 except TypeError: # conversion to Singular not supported 1841 1982 # we might want to print a warning here 1842 1983 if self.ring().term_order().is_global(): … … 1844 1985 else: 1845 1986 raise TypeError, "Local/unknown orderings not supported by 'toy_buchberger' implementation." 1846 1987 elif algorithm.startswith('singular:'): 1847 gb = self._groebner_basis_ using_singular(algorithm[9:])1988 gb = self._groebner_basis_singular(algorithm[9:]) 1848 1989 elif algorithm.startswith('libsingular:'): 1849 gb = self._groebner_basis_ using_libsingular(algorithm[len('libsingular:'):], *args, **kwds)1990 gb = self._groebner_basis_libsingular(algorithm[len('libsingular:'):], *args, **kwds) 1850 1991 elif algorithm == 'macaulay2:gb': 1851 gb = self._ macaulay2_groebner_basis(*args, **kwds)1992 gb = self._groebner_basis_macaulay2(*args, **kwds) 1852 1993 elif algorithm == 'magma:GroebnerBasis': 1853 gb = self._ magma_groebner_basis(*args, **kwds)1994 gb = self._groebner_basis_magma(*args, **kwds) 1854 1995 elif algorithm == 'toy:buchberger': 1855 1996 gb = toy_buchberger.buchberger(self, *args, **kwds) 1856 1997 elif algorithm == 'toy:buchberger2': … … 1859 2000 raise TypeError, "algorithm '%s' unknown"%algorithm 1860 2001 1861 2002 if self.ring().base_ring().is_field(): 1862 return Sequence( [f*f.lc()**(-1) for f in gb], immutable=True, check=False) 1863 else: 1864 return gb 2003 gb = Sequence( [f*f.lc()**(-1) for f in gb], immutable=True, check=False) 2004 return gb 1865 2005 1866 2006 def change_ring(self, P): 1867 2007 r""" … … 1991 2131 return False 1992 2132 return True 1993 2133 1994 def _ libsingular_normal_basis(self):1995 """2134 def _normal_basis_libsingular(self): 2135 r""" 1996 2136 Returns the normal basis for a given groebner basis. It will use 1997 2137 the Groebner Basis as computed by 1998 self._groebner_basis_using_libsingular().2138 \code{MPolynomialIdeal._groebner_basis_libsingular()}. 1999 2139 2000 2140 EXAMPLES: 2001 2141 sage: R.<x,y,z> = PolynomialRing(QQ) … … 2005 2145 2006 2146 """ 2007 2147 from sage.rings.polynomial.multi_polynomial_ideal_libsingular import kbase_libsingular 2008 gb = self._groebner_basis_ using_libsingular()2148 gb = self._groebner_basis_libsingular() 2009 2149 2010 2150 return kbase_libsingular(self.ring().ideal(gb)) 2011 2151 2012 def normal_basis(self, algorithm='libsingular' ):2152 def normal_basis(self, algorithm='libsingular', singular=singular_default): 2013 2153 """ 2014 2154 Returns a vector space basis (consisting of monomials) of the quotient 2015 2155 ring by the ideal, resp. of a free module by the module, in case it is … … 2030 2170 """ 2031 2171 2032 2172 if algorithm == 'libsingular': 2033 return self._ libsingular_normal_basis()2173 return self._normal_basis_libsingular() 2034 2174 else: 2035 2175 gb = self.groebner_basis() 2036 2176 return list(singular.kbase(self.ring().ideal(gb))) -
a/sage/rings/polynomial/pbori.pyx
old new 3085 3085 def groebner_basis(self, **kwds): 3086 3086 r""" 3087 3087 Return a Groebner basis of this ideal. 3088 3089 3090 3091 selection_size, maximum number of polynomials for parallel reductions3092 3088 3093 3089 INPUT: 3094 3090 other_ordering_first -- possible values are \code{False} or an -
a/sage/schemes/generic/algebraic_scheme.py
old new 276 276 sage: V.irreducible_components() 277 277 [ 278 278 Closed subscheme of Projective Space of dimension 4 over Rational Field defined by: 279 w^5 - 2*z^3*v^2, 279 w, 280 Closed subscheme of Projective Space of dimension 4 over Rational Field defined by: 281 x^2 - y^2 - z^2, 280 282 Closed subscheme of Projective Space of dimension 4 over Rational Field defined by: 281 283 x^2*z - v^3, 282 284 Closed subscheme of Projective Space of dimension 4 over Rational Field defined by: 283 x^2 - y^2 - z^2, 284 Closed subscheme of Projective Space of dimension 4 over Rational Field defined by: 285 w 285 w^5 - 2*z^3*v^2 286 286 ] 287 287 """ 288 288 try: -
a/sage/schemes/generic/divisor.py
old new 17 17 sage: D1.parent() is D2.parent() 18 18 True 19 19 sage: D = D1 - D2 + D3; D 20 10*(x + 2*z, y + z) + 3*(x, y) - (x,z)20 -(x, z) + 3*(x, y) + 10*(x + 2*z, y + z) 21 21 sage: D[1][0] 22 22 3 23 23 sage: D[1][1] 24 24 Ideal (x, y) of Multivariate Polynomial Ring in x, y, z over Finite Field of size 5 25 25 sage: C.divisor([(3, pts[0]), (-1, pts[1]), (10,pts[5])]) 26 10*(x + 2*z, y + z) + 3*(x, y) - (x,z)26 -(x, z) + 3*(x, y) + 10*(x + 2*z, y + z) 27 27 """ 28 28 #******************************************************************************* 29 29 # Copyright (C) 2005 David Kohel <kohel@maths.usyd.edu.au> … … 98 98 sage: pts = C.rational_points(); pts 99 99 [(0, 0), (2, 2), (2, 3), (3, 1), (3, 4)] 100 100 sage: D = C.divisor(pts[0])*3 - C.divisor(pts[1]); D 101 -(x - 2, y - 2) + 3*(x, y)101 3*(x, y) - (x - 2, y - 2) 102 102 sage: D.scheme() 103 103 Affine Curve over Finite Field of size 5 defined by -x^9 + y^2 - x 104 104 """ … … 135 135 sage: E.divisor([P, P]) 136 136 2*(x, y) 137 137 sage: E.divisor([(3,P), (-4,5*P)]) 138 -4*(x - 1/4*z, y + 5/8*z) + 3*(x, y)138 3*(x, y) - 4*(x - 1/4*z, y + 5/8*z) 139 139 """ 140 140 def __init__(self, v, check=True, reduce=True, parent=None): 141 141 """ … … 221 221 sage: pts = C.rational_points(); pts 222 222 [(0, 0), (2, 2), (2, 3), (3, 1), (3, 4)] 223 223 sage: D = C.divisor([(3,pts[0]), (-1, pts[1])]); D 224 -(x - 2, y - 2) + 3*(x, y)224 3*(x, y) - (x - 2, y - 2) 225 225 sage: D.support() 226 226 [(0, 0), (2, 2)] 227 227 "