PageRenderTime 79ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/sage/rings/polynomial/multi_polynomial_ideal.py

https://bitbucket.org/tkluck/sage-main
Python | 4532 lines | 4412 code | 19 blank | 101 comment | 31 complexity | a698ba9da71429aa213a6477f583747f MD5 | raw file
  1. # -*- coding: utf-8 -*-
  2. r"""
  3. Ideals in multivariate polynomial rings.
  4. Sage has a powerful system to compute with multivariate polynomial
  5. rings. Most algorithms dealing with these ideals are centered the
  6. computation of *Groebner bases*. Sage mainly uses Singular to
  7. implement this functionality. Singular is widely regarded as the best
  8. open-source system for Groebner basis calculation in multivariate
  9. polynomial rings over fields.
  10. AUTHORS:
  11. - William Stein
  12. - Kiran S. Kedlaya (2006-02-12): added Macaulay2 analogues of some
  13. Singular features
  14. - Martin Albrecht (2008,2007): refactoring, many Singular related
  15. functions
  16. - Martin Albrecht (2009): added Groebner basis over rings
  17. functionality from Singular 3.1
  18. - John Perry (2012): bug fixing equality & containment of ideals
  19. EXAMPLES:
  20. We compute a Groebner basis for some given ideal. The type returned by
  21. the ``groebner_basis`` method is ``PolynomialSequence``, i.e. it is not a
  22. :class:`MPolynomialIdeal`::
  23. sage: x,y,z = QQ['x,y,z'].gens()
  24. sage: I = ideal(x^5 + y^4 + z^3 - 1, x^3 + y^3 + z^2 - 1)
  25. sage: B = I.groebner_basis()
  26. sage: type(B)
  27. <class 'sage.rings.polynomial.multi_polynomial_sequence.PolynomialSequence_generic'>
  28. Groebner bases can be used to solve the ideal membership problem::
  29. sage: f,g,h = B
  30. sage: (2*x*f + g).reduce(B)
  31. 0
  32. sage: (2*x*f + g) in I
  33. True
  34. sage: (2*x*f + 2*z*h + y^3).reduce(B)
  35. y^3
  36. sage: (2*x*f + 2*z*h + y^3) in I
  37. False
  38. We compute a Groebner basis for Cyclic 6, which is a standard
  39. benchmark and test ideal. ::
  40. sage: R.<x,y,z,t,u,v> = QQ['x,y,z,t,u,v']
  41. sage: I = sage.rings.ideal.Cyclic(R,6)
  42. sage: B = I.groebner_basis()
  43. sage: len(B)
  44. 45
  45. We compute in a quotient of a polynomial ring over `\ZZ/17\ZZ`::
  46. sage: R.<x,y> = ZZ[]
  47. sage: S.<a,b> = R.quotient((x^2 + y^2, 17))
  48. sage: S
  49. Quotient of Multivariate Polynomial Ring in x, y over Integer Ring
  50. by the ideal (x^2 + y^2, 17)
  51. sage: a^2 + b^2 == 0
  52. True
  53. sage: a^3 - b^2
  54. -a*b^2 - b^2
  55. Note that the result of a computation is not necessarily reduced::
  56. sage: (a+b)^17
  57. 256*a*b^16 + 256*b^17
  58. sage: S(17) == 0
  59. True
  60. Or we can work with `\ZZ/17\ZZ`` directly::
  61. sage: R.<x,y> = Zmod(17)[]
  62. sage: S.<a,b> = R.quotient((x^2 + y^2,))
  63. sage: S
  64. Quotient of Multivariate Polynomial Ring in x, y over Ring of
  65. integers modulo 17 by the ideal (x^2 + y^2)
  66. sage: a^2 + b^2 == 0
  67. True
  68. sage: a^3 - b^2
  69. -a*b^2 - b^2
  70. sage: (a+b)^17
  71. a*b^16 + b^17
  72. sage: S(17) == 0
  73. True
  74. Working with a polynomial ring over `\ZZ`::
  75. sage: R.<x,y,z,w> = ZZ[]
  76. sage: I = ideal(x^2 + y^2 - z^2 - w^2, x-y)
  77. sage: J = I^2
  78. sage: J.groebner_basis()
  79. [4*y^4 - 4*y^2*z^2 + z^4 - 4*y^2*w^2 + 2*z^2*w^2 + w^4,
  80. 2*x*y^2 - 2*y^3 - x*z^2 + y*z^2 - x*w^2 + y*w^2,
  81. x^2 - 2*x*y + y^2]
  82. sage: y^2 - 2*x*y + x^2 in J
  83. True
  84. sage: 0 in J
  85. True
  86. We do a Groebner basis computation over a number field::
  87. sage: K.<zeta> = CyclotomicField(3)
  88. sage: R.<x,y,z> = K[]; R
  89. Multivariate Polynomial Ring in x, y, z over Cyclotomic Field of order 3 and degree 2
  90. sage: i = ideal(x - zeta*y + 1, x^3 - zeta*y^3); i
  91. Ideal (x + (-zeta)*y + 1, x^3 + (-zeta)*y^3) of Multivariate
  92. Polynomial Ring in x, y, z over Cyclotomic Field of order 3 and degree 2
  93. sage: i.groebner_basis()
  94. [y^3 + (2*zeta + 1)*y^2 + (zeta - 1)*y + (-1/3*zeta - 2/3), x + (-zeta)*y + 1]
  95. sage: S = R.quotient(i); S
  96. Quotient of Multivariate Polynomial Ring in x, y, z over
  97. Cyclotomic Field of order 3 and degree 2 by the ideal (x +
  98. (-zeta)*y + 1, x^3 + (-zeta)*y^3)
  99. sage: S.0 - zeta*S.1
  100. -1
  101. sage: S.0^3 - zeta*S.1^3
  102. 0
  103. Two examples from the Mathematica documentation (done in Sage):
  104. We compute a Groebner basis::
  105. sage: R.<x,y> = PolynomialRing(QQ, order='lex')
  106. sage: ideal(x^2 - 2*y^2, x*y - 3).groebner_basis()
  107. [x - 2/3*y^3, y^4 - 9/2]
  108. We show that three polynomials have no common root::
  109. sage: R.<x,y> = QQ[]
  110. sage: ideal(x+y, x^2 - 1, y^2 - 2*x).groebner_basis()
  111. [1]
  112. The next example shows how we can use Groebner bases over `\ZZ` to
  113. find the primes modulo which a system of equations has a solution,
  114. when the system has no solutions over the rationals.
  115. We first form a certain ideal `I` in `\ZZ[x, y, z]`, and note that
  116. the Groebner basis of `I` over `\QQ` contains 1, so there are no
  117. solutions over `\QQ` or an algebraic closure of it (this is not
  118. surprising as there are 4 equations in 3 unknowns). ::
  119. sage: P.<x,y,z> = PolynomialRing(ZZ,order='lex')
  120. sage: I = ideal(-y^2 - 3*y + z^2 + 3, -2*y*z + z^2 + 2*z + 1, \
  121. x*z + y*z + z^2, -3*x*y + 2*y*z + 6*z^2)
  122. sage: I.change_ring(P.change_ring(QQ)).groebner_basis()
  123. [1]
  124. However, when we compute the Groebner basis of I (defined over
  125. `\ZZ``), we note that there is a certain integer in the ideal
  126. which is not 1. ::
  127. sage: I.groebner_basis()
  128. [x + 130433*y + 59079*z, y^2 + 3*y + 17220, y*z + 5*y + 14504, 2*y + 158864, z^2 + 17223, 2*z + 41856, 164878]
  129. Now for each prime `p` dividing this integer 164878, the Groebner
  130. basis of I modulo `p` will be non-trivial and will thus give a
  131. solution of the original system modulo `p`. ::
  132. sage: factor(164878)
  133. 2 * 7 * 11777
  134. sage: I.change_ring(P.change_ring( GF(2) )).groebner_basis()
  135. [x + y + z, y^2 + y, y*z + y, z^2 + 1]
  136. sage: I.change_ring(P.change_ring( GF(7) )).groebner_basis()
  137. [x - 1, y + 3, z - 2]
  138. sage: I.change_ring(P.change_ring( GF(11777 ))).groebner_basis()
  139. [x + 5633, y - 3007, z - 2626]
  140. The Groebner basis modulo any product of the prime factors is also non-trivial. ::
  141. sage: I.change_ring(P.change_ring( IntegerModRing(2*7) )).groebner_basis()
  142. [x + y + z, y^2 + 3*y, y*z + 11*y + 4, 2*y + 6, z^2 + 3, 2*z + 10]
  143. Modulo any other prime the Groebner basis is trivial so there are
  144. no other solutions. For example::
  145. sage: I.change_ring( P.change_ring( GF(3) ) ).groebner_basis()
  146. [1]
  147. TESTS::
  148. sage: x,y,z = QQ['x,y,z'].gens()
  149. sage: I = ideal(x^5 + y^4 + z^3 - 1, x^3 + y^3 + z^2 - 1)
  150. sage: I == loads(dumps(I))
  151. True
  152. .. note::
  153. Sage distinguishes between lists or sequences of polynomials and
  154. ideals. Thus an ideal is not identified with a particular set of
  155. generators. For sequences of multivariate polynomials see
  156. :class:`sage.rings.polynomial.multi_polynomial_sequence.PolynomialSequence_generic`.
  157. """
  158. #*****************************************************************************
  159. #
  160. # Sage
  161. #
  162. # Copyright (C) 2005 William Stein <wstein@gmail.com>
  163. # Copyright (C) 2008,2009 Martin Albrecht <malb@informatik.uni-bremen.de>
  164. #
  165. # Distributed under the terms of the GNU General Public License (GPL)
  166. #
  167. # This code is distributed in the hope that it will be useful,
  168. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  169. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  170. # General Public License for more details.
  171. #
  172. # The full text of the GPL is available at:
  173. #
  174. # http://www.gnu.org/licenses/
  175. #*****************************************************************************
  176. from sage.interfaces.all import (singular as singular_default,
  177. macaulay2 as macaulay2_default,
  178. magma as magma_default)
  179. from sage.interfaces.expect import StdOutContext
  180. from sage.rings.ideal import Ideal_generic
  181. from sage.rings.noncommutative_ideals import Ideal_nc
  182. from sage.rings.integer import Integer
  183. from sage.structure.sequence import Sequence
  184. from sage.misc.cachefunc import cached_method
  185. from sage.misc.misc import prod, verbose, get_verbose
  186. from sage.misc.method_decorator import MethodDecorator
  187. from sage.rings.integer_ring import ZZ
  188. import sage.rings.polynomial.toy_buchberger as toy_buchberger
  189. import sage.rings.polynomial.toy_variety as toy_variety
  190. import sage.rings.polynomial.toy_d_basis as toy_d_basis
  191. from warnings import warn
  192. class LibSingularDefaultContext:
  193. def __init__(self, singular=singular_default):
  194. from sage.libs.singular.option import opt_ctx
  195. self.libsingular_option_context = opt_ctx
  196. def __enter__(self):
  197. """
  198. EXAMPLE::
  199. sage: from sage.rings.polynomial.multi_polynomial_ideal import SingularDefaultContext
  200. sage: P.<a,b,c> = PolynomialRing(QQ,3, order='lex')
  201. sage: I = sage.rings.ideal.Katsura(P,3)
  202. sage: singular.option('noredTail')
  203. sage: singular.option('noredThrough')
  204. sage: Is = I._singular_()
  205. sage: with SingularDefaultContext(): rgb = Is.groebner()
  206. sage: rgb
  207. 84*c^4-40*c^3+c^2+c,
  208. 7*b+210*c^3-79*c^2+3*c,
  209. 7*a-420*c^3+158*c^2+8*c-7
  210. """
  211. self.libsingular_option_context.__enter__()
  212. self.libsingular_option_context.opt.reset_default()
  213. self.libsingular_option_context.opt['red_sb'] = True
  214. self.libsingular_option_context.opt['red_tail'] = True
  215. self.libsingular_option_context.opt['deg_bound'] = 0
  216. self.libsingular_option_context.opt['mult_bound'] = 0
  217. def __exit__(self, typ, value, tb):
  218. """
  219. EXAMPLE::
  220. sage: from sage.rings.polynomial.multi_polynomial_ideal import SingularDefaultContext
  221. sage: P.<a,b,c> = PolynomialRing(QQ,3, order='lex')
  222. sage: I = sage.rings.ideal.Katsura(P,3)
  223. sage: singular.option('noredTail')
  224. sage: singular.option('noredThrough')
  225. sage: Is = I._singular_()
  226. sage: with SingularDefaultContext(): rgb = Is.groebner()
  227. sage: rgb
  228. 84*c^4-40*c^3+c^2+c,
  229. 7*b+210*c^3-79*c^2+3*c,
  230. 7*a-420*c^3+158*c^2+8*c-7
  231. """
  232. self.libsingular_option_context.__exit__(typ,value,tb)
  233. class SingularDefaultContext:
  234. """
  235. Within this context all Singular Groebner basis calculations are
  236. reduced automatically.
  237. AUTHORS:
  238. - Martin Albrecht
  239. - Simon King
  240. """
  241. def __init__(self, singular=singular_default):
  242. """
  243. Within this context all Singular Groebner basis calculations
  244. are reduced automatically.
  245. INPUT:
  246. - ``singular`` - Singular instance (default: default instance)
  247. EXAMPLE::
  248. sage: from sage.rings.polynomial.multi_polynomial_ideal import SingularDefaultContext
  249. sage: P.<a,b,c> = PolynomialRing(QQ,3, order='lex')
  250. sage: I = sage.rings.ideal.Katsura(P,3)
  251. sage: singular.option('noredTail')
  252. sage: singular.option('noredThrough')
  253. sage: Is = I._singular_()
  254. sage: gb = Is.groebner()
  255. sage: gb
  256. 84*c^4-40*c^3+c^2+c,
  257. 7*b+210*c^3-79*c^2+3*c,
  258. a+2*b+2*c-1
  259. ::
  260. sage: with SingularDefaultContext(): rgb = Is.groebner()
  261. sage: rgb
  262. 84*c^4-40*c^3+c^2+c,
  263. 7*b+210*c^3-79*c^2+3*c,
  264. 7*a-420*c^3+158*c^2+8*c-7
  265. Note that both bases are Groebner bases because they have
  266. pairwise prime leading monomials but that the monic version of
  267. the last element in ``rgb`` is smaller than the last element
  268. of ``gb`` with respect to the lexicographical term ordering. ::
  269. sage: (7*a-420*c^3+158*c^2+8*c-7)/7 < (a+2*b+2*c-1)
  270. True
  271. .. note::
  272. This context is used automatically internally whenever a
  273. Groebner basis is computed so the user does not need to use
  274. it manually.
  275. """
  276. self.singular = singular
  277. def __enter__(self):
  278. """
  279. EXAMPLE::
  280. sage: from sage.rings.polynomial.multi_polynomial_ideal import SingularDefaultContext
  281. sage: P.<a,b,c> = PolynomialRing(QQ,3, order='lex')
  282. sage: I = sage.rings.ideal.Katsura(P,3)
  283. sage: singular.option('noredTail')
  284. sage: singular.option('noredThrough')
  285. sage: Is = I._singular_()
  286. sage: with SingularDefaultContext(): rgb = Is.groebner()
  287. sage: rgb
  288. 84*c^4-40*c^3+c^2+c,
  289. 7*b+210*c^3-79*c^2+3*c,
  290. 7*a-420*c^3+158*c^2+8*c-7
  291. """
  292. try:
  293. self.bck_degBound = int(self.singular.eval('degBound'))
  294. except RuntimeError:
  295. self.bck_degBound = int(0)
  296. try:
  297. self.bck_multBound = int(self.singular.eval('multBound'))
  298. except RuntimeError:
  299. self.bck_multBound = int(0)
  300. self.o = self.singular.option("get")
  301. self.singular.option('set',self.singular._saved_options)
  302. self.singular.option("redSB")
  303. self.singular.option("redTail")
  304. try:
  305. self.singular.eval('degBound=0')
  306. except RuntimeError:
  307. pass
  308. try:
  309. self.singular.eval('multBound=0')
  310. except RuntimeError:
  311. pass
  312. def __exit__(self, typ, value, tb):
  313. """
  314. EXAMPLE::
  315. sage: from sage.rings.polynomial.multi_polynomial_ideal import SingularDefaultContext
  316. sage: P.<a,b,c> = PolynomialRing(QQ,3, order='lex')
  317. sage: I = sage.rings.ideal.Katsura(P,3)
  318. sage: singular.option('noredTail')
  319. sage: singular.option('noredThrough')
  320. sage: Is = I._singular_()
  321. sage: with SingularDefaultContext(): rgb = Is.groebner()
  322. sage: rgb
  323. 84*c^4-40*c^3+c^2+c,
  324. 7*b+210*c^3-79*c^2+3*c,
  325. 7*a-420*c^3+158*c^2+8*c-7
  326. """
  327. self.singular.option("set",self.o)
  328. try:
  329. self.singular.eval('degBound=%d'%self.bck_degBound)
  330. except RuntimeError:
  331. pass
  332. try:
  333. self.singular.eval('multBound=%d'%self.bck_multBound)
  334. except RuntimeError:
  335. pass
  336. def singular_standard_options(func):
  337. r"""
  338. Decorator to force a reduced Singular groebner basis.
  339. TESTS::
  340. sage: P.<a,b,c,d,e> = PolynomialRing(GF(127))
  341. sage: J = sage.rings.ideal.Cyclic(P).homogenize()
  342. sage: from sage.misc.sageinspect import sage_getsource
  343. sage: "buchberger" in sage_getsource(J.interreduced_basis) #indirect doctest
  344. True
  345. The following tests against a bug that was fixed in trac ticket #11298::
  346. sage: from sage.misc.sageinspect import sage_getsourcelines, sage_getargspec
  347. sage: P.<x,y> = QQ[]
  348. sage: I = P*[x,y]
  349. sage: sage_getargspec(I.interreduced_basis)
  350. ArgSpec(args=['self'], varargs=None, keywords=None, defaults=None)
  351. sage: sage_getsourcelines(I.interreduced_basis)
  352. ([' @singular_standard_options\n',
  353. ' @libsingular_standard_options\n',
  354. ' def interreduced_basis(self):\n',
  355. ...
  356. ' return ret\n'], ...)
  357. .. note::
  358. This decorator is used automatically internally so the user
  359. does not need to use it manually.
  360. """
  361. from sage.misc.decorators import sage_wraps
  362. @sage_wraps(func)
  363. def wrapper(*args, **kwds):
  364. # """
  365. # Execute function in ``SingularDefaultContext``.
  366. # """
  367. with SingularDefaultContext():
  368. return func(*args, **kwds)
  369. return wrapper
  370. def libsingular_standard_options(func):
  371. r"""
  372. Decorator to force a reduced Singular groebner basis.
  373. TESTS::
  374. sage: P.<a,b,c,d,e> = PolynomialRing(GF(127))
  375. sage: J = sage.rings.ideal.Cyclic(P).homogenize()
  376. sage: from sage.misc.sageinspect import sage_getsource
  377. sage: "buchberger" in sage_getsource(J.interreduced_basis)
  378. True
  379. The following tests against a bug that was fixed in trac ticket #11298::
  380. sage: from sage.misc.sageinspect import sage_getsourcelines, sage_getargspec
  381. sage: P.<x,y> = QQ[]
  382. sage: I = P*[x,y]
  383. sage: sage_getargspec(I.interreduced_basis)
  384. ArgSpec(args=['self'], varargs=None, keywords=None, defaults=None)
  385. sage: sage_getsourcelines(I.interreduced_basis)
  386. ([' @singular_standard_options\n',
  387. ' @libsingular_standard_options\n',
  388. ' def interreduced_basis(self):\n',
  389. ...
  390. ' return ret\n'], ...)
  391. .. note::
  392. This decorator is used automatically internally so the user
  393. does not need to use it manually.
  394. """
  395. from sage.misc.decorators import sage_wraps
  396. @sage_wraps(func)
  397. def wrapper(*args, **kwds):
  398. """
  399. Execute function in ``LibSingularDefaultContext``.
  400. """
  401. with LibSingularDefaultContext():
  402. return func(*args, **kwds)
  403. return wrapper
  404. class MagmaDefaultContext:
  405. """
  406. Context to force preservation of verbosity options for Magma's
  407. Groebner basis computation.
  408. """
  409. def __init__(self, magma=magma_default):
  410. """
  411. INPUT:
  412. - ``magma`` - (default: ``magma_default``)
  413. EXAMPLE::
  414. sage: from sage.rings.polynomial.multi_polynomial_ideal import MagmaDefaultContext
  415. sage: magma.SetVerbose('Groebner',1) # optional - magma
  416. sage: with MagmaDefaultContext(): magma.GetVerbose('Groebner') # optional - magma
  417. 0
  418. """
  419. self.magma = magma
  420. def __enter__(self):
  421. """
  422. EXAMPLE::
  423. sage: from sage.rings.polynomial.multi_polynomial_ideal import MagmaDefaultContext
  424. sage: magma.SetVerbose('Groebner',1) # optional - magma
  425. sage: with MagmaDefaultContext(): magma.GetVerbose('Groebner') # optional - magma
  426. 0
  427. """
  428. self.groebner_basis_verbose = self.magma.GetVerbose('Groebner')
  429. self.magma.SetVerbose('Groebner',0)
  430. def __exit__(self, typ, value, tb):
  431. """
  432. EXAMPLE::
  433. sage: from sage.rings.polynomial.multi_polynomial_ideal import MagmaDefaultContext
  434. sage: magma.SetVerbose('Groebner',1) # optional - magma
  435. sage: with MagmaDefaultContext(): magma.GetVerbose('Groebner') # optional - magma
  436. 0
  437. sage: magma.GetVerbose('Groebner') # optional - magma
  438. 1
  439. """
  440. self.magma.SetVerbose('Groebner',self.groebner_basis_verbose)
  441. def magma_standard_options(func):
  442. """
  443. Decorator to force default options for Magma.
  444. EXAMPLE::
  445. sage: P.<a,b,c,d,e> = PolynomialRing(GF(127))
  446. sage: J = sage.rings.ideal.Cyclic(P).homogenize()
  447. sage: from sage.misc.sageinspect import sage_getsource
  448. sage: "mself" in sage_getsource(J._groebner_basis_magma)
  449. True
  450. """
  451. from sage.misc.decorators import sage_wraps
  452. @sage_wraps(func)
  453. def wrapper(*args, **kwds):
  454. """
  455. Execute function in ``MagmaDefaultContext``.
  456. """
  457. with MagmaDefaultContext():
  458. return func(*args, **kwds)
  459. return wrapper
  460. class RequireField(MethodDecorator):
  461. """
  462. Decorator which throws an exception if a computation over a
  463. coefficient ring which is not a field is attempted.
  464. .. note::
  465. This decorator is used automatically internally so the user
  466. does not need to use it manually.
  467. """
  468. def __call__(self, *args, **kwds):
  469. """
  470. EXAMPLE::
  471. sage: P.<x,y,z> = PolynomialRing(ZZ)
  472. sage: I = ideal( x^2 - 3*y, y^3 - x*y, z^3 - x, x^4 - y*z + 1 )
  473. sage: from sage.rings.polynomial.multi_polynomial_ideal import RequireField
  474. sage: class Foo(I.__class__):
  475. ... @RequireField
  476. ... def bar(I):
  477. ... return I.groebner_basis()
  478. ...
  479. sage: J = Foo(I.ring(), I.gens())
  480. sage: J.bar()
  481. Traceback (most recent call last):
  482. ...
  483. ValueError: Coefficient ring must be a field for function 'bar'.
  484. """
  485. R = self._instance.ring()
  486. if not R.base_ring().is_field():
  487. raise ValueError("Coefficient ring must be a field for function '%s'."%(self.f.__name__))
  488. return self.f(self._instance, *args, **kwds)
  489. require_field = RequireField
  490. def is_MPolynomialIdeal(x):
  491. """
  492. Return ``True`` if the provided argument ``x`` is an ideal in the
  493. multivariate polynomial ring.
  494. INPUT:
  495. - ``x`` - an arbitrary object
  496. EXAMPLES::
  497. sage: from sage.rings.polynomial.all import is_MPolynomialIdeal
  498. sage: P.<x,y,z> = PolynomialRing(QQ)
  499. sage: I = [x + 2*y + 2*z - 1, x^2 + 2*y^2 + 2*z^2 - x, 2*x*y + 2*y*z - y]
  500. Sage distinguishes between a list of generators for an ideal and
  501. the ideal itself. This distinction is inconsistent with Singular
  502. but matches Magma's behavior. ::
  503. sage: is_MPolynomialIdeal(I)
  504. False
  505. ::
  506. sage: I = Ideal(I)
  507. sage: is_MPolynomialIdeal(I)
  508. True
  509. """
  510. return isinstance(x, MPolynomialIdeal)
  511. class MPolynomialIdeal_magma_repr:
  512. def _magma_init_(self, magma):
  513. """
  514. Returns a Magma ideal matching this ideal if the base ring
  515. coerces to Magma and Magma is available.
  516. INPUT:
  517. - ``magma`` - Magma instance
  518. EXAMPLES::
  519. sage: R.<a,b,c,d,e,f,g,h,i,j> = PolynomialRing(GF(127),10)
  520. sage: I = sage.rings.ideal.Cyclic(R,4) # indirect doctest
  521. sage: magma(I) # optional - magma
  522. Ideal of Polynomial ring of rank 10 over GF(127)
  523. Order: Graded Reverse Lexicographical
  524. Variables: a, b, c, d, e, f, g, h, i, j
  525. Basis:
  526. [
  527. a + b + c + d,
  528. a*b + b*c + a*d + c*d,
  529. a*b*c + a*b*d + a*c*d + b*c*d,
  530. a*b*c*d + 126
  531. ]
  532. """
  533. P = magma(self.ring())
  534. G = magma(self.gens())
  535. return 'ideal<%s|%s>'%(P.name(), G._ref())
  536. @magma_standard_options
  537. def _groebner_basis_magma(self, deg_bound=None, prot=False, magma=magma_default):
  538. """
  539. Computes a Groebner Basis for this ideal using Magma if
  540. available.
  541. INPUT:
  542. - ``deg_bound`` - only compute to degree ``deg_bound``, that
  543. is, ignore all S-polynomials of higher degree. (default:
  544. ``None``)
  545. - ``prot`` - if ``True`` Magma's protocol is printed to
  546. stdout.
  547. - ``magma`` - Magma instance or None (default instance) (default: None)
  548. EXAMPLES::
  549. sage: R.<a,b,c,d,e,f,g,h,i,j> = PolynomialRing(GF(127),10)
  550. sage: I = sage.rings.ideal.Cyclic(R,6)
  551. sage: gb = I.groebner_basis('magma:GroebnerBasis') # indirect doctest; optional - magma
  552. sage: len(gb) # optional - magma
  553. 45
  554. """
  555. R = self.ring()
  556. if not deg_bound:
  557. mself = magma(self)
  558. else:
  559. mself = magma(self.gens())
  560. if get_verbose() >= 2:
  561. prot = True
  562. from sage.interfaces.magma import MagmaGBLogPrettyPrinter
  563. if prot:
  564. log_parser = MagmaGBLogPrettyPrinter(verbosity=get_verbose()+ 1, style="sage" if prot=="sage" else "magma")
  565. else:
  566. log_parser = None
  567. ctx = StdOutContext(magma, silent=False if prot else True, stdout=log_parser)
  568. if prot:
  569. magma.SetVerbose('Groebner',1)
  570. with ctx:
  571. if deg_bound:
  572. mgb = mself.GroebnerBasis(deg_bound)
  573. else:
  574. mgb = mself.GroebnerBasis()
  575. if prot == "sage":
  576. print
  577. print "Highest degree reached during computation: %2d."%log_parser.max_deg
  578. # TODO: rewrite this to be much more sophisticated in multi-level nested cases.
  579. mgb = [str(mgb[i+1]) for i in range(len(mgb))]
  580. if R.base_ring().degree() > 1:
  581. a = str(R.base_ring().gen())
  582. mgb = [e.replace("$.1",a) for e in mgb]
  583. from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence
  584. B = PolynomialSequence([R(e) for e in mgb], R, immutable=True)
  585. return B
  586. class MPolynomialIdeal_singular_base_repr:
  587. @require_field
  588. def syzygy_module(self):
  589. r"""
  590. Computes the first syzygy (i.e., the module of relations of the
  591. given generators) of the ideal.
  592. EXAMPLE::
  593. sage: R.<x,y> = PolynomialRing(QQ)
  594. sage: f = 2*x^2 + y
  595. sage: g = y
  596. sage: h = 2*f + g
  597. sage: I = Ideal([f,g,h])
  598. sage: M = I.syzygy_module(); M
  599. [ -2 -1 1]
  600. [ -y 2*x^2 + y 0]
  601. sage: G = vector(I.gens())
  602. sage: M*G
  603. (0, 0)
  604. ALGORITHM: Uses Singular's syz command
  605. """
  606. import sage.libs.singular
  607. syz = sage.libs.singular.ff.syz
  608. from sage.matrix.constructor import matrix
  609. #return self._singular_().syz().transpose().sage_matrix(self.ring())
  610. S = syz(self)
  611. return matrix(self.ring(), S)
  612. @libsingular_standard_options
  613. def _groebner_basis_libsingular(self, algorithm="groebner", *args, **kwds):
  614. """
  615. Return the reduced Groebner basis of this ideal. If the
  616. Groebner basis for this ideal has been calculated before the
  617. cached Groebner basis is returned regardless of the requested
  618. algorithm.
  619. INPUT:
  620. - ``algorithm`` - see below for available algorithms
  621. - ``redsb`` - return a reduced Groebner basis (default: ``True``)
  622. - ``red_tail`` - perform tail reduction (default: ``True``)
  623. ALGORITHMS:
  624. 'groebner'
  625. Singular's heuristic script (default)
  626. 'std'
  627. Buchberger's algorithm
  628. 'slimgb'
  629. the *SlimGB* algorithm
  630. 'stdhilb'
  631. Hilbert Basis driven Groebner basis
  632. 'stdfglm'
  633. Buchberger and FGLM
  634. EXAMPLES:
  635. We compute a Groebner basis of 'cyclic 4' relative to
  636. lexicographic ordering. ::
  637. sage: R.<a,b,c,d> = PolynomialRing(QQ, 4, order='lex')
  638. sage: I = sage.rings.ideal.Cyclic(R,4); I
  639. Ideal (a + b + c + d, a*b + a*d + b*c + c*d, a*b*c + a*b*d
  640. + a*c*d + b*c*d, a*b*c*d - 1) of Multivariate Polynomial
  641. Ring in a, b, c, d over Rational Field
  642. ::
  643. sage: I._groebner_basis_libsingular()
  644. [c^2*d^6 - c^2*d^2 - d^4 + 1, c^3*d^2 + c^2*d^3 - c - d,
  645. b*d^4 - b + d^5 - d, b*c - b*d + c^2*d^4 + c*d - 2*d^2,
  646. b^2 + 2*b*d + d^2, a + b + c + d]
  647. ALGORITHM:
  648. Uses libSINGULAR.
  649. """
  650. from sage.rings.polynomial.multi_polynomial_ideal_libsingular import std_libsingular, slimgb_libsingular
  651. from sage.libs.singular import singular_function
  652. from sage.libs.singular.option import opt
  653. import sage.libs.singular
  654. groebner = sage.libs.singular.ff.groebner
  655. if get_verbose()>=2:
  656. opt['prot'] = True
  657. for name,value in kwds.iteritems():
  658. if value is not None:
  659. opt[name] = value
  660. T = self.ring().term_order()
  661. if algorithm == "std":
  662. S = std_libsingular(self)
  663. elif algorithm == "slimgb":
  664. S = slimgb_libsingular(self)
  665. elif algorithm == "groebner":
  666. S = groebner(self)
  667. else:
  668. try:
  669. fnc = singular_function(algorithm)
  670. S = fnc(self)
  671. except NameError:
  672. raise NameError("Algorithm '%s' unknown"%algorithm)
  673. return S
  674. class MPolynomialIdeal_singular_repr(
  675. MPolynomialIdeal_singular_base_repr):
  676. """
  677. An ideal in a multivariate polynomial ring, which has an
  678. underlying Singular ring associated to it.
  679. """
  680. def _singular_(self, singular=singular_default):
  681. """
  682. Return Singular ideal corresponding to this ideal.
  683. EXAMPLES::
  684. sage: R.<x,y> = PolynomialRing(QQ, 2)
  685. sage: I = R.ideal([x^3 + y, y])
  686. sage: S = I._singular_()
  687. sage: S
  688. x^3+y,
  689. y
  690. """
  691. try:
  692. self.ring()._singular_(singular).set_ring()
  693. I = self.__singular
  694. if not (I.parent() is singular):
  695. raise ValueError
  696. I._check_valid()
  697. return I
  698. except (AttributeError, ValueError):
  699. self.ring()._singular_(singular).set_ring()
  700. try:
  701. # this may fail for quotient ring elements, but is
  702. # faster
  703. gens = [str(x) for x in self.gens()]
  704. if len(gens) == 0:
  705. gens = ['0']
  706. self.__singular = singular.ideal(gens)
  707. except TypeError:
  708. gens = [str(x.lift()) for x in self.gens()]
  709. if len(gens) == 0:
  710. gens = ['0']
  711. self.__singular = singular.ideal(gens)
  712. return self.__singular
  713. @cached_method
  714. def _groebner_strategy(self):
  715. """
  716. Return Singular's Groebner Strategy object for the Groebner
  717. basis of this ideal which implements some optimized functions.
  718. EXAMPLE::
  719. sage: R.<x,y> = PolynomialRing(QQ,2)
  720. sage: I = R.ideal([y^3 - x^2])
  721. sage: I._groebner_strategy()
  722. Groebner Strategy for ideal generated by 1 elements over
  723. Multivariate Polynomial Ring in x, y over Rational Field
  724. .. note::
  725. This function is mainly used internally.
  726. """
  727. from sage.libs.singular.groebner_strategy import GroebnerStrategy
  728. return GroebnerStrategy(MPolynomialIdeal(self.ring(), self.groebner_basis()))
  729. def plot(self, singular=singular_default):
  730. """
  731. If you somehow manage to install surf, perhaps you can use
  732. this function to implicitly plot the real zero locus of this
  733. ideal (if principal).
  734. INPUT:
  735. - ``self`` - must be a principal ideal in 2 or 3 vars
  736. over QQ.
  737. EXAMPLES:
  738. Implicit plotting in 2-d::
  739. sage: R.<x,y> = PolynomialRing(QQ,2)
  740. sage: I = R.ideal([y^3 - x^2])
  741. sage: I.plot() # cusp
  742. sage: I = R.ideal([y^2 - x^2 - 1])
  743. sage: I.plot() # hyperbola
  744. sage: I = R.ideal([y^2 + x^2*(1/4) - 1])
  745. sage: I.plot() # ellipse
  746. sage: I = R.ideal([y^2-(x^2-1)*(x-2)])
  747. sage: I.plot() # elliptic curve
  748. Implicit plotting in 3-d::
  749. sage: R.<x,y,z> = PolynomialRing(QQ,3)
  750. sage: I = R.ideal([y^2 + x^2*(1/4) - z])
  751. sage: I.plot() # a cone; optional - surf
  752. sage: I = R.ideal([y^2 + z^2*(1/4) - x])
  753. sage: I.plot() # same code, from a different angle; optional - surf
  754. sage: I = R.ideal([x^2*y^2+x^2*z^2+y^2*z^2-16*x*y*z])
  755. sage: I.plot() # Steiner surface; optional - surf
  756. AUTHORS:
  757. - David Joyner (2006-02-12)
  758. """
  759. if self.ring().characteristic() != 0:
  760. raise TypeError, "base ring must have characteristic 0"
  761. if not self.is_principal():
  762. raise TypeError, "self must be principal"
  763. singular.lib('surf')
  764. I = singular(self)
  765. I.plot()
  766. @require_field
  767. @libsingular_standard_options
  768. def complete_primary_decomposition(self, algorithm="sy"):
  769. r"""
  770. Return a list of primary ideals and their associated primes such
  771. that the intersection of the primary ideal `Q_i` is
  772. `I` = ``self``.
  773. An ideal `Q` is called primary if it is a proper ideal of
  774. the ring `R` and if whenever `ab \in Q` and
  775. `a \not\in Q` then `b^n \in Q` for some
  776. `n \in \ZZ`.
  777. If `Q` is a primary ideal of the ring `R`, then the
  778. radical ideal `P` of `Q`, i.e.
  779. `P = \{a \in R, a^n \in Q\}` for some
  780. `n \in \ZZ`, is called the
  781. *associated prime* of `Q`.
  782. If `I` is a proper ideal of the ring `R` then there
  783. exists a decomposition in primary ideals `Q_i` such that
  784. - their intersection is `I`
  785. - none of the `Q_i` contains the intersection of the
  786. rest, and
  787. - the associated prime ideals of `Q_i` are pairwise
  788. different.
  789. This method returns these `Q_i` and their associated
  790. primes.
  791. INPUT:
  792. - ``algorithm`` - string:
  793. - ``'sy'`` - (default) use the shimoyama-yokoyama algorithm
  794. - ``'gtz'`` - use the gianni-trager-zacharias algorithm
  795. OUTPUT:
  796. - ``list`` - a list of primary ideals and their
  797. associated primes [(primary ideal, associated prime), ...]
  798. EXAMPLES::
  799. sage: R.<x,y,z> = PolynomialRing(QQ, 3, order='lex')
  800. sage: p = z^2 + 1; q = z^3 + 2
  801. sage: I = (p*q^2, y-z^2)*R
  802. sage: pd = I.complete_primary_decomposition(); pd
  803. [(Ideal (z^6 + 4*z^3 + 4, y - z^2) of Multivariate Polynomial Ring in x, y, z over Rational Field,
  804. Ideal (z^3 + 2, y - z^2) of Multivariate Polynomial Ring in x, y, z over Rational Field),
  805. (Ideal (z^2 + 1, y + 1) of Multivariate Polynomial Ring in x, y, z over Rational Field,
  806. Ideal (z^2 + 1, y + 1) of Multivariate Polynomial Ring in x, y, z over Rational Field)]
  807. sage: I.primary_decomposition_complete(algorithm = 'gtz')
  808. [(Ideal (z^6 + 4*z^3 + 4, y - z^2) of Multivariate Polynomial Ring in x, y, z over Rational Field,
  809. Ideal (z^3 + 2, y - z^2) of Multivariate Polynomial Ring in x, y, z over Rational Field),
  810. (Ideal (z^2 + 1, y - z^2) of Multivariate Polynomial Ring in x, y, z over Rational Field,
  811. Ideal (z^2 + 1, y - z^2) of Multivariate Polynomial Ring in x, y, z over Rational Field)]
  812. sage: reduce(lambda Qi,Qj: Qi.intersection(Qj), [Qi for (Qi,radQi) in pd]) == I
  813. True
  814. sage: [Qi.radical() == radQi for (Qi,radQi) in pd]
  815. [True, True]
  816. sage: P.<x,y,z> = PolynomialRing(ZZ)
  817. sage: I = ideal( x^2 - 3*y, y^3 - x*y, z^3 - x, x^4 - y*z + 1 )
  818. sage: I.complete_primary_decomposition()
  819. Traceback (most recent call last):
  820. ...
  821. ValueError: Coefficient ring must be a field for function 'complete_primary_decomposition'.
  822. ALGORITHM:
  823. Uses Singular.
  824. .. note::
  825. See [BW93]_ for an introduction to primary decomposition.
  826. """
  827. try:
  828. return self.__complete_primary_decomposition[algorithm]
  829. except AttributeError:
  830. self.__complete_primary_decomposition = {}
  831. except KeyError:
  832. pass
  833. import sage.libs.singular
  834. if algorithm == 'sy':
  835. primdecSY = sage.libs.singular.ff.primdec__lib.primdecSY
  836. P = primdecSY(self)
  837. elif algorithm == 'gtz':
  838. primdecGTZ = sage.libs.singular.ff.primdec__lib.primdecGTZ
  839. P = primdecGTZ(self)
  840. R = self.ring()
  841. V = [(R.ideal(X[0]), R.ideal(X[1])) for X in P]
  842. V = Sequence(V)
  843. self.__complete_primary_decomposition[algorithm] = V
  844. return self.__complete_primary_decomposition[algorithm]
  845. # Seems useful for Tab-Completion
  846. primary_decomposition_complete = complete_primary_decomposition
  847. @require_field
  848. def primary_decomposition(self, algorithm='sy'):
  849. r"""
  850. Return a list of primary ideals such that their intersection is
  851. `I` = ``self``.
  852. An ideal `Q` is called primary if it is a proper ideal of
  853. the ring `R` and if whenever `ab \in Q` and
  854. `a \not\in Q` then `b^n \in Q` for some
  855. `n \in \ZZ`.
  856. If `I` is a proper ideal of the ring `R` then there
  857. exists a decomposition in primary ideals `Q_i` such that
  858. - their intersection is `I`
  859. - none of the `Q_i` contains the intersection of the
  860. rest, and
  861. - the associated prime ideals of `Q_i` are pairwise
  862. different.
  863. This method returns these `Q_i`.
  864. INPUT:
  865. - ``algorithm`` - string:
  866. - ``'sy'`` - (default) use the shimoyama-yokoyama algorithm
  867. - ``'gtz'`` - use the gianni-trager-zacharias algorithm
  868. EXAMPLES::
  869. sage: R.<x,y,z> = PolynomialRing(QQ, 3, order='lex')
  870. sage: p = z^2 + 1; q = z^3 + 2
  871. sage: I = (p*q^2, y-z^2)*R
  872. sage: pd = I.primary_decomposition(); pd
  873. [Ideal (z^6 + 4*z^3 + 4, y - z^2) of Multivariate Polynomial Ring in x, y, z over Rational Field,
  874. Ideal (z^2 + 1, y + 1) of Multivariate Polynomial Ring in x, y, z over Rational Field]
  875. ::
  876. sage: reduce(lambda Qi,Qj: Qi.intersection(Qj), pd) == I
  877. True
  878. ALGORITHM:
  879. Uses Singular.
  880. REFERENCES:
  881. - Thomas Becker and Volker Weispfenning. Groebner Bases - A
  882. Computational Approach To Commutative Algebra. Springer, New
  883. York 1993.
  884. """
  885. return [I for I, _ in self.complete_primary_decomposition(algorithm)]
  886. @require_field
  887. def associated_primes(self, algorithm='sy'):
  888. r"""
  889. Return a list of the associated primes of primary ideals of
  890. which the intersection is `I` = ``self``.
  891. An ideal `Q` is called primary if it is a proper ideal of
  892. the ring `R` and if whenever `ab \in Q` and
  893. `a \not\in Q` then `b^n \in Q` for some
  894. `n \in \ZZ`.
  895. If `Q` is a primary ideal of the ring `R`, then the
  896. radical ideal `P` of `Q`, i.e.
  897. `P = \{a \in R, a^n \in Q\}` for some
  898. `n \in \ZZ`, is called the
  899. *associated prime* of `Q`.
  900. If `I` is a proper ideal of the ring `R` then there
  901. exists a decomposition in primary ideals `Q_i` such that
  902. - their intersection is `I`
  903. - none of the `Q_i` contains the intersection of the
  904. rest, and
  905. - the associated prime ideals of `Q_i` are pairwise
  906. different.
  907. This method returns the associated primes of the `Q_i`.
  908. INPUT:
  909. - ``algorithm`` - string:
  910. - ``'sy'`` - (default) use the shimoyama-yokoyama algorithm
  911. - ``'gtz'`` - use the gianni-trager-zacharias algorithm
  912. OUTPUT:
  913. - ``list`` - a list of associated primes
  914. EXAMPLES::
  915. sage: R.<x,y,z> = PolynomialRing(QQ, 3, order='lex')
  916. sage: p = z^2 + 1; q = z^3 + 2
  917. sage: I = (p*q^2, y-z^2)*R
  918. sage: pd = I.associated_primes(); pd
  919. [Ideal (z^3 + 2, y - z^2) of Multivariate Polynomial Ring in x, y, z over Rational Field,
  920. Ideal (z^2 + 1, y + 1) of Multivariate Polynomial Ring in x, y, z over Rational Field]
  921. ALGORITHM:
  922. Uses Singular.
  923. REFERENCES:
  924. - Thomas Becker and Volker Weispfenning. Groebner Bases - A
  925. Computational Approach To Commutative Algebra. Springer, New
  926. York 1993.
  927. """
  928. return [P for _,P in self.complete_primary_decomposition(algorithm)]
  929. def is_prime(self, **kwds):
  930. r"""
  931. Return ``True`` if this ideal is prime.
  932. INPUT:
  933. - keyword arguments are passed on to
  934. ``complete_primary_decomposition``; in this way you can
  935. specify the algorithm to use.
  936. EXAMPLES::
  937. sage: R.<x, y> = PolynomialRing(QQ, 2)
  938. sage: I = (x^2 - y^2 - 1)*R
  939. sage: I.is_prime()
  940. True
  941. sage: (I^2).is_prime()
  942. False
  943. sage: J = (x^2 - y^2)*R
  944. sage: J.is_prime()
  945. False
  946. sage: (J^3).is_prime()
  947. False
  948. sage: (I * J).is_prime()
  949. False
  950. The following is Trac #5982. Note that the quotient ring
  951. is not recognized as being a field at this time, so the
  952. fraction field is not the quotient ring itself::
  953. sage: Q = R.quotient(I); Q
  954. Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2 - y^2 - 1)
  955. sage: Q.fraction_field()
  956. Fraction Field of Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2 - y^2 - 1)
  957. """
  958. if not self.ring().base_ring().is_field():
  959. raise NotImplementedError
  960. CPD = self.complete_primary_decomposition(**kwds)
  961. if len(CPD) != 1:
  962. return False
  963. _, P = CPD[0]
  964. return self == P
  965. @require_field
  966. @singular_standard_options
  967. @libsingular_standard_options
  968. def triangular_decomposition(self, algorithm=None, singular=singular_default):
  969. """
  970. Decompose zero-dimensional ideal ``self`` into triangular
  971. sets.
  972. This requires that the given basis is reduced w.r.t. to the
  973. lexicographical monomial ordering. If the basis of self does
  974. not have this property, the required Groebner basis is
  975. computed implicitly.
  976. INPUT:
  977. - ``algorithm`` - string or None (default: None)
  978. ALGORITHMS:
  979. - ``singular:triangL`` - decomposition of self into triangular
  980. systems (Lazard).
  981. - ``singular:triangLfak`` - decomp. of self into tri. systems
  982. plus factorization.
  983. - ``singular:triangM`` - decomposition of self into
  984. triangular systems (Moeller).
  985. OUTPUT: a list `T` of lists `t` such that the variety of
  986. ``self`` is the union of the varieties of `t` in `L` and each
  987. `t` is in triangular form.
  988. EXAMPLE::
  989. sage: P.<e,d,c,b,a> = PolynomialRing(QQ,5,order='lex')
  990. sage: I = sage.rings.ideal.Cyclic(P)
  991. sage: GB = Ideal(I.groebner_basis('libsingular:stdfglm'))
  992. sage: GB.triangular_decomposition('singular:triangLfak')
  993. [Ideal (a - 1, b - 1, c - 1, d^2 + 3*d + 1, e + d + 3) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field,
  994. Ideal (a - 1, b - 1, c^2 + 3*c + 1, d + c + 3, e - 1) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field,
  995. Ideal (a - 1, b^2 + 3*b + 1, c + b + 3, d - 1, e - 1) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field,
  996. Ideal (a - 1, b^4 + b^3 + b^2 + b + 1, -c + b^2, -d + b^3, e + b^3 + b^2 + b + 1) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field,
  997. Ideal (a^2 + 3*a + 1, b - 1, c - 1, d - 1, e + a + 3) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field,
  998. Ideal (a^2 + 3*a + 1, b + a + 3, c - 1, d - 1, e - 1) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field,
  999. Ideal (a^4 - 4*a^3 + 6*a^2 + a + 1, -11*b^2 + 6*b*a^3 - 26*b*a^2 + 41*b*a - 4*b - 8*a^3 + 31*a^2 - 40*a - 24, 11*c + 3*a^3 - 13*a^2 + 26*a - 2, 11*d + 3*a^3 - 13*a^2 + 26*a - 2, -11*e - 11*b + 6*a^3 - 26*a^2 + 41*a - 4) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field,
  1000. Ideal (a^4 + a^3 + a^2 + a + 1, b - 1, c + a^3 + a^2 + a + 1, -d + a^3, -e + a^2) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field,
  1001. Ideal (a^4 + a^3 + a^2 + a + 1, b - a, c - a, d^2 + 3*d*a + a^2, e + d + 3*a) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field,
  1002. Ideal (a^4 + a^3 + a^2 + a + 1, b - a, c^2 + 3*c*a + a^2, d + c + 3*a, e - a) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field,
  1003. Ideal (a^4 + a^3 + a^2 + a + 1, b^2 + 3*b*a + a^2, c + b + 3*a, d - a, e - a) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field,
  1004. Ideal (a^4 + a^3 + a^2 + a + 1, b^3 + b^2*a + b^2 + b*a^2 + b*a + b + a^3 + a^2 + a + 1, c + b^2*a^3 + b^2*a^2 + b^2*a + b^2, -d + b^2*a^2 + b^2*a + b^2 + b*a^2 + b*a + a^2, -e + b^2*a^3 - b*a^2 - b*a - b - a^2 - a) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field,
  1005. Ideal (a^4 + a^3 + 6*a^2 - 4*a + 1, -11*b^2 + 6*b*a^3 + 10*b*a^2 + 39*b*a + 2*b + 16*a^3 + 23*a^2 + 104*a - 24, 11*c + 3*a^3 + 5*a^2 + 25*a + 1, 11*d + 3*a^3 + 5*a^2 + 25*a + 1, -11*e - 11*b + 6*a^3 + 10*a^2 + 39*a + 2) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field]
  1006. sage: R.<x1,x2> = PolynomialRing(QQ, 2, order='lex')
  1007. sage: f1 = 1/2*((x1^2 + 2*x1 - 4)*x2^2 + 2*(x1^2 + x1)*x2 + x1^2)
  1008. sage: f2 = 1/2*((x1^2 + 2*x1 + 1)*x2^2 + 2*(x1^2 + x1)*x2 - 4*x1^2)
  1009. sage: I = Ideal(f1,f2)
  1010. sage: I.triangular_decomposition()
  1011. [Ideal (x2, x1^2) of Multivariate Polynomial Ring in x1, x2 over Rational Field,
  1012. Ideal (x2, x1^2) of Multivariate Polynomial Ring in x1, x2 over Rational Field,
  1013. Ideal (x2, x1^2) of Multivariate Polynomial Ring in x1, x2 over Rational Field,
  1014. Ideal (x2^4 + 4*x2^3 - 6*x2^2 - 20*x2 + 5, 8*x1 - x2^3 + x2^2 + 13*x2 - 5) of Multivariate Polynomial Ring in x1, x2 over Rational Field]
  1015. TESTS::
  1016. sage: R.<x,y> = QQ[]
  1017. sage: J = Ideal(x^2+y^2-2, y^2-1)
  1018. sage: J.triangular_decomposition()
  1019. [Ideal (y^2 - 1, x^2 - 1) of Multivariate Polynomial Ring in x, y over Rational Field]
  1020. """
  1021. P = self.ring()
  1022. is_groebner = self.basis_is_groebner()
  1023. # make sure to work w.r.t. 'lex'
  1024. if P.term_order() != 'lex':
  1025. Q = P.change_ring(order='lex')
  1026. else:
  1027. Q = P
  1028. # the Singular routines are quite picky about their input.
  1029. if is_groebner:
  1030. if Q == P:
  1031. I = MPolynomialIdeal(P, self.interreduced_basis()[::-1])
  1032. else:
  1033. I = self
  1034. I = MPolynomialIdeal(P, I.transformed_basis('fglm')[::-1]) # -> 'lex'
  1035. I = I.change_ring(Q) # transform to 'lex' GB
  1036. else:
  1037. if Q == P:
  1038. I = MPolynomialIdeal(P, self.groebner_basis()[::-1])
  1039. else:
  1040. I = self.change_ring(Q) # transform to 'lex' GB
  1041. I = MPolynomialIdeal(Q, I.groebner_basis()[::-1])
  1042. if I.dimension() != 0:
  1043. raise TypeError, "dimension must be zero"
  1044. from sage.libs.singular.function import singular_function
  1045. from sage.libs.singular.function import lib as singular_lib
  1046. singular_lib('triang.lib')
  1047. if algorithm is None:
  1048. algorithm = "singular:triangL"
  1049. if algorithm in ("singular:triangL","singular:triangLfak","singular:triangM"):
  1050. f = singular_function(algorithm[9:])
  1051. Tbar = f(I, attributes={I:{'isSB':1}})
  1052. else:
  1053. raise TypeError, "algorithm '%s' unknown"%algorithm
  1054. T = Sequence([ MPolynomialIdeal(Q,t) for t in Tbar])
  1055. f = lambda x,y: cmp(x.gens(), y.gens())
  1056. T.sort(f)
  1057. return T
  1058. @require_field
  1059. def dimension(self, singular=singular_default):
  1060. """
  1061. The dimension of the ring modulo this ideal.
  1062. EXAMPLE::
  1063. sage: P.<x,y,z> = PolynomialRing(GF(32003),order='degrevlex')
  1064. sage: I = ideal(x^2-y,x^3)
  1065. sage: I.dimension()
  1066. 1
  1067. For polynomials over a finite field of order too large for Singular,
  1068. this falls back on a toy implementation of Buchberger to compute
  1069. the Groebner basis, then uses the algorithm described in Chapter 9,
  1070. Section 1 of Cox, Little, and O'Shea's "Ideals, Varieties, and Algorithms".
  1071. EXAMPLE::
  1072. sage: R.<x,y> = PolynomialRing(GF(2147483659),order='lex')
  1073. sage: I = R.ideal([x*y,x*y+1])
  1074. sage: I.dimension()
  1075. verbose 0 (...: multi_polynomial_ideal.py, dimension) Warning: falling back to very slow toy implementation.
  1076. 0
  1077. sage: I=ideal([x*(x*y+1),y*(x*y+1)])
  1078. sage: I.dimension()
  1079. verbose 0 (...: multi_polynomial_ideal.py, dimension) Warning: falling back to very slow toy implementation.
  1080. 1
  1081. sage: I = R.ideal([x^3*y,x*y^2])
  1082. sage: I.dimension()
  1083. verbose 0 (...: multi_polynomial_ideal.py, dimension) Warning: falling back to very slow toy implementation.
  1084. 1
  1085. sage: R.<x,y> = PolynomialRing(GF(2147483659),order='lex')
  1086. sage: I = R.ideal(0)
  1087. sage: I.dimension()
  1088. verbose 0 (...: multi_polynomial_ideal.py, dimension) Warning: falling back to very slow toy implementation.
  1089. 2
  1090. ALGORITHM:
  1091. Uses Singular, unless the characteristic is too large.
  1092. .. note::
  1093. Requires computation of a Groebner basis, which can be a
  1094. very expensive operation.
  1095. """
  1096. try:
  1097. return self.__dimension
  1098. except AttributeError:
  1099. try:
  1100. import sage.libs.singular
  1101. dim = sage.libs.singular.ff.dim
  1102. v = MPolynomialIdeal(self.ring(),self.groebner_basis())
  1103. self.__dimension = Integer(dim(v, attributes={v:{'isSB':1}}))
  1104. except TypeError:
  1105. try:
  1106. v = self._groebner_basis_singular_raw()
  1107. self.__dimension = Integer(v.dim())
  1108. except TypeError:
  1109. if not self.base_ring().is_field():
  1110. raise NotImplementedError, "dimension() is implemented only over fields."
  1111. if self.ring().term_order().is_global():
  1112. verbose("Warning: falling back to very slow toy implementation.", level=0)
  1113. # See Chapter 9, Section 1 of Cox, Little, O'Shea's "Ideals, Varieties,
  1114. # and Algorithms".
  1115. from sage.sets.set import Set
  1116. gb = toy_buchberger.buchberger_improved(self)
  1117. ring_vars = self.ring().gens()
  1118. n = len(ring_vars)
  1119. lms = [each.lm() for each in gb]
  1120. # compute M_j, denoted by var_lms
  1121. var_lms = [Set([]) for each in lms]
  1122. for j in xrange(len(ring_vars)):
  1123. for i in xrange(len(lms)):
  1124. if lms[i].degree(ring_vars[j]) > 0:
  1125. var_lms[i] += Set([j+1])
  1126. # compute intersections of M_j and J
  1127. # we assume that the iterator starts with the empty set,
  1128. # then iterates through all subsets of order 1,
  1129. # then through all subsets of order 2, etc...
  1130. # the way Sage currently operates
  1131. all_J = Set([each + 1 for each in range(n)]).subsets()
  1132. min_dimension = -1
  1133. all_J = iter(all_J)
  1134. while min_dimension == -1:
  1135. try:
  1136. J = all_J.next()
  1137. except StopIteration:
  1138. min_dimension = n
  1139. break
  1140. J_intersects_all = True
  1141. i = 0
  1142. while J_intersects_all and i < len(var_lms):
  1143. J_intersects_all = J.intersection(var_lms[i]) != Set([])
  1144. i += 1
  1145. if J_intersects_all:
  1146. min_dimension = len(J)
  1147. return n - min_dimension
  1148. else:
  1149. raise TypeError, "Local/unknown orderings not supported by 'toy_buchberger' implementation."
  1150. return self.__dimension
  1151. @require_field
  1152. def vector_space_dimension(self):
  1153. """
  1154. Return the vector space dimension of the ring modulo this ideal. If
  1155. the ideal is not zero-dimensional, a TypeError is raised.
  1156. ALGORITHM:
  1157. Uses Singular.
  1158. EXAMPLE::
  1159. sage: R.<u,v> = PolynomialRing(QQ)
  1160. sage: g = u^4 + v^4 + u^3 + v^3
  1161. sage: I = ideal(g) + ideal(g.gradient())
  1162. sage: I.dimension()
  1163. 0
  1164. sage: I.vector_space_dimension()
  1165. 4
  1166. """
  1167. R = self.ring()
  1168. gb = R.ideal(self.groebner_basis())
  1169. import sage.libs.singular
  1170. vdim = sage.libs.singular.ff.vdim
  1171. vd = Integer(vdim(gb, attributes={gb:{'isSB':1}}))
  1172. if vd == -1:
  1173. raise TypeError("ideal is not zero dimensional")
  1174. else:
  1175. return vd
  1176. @require_field
  1177. def _groebner_basis_ginv(self, algorithm="TQ", criteria='CritPartially', division_interface="Janet"):
  1178. """
  1179. Compute a Groebner basis using GINV.
  1180. INPUT:
  1181. - ``algorithm`` - "TQ", "TQBlockHigh", "TQBlockLow" or "TQDegree"
  1182. - ``criteria`` - "Without" (without any criteria)
  1183. - "C1", "CritPartially" (partial involutive criteria)
  1184. - "C1C2C3", "C1C2C3C4" (full involutive criteria)
  1185. - ``division_interface`` - either "Janet" or "JanetLike"
  1186. EXAMPLES:
  1187. Currently, only GF(p) and QQ are supported as base fields::
  1188. sage: P.<x,y,z> = PolynomialRing(QQ,order='degrevlex')
  1189. sage: I = sage.rings.ideal.Katsura(P)
  1190. sage: I.groebner_basis(algorithm='ginv') # optional - ginv
  1191. [z^3 - 79/210*z^2 + 1/30*y + 1/70*z, y^2 - 3/5*z^2 - 1/5*y + 1/5*z, y*z + 6/5*z^2 - 1/10*y - 2/5*z, x + 2*y + 2*z - 1]
  1192. sage: P.<x,y,z> = PolynomialRing(GF(127),order='degrevlex')
  1193. sage: I = sage.rings.ideal.Katsura(P)
  1194. sage: I.groebner_basis(algorithm='ginv') # optional - ginv
  1195. ...
  1196. [z^3 + 22*z^2 - 55*y + 49*z, y^2 - 26*z^2 - 51*y + 51*z, y*z + 52*z^2 + 38*y + 25*z, x + 2*y + 2*z - 1]
  1197. .. note::
  1198. Criterion C1 is Buchberger's co-prime criterion. Criteria
  1199. C2, C3 and C4 in the aggregate are equivalent to the second
  1200. (chain) Buchberger's criterion. Supported term orderings are
  1201. 'lex' and 'degrevlex', supported base rings are GF(p) with p
  1202. < 2^16 and QQ.
  1203. """
  1204. P = self.ring()
  1205. T = P.term_order()
  1206. K = P.base_ring()
  1207. try:
  1208. import ginv
  1209. except ImportError:
  1210. raise ImportError("""GINV is missing, to install use "install_package('ginv')".""")
  1211. st = ginv.SystemType("Polynomial")
  1212. term_order_map = {'degrevlex':"DegRevLex",'lex':"Lex"}
  1213. try:
  1214. im = ginv.MonomInterface(term_order_map[T.name()], st, list(P.variable_names()))
  1215. except KeyError:
  1216. raise NotImplementedError("Term order '%s' not supported by Sage's GINV interface or GINV"%T.term_order())
  1217. from sage.all import QQ
  1218. if K is QQ:
  1219. ic = ginv.CoeffInterface("GmpQ", st)
  1220. elif K.order() <= 2**16 and K.order().is_prime():
  1221. ic = ginv.CoeffInterface("ModularShort", st, modularShort=K.order())
  1222. else:
  1223. raise NotImplementedError("GINV interface for base ring '%s' is not implemented."%K)
  1224. ip = ginv.PolyInterface("PolyList", st, im, ic)
  1225. iw = ginv.WrapInterface(criteria, ip)
  1226. iD = ginv.DivisionInterface(division_interface, iw)
  1227. system = [ginv.Poly(ip, str(f)) for f in self.gens()]
  1228. G = ginv.basisBuild(algorithm, iD, system)
  1229. G = Sequence([P(str(f)) for f in G.iterGB()])
  1230. return G
  1231. @singular_standard_options
  1232. def _groebner_basis_singular(self, algorithm="groebner", *args, **kwds):
  1233. """
  1234. Return the reduced Groebner basis of this ideal. If the
  1235. Groebner basis for this ideal has been calculated before, the
  1236. cached Groebner basis is returned regardless of the requested
  1237. algorithm.
  1238. INPUT:
  1239. - ``algorithm`` - see below for available algorithms
  1240. ALGORITHMS:
  1241. 'groebner'
  1242. use Singular's groebner heuristic to choose an algorithm (default)
  1243. 'std'
  1244. Buchberger's algorithm
  1245. 'stdhilb'
  1246. computes the standard basis of the homogeneous ideal in the
  1247. base ring, via a Hilbert driven standard basis computation.
  1248. 'stdfglm'
  1249. computes the standard basis of the ideal in the base ring via fglm
  1250. (from the degrevlex ordering to the ordering of the base ring).
  1251. 'slimgb'
  1252. the *SlimGB* algorithm
  1253. EXAMPLES:
  1254. We compute a Groebner basis of 'cyclic 4' relative to
  1255. lexicographic ordering. ::
  1256. sage: R.<a,b,c,d> = PolynomialRing(QQ, 4, order='lex')
  1257. sage: I = sage.rings.ideal.Cyclic(R,4); I
  1258. Ideal (a + b + c + d, a*b + a*d + b*c + c*d, a*b*c + a*b*d
  1259. + a*c*d + b*c*d, a*b*c*d - 1) of Multivariate Polynomial
  1260. Ring in a, b, c, d over Rational Field
  1261. ::
  1262. sage: I._groebner_basis_singular()
  1263. [c^2*d^6 - c^2*d^2 - d^4 + 1, c^3*d^2 + c^2*d^3 - c - d,
  1264. b*d^4 - b + d^5 - d, b*c - b*d + c^2*d^4 + c*d - 2*d^2,
  1265. b^2 + 2*b*d + d^2, a + b + c + d]
  1266. ALGORITHM:
  1267. Uses Singular.
  1268. .. note::
  1269. This method is called by the :meth:`.groebner_basis` method
  1270. and the user usually doesn't need to bother with this one.
  1271. """
  1272. from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence
  1273. R = self.ring()
  1274. S = self._groebner_basis_singular_raw(algorithm=algorithm, *args, **kwds)
  1275. S = PolynomialSequence([R(S[i+1]) for i in range(len(S))], R, immutable=True)
  1276. return S
  1277. @cached_method
  1278. def _groebner_basis_singular_raw(self, algorithm="groebner", singular=singular_default, *args, **kwds):
  1279. r"""
  1280. Return a Groebner basis in Singular format.
  1281. INPUT:
  1282. - ``algorithm`` - Singular function to call (default: ``groebner``)
  1283. - ``singular`` - Singular instance to use (default: ``singular_default``)
  1284. - ``args`` - ignored
  1285. - ``kwds`` - Singular options
  1286. EXAMPLE::
  1287. sage: R.<a,b,c,d> = PolynomialRing(QQ, 4, order='lex')
  1288. sage: I = sage.rings.ideal.Cyclic(R,4)
  1289. sage: I._groebner_basis_singular() # indirect doctest
  1290. [c^2*d^6 - c^2*d^2 - d^4 + 1, c^3*d^2 + c^2*d^3 - c - d,
  1291. b*d^4 - b + d^5 - d, b*c - b*d + c^2*d^4 + c*d - 2*d^2,
  1292. b^2 + 2*b*d + d^2, a + b + c + d]
  1293. """
  1294. #try:
  1295. # return self.__gb_singular
  1296. #except AttributeError:
  1297. # pass
  1298. # singular options are preserved by @singular_standard_options,
  1299. # so we don't eed to do that here too
  1300. from sage.libs.singular.option import _options_py_to_singular
  1301. S = self._singular_() # for degBound, we need to ensure
  1302. # that a ring is defined
  1303. if get_verbose() >= 2:
  1304. kwds['prot'] = True
  1305. for o,v in kwds.iteritems():
  1306. o = _options_py_to_singular.get(o,o)
  1307. if v:
  1308. if o in ['degBound','multBound']:
  1309. singular.eval(o+'=%d'%v)
  1310. else:
  1311. singular.option(o)
  1312. else:
  1313. if o in ['degBound','multBound']:
  1314. singular.eval(o+'=0')
  1315. else:
  1316. singular.option("no"+o)
  1317. obj = self._singular_()
  1318. prot = kwds.get('prot',False)
  1319. if prot == "sage":
  1320. if algorithm == 'slimgb':
  1321. warn("'slimgb' does not print sufficient information for prot='sage' to work reliably, the highest degree reached might be too low.")
  1322. from sage.interfaces.singular import SingularGBLogPrettyPrinter
  1323. log_parser = SingularGBLogPrettyPrinter(verbosity=get_verbose()+1)
  1324. else:
  1325. log_parser = None
  1326. ctx = StdOutContext(singular, silent=False if prot else True, stdout=log_parser)
  1327. with ctx:
  1328. if algorithm=="groebner":
  1329. S = obj.groebner()
  1330. elif algorithm=="std":
  1331. S = obj.std()
  1332. elif algorithm=="slimgb":
  1333. S = obj.slimgb()
  1334. elif algorithm=="stdhilb":
  1335. S = obj.stdhilb()
  1336. elif algorithm=="stdfglm":
  1337. S = obj.stdfglm()
  1338. else:
  1339. raise TypeError, "algorithm '%s' unknown"%algorithm
  1340. self.__gb_singular = S
  1341. if prot == "sage":
  1342. print
  1343. print "Highest degree reached during computation: %2d."%log_parser.max_deg
  1344. return S
  1345. @require_field
  1346. def genus(self):
  1347. """
  1348. Return the genus of the projective curve defined by this ideal,
  1349. which must be 1 dimensional.
  1350. EXAMPLE:
  1351. Consider the hyperelliptic curve `y^2 = 4x^5 - 30x^3 + 45x -
  1352. 22` over `\QQ`, it has genus 2::
  1353. sage: P, x = PolynomialRing(QQ,"x").objgen()
  1354. sage: f = 4*x^5 - 30*x^3 + 45*x - 22
  1355. sage: C = HyperellipticCurve(f); C
  1356. Hyperelliptic Curve over Rational Field defined by y^2 = 4*x^5 - 30*x^3 + 45*x - 22
  1357. sage: C.genus()
  1358. 2
  1359. ::
  1360. sage: P.<x,y> = PolynomialRing(QQ)
  1361. sage: f = y^2 - 4*x^5 - 30*x^3 + 45*x - 22
  1362. sage: I = Ideal([f])
  1363. sage: I.genus()
  1364. 2
  1365. """
  1366. try:
  1367. return self.__genus
  1368. except AttributeError:
  1369. import sage.libs.singular
  1370. genus = sage.libs.singular.ff.normal__lib.genus
  1371. self.__genus = Integer(genus(self))
  1372. return self.__genus
  1373. @libsingular_standard_options
  1374. def intersection(self, *others):
  1375. """
  1376. Return the intersection of the arguments with this ideal.
  1377. EXAMPLES::
  1378. sage: R.<x,y> = PolynomialRing(QQ, 2, order='lex')
  1379. sage: I = x*R
  1380. sage: J = y*R
  1381. sage: I.intersection(J)
  1382. Ideal (x*y) of Multivariate Polynomial Ring in x, y over Rational Field
  1383. The following simple example illustrates that the product need
  1384. not equal the intersection. ::
  1385. sage: I = (x^2, y)*R
  1386. sage: J = (y^2, x)*R
  1387. sage: K = I.intersection(J); K
  1388. Ideal (y^2, x*y, x^2) of Multivariate Polynomial Ring in x, y over Rational Field
  1389. sage: IJ = I*J; IJ
  1390. Ideal (x^2*y^2, x^3, y^3, x*y) of Multivariate Polynomial Ring in x, y over Rational Field
  1391. sage: IJ == K
  1392. False
  1393. Intersection of several ideals::
  1394. sage: R.<x,y,z> = PolynomialRing(QQ, 3, order='lex')
  1395. sage: I1 = x*R
  1396. sage: I2 = y*R
  1397. sage: I3 = (x, y)*R
  1398. sage: I4 = (x^2 + x*y*z, y^2 - z^3*y, z^3 + y^5*x*z)*R
  1399. sage: I1.intersection(I2, I3, I4)
  1400. Ideal (x*y*z^20 - x*y*z^3, x*y^2 - x*y*z^3, x^2*y + x*y*z^4) of Multivariate Polynomial Ring in x, y, z over Rational Field
  1401. The ideals must share the same ring::
  1402. sage: R2.<x,y> = PolynomialRing(QQ, 2, order='lex')
  1403. sage: R3.<x,y,z> = PolynomialRing(QQ, 3, order='lex')
  1404. sage: I2 = x*R2
  1405. sage: I3 = x*R3
  1406. sage: I2.intersection(I3)
  1407. Traceback (most recent call last):
  1408. ...
  1409. TypeError: Intersection is only available for ideals of the same ring.
  1410. """
  1411. R = self.ring()
  1412. for other in others:
  1413. if not isinstance(other, MPolynomialIdeal_singular_repr) or other.ring() != R:
  1414. raise TypeError, "Intersection is only available for ideals of the same ring."
  1415. import sage.libs.singular
  1416. intersect = sage.libs.singular.ff.intersect
  1417. K = intersect(self, *others)
  1418. return R.ideal(K)
  1419. @require_field
  1420. @libsingular_standard_options
  1421. def minimal_associated_primes(self):
  1422. """
  1423. OUTPUT:
  1424. - ``list`` - a list of prime ideals
  1425. EXAMPLES::
  1426. sage: R.<x,y,z> = PolynomialRing(QQ, 3, 'xyz')
  1427. sage: p = z^2 + 1; q = z^3 + 2
  1428. sage: I = (p*q^2, y-z^2)*R
  1429. sage: I.minimal_associated_primes ()
  1430. [Ideal (z^2 + 1, -z^2 + y) of Multivariate Polynomial Ring
  1431. in x, y, z over Rational Field, Ideal (z^3 + 2, -z^2 + y)
  1432. of Multivariate Polynomial Ring in x, y, z over Rational
  1433. Field]
  1434. ALGORITHM:
  1435. Uses Singular.
  1436. """
  1437. import sage.libs.singular
  1438. minAssGTZ = sage.libs.singular.ff.primdec__lib.minAssGTZ
  1439. M = minAssGTZ(self)
  1440. R = self.ring()
  1441. return [R.ideal(J) for J in M]
  1442. @require_field
  1443. @libsingular_standard_options
  1444. def radical(self):
  1445. r"""
  1446. The radical of this ideal.
  1447. EXAMPLES:
  1448. This is an obviously not radical ideal::
  1449. sage: R.<x,y,z> = PolynomialRing(QQ, 3)
  1450. sage: I = (x^2, y^3, (x*z)^4 + y^3 + 10*x^2)*R
  1451. sage: I.radical()
  1452. Ideal (y, x) of Multivariate Polynomial Ring in x, y, z over Rational Field
  1453. That the radical is correct is clear from the Groebner basis. ::
  1454. sage: I.groebner_basis()
  1455. [y^3, x^2]
  1456. This is the example from the Singular manual::
  1457. sage: p = z^2 + 1; q = z^3 + 2
  1458. sage: I = (p*q^2, y-z^2)*R
  1459. sage: I.radical()
  1460. Ideal (z^2 - y, y^2*z + y*z + 2*y + 2) of Multivariate Polynomial Ring in x, y, z over Rational Field
  1461. .. note::
  1462. From the Singular manual: A combination of the algorithms
  1463. of Krick/Logar and Kemper is used. Works also in positive
  1464. characteristic (Kempers algorithm).
  1465. ::
  1466. sage: R.<x,y,z> = PolynomialRing(GF(37), 3)
  1467. sage: p = z^2 + 1; q = z^3 + 2
  1468. sage: I = (p*q^2, y - z^2)*R
  1469. sage: I.radical()
  1470. Ideal (z^2 - y, y^2*z + y*z + 2*y + 2) of Multivariate Polynomial Ring in x, y, z over Finite Field of size 37
  1471. """
  1472. import sage.libs.singular
  1473. radical = sage.libs.singular.ff.primdec__lib.radical
  1474. r = radical(self)
  1475. S = self.ring()
  1476. #I = self._singular_()
  1477. #I.parent().lib('primdec.lib')
  1478. #r = I.radical()
  1479. return S.ideal(r)
  1480. @require_field
  1481. @libsingular_standard_options
  1482. def integral_closure(self, p=0, r=True, singular=singular_default):
  1483. """
  1484. Let `I` = ``self``.
  1485. Returns the integral closure of `I, ..., I^p`, where `sI` is
  1486. an ideal in the polynomial ring `R=k[x(1),...x(n)]`. If `p` is
  1487. not given, or `p=0`, compute the closure of all powers up to
  1488. the maximum degree in t occurring in the closure of `R[It]`
  1489. (so this is the last power whose closure is not just the
  1490. sum/product of the smaller). If `r` is given and ``r is
  1491. True``, ``I.integral_closure()`` starts with a check whether I
  1492. is already a radical ideal.
  1493. INPUT:
  1494. - ``p`` - powers of I (default: 0)
  1495. - ``r`` - check whether self is a radical ideal first (default: ``True``)
  1496. EXAMPLE::
  1497. sage: R.<x,y> = QQ[]
  1498. sage: I = ideal([x^2,x*y^4,y^5])
  1499. sage: I.integral_closure()
  1500. [x^2, y^5, -x*y^3]
  1501. ALGORITHM:
  1502. Uses libSINGULAR.
  1503. """
  1504. from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence
  1505. R = self.ring()
  1506. import sage.libs.singular
  1507. normalI = sage.libs.singular.ff.reesclos__lib.normalI
  1508. ret = PolynomialSequence(normalI(self, p, int(r))[0], R, immutable=True)
  1509. return ret
  1510. @require_field
  1511. def syzygy_module(self):
  1512. r"""
  1513. Computes the first syzygy (i.e., the module of relations of the
  1514. given generators) of the ideal.
  1515. EXAMPLE::
  1516. sage: R.<x,y> = PolynomialRing(QQ)
  1517. sage: f = 2*x^2 + y
  1518. sage: g = y
  1519. sage: h = 2*f + g
  1520. sage: I = Ideal([f,g,h])
  1521. sage: M = I.syzygy_module(); M
  1522. [ -2 -1 1]
  1523. [ -y 2*x^2 + y 0]
  1524. sage: G = vector(I.gens())
  1525. sage: M*G
  1526. (0, 0)
  1527. ALGORITHM:
  1528. Uses Singular's syz command.
  1529. """
  1530. import sage.libs.singular
  1531. syz = sage.libs.singular.ff.syz
  1532. from sage.matrix.constructor import matrix
  1533. #return self._singular_().syz().transpose().sage_matrix(self.ring())
  1534. S = syz(self)
  1535. return matrix(self.ring(), S)
  1536. def reduced_basis(self):
  1537. r"""
  1538. .. warning::
  1539. This function is deprecated. It will be removed in a future
  1540. release of Sage. Please use the :meth:`interreduced_basis`
  1541. function instead.
  1542. If this ideal is spanned by `(f_1, ..., f_n)` this method
  1543. returns `(g_1, ..., g_s)` such that:
  1544. - `(f_1,...,f_n) = (g_1,...,g_s)`
  1545. - `LT(g_i) != LT(g_j)` for all `i != j`
  1546. - `LT(g_i)` does not divide `m` for all monomials `m`
  1547. of `\{g_1,...,g_{i-1},g_{i+1},...,g_s\}`
  1548. - `LC(g_i) == 1` for all `i`.
  1549. EXAMPLES::
  1550. sage: R.<x,y,z> = PolynomialRing(QQ)
  1551. sage: I = Ideal([z*x+y^3,z+y^3,z+x*y])
  1552. sage: I.reduced_basis()
  1553. doctest:...: DeprecationWarning: This function is deprecated. It will be removed in a future release of Sage. Please use the interreduced_basis() function instead.
  1554. See http://trac.sagemath.org/5058 for details.
  1555. [y^3 + z, x*y + z, x*z - z]
  1556. sage: R.<x,y,z> = PolynomialRing(QQ,order='negdegrevlex')
  1557. sage: I = Ideal([z*x+y^3,z+y^3,z+x*y])
  1558. sage: I.reduced_basis()
  1559. [z + x*y, x*y - y^3, x^2*y - y^3]
  1560. ALGORITHM:
  1561. Uses Singular's interred command or
  1562. ``toy_buchberger.inter_reduction`` if conversion to
  1563. Singular fails.
  1564. """
  1565. from sage.misc.superseded import deprecation
  1566. deprecation(5058, "This function is deprecated. It will be removed in a future release of Sage. Please use the interreduced_basis() function instead.")
  1567. return self.interreduced_basis()
  1568. @singular_standard_options
  1569. @libsingular_standard_options
  1570. def interreduced_basis(self):
  1571. r"""
  1572. If this ideal is spanned by `(f_1, ..., f_n)` this method
  1573. returns `(g_1, ..., g_s)` such that:
  1574. - `(f_1,...,f_n) = (g_1,...,g_s)`
  1575. - `LT(g_i) != LT(g_j)` for all `i != j`
  1576. - `LT(g_i)` does not divide `m` for all monomials `m` of
  1577. `\{g_1,...,g_{i-1},g_{i+1},...,g_s\}`
  1578. - `LC(g_i) == 1` for all `i` if the coefficient ring is a field.
  1579. EXAMPLE::
  1580. sage: R.<x,y,z> = PolynomialRing(QQ)
  1581. sage: I = Ideal([z*x+y^3,z+y^3,z+x*y])
  1582. sage: I.interreduced_basis()
  1583. [y^3 + z, x*y + z, x*z - z]
  1584. Note that tail reduction for local orderings is not well-defined::
  1585. sage: R.<x,y,z> = PolynomialRing(QQ,order='negdegrevlex')
  1586. sage: I = Ideal([z*x+y^3,z+y^3,z+x*y])
  1587. sage: I.interreduced_basis()
  1588. [z + x*y, x*y - y^3, x^2*y - y^3]
  1589. A fixed error with nonstandard base fields::
  1590. sage: R.<t>=QQ['t']
  1591. sage: K.<x,y>=R.fraction_field()['x,y']
  1592. sage: I=t*x*K
  1593. sage: I.interreduced_basis()
  1594. [x]
  1595. The interreduced basis of 0 is 0::
  1596. sage: P.<x,y,z> = GF(2)[]
  1597. sage: Ideal(P(0)).interreduced_basis()
  1598. [0]
  1599. ALGORITHM:
  1600. Uses Singular's interred command or
  1601. :func:`sage.rings.polynomial.toy_buchberger.inter_reduction``
  1602. if conversion to Singular fails.
  1603. """
  1604. from sage.rings.polynomial.multi_polynomial_ideal_libsingular import interred_libsingular
  1605. from sage.rings.polynomial.multi_polynomial_libsingular import MPolynomialRing_libsingular
  1606. from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence
  1607. R = self.ring()
  1608. if isinstance(R,MPolynomialRing_libsingular):
  1609. return PolynomialSequence(R, interred_libsingular(self), immutable=True)
  1610. else:
  1611. try:
  1612. s = self._singular_().parent()
  1613. o = s.option("get")
  1614. s.option("redTail")
  1615. ret = []
  1616. for f in self._singular_().interred():
  1617. f = R(f)
  1618. ret.append(f.lc()**(-1)*f) # lead coeffs are not reduced by interred
  1619. s.option("set",o)
  1620. except TypeError:
  1621. ret = toy_buchberger.inter_reduction(self.gens())
  1622. ret = sorted(ret, reverse=True)
  1623. ret = PolynomialSequence(R, ret, immutable=True)
  1624. return ret
  1625. @cached_method
  1626. @singular_standard_options
  1627. def basis_is_groebner(self, singular=singular_default):
  1628. r"""
  1629. Returns ``True`` if the generators of this ideal
  1630. (``self.gens()``) form a Groebner basis.
  1631. Let `I` be the set of generators of this ideal. The check is
  1632. performed by trying to lift `Syz(LM(I))` to `Syz(I)` as `I`
  1633. forms a Groebner basis if and only if for every element `S` in
  1634. `Syz(LM(I))`:
  1635. .. math::
  1636. S * G = \sum_{i=0}^{m} h_ig_i ---->_G 0.
  1637. ALGORITHM:
  1638. Uses Singular.
  1639. EXAMPLE::
  1640. sage: R.<a,b,c,d,e,f,g,h,i,j> = PolynomialRing(GF(127),10)
  1641. sage: I = sage.rings.ideal.Cyclic(R,4)
  1642. sage: I.basis_is_groebner()
  1643. False
  1644. sage: I2 = Ideal(I.groebner_basis())
  1645. sage: I2.basis_is_groebner()
  1646. True
  1647. A more complicated example::
  1648. sage: R.<U6,U5,U4,U3,U2, u6,u5,u4,u3,u2, h> = PolynomialRing(GF(7583))
  1649. sage: l = [u6 + u5 + u4 + u3 + u2 - 3791*h, \
  1650. U6 + U5 + U4 + U3 + U2 - 3791*h, \
  1651. U2*u2 - h^2, U3*u3 - h^2, U4*u4 - h^2, \
  1652. U5*u4 + U5*u3 + U4*u3 + U5*u2 + U4*u2 + U3*u2 - 3791*U5*h - 3791*U4*h - 3791*U3*h - 3791*U2*h - 2842*h^2, \
  1653. U4*u5 + U3*u5 + U2*u5 + U3*u4 + U2*u4 + U2*u3 - 3791*u5*h - 3791*u4*h - 3791*u3*h - 3791*u2*h - 2842*h^2, \
  1654. U5*u5 - h^2, U4*U2*u3 + U5*U3*u2 + U4*U3*u2 + U3^2*u2 - 3791*U5*U3*h - 3791*U4*U3*h - 3791*U3^2*h - 3791*U5*U2*h \
  1655. - 3791*U4*U2*h + U3*U2*h - 3791*U2^2*h - 3791*U4*u3*h - 3791*U4*u2*h - 3791*U3*u2*h - 2843*U5*h^2 + 1897*U4*h^2 - 946*U3*h^2 - 947*U2*h^2 + 2370*h^3, \
  1656. U3*u5*u4 + U2*u5*u4 + U3*u4^2 + U2*u4^2 + U2*u4*u3 - 3791*u5*u4*h - 3791*u4^2*h - 3791*u4*u3*h - 3791*u4*u2*h + u5*h^2 - 2842*u4*h^2, \
  1657. U2*u5*u4*u3 + U2*u4^2*u3 + U2*u4*u3^2 - 3791*u5*u4*u3*h - 3791*u4^2*u3*h - 3791*u4*u3^2*h - 3791*u4*u3*u2*h + u5*u4*h^2 + u4^2*h^2 + u5*u3*h^2 - 2842*u4*u3*h^2, \
  1658. U5^2*U4*u3 + U5*U4^2*u3 + U5^2*U4*u2 + U5*U4^2*u2 + U5^2*U3*u2 + 2*U5*U4*U3*u2 + U5*U3^2*u2 - 3791*U5^2*U4*h - 3791*U5*U4^2*h - 3791*U5^2*U3*h \
  1659. + U5*U4*U3*h - 3791*U5*U3^2*h - 3791*U5^2*U2*h + U5*U4*U2*h + U5*U3*U2*h - 3791*U5*U2^2*h - 3791*U5*U3*u2*h - 2842*U5^2*h^2 + 1897*U5*U4*h^2 \
  1660. - U4^2*h^2 - 947*U5*U3*h^2 - U4*U3*h^2 - 948*U5*U2*h^2 - U4*U2*h^2 - 1422*U5*h^3 + 3791*U4*h^3, \
  1661. u5*u4*u3*u2*h + u4^2*u3*u2*h + u4*u3^2*u2*h + u4*u3*u2^2*h + 2*u5*u4*u3*h^2 + 2*u4^2*u3*h^2 + 2*u4*u3^2*h^2 + 2*u5*u4*u2*h^2 + 2*u4^2*u2*h^2 \
  1662. + 2*u5*u3*u2*h^2 + 1899*u4*u3*u2*h^2, \
  1663. U5^2*U4*U3*u2 + U5*U4^2*U3*u2 + U5*U4*U3^2*u2 - 3791*U5^2*U4*U3*h - 3791*U5*U4^2*U3*h - 3791*U5*U4*U3^2*h - 3791*U5*U4*U3*U2*h \
  1664. + 3791*U5*U4*U3*u2*h + U5^2*U4*h^2 + U5*U4^2*h^2 + U5^2*U3*h^2 - U4^2*U3*h^2 - U5*U3^2*h^2 - U4*U3^2*h^2 - U5*U4*U2*h^2 \
  1665. - U5*U3*U2*h^2 - U4*U3*U2*h^2 + 3791*U5*U4*h^3 + 3791*U5*U3*h^3 + 3791*U4*U3*h^3, \
  1666. u4^2*u3*u2*h^2 + 1515*u5*u3^2*u2*h^2 + u4*u3^2*u2*h^2 + 1515*u5*u4*u2^2*h^2 + 1515*u5*u3*u2^2*h^2 + u4*u3*u2^2*h^2 \
  1667. + 1521*u5*u4*u3*h^3 - 3028*u4^2*u3*h^3 - 3028*u4*u3^2*h^3 + 1521*u5*u4*u2*h^3 - 3028*u4^2*u2*h^3 + 1521*u5*u3*u2*h^3 + 3420*u4*u3*u2*h^3, \
  1668. U5^2*U4*U3*U2*h + U5*U4^2*U3*U2*h + U5*U4*U3^2*U2*h + U5*U4*U3*U2^2*h + 2*U5^2*U4*U3*h^2 + 2*U5*U4^2*U3*h^2 + 2*U5*U4*U3^2*h^2 \
  1669. + 2*U5^2*U4*U2*h^2 + 2*U5*U4^2*U2*h^2 + 2*U5^2*U3*U2*h^2 - 2*U4^2*U3*U2*h^2 - 2*U5*U3^2*U2*h^2 - 2*U4*U3^2*U2*h^2 \
  1670. - 2*U5*U4*U2^2*h^2 - 2*U5*U3*U2^2*h^2 - 2*U4*U3*U2^2*h^2 - U5*U4*U3*h^3 - U5*U4*U2*h^3 - U5*U3*U2*h^3 - U4*U3*U2*h^3]
  1671. sage: Ideal(l).basis_is_groebner()
  1672. False
  1673. sage: gb = Ideal(l).groebner_basis()
  1674. sage: Ideal(gb).basis_is_groebner()
  1675. True
  1676. .. note::
  1677. From the Singular Manual for the reduce function we use in
  1678. this method: 'The result may have no meaning if the second
  1679. argument (``self``) is not a standard basis'. I (malb)
  1680. believe this refers to the mathematical fact that the
  1681. results may have no meaning if self is no standard basis,
  1682. i.e., Singular doesn't 'add' any additional 'nonsense' to
  1683. the result. So we may actually use reduce to determine if
  1684. self is a Groebner basis.
  1685. """
  1686. from sage.matrix.constructor import matrix
  1687. from sage.libs.singular.option import opt_verb_ctx
  1688. import sage.libs.singular
  1689. sing_reduce = sage.libs.singular.ff.reduce
  1690. syz = sage.libs.singular.ff.syz
  1691. R = self.ring()
  1692. if not R.base_ring().is_field():
  1693. raise ValueError("Coefficient ring must be a field for function 'basis_is_groebner'.")
  1694. try:
  1695. F = matrix(R, 1, self.ngens(), self.gens())
  1696. LTF = matrix(R, 1, self.ngens(), [f.lt() for f in self.gens()])
  1697. with opt_verb_ctx(notWarnSB=True):
  1698. M = F * matrix(R, syz(LTF)).transpose()
  1699. M.set_immutable()
  1700. M = sing_reduce(M, self)
  1701. if any(M):
  1702. return False
  1703. return True
  1704. except TypeError:
  1705. R._singular_().set_ring()
  1706. F = singular( tuple(self.gens()), "module" )
  1707. LTF = singular( [f.lt() for f in self.gens()] , "module" )
  1708. M = (F * LTF.syz()).reduce(self._singular_())
  1709. for i in range(M.ncols()):
  1710. if int(singular.eval("%s[1,%s+1]!=0"%(M.name(),i))):
  1711. return False
  1712. self._singular_().attrib('isSB',1)
  1713. return True
  1714. @require_field
  1715. @singular_standard_options
  1716. @libsingular_standard_options
  1717. def transformed_basis(self, algorithm="gwalk", other_ring=None, singular=singular_default):
  1718. """
  1719. Returns a lex or ``other_ring`` Groebner Basis for this ideal.
  1720. INPUT:
  1721. - ``algorithm`` - see below for options.
  1722. - ``other_ring`` - only valid for algorithm 'fglm', if
  1723. provided conversion will be performed to this
  1724. ring. Otherwise a lex Groebner basis will be returned.
  1725. ALGORITHMS:
  1726. fglm
  1727. FGLM algorithm. The input ideal must be given with a reduced
  1728. Groebner Basis of a zero-dimensional ideal
  1729. gwalk
  1730. Groebner Walk algorithm (*default*)
  1731. awalk1
  1732. 'first alternative' algorithm
  1733. awalk2
  1734. 'second alternative' algorithm
  1735. twalk
  1736. Tran algorithm
  1737. fwalk
  1738. Fractal Walk algorithm
  1739. EXAMPLES::
  1740. sage: R.<x,y,z> = PolynomialRing(QQ,3)
  1741. sage: I = Ideal([y^3+x^2,x^2*y+x^2, x^3-x^2, z^4-x^2-y])
  1742. sage: I = Ideal(I.groebner_basis())
  1743. sage: S.<z,x,y> = PolynomialRing(QQ,3,order='lex')
  1744. sage: J = Ideal(I.transformed_basis('fglm',S))
  1745. sage: J
  1746. Ideal (z^4 + y^3 - y, x^2 + y^3, x*y^3 - y^3, y^4 + y^3)
  1747. of Multivariate Polynomial Ring in z, x, y over Rational Field
  1748. ::
  1749. sage: R.<z,y,x>=PolynomialRing(GF(32003),3,order='lex')
  1750. sage: I=Ideal([y^3+x*y*z+y^2*z+x*z^3,3+x*y+x^2*y+y^2*z])
  1751. sage: I.transformed_basis('gwalk')
  1752. [z*y^2 + y*x^2 + y*x + 3,
  1753. z*x + 8297*y^8*x^2 + 8297*y^8*x + 3556*y^7 - 8297*y^6*x^4 + 15409*y^6*x^3 - 8297*y^6*x^2
  1754. - 8297*y^5*x^5 + 15409*y^5*x^4 - 8297*y^5*x^3 + 3556*y^5*x^2 + 3556*y^5*x + 3556*y^4*x^3
  1755. + 3556*y^4*x^2 - 10668*y^4 - 10668*y^3*x - 8297*y^2*x^9 - 1185*y^2*x^8 + 14224*y^2*x^7
  1756. - 1185*y^2*x^6 - 8297*y^2*x^5 - 14223*y*x^7 - 10666*y*x^6 - 10666*y*x^5 - 14223*y*x^4
  1757. + x^5 + 2*x^4 + x^3,
  1758. y^9 - y^7*x^2 - y^7*x - y^6*x^3 - y^6*x^2 - 3*y^6 - 3*y^5*x - y^3*x^7 - 3*y^3*x^6
  1759. - 3*y^3*x^5 - y^3*x^4 - 9*y^2*x^5 - 18*y^2*x^4 - 9*y^2*x^3 - 27*y*x^3 - 27*y*x^2 - 27*x]
  1760. ALGORITHM:
  1761. Uses Singular.
  1762. """
  1763. from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence
  1764. R = self.ring()
  1765. if self.basis_is_groebner():
  1766. I = R.ideal(self.interreduced_basis())
  1767. else:
  1768. I = R.ideal(self.groebner_basis())
  1769. if algorithm in ("gwalk","awalk1","awalk2","twalk","fwalk"):
  1770. from sage.libs.singular.function import lib
  1771. from sage.libs.singular.function import singular_function
  1772. lib("grwalk.lib")
  1773. gb = singular_function(algorithm)(I)
  1774. return PolynomialSequence(R, sorted(gb,reverse=True), immutable=True)
  1775. elif algorithm == "fglm":
  1776. # new ring
  1777. if other_ring is None:
  1778. nR = R.change_ring(order='lex')
  1779. else:
  1780. nR = other_ring
  1781. Rs = singular(R)
  1782. Is = singular(I)
  1783. Is.attrib('isSB',1)
  1784. singular(nR).set_ring()
  1785. nIs = singular.fglm(Rs,Is)
  1786. return PolynomialSequence(nR, sorted([nR(f) for f in nIs],reverse=True), immutable=True)
  1787. else:
  1788. raise TypeError, "Cannot convert basis with given algorithm"
  1789. @libsingular_standard_options
  1790. def elimination_ideal(self, variables):
  1791. r"""
  1792. Returns the elimination ideal this ideal with respect to the
  1793. variables given in ``variables``.
  1794. INPUT:
  1795. - ``variables`` - a list or tuple of variables in ``self.ring()``
  1796. EXAMPLE::
  1797. sage: R.<x,y,t,s,z> = PolynomialRing(QQ,5)
  1798. sage: I = R * [x-t,y-t^2,z-t^3,s-x+y^3]
  1799. sage: I.elimination_ideal([t,s])
  1800. Ideal (y^2 - x*z, x*y - z, x^2 - y) of Multivariate
  1801. Polynomial Ring in x, y, t, s, z over Rational Field
  1802. ALGORITHM:
  1803. Uses Singular.
  1804. .. note::
  1805. Requires computation of a Groebner basis, which can be a very
  1806. expensive operation.
  1807. """
  1808. import sage.libs.singular
  1809. eliminate = sage.libs.singular.ff.eliminate
  1810. if not isinstance(variables, (list,tuple)):
  1811. variables = (variables,)
  1812. R = self.ring()
  1813. Is = MPolynomialIdeal(R,self.groebner_basis())
  1814. return MPolynomialIdeal(R, eliminate(Is, prod(variables)) )
  1815. @libsingular_standard_options
  1816. def quotient(self, J):
  1817. r"""
  1818. Given ideals `I` = ``self`` and `J` in the same polynomial
  1819. ring `P`, return the ideal quotient of `I` by `J` consisting
  1820. of the polynomials `a` of `P` such that `\{aJ \subset I\}`.
  1821. This is also referred to as the colon ideal
  1822. (`I`:`J`).
  1823. INPUT:
  1824. - ``J`` - multivariate polynomial ideal
  1825. EXAMPLE::
  1826. sage: R.<x,y,z> = PolynomialRing(GF(181),3)
  1827. sage: I = Ideal([x^2+x*y*z,y^2-z^3*y,z^3+y^5*x*z])
  1828. sage: J = Ideal([x])
  1829. sage: Q = I.quotient(J)
  1830. sage: y*z + x in I
  1831. False
  1832. sage: x in J
  1833. True
  1834. sage: x * (y*z + x) in I
  1835. True
  1836. """
  1837. R = self.ring()
  1838. if not isinstance(J, MPolynomialIdeal):
  1839. raise TypeError, "J needs to be a multivariate polynomial ideal"
  1840. if not R is J.ring() and not R == J.ring():
  1841. raise TypeError, "base rings do not match"
  1842. import sage.libs.singular
  1843. quotient = sage.libs.singular.ff.quotient
  1844. return R.ideal(quotient(self, J))
  1845. @require_field
  1846. def variety(self, ring=None):
  1847. r"""
  1848. Return the variety of this ideal.
  1849. Given a zero-dimensional ideal `I` (== ``self``) of a
  1850. polynomial ring `P` whose order is lexicographic, return the
  1851. variety of `I` as a list of dictionaries with ``(variable, value)``
  1852. pairs. By default, the variety of the ideal over its
  1853. coefficient field `K` is returned; ``ring`` can be specified
  1854. to find the variety over a different ring.
  1855. These dictionaries have cardinality equal to the number of
  1856. variables in `P` and represent assignments of values to these
  1857. variables such that all polynomials in `I` vanish.
  1858. If ``ring`` is specified, then a triangular decomposition of
  1859. ``self`` is found over the original coefficient field `K`;
  1860. then the triangular systems are solved using root-finding over
  1861. ``ring``. This is particularly useful when `K` is ``QQ`` (to
  1862. allow fast symbolic computation of the triangular
  1863. decomposition) and ``ring`` is ``RR``, ``AA``, ``CC``, or
  1864. ``QQbar`` (to compute the whole real or complex variety of the
  1865. ideal).
  1866. Note that with ``ring=RR`` or ``CC``, computation is done
  1867. numerically and potentially inaccurately; in particular, the
  1868. number of points in the real variety may be miscomputed. With
  1869. ``ring=AA`` or ``QQbar``, computation is done exactly
  1870. (which may be much slower, of course).
  1871. INPUT:
  1872. - ``ring`` - return roots in the ``ring`` instead of the base
  1873. ring of this ideal (default: ``None``)
  1874. - ``proof`` - return a provably correct result (default: ``True``)
  1875. EXAMPLE::
  1876. sage: K.<w> = GF(27) # this example is from the MAGMA handbook
  1877. sage: P.<x, y> = PolynomialRing(K, 2, order='lex')
  1878. sage: I = Ideal([ x^8 + y + 2, y^6 + x*y^5 + x^2 ])
  1879. sage: I = Ideal(I.groebner_basis()); I
  1880. Ideal (x - y^47 - y^45 + y^44 - y^43 + y^41 - y^39 - y^38
  1881. - y^37 - y^36 + y^35 - y^34 - y^33 + y^32 - y^31 + y^30 +
  1882. y^28 + y^27 + y^26 + y^25 - y^23 + y^22 + y^21 - y^19 -
  1883. y^18 - y^16 + y^15 + y^13 + y^12 - y^10 + y^9 + y^8 + y^7
  1884. - y^6 + y^4 + y^3 + y^2 + y - 1, y^48 + y^41 - y^40 + y^37
  1885. - y^36 - y^33 + y^32 - y^29 + y^28 - y^25 + y^24 + y^2 + y
  1886. + 1) of Multivariate Polynomial Ring in x, y over Finite
  1887. Field in w of size 3^3
  1888. sage: V = I.variety(); V
  1889. [{y: w^2 + 2, x: 2*w}, {y: w^2 + w, x: 2*w + 1}, {y: w^2 + 2*w, x: 2*w + 2}]
  1890. sage: [f.subs(v) for f in I.gens() for v in V] # check that all polynomials vanish
  1891. [0, 0, 0, 0, 0, 0]
  1892. sage: [I.subs(v).is_zero() for v in V] # same test, but nicer syntax
  1893. [True, True, True]
  1894. However, we only account for solutions in the ground field and not
  1895. in the algebraic closure::
  1896. sage: I.vector_space_dimension()
  1897. 48
  1898. Here we compute the points of intersection of a hyperbola and a
  1899. circle, in several fields::
  1900. sage: K.<x, y> = PolynomialRing(QQ, 2, order='lex')
  1901. sage: I = Ideal([ x*y - 1, (x-2)^2 + (y-1)^2 - 1])
  1902. sage: I = Ideal(I.groebner_basis()); I
  1903. Ideal (x + y^3 - 2*y^2 + 4*y - 4, y^4 - 2*y^3 + 4*y^2 - 4*y + 1)
  1904. of Multivariate Polynomial Ring in x, y over Rational Field
  1905. These two curves have one rational intersection::
  1906. sage: I.variety()
  1907. [{y: 1, x: 1}]
  1908. There are two real intersections::
  1909. sage: I.variety(ring=RR)
  1910. [{y: 0.361103080528647, x: 2.76929235423863},
  1911. {y: 1.00000000000000, x: 1.00000000000000}]
  1912. sage: I.variety(ring=AA)
  1913. [{x: 2.769292354238632?, y: 0.3611030805286474?},
  1914. {x: 1, y: 1}]
  1915. and a total of four intersections::
  1916. sage: I.variety(ring=CC)
  1917. [{y: 0.31944845973567... - 1.6331702409152...*I,
  1918. x: 0.11535382288068... + 0.58974280502220...*I},
  1919. {y: 0.31944845973567... + 1.6331702409152...*I,
  1920. x: 0.11535382288068... - 0.58974280502220...*I},
  1921. {y: 0.36110308052864..., x: 2.7692923542386...},
  1922. {y: 1.00000000000000, x: 1.00000000000000}]
  1923. sage: I.variety(ring=QQbar)
  1924. [{y: 0.3194484597356763? - 1.633170240915238?*I,
  1925. x: 0.11535382288068429? + 0.5897428050222055?*I},
  1926. {y: 0.3194484597356763? + 1.633170240915238?*I,
  1927. x: 0.11535382288068429? - 0.5897428050222055?*I},
  1928. {y: 0.3611030805286474?, x: 2.769292354238632?},
  1929. {y: 1, x: 1}]
  1930. Computation over floating point numbers may compute only a partial solution,
  1931. or even none at all. Notice that x values are missing from the following variety::
  1932. sage: R.<x,y> = CC[]
  1933. sage: I = ideal([x^2+y^2-1,x*y-1])
  1934. sage: I.variety()
  1935. verbose 0 (...: multi_polynomial_ideal.py, variety) Warning: computations in the complex field are inexact; variety may be computed partially or incorrectly.
  1936. verbose 0 (...: multi_polynomial_ideal.py, variety) Warning: falling back to very slow toy implementation.
  1937. [{y: -0.86602540378443... - 0.500000000000000*I},
  1938. {y: -0.86602540378443... + 0.500000000000000*I},
  1939. {y: 0.86602540378443... - 0.500000000000000*I},
  1940. {y: 0.86602540378443... + 0.500000000000000*I}]
  1941. This is due to precision error,
  1942. which causes the computation of an intermediate Groebner basis to fail.
  1943. If the ground field's characteristic is too large for
  1944. Singular, we resort to a toy implementation::
  1945. sage: R.<x,y> = PolynomialRing(GF(2147483659),order='lex')
  1946. sage: I=ideal([x^3-2*y^2,3*x+y^4])
  1947. sage: I.variety()
  1948. verbose 0 (...: multi_polynomial_ideal.py, groebner_basis) Warning: falling back to very slow toy implementation.
  1949. verbose 0 (...: multi_polynomial_ideal.py, dimension) Warning: falling back to very slow toy implementation.
  1950. verbose 0 (...: multi_polynomial_ideal.py, variety) Warning: falling back to very slow toy implementation.
  1951. [{y: 0, x: 0}]
  1952. TESTS::
  1953. sage: K.<w> = GF(27)
  1954. sage: P.<x, y> = PolynomialRing(K, 2, order='lex')
  1955. sage: I = Ideal([ x^8 + y + 2, y^6 + x*y^5 + x^2 ])
  1956. Testing the robustness of the Singular interface::
  1957. sage: T = I.triangular_decomposition('singular:triangLfak')
  1958. sage: I.variety()
  1959. [{y: w^2 + 2, x: 2*w}, {y: w^2 + w, x: 2*w + 1}, {y: w^2 + 2*w, x: 2*w + 2}]
  1960. Testing that a bug is indeed fixed ::
  1961. sage: R = PolynomialRing(GF(2), 30, ['x%d'%(i+1) for i in range(30)], order='lex')
  1962. sage: R.inject_variables()
  1963. Defining...
  1964. sage: I = Ideal([x1 + 1, x2, x3 + 1, x5*x10 + x10 + x18, x5*x11 + x11, \
  1965. x5*x18, x6, x7 + 1, x9, x10*x11 + x10 + x18, x10*x18 + x18, \
  1966. x11*x18, x12, x13, x14, x15, x16 + 1, x17 + x18 + 1, x19, x20, \
  1967. x21 + 1, x22, x23, x24, x25 + 1, x28 + 1, x29 + 1, x30, x8, \
  1968. x26, x1^2 + x1, x2^2 + x2, x3^2 + x3, x4^2 + x4, x5^2 + x5, \
  1969. x6^2 + x6, x7^2 + x7, x8^2 + x8, x9^2 + x9, x10^2 + x10, \
  1970. x11^2 + x11, x12^2 + x12, x13^2 + x13, x14^2 + x14, x15^2 + x15, \
  1971. x16^2 + x16, x17^2 + x17, x18^2 + x18, x19^2 + x19, x20^2 + x20, \
  1972. x21^2 + x21, x22^2 + x22, x23^2 + x23, x24^2 + x24, x25^2 + x25, \
  1973. x26^2 + x26, x27^2 + x27, x28^2 + x28, x29^2 + x29, x30^2 + x30])
  1974. sage: I.basis_is_groebner()
  1975. True
  1976. sage: for V in I.variety(): print V # long time (6s on sage.math, 2011)
  1977. {x14: 0, x24: 0, x16: 1, x1: 1, x3: 1, x2: 0, x5: 0, x4: 0, x19: 0, x18: 0, x7: 1, x6: 0, x10: 0, x30: 0, x28: 1, x29: 1, x13: 0, x27: 0, x11: 0, x25: 1, x9: 0, x8: 0, x20: 0, x17: 1, x23: 0, x26: 0, x15: 0, x21: 1, x12: 0, x22: 0}
  1978. {x14: 0, x24: 0, x16: 1, x1: 1, x3: 1, x2: 0, x5: 0, x4: 1, x19: 0, x18: 0, x7: 1, x6: 0, x10: 0, x30: 0, x28: 1, x29: 1, x13: 0, x27: 0, x11: 0, x25: 1, x9: 0, x8: 0, x20: 0, x17: 1, x23: 0, x26: 0, x15: 0, x21: 1, x12: 0, x22: 0}
  1979. {x14: 0, x24: 0, x16: 1, x1: 1, x3: 1, x2: 0, x5: 1, x4: 0, x19: 0, x18: 0, x7: 1, x6: 0, x10: 0, x30: 0, x28: 1, x29: 1, x13: 0, x27: 0, x11: 0, x25: 1, x9: 0, x8: 0, x20: 0, x17: 1, x23: 0, x26: 0, x15: 0, x21: 1, x12: 0, x22: 0}
  1980. {x14: 0, x24: 0, x16: 1, x1: 1, x3: 1, x2: 0, x5: 1, x4: 1, x19: 0, x18: 0, x7: 1, x6: 0, x10: 0, x30: 0, x28: 1, x29: 1, x13: 0, x27: 0, x11: 0, x25: 1, x9: 0, x8: 0, x20: 0, x17: 1, x23: 0, x26: 0, x15: 0, x21: 1, x12: 0, x22: 0}
  1981. {x14: 0, x24: 0, x16: 1, x1: 1, x3: 1, x2: 0, x5: 1, x4: 0, x19: 0, x18: 0, x7: 1, x6: 0, x10: 0, x30: 0, x28: 1, x29: 1, x13: 0, x27: 0, x11: 1, x25: 1, x9: 0, x8: 0, x20: 0, x17: 1, x23: 0, x26: 0, x15: 0, x21: 1, x12: 0, x22: 0}
  1982. {x14: 0, x24: 0, x16: 1, x1: 1, x3: 1, x2: 0, x5: 1, x4: 1, x19: 0, x18: 0, x7: 1, x6: 0, x10: 0, x30: 0, x28: 1, x29: 1, x13: 0, x27: 0, x11: 1, x25: 1, x9: 0, x8: 0, x20: 0, x17: 1, x23: 0, x26: 0, x15: 0, x21: 1, x12: 0, x22: 0}
  1983. {x14: 0, x24: 0, x16: 1, x1: 1, x3: 1, x2: 0, x5: 1, x4: 0, x19: 0, x18: 0, x7: 1, x6: 0, x10: 1, x30: 0, x28: 1, x29: 1, x13: 0, x27: 0, x11: 1, x25: 1, x9: 0, x8: 0, x20: 0, x17: 1, x23: 0, x26: 0, x15: 0, x21: 1, x12: 0, x22: 0}
  1984. {x14: 0, x24: 0, x16: 1, x1: 1, x3: 1, x2: 0, x5: 1, x4: 1, x19: 0, x18: 0, x7: 1, x6: 0, x10: 1, x30: 0, x28: 1, x29: 1, x13: 0, x27: 0, x11: 1, x25: 1, x9: 0, x8: 0, x20: 0, x17: 1, x23: 0, x26: 0, x15: 0, x21: 1, x12: 0, x22: 0}
  1985. {x14: 0, x24: 0, x16: 1, x1: 1, x3: 1, x2: 0, x5: 0, x4: 0, x19: 0, x18: 1, x7: 1, x6: 0, x10: 1, x30: 0, x28: 1, x29: 1, x13: 0, x27: 0, x11: 0, x25: 1, x9: 0, x8: 0, x20: 0, x17: 0, x23: 0, x26: 0, x15: 0, x21: 1, x12: 0, x22: 0}
  1986. {x14: 0, x24: 0, x16: 1, x1: 1, x3: 1, x2: 0, x5: 0, x4: 1, x19: 0, x18: 1, x7: 1, x6: 0, x10: 1, x30: 0, x28: 1, x29: 1, x13: 0, x27: 0, x11: 0, x25: 1, x9: 0, x8: 0, x20: 0, x17: 0, x23: 0, x26: 0, x15: 0, x21: 1, x12: 0, x22: 0}
  1987. {x14: 0, x24: 0, x16: 1, x1: 1, x3: 1, x2: 0, x5: 0, x4: 0, x19: 0, x18: 0, x7: 1, x6: 0, x10: 0, x30: 0, x28: 1, x29: 1, x13: 0, x27: 1, x11: 0, x25: 1, x9: 0, x8: 0, x20: 0, x17: 1, x23: 0, x26: 0, x15: 0, x21: 1, x12: 0, x22: 0}
  1988. {x14: 0, x24: 0, x16: 1, x1: 1, x3: 1, x2: 0, x5: 0, x4: 1, x19: 0, x18: 0, x7: 1, x6: 0, x10: 0, x30: 0, x28: 1, x29: 1, x13: 0, x27: 1, x11: 0, x25: 1, x9: 0, x8: 0, x20: 0, x17: 1, x23: 0, x26: 0, x15: 0, x21: 1, x12: 0, x22: 0}
  1989. {x14: 0, x24: 0, x16: 1, x1: 1, x3: 1, x2: 0, x5: 1, x4: 0, x19: 0, x18: 0, x7: 1, x6: 0, x10: 0, x30: 0, x28: 1, x29: 1, x13: 0, x27: 1, x11: 0, x25: 1, x9: 0, x8: 0, x20: 0, x17: 1, x23: 0, x26: 0, x15: 0, x21: 1, x12: 0, x22: 0}
  1990. {x14: 0, x24: 0, x16: 1, x1: 1, x3: 1, x2: 0, x5: 1, x4: 1, x19: 0, x18: 0, x7: 1, x6: 0, x10: 0, x30: 0, x28: 1, x29: 1, x13: 0, x27: 1, x11: 0, x25: 1, x9: 0, x8: 0, x20: 0, x17: 1, x23: 0, x26: 0, x15: 0, x21: 1, x12: 0, x22: 0}
  1991. {x14: 0, x24: 0, x16: 1, x1: 1, x3: 1, x2: 0, x5: 1, x4: 0, x19: 0, x18: 0, x7: 1, x6: 0, x10: 0, x30: 0, x28: 1, x29: 1, x13: 0, x27: 1, x11: 1, x25: 1, x9: 0, x8: 0, x20: 0, x17: 1, x23: 0, x26: 0, x15: 0, x21: 1, x12: 0, x22: 0}
  1992. {x14: 0, x24: 0, x16: 1, x1: 1, x3: 1, x2: 0, x5: 1, x4: 1, x19: 0, x18: 0, x7: 1, x6: 0, x10: 0, x30: 0, x28: 1, x29: 1, x13: 0, x27: 1, x11: 1, x25: 1, x9: 0, x8: 0, x20: 0, x17: 1, x23: 0, x26: 0, x15: 0, x21: 1, x12: 0, x22: 0}
  1993. {x14: 0, x24: 0, x16: 1, x1: 1, x3: 1, x2: 0, x5: 1, x4: 0, x19: 0, x18: 0, x7: 1, x6: 0, x10: 1, x30: 0, x28: 1, x29: 1, x13: 0, x27: 1, x11: 1, x25: 1, x9: 0, x8: 0, x20: 0, x17: 1, x23: 0, x26: 0, x15: 0, x21: 1, x12: 0, x22: 0}
  1994. {x14: 0, x24: 0, x16: 1, x1: 1, x3: 1, x2: 0, x5: 1, x4: 1, x19: 0, x18: 0, x7: 1, x6: 0, x10: 1, x30: 0, x28: 1, x29: 1, x13: 0, x27: 1, x11: 1, x25: 1, x9: 0, x8: 0, x20: 0, x17: 1, x23: 0, x26: 0, x15: 0, x21: 1, x12: 0, x22: 0}
  1995. {x14: 0, x24: 0, x16: 1, x1: 1, x3: 1, x2: 0, x5: 0, x4: 0, x19: 0, x18: 1, x7: 1, x6: 0, x10: 1, x30: 0, x28: 1, x29: 1, x13: 0, x27: 1, x11: 0, x25: 1, x9: 0, x8: 0, x20: 0, x17: 0, x23: 0, x26: 0, x15: 0, x21: 1, x12: 0, x22: 0}
  1996. {x14: 0, x24: 0, x16: 1, x1: 1, x3: 1, x2: 0, x5: 0, x4: 1, x19: 0, x18: 1, x7: 1, x6: 0, x10: 1, x30: 0, x28: 1, x29: 1, x13: 0, x27: 1, x11: 0, x25: 1, x9: 0, x8: 0, x20: 0, x17: 0, x23: 0, x26: 0, x15: 0, x21: 1, x12: 0, x22: 0}
  1997. Check that the issue at :trac:`7425` is fixed::
  1998. sage: R.<x, y, z> = QQ[]
  1999. sage: I = R.ideal([x^2-y^3*z, x+y*z])
  2000. sage: I.dimension()
  2001. 1
  2002. sage: I.variety()
  2003. Traceback (most recent call last):
  2004. ...
  2005. ValueError: The dimension of the ideal is 1, but it should be 0
  2006. Check that the issue at :trac:`7425` is fixed::
  2007. sage: S.<t>=PolynomialRing(QQ)
  2008. sage: F.<q>=QQ.extension(t^4+1)
  2009. sage: R.<x,y>=PolynomialRing(F)
  2010. sage: I=R.ideal(x,y^4+1)
  2011. sage: I.variety()
  2012. [...{y: -q^3, x: 0}...]
  2013. Check that computing the variety of the ``[1]`` ideal is allowed (:trac:`13977`)::
  2014. sage: R.<x,y> = QQ[]
  2015. sage: I = R.ideal(1)
  2016. sage: I.variety()
  2017. []
  2018. ALGORITHM:
  2019. Uses triangular decomposition.
  2020. """
  2021. def _variety(T, V, v=None):
  2022. """
  2023. Return variety ``V`` for one triangular set of
  2024. polynomials ``T``.
  2025. """
  2026. if v is None: v = {}
  2027. found = False
  2028. for f in T:
  2029. if f.is_univariate() and not f.is_constant():
  2030. T.remove(f); found = True; break
  2031. if found is False:
  2032. V.append(v)
  2033. return V
  2034. variable = f.variable(0)
  2035. roots = f.univariate_polynomial().roots(ring=ring)
  2036. for root,_ in roots:
  2037. vbar = v.copy()
  2038. vbar[variable] = root
  2039. Tbar = [ f.subs({variable:root}) for f in T ]
  2040. _variety(Tbar,V,vbar)
  2041. return V
  2042. d = self.dimension()
  2043. if d > 0:
  2044. raise ValueError, "The dimension of the ideal is %s, but it should be 0"%d
  2045. if d == -1:
  2046. return []
  2047. import sage.rings.complex_field as CCmod
  2048. if isinstance(self.base_ring(), CCmod.ComplexField_class):
  2049. verbose("Warning: computations in the complex field are inexact; variety may be computed partially or incorrectly.", level=0)
  2050. P = self.ring()
  2051. if ring is not None: P = P.change_ring(ring)
  2052. try:
  2053. TI = self.triangular_decomposition('singular:triangLfak')
  2054. T = [list(each.gens()) for each in TI]
  2055. except TypeError, msg: # conversion to Singular not supported
  2056. if self.ring().term_order().is_global():
  2057. verbose("Warning: falling back to very slow toy implementation.", level=0)
  2058. T = toy_variety.triangular_factorization(self.groebner_basis())
  2059. else:
  2060. raise TypeError, "Local/unknown orderings not supported by 'toy_buchberger' implementation."
  2061. V = []
  2062. for t in T:
  2063. Vbar = _variety(list(t),[])
  2064. #Vbar = _variety(list(t.gens()),[])
  2065. for v in Vbar:
  2066. V.append(dict([(P(var),val) for var,val in v.iteritems()]))
  2067. V.sort()
  2068. return Sequence(V)
  2069. @require_field
  2070. def hilbert_polynomial(self):
  2071. r"""
  2072. Return the Hilbert polynomial of this ideal.
  2073. Let `I` = ``self`` be a homogeneous ideal and
  2074. `R` = ``self.ring()`` be a graded commutative
  2075. algebra (`R = \oplus R_d`) over a field `K`. The
  2076. Hilbert polynomial is the unique polynomial `HP(t)` with
  2077. rational coefficients such that `HP(d) = dim_K R_d` for
  2078. all but finitely many positive integers `d`.
  2079. EXAMPLE::
  2080. sage: P.<x,y,z> = PolynomialRing(QQ)
  2081. sage: I = Ideal([x^3*y^2 + 3*x^2*y^2*z + y^3*z^2 + z^5])
  2082. sage: I.hilbert_polynomial()
  2083. 5*t - 5
  2084. """
  2085. if not self.is_homogeneous():
  2086. raise TypeError("Ideal must be homogeneous.")
  2087. import sage.libs.singular
  2088. hilbPoly = sage.libs.singular.ff.poly__lib.hilbPoly
  2089. hp = hilbPoly(self)
  2090. t = ZZ['t'].gen()
  2091. fp = ZZ(len(hp)-1).factorial()
  2092. return sum([ZZ(hp[i])*t**i for i in xrange(len(hp))])/fp
  2093. @require_field
  2094. def hilbert_series(self, singular=singular_default):
  2095. r"""
  2096. Return the Hilbert series of this ideal.
  2097. Let `I` = ``self`` be a homogeneous ideal and
  2098. `R` = ``self.ring()`` be a graded commutative
  2099. algebra (`R = \oplus R_d`) over a field
  2100. `K`. Then the Hilbert function is defined as
  2101. `H(d) = dim_K R_d` and the Hilbert series of `I`
  2102. is defined as the formal power series
  2103. `HS(t) = \sum_0^{\infty} H(d) t^d`.
  2104. This power series can be expressed as
  2105. `HS(t) = Q(t)/(1-t)^n` where `Q(t)` is a polynomial
  2106. over `Z` and `n` the number of variables in
  2107. `R`. This method returns `Q(t)/(1-t)^n`.
  2108. EXAMPLE::
  2109. sage: P.<x,y,z> = PolynomialRing(QQ)
  2110. sage: I = Ideal([x^3*y^2 + 3*x^2*y^2*z + y^3*z^2 + z^5])
  2111. sage: I.hilbert_series()
  2112. (-t^4 - t^3 - t^2 - t - 1)/(-t^2 + 2*t - 1)
  2113. """
  2114. if not self.is_homogeneous():
  2115. raise TypeError("Ideal must be homogeneous.")
  2116. import sage.libs.singular
  2117. hilb = sage.libs.singular.ff.hilb
  2118. gb = self.groebner_basis()
  2119. t = ZZ['t'].gen()
  2120. n = self.ring().ngens()
  2121. gb = MPolynomialIdeal(self.ring(),gb)
  2122. hs = hilb(gb,1, attributes={gb:{'isSB':1}})
  2123. return sum([ZZ(hs[i])*t**i for i in xrange(len(hs)-1)])/(1-t)**n
  2124. @require_field
  2125. def _normal_basis_libsingular(self):
  2126. r"""
  2127. Returns the normal basis for a given groebner basis. It will use
  2128. the Groebner Basis as computed by
  2129. ``MPolynomialIdeal._groebner_basis_libsingular()``.
  2130. EXAMPLES::
  2131. sage: R.<x,y,z> = PolynomialRing(QQ)
  2132. sage: I = R.ideal(x^2-2*x*z+5, x*y^2+y*z+1, 3*y^2-8*x*z)
  2133. sage: I.normal_basis() #indirect doctest
  2134. [z^2, y*z, x*z, z, x*y, y, x, 1]
  2135. """
  2136. from sage.rings.polynomial.multi_polynomial_ideal_libsingular import kbase_libsingular
  2137. from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence
  2138. gb = self._groebner_basis_libsingular()
  2139. return PolynomialSequence(self.ring(), kbase_libsingular(self.ring().ideal(gb)), immutable=True)
  2140. @require_field
  2141. def normal_basis(self, algorithm='libsingular', singular=singular_default):
  2142. """
  2143. Returns a vector space basis (consisting of monomials) of the
  2144. quotient ring by the ideal, resp. of a free module by the module,
  2145. in case it is finite dimensional and if the input is a standard
  2146. basis with respect to the ring ordering.
  2147. INPUT:
  2148. ``algorithm`` - defaults to use libsingular, if it is anything
  2149. else we will use the ``kbase()`` command
  2150. EXAMPLES::
  2151. sage: R.<x,y,z> = PolynomialRing(QQ)
  2152. sage: I = R.ideal(x^2+y^2+z^2-4, x^2+2*y^2-5, x*z-1)
  2153. sage: I.normal_basis()
  2154. [y*z^2, z^2, y*z, z, x*y, y, x, 1]
  2155. sage: I.normal_basis(algorithm='singular')
  2156. [y*z^2, z^2, y*z, z, x*y, y, x, 1]
  2157. """
  2158. from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence
  2159. if algorithm == 'libsingular':
  2160. return self._normal_basis_libsingular()
  2161. else:
  2162. gb = self.groebner_basis()
  2163. R = self.ring()
  2164. return PolynomialSequence(R, [R(f) for f in singular.kbase(R.ideal(gb))], immutable=True)
  2165. class MPolynomialIdeal_macaulay2_repr:
  2166. """
  2167. An ideal in a multivariate polynomial ring, which has an underlying
  2168. Macaulay2 ring associated to it.
  2169. EXAMPLES::
  2170. sage: R.<x,y,z,w> = PolynomialRing(ZZ, 4)
  2171. sage: I = ideal(x*y-z^2, y^2-w^2)
  2172. sage: I
  2173. Ideal (x*y - z^2, y^2 - w^2) of Multivariate Polynomial Ring in x, y, z, w over Integer Ring
  2174. """
  2175. def _macaulay2_(self, macaulay2=None):
  2176. """
  2177. Return Macaulay2 ideal corresponding to this ideal.
  2178. EXAMPLES::
  2179. sage: R.<x,y,z,w> = PolynomialRing(ZZ, 4)
  2180. sage: I = ideal(x*y-z^2, y^2-w^2) #indirect doctest
  2181. sage: macaulay2(I) # optional - macaulay2
  2182. Ideal (x*y - z^2, y^2 - w^2) of Multivariate Polynomial Ring in x, y, z, w over Integer Ring
  2183. """
  2184. if macaulay2 is None: macaulay2 = macaulay2_default
  2185. try:
  2186. I = self.__macaulay2[macaulay2]
  2187. I._check_valid()
  2188. return I
  2189. except KeyError:
  2190. pass
  2191. except AttributeError:
  2192. self.__macaulay2 = {}
  2193. except ValueError:
  2194. pass
  2195. R = self.ring()
  2196. R._macaulay2_set_ring(macaulay2)
  2197. gens = [repr(x) for x in self.gens()]
  2198. if len(gens) == 0:
  2199. gens = ['0']
  2200. z = macaulay2.ideal(gens)
  2201. self.__macaulay2[macaulay2] = z
  2202. return z
  2203. def _groebner_basis_macaulay2(self):
  2204. r"""
  2205. Return the Groebner basis for this ideal, computed using
  2206. Macaulay2.
  2207. ALGORITHM:
  2208. Computed using Macaulay2. A big advantage of Macaulay2 is that
  2209. it can compute the Groebner basis of ideals in polynomial
  2210. rings over the integers.
  2211. EXAMPLE::
  2212. sage: R.<x,y,z,w> = PolynomialRing(ZZ, 4)
  2213. sage: I = ideal(x*y-z^2, y^2-w^2)
  2214. sage: I.groebner_basis('macaulay2') # indirect doctest; optional - macaulay2
  2215. [z^4 - x^2*w^2, y*z^2 - x*w^2, x*y - z^2, y^2 - w^2]
  2216. The Groebner basis can be used to compute in
  2217. `\ZZ/n\ZZ[x,\ldots]`.
  2218. ::
  2219. sage: R.<x,y,z> = ZZ[]
  2220. sage: I = ideal([y^2*z - x^3 - 19*x*z, y^2, 19^2])
  2221. sage: I.groebner_basis('macaulay2') # optional - macaulay2
  2222. [x^3 + 19*x*z, y^2, 361]
  2223. sage: I = ideal([y^2*z - x^3 - 19^2*x*z, y^2, 19^2])
  2224. sage: I.groebner_basis('macaulay2') # optional - macaulay2
  2225. [x^3, y^2, 361]
  2226. """
  2227. from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence
  2228. I = self._macaulay2_()
  2229. G = str(I.gb().generators().external_string()).replace('\n','')
  2230. i = G.rfind('{{')
  2231. j = G.rfind('}}')
  2232. G = G[i+2:j].split(',')
  2233. R = self.ring()
  2234. B = [R(f) for f in G]
  2235. B = PolynomialSequence(self.ring(), B, immutable=True)
  2236. return B
  2237. def _reduce_using_macaulay2(self, f):
  2238. """
  2239. EXAMPLES::
  2240. sage: R.<x,y,z,w> = PolynomialRing(ZZ, 4)
  2241. sage: I = ideal(x*y-z^2, y^2-w^2)
  2242. sage: I._reduce_using_macaulay2(x*y-z^2 + y^2) # optional - macaulay2
  2243. w^2
  2244. """
  2245. I = self._macaulay2_()
  2246. M2 = I.parent()
  2247. k = M2('(%r) %% %s'%(f, I.name()))
  2248. R = self.ring()
  2249. return R(k)
  2250. class NCPolynomialIdeal(MPolynomialIdeal_singular_repr, Ideal_nc):
  2251. def __init__(self, ring, gens, coerce=True, side = "left"):
  2252. r"""
  2253. Creates a non-commutative polynomial ideal.
  2254. INPUT:
  2255. - ``ring`` - the g-algebra to which this ideal belongs
  2256. - ``gens`` - the generators of this ideal
  2257. - ``coerce`` (optional - default True) - generators are
  2258. coerced into the ring before creating the ideal
  2259. - ``side`` - optional string, either "left" (default)
  2260. or "twosided"; defines whether this ideal is left
  2261. of two-sided.
  2262. EXAMPLES::
  2263. sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
  2264. sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
  2265. sage: H.inject_variables()
  2266. Defining x, y, z
  2267. sage: I = H.ideal([y^2, x^2, z^2-H.one_element()],coerce=False) # indirect doctest
  2268. sage: I
  2269. Left Ideal (y^2, x^2, z^2 - 1) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: x*y - z, z*y: y*z - 2*y, z*x: x*z + 2*x}
  2270. sage: H.ideal([y^2, x^2, z^2-H.one_element()], side="twosided")
  2271. Twosided Ideal (y^2, x^2, z^2 - 1) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: x*y - z, z*y: y*z - 2*y, z*x: x*z + 2*x}
  2272. sage: H.ideal([y^2, x^2, z^2-H.one_element()], side="right")
  2273. Traceback (most recent call last):
  2274. ...
  2275. ValueError: Only left and two-sided ideals are allowed.
  2276. """
  2277. if side == "right":
  2278. raise ValueError, "Only left and two-sided ideals are allowed."
  2279. Ideal_nc.__init__(self, ring, gens, coerce=coerce, side=side)
  2280. def __call_singular(self, cmd, arg = None):
  2281. """
  2282. Internal function for calling a Singular function.
  2283. INPUT:
  2284. - ``cmd`` - string, representing a Singular function
  2285. - ``arg`` (Default: None) - arguments for which cmd is called
  2286. OUTPUT:
  2287. - result of the Singular function call
  2288. EXAMPLES::
  2289. sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
  2290. sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
  2291. sage: H.inject_variables()
  2292. Defining x, y, z
  2293. sage: id = H.ideal(x + y, y + z)
  2294. sage: id.std() # indirect doctest
  2295. Left Ideal (z, y, x) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: x*y - z, z*y: y*z - 2*y, z*x: x*z + 2*x}
  2296. """
  2297. from sage.libs.singular.function import singular_function
  2298. fun = singular_function(cmd)
  2299. if arg is None:
  2300. return fun(self, ring=self.ring())
  2301. return fun(self, arg, ring=self.ring())
  2302. @cached_method
  2303. def std(self):
  2304. r"""
  2305. Computes a GB of the ideal. It is two-sided if and only if the ideal is two-sided.
  2306. EXAMPLES::
  2307. sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
  2308. sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
  2309. sage: H.inject_variables()
  2310. Defining x, y, z
  2311. sage: I = H.ideal([y^2, x^2, z^2-H.one_element()],coerce=False)
  2312. sage: I.std()
  2313. Left Ideal (z^2 - 1, y*z - y, x*z + x, y^2, 2*x*y - z - 1, x^2) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: x*y - z, z*y: y*z - 2*y, z*x: x*z + 2*x}
  2314. If the ideal is a left ideal, then std returns a left
  2315. Groebner basis. But if it is a two-sided ideal, then
  2316. the output of std and :meth:`twostd` coincide::
  2317. sage: JL = H.ideal([x^3, y^3, z^3 - 4*z])
  2318. sage: JL
  2319. Left Ideal (x^3, y^3, z^3 - 4*z) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: x*y - z, z*y: y*z - 2*y, z*x: x*z + 2*x}
  2320. sage: JL.std()
  2321. Left Ideal (z^3 - 4*z, y*z^2 - 2*y*z, x*z^2 + 2*x*z, 2*x*y*z - z^2 - 2*z, y^3, x^3) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: x*y - z, z*y: y*z - 2*y, z*x: x*z + 2*x}
  2322. sage: JT = H.ideal([x^3, y^3, z^3 - 4*z], side='twosided')
  2323. sage: JT
  2324. Twosided Ideal (x^3, y^3, z^3 - 4*z) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: x*y - z, z*y: y*z - 2*y, z*x: x*z + 2*x}
  2325. sage: JT.std()
  2326. Twosided Ideal (z^3 - 4*z, y*z^2 - 2*y*z, x*z^2 + 2*x*z, y^2*z - 2*y^2, 2*x*y*z - z^2 - 2*z, x^2*z + 2*x^2, y^3, x*y^2 - y*z, x^2*y - x*z - 2*x, x^3) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: x*y - z, z*y: y*z - 2*y, z*x: x*z + 2*x}
  2327. sage: JT.std() == JL.twostd()
  2328. True
  2329. ALGORITHM: Uses Singular's std command
  2330. """
  2331. if self.side() == 'twosided':
  2332. return self.twostd()
  2333. return self.ring().ideal( self.__call_singular('std'), side=self.side())
  2334. # return self.__call_singular('std')
  2335. @cached_method
  2336. def twostd(self):
  2337. r"""
  2338. Computes a two-sided GB of the ideal (even if it is a left ideal).
  2339. EXAMPLES::
  2340. sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
  2341. sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
  2342. sage: H.inject_variables()
  2343. Defining x, y, z
  2344. sage: I = H.ideal([y^2, x^2, z^2-H.one_element()],coerce=False)
  2345. sage: I.twostd()
  2346. Twosided Ideal (z^2 - 1, y*z - y, x*z + x, y^2, 2*x*y - z - 1, x^2) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field...
  2347. ALGORITHM: Uses Singular's twostd command
  2348. """
  2349. return self.ring().ideal( self.__call_singular('twostd'), side='twosided')
  2350. # return self.__call_singular('twostd')
  2351. # def syz(self):
  2352. # return self.__call_singular('syz')
  2353. @cached_method
  2354. def _groebner_strategy(self):
  2355. """
  2356. Return Singular's Groebner Strategy object for the Groebner
  2357. basis of this ideal which implements some optimized functions.
  2358. EXAMPLE::
  2359. sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
  2360. sage: H.<x,y,z> = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
  2361. sage: I = H.ideal([y^2, x^2, z^2-H.one_element()],coerce=False)
  2362. sage: I._groebner_strategy()
  2363. Groebner Strategy for ideal generated by 6 elements over
  2364. Noncommutative Multivariate Polynomial Ring in x, y, z over Rational
  2365. Field, nc-relations: {y*x: x*y - z, z*y: y*z - 2*y, z*x: x*z + 2*x}
  2366. .. note::
  2367. This function is mainly used internally.
  2368. """
  2369. from sage.libs.singular.groebner_strategy import NCGroebnerStrategy
  2370. return NCGroebnerStrategy(self.std())
  2371. def reduce(self,p):
  2372. """
  2373. Reduce an element modulo a Groebner basis for this ideal.
  2374. It returns 0 if and only if the element is in this ideal. In any
  2375. case, this reduction is unique up to monomial orders.
  2376. NOTE:
  2377. There are left and two-sided ideals. Hence,
  2378. EXAMPLE::
  2379. sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
  2380. sage: H.<x,y,z> = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
  2381. sage: I = H.ideal([y^2, x^2, z^2-H.one_element()],coerce=False, side='twosided')
  2382. sage: Q = H.quotient(I); Q
  2383. Quotient of Noncommutative Multivariate Polynomial Ring in x, y, z
  2384. over Rational Field, nc-relations: {y*x: x*y - z, z*y: y*z - 2*y,
  2385. z*x: x*z + 2*x} by the ideal (y^2, x^2, z^2 - 1)
  2386. sage: Q.2^2 == Q.one_element() # indirect doctest
  2387. True
  2388. Here, we see that the relation that we just found in the quotient
  2389. is actually a consequence of the given relations:
  2390. sage: I.std()
  2391. Twosided Ideal (z^2 - 1, y*z - y, x*z + x, y^2, 2*x*y - z - 1, x^2)
  2392. of Noncommutative Multivariate Polynomial Ring in x, y, z over
  2393. Rational Field, nc-relations: {y*x: x*y - z, z*y: y*z - 2*y, z*x: x*z + 2*x}
  2394. Here is the corresponding direct test::
  2395. sage: I.reduce(z^2)
  2396. 1
  2397. """
  2398. return self._groebner_strategy().normal_form(p)
  2399. def _contains_(self,p):
  2400. """
  2401. EXAMPLE:
  2402. We define a left and a two-sided ideal::
  2403. sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
  2404. sage: H.<x,y,z> = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
  2405. sage: JL = H.ideal([x^3, y^3, z^3 - 4*z])
  2406. sage: JL.std()
  2407. Left Ideal (z^3 - 4*z, y*z^2 - 2*y*z, x*z^2 + 2*x*z, 2*x*y*z - z^2 - 2*z, y^3, x^3) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: x*y - z, z*y: y*z - 2*y, z*x: x*z + 2*x}
  2408. sage: JT = H.ideal([x^3, y^3, z^3 - 4*z], side='twosided')
  2409. sage: JT.std()
  2410. Twosided Ideal (z^3 - 4*z, y*z^2 - 2*y*z, x*z^2 + 2*x*z, y^2*z - 2*y^2, 2*x*y*z - z^2 - 2*z, x^2*z + 2*x^2, y^3, x*y^2 - y*z, x^2*y - x*z - 2*x, x^3) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: x*y - z, z*y: y*z - 2*y, z*x: x*z + 2*x}
  2411. Apparently, ``x*y^2-y*z`` should be in the two-sided, but not
  2412. in the left ideal::
  2413. sage: x*y^2-y*z in JL #indirect doctest
  2414. False
  2415. sage: x*y^2-y*z in JT
  2416. True
  2417. """
  2418. return self.reduce(p).is_zero()
  2419. @require_field
  2420. def syzygy_module(self):
  2421. r"""
  2422. Computes the first syzygy (i.e., the module of relations of the
  2423. given generators) of the ideal.
  2424. NOTE:
  2425. Only left syzygies can be computed. So, even if the ideal is
  2426. two-sided, then the syzygies are only one-sided. In that case,
  2427. a warning is printed.
  2428. EXAMPLE::
  2429. sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
  2430. sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
  2431. sage: H.inject_variables()
  2432. Defining x, y, z
  2433. sage: I = H.ideal([y^2, x^2, z^2-H.one_element()],coerce=False)
  2434. sage: G = vector(I.gens()); G
  2435. d...: UserWarning: You are constructing a free module
  2436. over a noncommutative ring. Sage does not have a concept
  2437. of left/right and both sided modules, so be careful.
  2438. It's also not guaranteed that all multiplications are
  2439. done from the right side.
  2440. d...: UserWarning: You are constructing a free module
  2441. over a noncommutative ring. Sage does not have a concept
  2442. of left/right and both sided modules, so be careful.
  2443. It's also not guaranteed that all multiplications are
  2444. done from the right side.
  2445. (y^2, x^2, z^2 - 1)
  2446. sage: M = I.syzygy_module(); M
  2447. [ -z^2 - 8*z - 15 0 y^2]
  2448. [ 0 -z^2 + 8*z - 15 x^2]
  2449. [ x^2*z^2 + 8*x^2*z + 15*x^2 -y^2*z^2 + 8*y^2*z - 15*y^2 -4*x*y*z + 2*z^2 + 2*z]
  2450. [ x^2*y*z^2 + 9*x^2*y*z - 6*x*z^3 + 20*x^2*y - 72*x*z^2 - 282*x*z - 360*x -y^3*z^2 + 7*y^3*z - 12*y^3 6*y*z^2]
  2451. [ x^3*z^2 + 7*x^3*z + 12*x^3 -x*y^2*z^2 + 9*x*y^2*z - 4*y*z^3 - 20*x*y^2 + 52*y*z^2 - 224*y*z + 320*y -6*x*z^2]
  2452. [ x^2*y^2*z + 4*x^2*y^2 - 8*x*y*z^2 - 48*x*y*z + 12*z^3 - 64*x*y + 108*z^2 + 312*z + 288 -y^4*z + 4*y^4 0]
  2453. [ 2*x^3*y*z + 8*x^3*y + 9*x^2*z + 27*x^2 -2*x*y^3*z + 8*x*y^3 - 12*y^2*z^2 + 99*y^2*z - 195*y^2 -36*x*y*z + 24*z^2 + 18*z]
  2454. [ x^4*z + 4*x^4 -x^2*y^2*z + 4*x^2*y^2 - 4*x*y*z^2 + 32*x*y*z - 6*z^3 - 64*x*y + 66*z^2 - 240*z + 288 0]
  2455. [x^3*y^2*z + 4*x^3*y^2 + 18*x^2*y*z - 36*x*z^3 + 66*x^2*y - 432*x*z^2 - 1656*x*z - 2052*x -x*y^4*z + 4*x*y^4 - 8*y^3*z^2 + 62*y^3*z - 114*y^3 48*y*z^2 - 36*y*z]
  2456. sage: M*G
  2457. (0, 0, 0, 0, 0, 0, 0, 0, 0)
  2458. ALGORITHM: Uses Singular's syz command
  2459. """
  2460. if self.side() == 'twosided':
  2461. warn("The result of this Syzygy computation is one-sided (left)!")
  2462. import sage.libs.singular
  2463. syz = sage.libs.singular.ff.syz
  2464. from sage.matrix.constructor import matrix
  2465. #return self._singular_().syz().transpose().sage_matrix(self.ring())
  2466. S = syz(self)
  2467. return matrix(self.ring(), S)
  2468. def res(self, length):
  2469. r"""
  2470. Computes the resoltuion up to a given length of the ideal.
  2471. NOTE:
  2472. Only left syzygies can be computed. So, even if the ideal is
  2473. two-sided, then the resolution is only one-sided. In that case,
  2474. a warning is printed.
  2475. EXAMPLE::
  2476. sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
  2477. sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
  2478. sage: H.inject_variables()
  2479. Defining x, y, z
  2480. sage: I = H.ideal([y^2, x^2, z^2-H.one_element()],coerce=False)
  2481. sage: I.res(3)
  2482. <Resolution>
  2483. """
  2484. if self.side() == 'twosided':
  2485. warn("The resulting resolution is one-sided (left)!")
  2486. return self.__call_singular('res', length)
  2487. class MPolynomialIdeal( MPolynomialIdeal_singular_repr, \
  2488. MPolynomialIdeal_macaulay2_repr, \
  2489. MPolynomialIdeal_magma_repr, \
  2490. Ideal_generic ):
  2491. def __init__(self, ring, gens, coerce=True):
  2492. r"""
  2493. Create an ideal in a multivariate polynomial ring.
  2494. INPUT:
  2495. - ``ring`` - the ring the ideal is defined in
  2496. - ``gens`` - a list of generators for the ideal
  2497. - ``coerce`` - coerce elements to the ring ``ring``?
  2498. EXAMPLES::
  2499. sage: R.<x,y> = PolynomialRing(IntegerRing(), 2, order='lex')
  2500. sage: R.ideal([x, y])
  2501. Ideal (x, y) of Multivariate Polynomial Ring in x, y over Integer Ring
  2502. sage: R.<x0,x1> = GF(3)[]
  2503. sage: R.ideal([x0^2, x1^3])
  2504. Ideal (x0^2, x1^3) of Multivariate Polynomial Ring in x0, x1 over Finite Field of size 3
  2505. """
  2506. Ideal_generic.__init__(self, ring, gens, coerce=coerce)
  2507. self._gb_by_ordering = dict()
  2508. @cached_method
  2509. def gens(self):
  2510. """
  2511. Return a set of generators / a basis of self. This is usually the
  2512. set of generators provided during object creation.
  2513. EXAMPLE::
  2514. sage: P.<x,y> = PolynomialRing(QQ,2)
  2515. sage: I = Ideal([x,y+1]); I
  2516. Ideal (x, y + 1) of Multivariate Polynomial Ring in x, y over Rational Field
  2517. sage: I.gens()
  2518. [x, y + 1]
  2519. """
  2520. from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence
  2521. return PolynomialSequence(self.ring(), Ideal_generic.gens(self), immutable=True)
  2522. def __lt__(self, other):
  2523. """
  2524. Decides whether ``self`` is contained in ``other``.
  2525. INPUT:
  2526. - ``other`` -- a polynomial ideal
  2527. OUTPUT:
  2528. - ``True`` if ``self`` is contained in ``other``; ``False`` otherwise
  2529. ALGORITHM:
  2530. We use ideal membership to test whether ``self`` is a subset of ``other``.
  2531. #. Let $F$ be the generators of ``self``.
  2532. #. Let $G$ be a Groebner basis of ``other``.
  2533. #. If any $f\in F$ does not reduce to zero modulo $G$:
  2534. #. Return ``False``.
  2535. #. Else:
  2536. #. Return ``True``.
  2537. EXAMPLE::
  2538. sage: R.<x,y> = GF(32003)[]
  2539. sage: I = R*[x^2 + x, y]
  2540. sage: J = R*[x + 1, y]
  2541. sage: J < I
  2542. False
  2543. sage: I < J
  2544. True
  2545. TEST:
  2546. We test to make sure that pickling works with the cached Groebner basis::
  2547. sage: loads(dumps(I)).__getstate__()
  2548. (Monoid of ideals of Multivariate Polynomial Ring in x, y over Finite Field of size 32003, {'_Ideal_generic__ring': Multivariate Polynomial Ring in x, y over Finite Field of size 32003, '_cache__groebner_basis': {}, 'groebner_basis': Pickle of the cached method "groebner_basis", 'gens': Pickle of the cached method "gens", '_Ideal_generic__gens': (x^2 + x, y), '_gb_by_ordering': {'degrevlex': [x^2 + x, y]}})
  2549. """
  2550. # first check the type
  2551. if not isinstance(other, MPolynomialIdeal):
  2552. return False
  2553. # the ideals may be defined w.r.t. to different term orders
  2554. # but are still the same.
  2555. R = self.ring()
  2556. S = other.ring()
  2557. # separate next two tests to avoid unnecessary creation of Groebner basis
  2558. if S != R:
  2559. if S.change_ring(order=R.term_order()) != R: # rings are unique
  2560. return False
  2561. else:
  2562. # at this point, the rings are the same, but for the term order,
  2563. # and we can fix that easily
  2564. other_new = other.change_ring(R)
  2565. else:
  2566. other_new = other
  2567. # now, check whether the GBs are cached already
  2568. l = self.gens()
  2569. try:
  2570. if other_new.groebner_basis.is_in_cache():
  2571. r = other_new.groebner_basis()
  2572. elif len(other_new._gb_by_ordering) != 0:
  2573. r = other_new._gb_by_ordering.itervalues().next()
  2574. else: # use easy GB otherwise
  2575. l = self.change_ring(R.change_ring(order="degrevlex")).gens()
  2576. r = other_new.change_ring(R.change_ring(order="degrevlex")).groebner_basis()
  2577. # remember this Groebner basis for future reference
  2578. other._gb_by_ordering['degrevlex'] = r
  2579. except AttributeError: # e.g. quotient rings
  2580. r = other_new.groebner_basis()
  2581. for f in l:
  2582. if f.reduce(r) != 0:
  2583. return False
  2584. return True
  2585. def __gt__(self, other):
  2586. """
  2587. Decides whether ``self`` contains ``other``.
  2588. INPUT:
  2589. - ``other`` -- a polynomial ideal
  2590. OUTPUT:
  2591. - ``True`` if ``self`` contains ``other``; ``False`` otherwise
  2592. ALGORITHM:
  2593. #. Return ``other`` < ``self``.
  2594. .. SEEALSO: :meth:`__lt__`.
  2595. EXAMPLE::
  2596. sage: R.<x,y> = GF(32003)[]
  2597. sage: I = R*[x^2 + x, y]
  2598. sage: J = R*[x + 1, y]
  2599. sage: J > I
  2600. True
  2601. sage: I > J
  2602. False
  2603. """
  2604. return other.__lt__(self)
  2605. def __cmp__(self, other):
  2606. """
  2607. Comparison of ``self`` with ``other``.
  2608. INPUT:
  2609. - ``other`` -- a polynomial ideal
  2610. OUTPUT:
  2611. - 0 if ``self`` and ``other`` are the same ideal, 1 otherwise.
  2612. NOTES:
  2613. This algorithm relies on :meth:`.__eq__`.
  2614. EXAMPLE::
  2615. sage: R.<x,y> = ZZ[]; I = R*[x^2 + y, 2*y]; J = R*[x^2 + y]
  2616. sage: cmp(I,J)
  2617. 1
  2618. sage: cmp(J,I)
  2619. -1
  2620. sage: cmp(I,I)
  2621. 0
  2622. """
  2623. # first check the type
  2624. if not isinstance(other, MPolynomialIdeal):
  2625. return 1
  2626. # the ideals may be defined w.r.t. to different term orders
  2627. # but are still the same.
  2628. R = self.ring()
  2629. S = other.ring()
  2630. if R is not S: # rings are unique
  2631. if type(R) == type(S) and (R.base_ring() == S.base_ring()) and (R.ngens() == S.ngens()):
  2632. other = other.change_ring(R)
  2633. else:
  2634. return cmp((type(R), R.base_ring(), R.ngens()), (type(S), S.base_ring(), S.ngens()))
  2635. # now, check whether the GBs are cached already
  2636. l = self.gens()
  2637. try:
  2638. if other.groebner_basis.is_in_cache():
  2639. l = self.groebner_basis()
  2640. r = other.groebner_basis()
  2641. else: # use easy GB otherwise
  2642. l = self.change_ring(R.change_ring(order="degrevlex")).groebner_basis()
  2643. r = other.change_ring(R.change_ring(order="degrevlex")).groebner_basis()
  2644. except AttributeError: # e.g. quotient rings
  2645. l = self.groebner_basis()
  2646. r = other.groebner_basis()
  2647. return cmp(l,r)
  2648. def __eq__(self, other):
  2649. r"""
  2650. Decides whether ``self`` equals ``other``.
  2651. INPUT:
  2652. - ``other`` -- a polynomial ideal
  2653. OUTPUT:
  2654. - ``True`` if the ideals are the same; ``False`` otherwise
  2655. ALGORITHM:
  2656. #. Return ``True`` iff ``self`` and ``other`` contain each other.
  2657. .. SEEALSO::
  2658. :meth:`__lt__`
  2659. :meth:`__gt__`
  2660. EXAMPLE::
  2661. sage: R = PolynomialRing(QQ,'x,y,z')
  2662. sage: I = R.ideal()
  2663. sage: I == R.ideal()
  2664. True
  2665. ::
  2666. sage: R = PolynomialRing(QQ, names=[])
  2667. sage: R.ideal(0) == R.ideal(0)
  2668. verbose 0 (...: multi_polynomial_ideal.py, groebner_basis) Warning: falling back to very slow toy implementation.
  2669. verbose 0 (...: multi_polynomial_ideal.py, groebner_basis) Warning: falling back to very slow toy implementation.
  2670. True
  2671. ::
  2672. sage: R, (x,y) = PolynomialRing(QQ, 2, 'xy').objgens()
  2673. sage: I = (x^3 + y, y)*R
  2674. sage: J = (x^3 + y, y, y*x^3 + y^2)*R
  2675. sage: I == J
  2676. True
  2677. ::
  2678. sage: R = PolynomialRing(QQ, 'x,y,z', order='degrevlex')
  2679. sage: S = PolynomialRing(QQ, 'x,y,z', order='invlex')
  2680. sage: I = R.ideal([R.0,R.1])
  2681. sage: J = S.ideal([S.0,S.1])
  2682. sage: I == J
  2683. True
  2684. TEST:
  2685. This example checks :trac:`12802`::
  2686. sage: R.<x,y> = ZZ[]
  2687. sage: I = R * [ x^2 + y, 2*y ]
  2688. sage: J = R * [ x^2 - y, 2*y ]
  2689. sage: I == J
  2690. True
  2691. Another good test from the discussion in :trac:`12802`::
  2692. sage: Rx = PolynomialRing(QQ, 2, "x")
  2693. sage: Ix = Rx.ideal(Rx.0)
  2694. sage: Ry = PolynomialRing(QQ, 2, "y")
  2695. sage: Iy = Ry.ideal(Ry.0)
  2696. sage: Ix == Iy
  2697. False
  2698. However, this should work if only the orderings are different::
  2699. sage: R = PolynomialRing(QQ, 'x', 2, order='degrevlex')
  2700. sage: S = PolynomialRing(QQ, 'x', 2, order='lex')
  2701. sage: R == S
  2702. False
  2703. sage: I = R*[R.0^2 + R.1, R.1]
  2704. sage: J = S*[S.0^2 + S.1, S.1]
  2705. sage: I == J
  2706. True
  2707. """
  2708. return self < other and self > other
  2709. def groebner_fan(self, is_groebner_basis=False, symmetry=None, verbose=False):
  2710. r"""
  2711. Return the Groebner fan of this ideal.
  2712. The base ring must be `\QQ` or a finite field
  2713. `\GF{p}` of with `p <= 32749`.
  2714. EXAMPLES::
  2715. sage: P.<x,y> = PolynomialRing(QQ)
  2716. sage: i = ideal(x^2 - y^2 + 1)
  2717. sage: g = i.groebner_fan()
  2718. sage: g.reduced_groebner_bases()
  2719. [[x^2 - y^2 + 1], [-x^2 + y^2 - 1]]
  2720. INPUT:
  2721. - ``is_groebner_basis`` - bool (default False). if
  2722. True, then I.gens() must be a Groebner basis with respect to the
  2723. standard degree lexicographic term order.
  2724. - ``symmetry`` - default: None; if not None, describes
  2725. symmetries of the ideal
  2726. - ``verbose`` - default: False; if True, printout
  2727. useful info during computations
  2728. """
  2729. import sage.rings.polynomial.groebner_fan as groebner_fan
  2730. return groebner_fan.GroebnerFan(self, is_groebner_basis=is_groebner_basis,
  2731. symmetry=symmetry, verbose=verbose)
  2732. @cached_method
  2733. def groebner_basis(self, algorithm='', deg_bound=None, mult_bound=None, prot=False, *args, **kwds):
  2734. """
  2735. Return the reduced Groebner basis of this ideal.
  2736. A Groebner basis `g_1,...,g_n` for an ideal `I` is a
  2737. generating set such that `<LM(g_i)> = LM(I)`, i.e., the
  2738. leading monomial ideal of `I` is spanned by the leading terms
  2739. of `g_1,...,g_n`. Groebner bases are the key concept in
  2740. computational ideal theory in multivariate polynomial rings
  2741. which allows a variety of problems to be solved.
  2742. Additionally, a *reduced* Groebner basis `G` is a unique
  2743. representation for the ideal `<G>` with respect to the chosen
  2744. monomial ordering.
  2745. INPUT:
  2746. - ``algorithm`` - determines the algorithm to use, see below
  2747. for available algorithms.
  2748. - ``deg_bound`` - only compute to degree ``deg_bound``, that
  2749. is, ignore all S-polynomials of higher degree. (default:
  2750. ``None``)
  2751. - ``mult_bound`` - the computation is stopped if the ideal is
  2752. zero-dimensional in a ring with local ordering and its
  2753. multiplicity is lower than ``mult_bound``. Singular
  2754. only. (default: ``None``)
  2755. - ``prot`` - if set to ``True`` the computation protocol of
  2756. the underlying implementation is printed. If an algorithm
  2757. from the ``singular:`` or ``magma:`` family is used,
  2758. ``prot`` may also be ``sage`` in which case the output is
  2759. parsed and printed in a common format where the amount of
  2760. information printed can be controlled via calls to
  2761. :func:`set_verbose`.
  2762. - ``*args`` - additional parameters passed to the respective
  2763. implementations
  2764. - ``**kwds`` - additional keyword parameters passed to the
  2765. respective implementations
  2766. ALGORITHMS:
  2767. ''
  2768. autoselect (default)
  2769. 'singular:groebner'
  2770. Singular's ``groebner`` command
  2771. 'singular:std'
  2772. Singular's ``std`` command
  2773. 'singular:stdhilb'
  2774. Singular's ``stdhib`` command
  2775. 'singular:stdfglm'
  2776. Singular's ``stdfglm`` command
  2777. 'singular:slimgb'
  2778. Singular's ``slimgb`` command
  2779. 'libsingular:groebner'
  2780. libSingular's ``groebner`` command
  2781. 'libsingular:std'
  2782. libSingular's ``std`` command
  2783. 'libsingular:slimgb'
  2784. libSingular's ``slimgb`` command
  2785. 'libsingular:stdhilb'
  2786. libSingular's ``stdhib`` command
  2787. 'libsingular:stdfglm'
  2788. libSingular's ``stdfglm`` command
  2789. 'toy:buchberger'
  2790. Sage's toy/educational buchberger without Buchberger criteria
  2791. 'toy:buchberger2'
  2792. Sage's toy/educational buchberger with Buchberger criteria
  2793. 'toy:d_basis'
  2794. Sage's toy/educational algorithm for computation over PIDs
  2795. 'macaulay2:gb'
  2796. Macaulay2's ``gb`` command (if available)
  2797. 'magma:GroebnerBasis'
  2798. Magma's ``Groebnerbasis`` command (if available)
  2799. 'ginv:TQ', 'ginv:TQBlockHigh', 'ginv:TQBlockLow' and 'ginv:TQDegree'
  2800. One of GINV's implementations (if available)
  2801. If only a system is given - e.g. 'magma' - the default algorithm is
  2802. chosen for that system.
  2803. .. note::
  2804. The Singular and libSingular versions of the respective
  2805. algorithms are identical, but the former calls an external
  2806. Singular process while the later calls a C function,
  2807. i.e. the calling overhead is smaller. However, the
  2808. libSingular interface does not support pretty printing of
  2809. computation protocols.
  2810. EXAMPLES:
  2811. Consider Katsura-3 over QQ with lexicographical term
  2812. ordering. We compute the reduced Groebner basis using every
  2813. available implementation and check their equality.
  2814. ::
  2815. sage: P.<a,b,c> = PolynomialRing(QQ,3, order='lex')
  2816. sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching
  2817. sage: I.groebner_basis()
  2818. [a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c]
  2819. ::
  2820. sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching
  2821. sage: I.groebner_basis('libsingular:groebner')
  2822. [a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c]
  2823. ::
  2824. sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching
  2825. sage: I.groebner_basis('libsingular:std')
  2826. [a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c]
  2827. ::
  2828. sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching
  2829. sage: I.groebner_basis('libsingular:stdhilb')
  2830. [a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c]
  2831. ::
  2832. sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching
  2833. sage: I.groebner_basis('libsingular:stdfglm')
  2834. [a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c]
  2835. ::
  2836. sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching
  2837. sage: I.groebner_basis('libsingular:slimgb')
  2838. [a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c]
  2839. Note that ``toy:buchberger`` does not return the reduced Groebner
  2840. basis, ::
  2841. sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching
  2842. sage: I.groebner_basis('toy:buchberger')
  2843. [a^2 - a + 2*b^2 + 2*c^2,
  2844. a*b + b*c - 1/2*b, a + 2*b + 2*c - 1,
  2845. b^2 + 3*b*c - 1/2*b + 3*c^2 - c,
  2846. b*c - 1/10*b + 6/5*c^2 - 2/5*c,
  2847. b + 30*c^3 - 79/7*c^2 + 3/7*c,
  2848. c^6 - 79/210*c^5 - 229/2100*c^4 + 121/2520*c^3 + 1/3150*c^2 - 11/12600*c,
  2849. c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c]
  2850. but that ``toy:buchberger2`` does.::
  2851. sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching
  2852. sage: I.groebner_basis('toy:buchberger2')
  2853. [a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c]
  2854. ::
  2855. sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching
  2856. sage: I.groebner_basis('macaulay2:gb') # optional - macaulay2
  2857. [a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c]
  2858. ::
  2859. sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching
  2860. sage: I.groebner_basis('magma:GroebnerBasis') # optional - magma
  2861. [a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c]
  2862. Singular and libSingular can compute Groebner basis with degree
  2863. restrictions.::
  2864. sage: R.<x,y> = QQ[]
  2865. sage: I = R*[x^3+y^2,x^2*y+1]
  2866. sage: I.groebner_basis(algorithm='singular')
  2867. [x^3 + y^2, x^2*y + 1, y^3 - x]
  2868. sage: I.groebner_basis(algorithm='singular',deg_bound=2)
  2869. [x^3 + y^2, x^2*y + 1]
  2870. sage: I.groebner_basis()
  2871. [x^3 + y^2, x^2*y + 1, y^3 - x]
  2872. sage: I.groebner_basis(deg_bound=2)
  2873. [x^3 + y^2, x^2*y + 1]
  2874. A protocol is printed, if the verbosity level is at least 2,
  2875. or if the argument ``prot`` is provided. Historically, the
  2876. protocol did not appear during doctests, so, we skip the
  2877. examples with protocol output. ::
  2878. sage: set_verbose(2)
  2879. sage: I = R*[x^3+y^2,x^2*y+1]
  2880. sage: I.groebner_basis() # not tested
  2881. std in (0),(x,y),(dp(2),C)
  2882. [...:2]3ss4s6
  2883. (S:2)--
  2884. product criterion:1 chain criterion:0
  2885. [x^3 + y^2, x^2*y + 1, y^3 - x]
  2886. sage: I.groebner_basis(prot=False)
  2887. std in (0),(x,y),(dp(2),C)
  2888. [...:2]3ss4s6
  2889. (S:2)--
  2890. product criterion:1 chain criterion:0
  2891. [x^3 + y^2, x^2*y + 1, y^3 - x]
  2892. sage: set_verbose(0)
  2893. sage: I.groebner_basis(prot=True) # not tested
  2894. std in (0),(x,y),(dp(2),C)
  2895. [...:2]3ss4s6
  2896. (S:2)--
  2897. product criterion:1 chain criterion:0
  2898. [x^3 + y^2, x^2*y + 1, y^3 - x]
  2899. The list of available options is provided at
  2900. :class:`~sage.libs.singular.option.LibSingularOptions`.
  2901. Note that Groebner bases over `\ZZ` can also be computed.::
  2902. sage: P.<a,b,c> = PolynomialRing(ZZ,3)
  2903. sage: I = P * (a + 2*b + 2*c - 1, a^2 - a + 2*b^2 + 2*c^2, 2*a*b + 2*b*c - b)
  2904. sage: I.groebner_basis()
  2905. [b^3 - 23*b*c^2 + 3*b^2 + 5*b*c, 2*b*c^2 - 6*c^3 - b^2 - b*c + 2*c^2,
  2906. 42*c^3 + 5*b^2 + 4*b*c - 14*c^2, 2*b^2 + 6*b*c + 6*c^2 - b - 2*c,
  2907. 10*b*c + 12*c^2 - b - 4*c, a + 2*b + 2*c - 1]
  2908. ::
  2909. sage: I.groebner_basis('macaulay2') # optional - macaulay2
  2910. [b^3 + b*c^2 + 12*c^3 + b^2 + b*c - 4*c^2,
  2911. 2*b*c^2 - 6*c^3 + b^2 + 5*b*c + 8*c^2 - b - 2*c,
  2912. 42*c^3 + b^2 + 2*b*c - 14*c^2 + b,
  2913. 2*b^2 - 4*b*c - 6*c^2 + 2*c, 10*b*c + 12*c^2 - b - 4*c,
  2914. a + 2*b + 2*c - 1]
  2915. Groebner bases over `\ZZ/n\ZZ` are also supported::
  2916. sage: P.<a,b,c> = PolynomialRing(Zmod(1000),3)
  2917. sage: I = P * (a + 2*b + 2*c - 1, a^2 - a + 2*b^2 + 2*c^2, 2*a*b + 2*b*c - b)
  2918. sage: I.groebner_basis()
  2919. [b*c^2 + 992*b*c + 712*c^2 + 332*b + 96*c,
  2920. 2*c^3 + 589*b*c + 862*c^2 + 762*b + 268*c,
  2921. b^2 + 438*b*c + 281*b,
  2922. 5*b*c + 156*c^2 + 112*b + 948*c,
  2923. 50*c^2 + 600*b + 650*c, a + 2*b + 2*c + 999, 125*b]
  2924. Sage also supports local orderings::
  2925. sage: P.<x,y,z> = PolynomialRing(QQ,3,order='negdegrevlex')
  2926. sage: I = P * ( x*y*z + z^5, 2*x^2 + y^3 + z^7, 3*z^5 +y ^5 )
  2927. sage: I.groebner_basis()
  2928. [x^2 + 1/2*y^3, x*y*z + z^5, y^5 + 3*z^5, y^4*z - 2*x*z^5, z^6]
  2929. We can represent every element in the ideal as a combination
  2930. of the generators using the :meth:`~sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict.lift` method::
  2931. sage: P.<x,y,z> = PolynomialRing(QQ,3)
  2932. sage: I = P * ( x*y*z + z^5, 2*x^2 + y^3 + z^7, 3*z^5 +y ^5 )
  2933. sage: J = Ideal(I.groebner_basis())
  2934. sage: f = sum(P.random_element(terms=2)*f for f in I.gens())
  2935. sage: f
  2936. 1/2*y^2*z^7 - 1/4*y*z^8 + 2*x*z^5 + 95*z^6 + 1/2*y^5 - 1/4*y^4*z + x^2*y^2 + 3/2*x^2*y*z + 95*x*y*z^2
  2937. sage: f.lift(I.gens())
  2938. [2*x + 95*z, 1/2*y^2 - 1/4*y*z, 0]
  2939. sage: l = f.lift(J.gens()); l
  2940. [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1/2*y^2 + 1/4*y*z, 1/2*y^2*z^2 - 1/4*y*z^3 + 2*x + 95*z]
  2941. sage: sum(map(mul, zip(l,J.gens()))) == f
  2942. True
  2943. Groebner bases over fraction fields of polynomial rings are also supported::
  2944. sage: P.<t> = QQ[]
  2945. sage: F = Frac(P)
  2946. sage: R.<X,Y,Z> = F[]
  2947. sage: I = Ideal([f + P.random_element() for f in sage.rings.ideal.Katsura(R).gens()])
  2948. sage: I.groebner_basis()
  2949. [Z^3 + (79/105*t^2 - 79/105*t + 79/630)*Z^2 + (-11/105*t^4 + 22/105*t^3 - 17/45*t^2 + 197/630*t + 557/1890)*Y + ...,
  2950. Y^2 + (-3/5)*Z^2 + (2/5*t^2 - 2/5*t + 1/15)*Y + (-2/5*t^2 + 2/5*t - 1/15)*Z - 1/10*t^4 + 1/5*t^3 - 7/30*t^2 + 2/5*t + 11/90,
  2951. Y*Z + 6/5*Z^2 + (1/5*t^2 - 1/5*t + 1/30)*Y + (4/5*t^2 - 4/5*t + 2/15)*Z + 1/5*t^4 - 2/5*t^3 + 7/15*t^2 - 3/10*t - 11/45, X + 2*Y + 2*Z + t^2 - t - 1/3]
  2952. In cases where a characteristic cannot be determined, we use a toy implementation of Buchberger's algorithm
  2953. (see ticket 6581):
  2954. sage: R.<a,b> = QQ[]; I = R.ideal(a^2+b^2-1)
  2955. sage: Q = QuotientRing(R,I); K = Frac(Q)
  2956. sage: R2.<x,y> = K[]; J = R2.ideal([(a^2+b^2)*x + y, x+y])
  2957. sage: J.groebner_basis()
  2958. verbose 0 (...: multi_polynomial_ideal.py, groebner_basis) Warning: falling back to very slow toy implementation.
  2959. [x + y]
  2960. ALGORITHM:
  2961. Uses Singular, Magma (if available), Macaulay2 (if available),
  2962. or a toy implementation.
  2963. """
  2964. from sage.rings.finite_rings.integer_mod_ring import is_IntegerModRing
  2965. from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence
  2966. if algorithm.lower() == "magma":
  2967. algorithm = "magma:GroebnerBasis"
  2968. elif algorithm.lower() == "singular":
  2969. algorithm = "singular:groebner"
  2970. elif algorithm.lower() == "libsingular":
  2971. algorithm = "libsingular:groebner"
  2972. elif algorithm.lower() == "macaulay2":
  2973. algorithm = "macaulay2:gb"
  2974. elif algorithm.lower() == "toy":
  2975. algorithm = "toy:buchberger2"
  2976. if algorithm is '':
  2977. try:
  2978. gb = self._groebner_basis_libsingular("groebner", deg_bound=deg_bound, mult_bound=mult_bound, *args, **kwds)
  2979. except (TypeError,NameError), msg: # conversion to Singular not supported
  2980. try:
  2981. gb = self._groebner_basis_singular("groebner", deg_bound=deg_bound, mult_bound=mult_bound, *args, **kwds)
  2982. except (TypeError,NameError,NotImplementedError), msg: # conversion to Singular not supported
  2983. if self.ring().term_order().is_global() and is_IntegerModRing(self.ring().base_ring()) and not self.ring().base_ring().is_field():
  2984. verbose("Warning: falling back to very slow toy implementation.", level=0)
  2985. ch = self.ring().base_ring().characteristic()
  2986. R = self.ring().change_ring(ZZ)
  2987. I = R.ideal([R(f) for f in self.gens()+(ch,)])
  2988. gb = toy_d_basis.d_basis(I, *args, **kwds)
  2989. R = self.ring()
  2990. gb = filter(lambda f: f,[R(f) for f in gb])
  2991. else:
  2992. if self.ring().term_order().is_global():
  2993. verbose("Warning: falling back to very slow toy implementation.", level=0)
  2994. gb = toy_buchberger.buchberger_improved(self, *args, **kwds)
  2995. else:
  2996. raise TypeError, "Local/unknown orderings not supported by 'toy_buchberger' implementation."
  2997. elif algorithm.startswith('singular:'):
  2998. gb = self._groebner_basis_singular(algorithm[9:], deg_bound=deg_bound, mult_bound=mult_bound, prot=prot, *args, **kwds)
  2999. elif algorithm.startswith('libsingular:'):
  3000. if prot == "sage":
  3001. warn("The libsingular interface does not support prot='sage', reverting to 'prot=True'.")
  3002. gb = self._groebner_basis_libsingular(algorithm[len('libsingular:'):], deg_bound=deg_bound, mult_bound=mult_bound, prot=prot, *args, **kwds)
  3003. elif algorithm == 'macaulay2:gb':
  3004. gb = self._groebner_basis_macaulay2(prot=prot, *args, **kwds)
  3005. elif algorithm == 'magma:GroebnerBasis':
  3006. gb = self._groebner_basis_magma(prot=prot, deg_bound=deg_bound, *args, **kwds)
  3007. elif algorithm == 'toy:buchberger':
  3008. gb = toy_buchberger.buchberger(self, *args, **kwds)
  3009. elif algorithm == 'toy:buchberger2':
  3010. gb = toy_buchberger.buchberger_improved(self, *args, **kwds)
  3011. elif algorithm == 'toy:d_basis':
  3012. gb = toy_d_basis.d_basis(self, *args, **kwds)
  3013. elif algorithm.startswith('ginv'):
  3014. if algorithm == 'ginv':
  3015. gb = self._groebner_basis_ginv(*args, **kwds)
  3016. elif ":" in algorithm:
  3017. ginv,alg = algorithm.split(":")
  3018. gb = self._groebner_basis_ginv(algorithm=alg,*args, **kwds)
  3019. else:
  3020. raise NameError("Algorithm '%s' unknown."%algorithm)
  3021. else:
  3022. raise NameError("Algorithm '%s' unknown."%algorithm)
  3023. gb = sorted(gb, reverse=True)
  3024. if self.ring().base_ring().is_field():
  3025. _gb = []
  3026. for f in gb:
  3027. if f.lc():
  3028. _gb.append(f*f.lc()**(-1))
  3029. else:
  3030. _gb.append(f)
  3031. gb = _gb
  3032. elif self.ring().base_ring() is ZZ:
  3033. if gb[-1].degree() == 0:
  3034. gb = [f % gb[-1] for f in gb[:-1]] + [gb[-1]]
  3035. gb = PolynomialSequence(self.ring(), gb, immutable=True)
  3036. return gb
  3037. def change_ring(self, P):
  3038. r"""
  3039. Return the ideal ``I`` in ``P`` spanned by
  3040. the generators `g_1, ..., g_n` of self as returned by
  3041. ``self.gens()``.
  3042. INPUT:
  3043. - ``P`` - a multivariate polynomial ring
  3044. EXAMPLE::
  3045. sage: P.<x,y,z> = PolynomialRing(QQ,3,order='lex')
  3046. sage: I = sage.rings.ideal.Cyclic(P)
  3047. sage: I
  3048. Ideal (x + y + z, x*y + x*z + y*z, x*y*z - 1) of
  3049. Multivariate Polynomial Ring in x, y, z over Rational Field
  3050. ::
  3051. sage: I.groebner_basis()
  3052. [x + y + z, y^2 + y*z + z^2, z^3 - 1]
  3053. ::
  3054. sage: Q.<x,y,z> = P.change_ring(order='degrevlex'); Q
  3055. Multivariate Polynomial Ring in x, y, z over Rational Field
  3056. sage: Q.term_order()
  3057. Degree reverse lexicographic term order
  3058. ::
  3059. sage: J = I.change_ring(Q); J
  3060. Ideal (x + y + z, x*y + x*z + y*z, x*y*z - 1) of
  3061. Multivariate Polynomial Ring in x, y, z over Rational Field
  3062. ::
  3063. sage: J.groebner_basis()
  3064. [z^3 - 1, y^2 + y*z + z^2, x + y + z]
  3065. """
  3066. return P.ideal([P(f) for f in self.gens()])
  3067. def subs(self, in_dict=None, **kwds):
  3068. """
  3069. Substitute variables.
  3070. This method substitutes some variables in the polynomials that
  3071. generate the ideal with given values. Variables that are not
  3072. specified in the input remain unchanged.
  3073. INPUT:
  3074. - ``in_dict`` -- (optional) dictionary of inputs
  3075. - ``**kwds`` -- named parameters
  3076. OUTPUT:
  3077. A new ideal with modified generators. If possible, in the same
  3078. polynomial ring. Raises a ``TypeError`` if no common
  3079. polynomial ring of the substituted generators can be found.
  3080. EXAMPLES::
  3081. sage: R.<x,y> = PolynomialRing(ZZ,2,'xy')
  3082. sage: I = R.ideal(x^5+y^5, x^2 + y + x^2*y^2 + 5); I
  3083. Ideal (x^5 + y^5, x^2*y^2 + x^2 + y + 5) of Multivariate Polynomial Ring in x, y over Integer Ring
  3084. sage: I.subs(x=y)
  3085. Ideal (2*y^5, y^4 + y^2 + y + 5) of Multivariate Polynomial Ring in x, y over Integer Ring
  3086. sage: I.subs({x:y}) # same substitution but with dictionary
  3087. Ideal (2*y^5, y^4 + y^2 + y + 5) of Multivariate Polynomial Ring in x, y over Integer Ring
  3088. The new ideal can be in a different ring::
  3089. sage: R.<a,b> = PolynomialRing(QQ,2)
  3090. sage: S.<x,y> = PolynomialRing(QQ,2)
  3091. sage: I = R.ideal(a^2+b^2+a-b+2); I
  3092. Ideal (a^2 + b^2 + a - b + 2) of Multivariate Polynomial Ring in a, b over Rational Field
  3093. sage: I.subs(a=x, b=y)
  3094. Ideal (x^2 + y^2 + x - y + 2) of Multivariate Polynomial Ring in x, y over Rational Field
  3095. The resulting ring need not be a mulitvariate polynomial ring::
  3096. sage: T.<t> = PolynomialRing(QQ)
  3097. sage: I.subs(a=t, b=t)
  3098. Principal ideal (t^2 + 1) of Univariate Polynomial Ring in t over Rational Field
  3099. sage: var("z")
  3100. z
  3101. sage: I.subs(a=z, b=z)
  3102. Principal ideal (2*z^2 + 2) of Symbolic Ring
  3103. Variables that are not substituted remain unchanged::
  3104. sage: R.<x,y> = PolynomialRing(QQ,2)
  3105. sage: I = R.ideal(x^2+y^2+x-y+2); I
  3106. Ideal (x^2 + y^2 + x - y + 2) of Multivariate Polynomial Ring in x, y over Rational Field
  3107. sage: I.subs(x=1)
  3108. Ideal (y^2 - y + 4) of Multivariate Polynomial Ring in x, y over Rational Field
  3109. """
  3110. ring = self.ring()
  3111. generators = [f.subs(in_dict, **kwds) for f in self.gens()]
  3112. if not all(gen in ring for gen in generators):
  3113. ring = Sequence(generators).universe()
  3114. try:
  3115. return ring.ideal(generators)
  3116. except AttributeError:
  3117. raise TypeError('Cannot construct an ideal from the substituted generators!')
  3118. def reduce(self, f):
  3119. """
  3120. Reduce an element modulo the reduced Groebner basis for this ideal.
  3121. This returns 0 if and only if the element is in this ideal. In any
  3122. case, this reduction is unique up to monomial orders.
  3123. EXAMPLES::
  3124. sage: R.<x,y> = PolynomialRing(QQ, 2)
  3125. sage: I = (x^3 + y, y)*R
  3126. sage: I.reduce(y)
  3127. 0
  3128. sage: I.reduce(x^3)
  3129. 0
  3130. sage: I.reduce(x - y)
  3131. x
  3132. sage: I = (y^2 - (x^3 + x))*R
  3133. sage: I.reduce(x^3)
  3134. y^2 - x
  3135. sage: I.reduce(x^6)
  3136. y^4 - 2*x*y^2 + x^2
  3137. sage: (y^2 - x)^2
  3138. y^4 - 2*x*y^2 + x^2
  3139. .. note::
  3140. Requires computation of a Groebner basis, which can be a
  3141. very expensive operation.
  3142. """
  3143. try:
  3144. strat = self._groebner_strategy()
  3145. return strat.normal_form(f)
  3146. except (TypeError, NotImplementedError, ValueError):
  3147. pass
  3148. gb = self.groebner_basis()
  3149. return f.reduce(gb)
  3150. def _contains_(self, f):
  3151. r"""
  3152. Returns ``True`` if ``f`` is in this ideal,
  3153. ``False`` otherwise.
  3154. EXAMPLES::
  3155. sage: R, (x,y) = PolynomialRing(QQ, 2, 'xy').objgens()
  3156. sage: I = (x^3 + y, y)*R
  3157. sage: x in I # indirect doctest
  3158. False
  3159. sage: y in I
  3160. True
  3161. sage: x^3 + 2*y in I
  3162. True
  3163. .. note::
  3164. Requires computation of a Groebner basis, which can be a very
  3165. expensive operation.
  3166. """
  3167. g = f.reduce(self.groebner_basis())
  3168. return self.ring()(g).is_zero()
  3169. def homogenize(self, var='h'):
  3170. """
  3171. Return homogeneous ideal spanned by the homogeneous polynomials
  3172. generated by homogenizing the generators of this ideal.
  3173. INPUT:
  3174. - ``h`` - variable name or variable in cover ring
  3175. (default: 'h')
  3176. EXAMPLE::
  3177. sage: P.<x,y,z> = PolynomialRing(GF(2))
  3178. sage: I = Ideal([x^2*y + z + 1, x + y^2 + 1]); I
  3179. Ideal (x^2*y + z + 1, y^2 + x + 1) of Multivariate
  3180. Polynomial Ring in x, y, z over Finite Field of size 2
  3181. ::
  3182. sage: I.homogenize()
  3183. Ideal (x^2*y + z*h^2 + h^3, y^2 + x*h + h^2) of
  3184. Multivariate Polynomial Ring in x, y, z, h over Finite
  3185. Field of size 2
  3186. ::
  3187. sage: I.homogenize(y)
  3188. Ideal (x^2*y + y^3 + y^2*z, x*y) of Multivariate
  3189. Polynomial Ring in x, y, z over Finite Field of size 2
  3190. ::
  3191. sage: I = Ideal([x^2*y + z^3 + y^2*x, x + y^2 + 1])
  3192. sage: I.homogenize()
  3193. Ideal (x^2*y + x*y^2 + z^3, y^2 + x*h + h^2) of
  3194. Multivariate Polynomial Ring in x, y, z, h over Finite
  3195. Field of size 2
  3196. """
  3197. I = [f.homogenize(var) for f in self.gens()]
  3198. P = max(I, key=lambda x: x.parent().ngens()).parent()
  3199. return P.ideal([P(f) for f in I])
  3200. def is_homogeneous(self):
  3201. r"""
  3202. Return ``True`` if this ideal is spanned by homogeneous
  3203. polynomials, i.e. if it is a homogeneous ideal.
  3204. EXAMPLE::
  3205. sage: P.<x,y,z> = PolynomialRing(QQ,3)
  3206. sage: I = sage.rings.ideal.Katsura(P)
  3207. sage: I
  3208. Ideal (x + 2*y + 2*z - 1, x^2 + 2*y^2 + 2*z^2 - x, 2*x*y +
  3209. 2*y*z - y) of Multivariate Polynomial Ring in x, y, z over
  3210. Rational Field
  3211. ::
  3212. sage: I.is_homogeneous()
  3213. False
  3214. ::
  3215. sage: J = I.homogenize()
  3216. sage: J
  3217. Ideal (x + 2*y + 2*z - h, x^2 + 2*y^2 + 2*z^2 - x*h, 2*x*y
  3218. + 2*y*z - y*h) of Multivariate Polynomial Ring in x, y, z,
  3219. h over Rational Field
  3220. ::
  3221. sage: J.is_homogeneous()
  3222. True
  3223. """
  3224. for f in self.gens():
  3225. if not f.is_homogeneous():
  3226. return False
  3227. return True
  3228. def degree_of_semi_regularity(self):
  3229. r"""
  3230. Return the degree of semi-regularity of this ideal under the
  3231. assumption that it is semi-regular.
  3232. Let `\{f_1, ... , f_m\} \subset K[x_1 , ... , x_n]` be
  3233. homogeneous polynomials of degrees `d_1,... ,d_m`
  3234. respectively. This sequence is semi-regular if:
  3235. * `\{f_1, ... , f_m\} \neq K[x_1 , ... , x_n]`
  3236. * for all `1 \leq i \leq m` and `g \in K[x_1,\dots,x_n]`:
  3237. `deg(g \cdot pi ) < D` and
  3238. `g \cdot f_i \in <f_1 , \dots , f_{i-1}>` implies that
  3239. `g \in <f_1, ..., f_{i-1}>` where `D` is the degree of regularity.
  3240. This notion can be extended to affine polynomials by
  3241. considering their homogeneous components of highest degree.
  3242. The degree of regularity of a semi-regular sequence
  3243. `f_1, ...,f_m` of respective degrees `d_1,...,d_m` is given by the
  3244. index of the first non-positive coefficient of:
  3245. `\sum c_k z^k = \frac{\prod (1 - z^{d_i})}{(1-z)^n}`
  3246. EXAMPLE:
  3247. We consider a homogeneous example::
  3248. sage: n = 8
  3249. sage: K = GF(127)
  3250. sage: P = PolynomialRing(K,n,'x')
  3251. sage: s = [K.random_element() for _ in range(n)]
  3252. sage: L = []
  3253. sage: for i in range(2*n):
  3254. ... f = P.random_element(degree=2, terms=binomial(n,2))
  3255. ... f -= f(*s)
  3256. ... L.append(f.homogenize())
  3257. sage: I = Ideal(L)
  3258. sage: I.degree_of_semi_regularity()
  3259. 4
  3260. From this, we expect a Groebner basis computation to reach at
  3261. most degree 4. For homogeneous systems this is equivalent to
  3262. the largest degree in the Groebner basis::
  3263. sage: max(f.degree() for f in I.groebner_basis())
  3264. 4
  3265. We increase the number of polynomials and observe a decrease
  3266. the degree of regularity::
  3267. sage: for i in range(2*n):
  3268. ... f = P.random_element(degree=2, terms=binomial(n,2))
  3269. ... f -= f(*s)
  3270. ... L.append(f.homogenize())
  3271. sage: I = Ideal(L)
  3272. sage: I.degree_of_semi_regularity()
  3273. 3
  3274. sage: max(f.degree() for f in I.groebner_basis())
  3275. 3
  3276. The degree of regularity approaches 2 for quadratic systems as
  3277. the number of polynomials approaches `n^2`::
  3278. sage: for i in range((n-4)*n):
  3279. ... f = P.random_element(degree=2, terms=binomial(n,2))
  3280. ... f -= f(*s)
  3281. ... L.append(f.homogenize())
  3282. sage: I = Ideal(L)
  3283. sage: I.degree_of_semi_regularity()
  3284. 2
  3285. sage: max(f.degree() for f in I.groebner_basis())
  3286. 2
  3287. .. note::
  3288. It is unknown whether semi-regular sequences
  3289. exist. However, it is expected that random systems are
  3290. semi-regular sequences. For more details about
  3291. semi-regular sequences see [BFS04]_.
  3292. REFERENCES:
  3293. .. [BFS04] Magali Bardet, Jean-Charles Faugère, and Bruno
  3294. Salvy, On the complexity of Groebner basis computation of
  3295. semi-regular overdetermined algebraic equations.
  3296. Proc. International Conference on Polynomial System Solving
  3297. (ICPSS), pp. 71-75, 2004.
  3298. """
  3299. degs = [f.degree() for f in self.gens() if f!=0] # we ignore zeroes
  3300. m, n = self.ngens(), len(set(sum([f.variables() for f in self.gens()],())))
  3301. if m <= n:
  3302. raise ValueError("This function requires an overdefined system of polynomials.")
  3303. from sage.rings.all import QQ
  3304. from sage.misc.misc_c import prod
  3305. from sage.rings.power_series_ring import PowerSeriesRing
  3306. R,z = PowerSeriesRing(QQ,'z', default_prec=sum(degs)).objgen()
  3307. dreg = 0
  3308. s = prod([1-z**d for d in degs]) / (1-z)**n
  3309. for dreg in xrange(0,sum(degs)):
  3310. if s[dreg] < 0:
  3311. return ZZ(dreg)
  3312. else:
  3313. raise ValueError("BUG: Could not compute the degree of semi-regularity")
  3314. def plot(self, *args, **kwds):
  3315. """
  3316. Plot the real zero locus of this principal ideal.
  3317. INPUT:
  3318. - ``self`` - a principal ideal in 2 variables
  3319. - ``algorithm`` - set this to 'surf' if you want 'surf' to
  3320. plot the ideal (default: None)
  3321. - ``*args`` - optional tuples ``(variable, minimum, maximum)``
  3322. for plotting dimensions
  3323. - ``**kwds`` - optional keyword arguments passed on to
  3324. ``implicit_plot``
  3325. EXAMPLES:
  3326. Implicit plotting in 2-d::
  3327. sage: R.<x,y> = PolynomialRing(QQ,2)
  3328. sage: I = R.ideal([y^3 - x^2])
  3329. sage: I.plot() # cusp
  3330. ::
  3331. sage: I = R.ideal([y^2 - x^2 - 1])
  3332. sage: I.plot((x,-3, 3), (y, -2, 2)) # hyperbola
  3333. ::
  3334. sage: I = R.ideal([y^2 + x^2*(1/4) - 1])
  3335. sage: I.plot() # ellipse
  3336. ::
  3337. sage: I = R.ideal([y^2-(x^2-1)*(x-2)])
  3338. sage: I.plot() # elliptic curve
  3339. ::
  3340. sage: f = ((x+3)^3 + 2*(x+3)^2 - y^2)*(x^3 - y^2)*((x-3)^3-2*(x-3)^2-y^2)
  3341. sage: I = R.ideal(f)
  3342. sage: I.plot() # the Singular logo
  3343. This used to be trac #5267::
  3344. sage: I = R.ideal([-x^2*y+1])
  3345. sage: I.plot()
  3346. AUTHORS:
  3347. - Martin Albrecht (2008-09)
  3348. """
  3349. from sage.rings.rational_field import QQ
  3350. from sage.rings.real_mpfr import RR
  3351. from sage.plot.all import implicit_plot
  3352. K = self.base_ring()
  3353. try:
  3354. RR._coerce_(K(1))
  3355. except TypeError:
  3356. raise NotImplementedError, "Plotting of curves over %s not implemented yet"%K
  3357. if not self.is_principal():
  3358. raise TypeError, "Ideal must be principal."
  3359. f = self.gens()[0]
  3360. variables = sorted(f.variables(), reverse=True)
  3361. if len(variables) == 2 and kwds.get('algorithm','') != 'surf':
  3362. V = [(variables[0], None, None), (variables[1], None, None)]
  3363. if len(args) > 2:
  3364. raise TypeError, "Expected up to 2 optional parameters but got %d."%len(args)
  3365. # first check whether user supplied boundaries
  3366. for e in args:
  3367. if not isinstance(e, (tuple, list)) or len(e) != 3:
  3368. raise TypeError, "Optional parameter must be list or tuple or length 3."
  3369. v,mi,ma = e
  3370. if v not in variables:
  3371. raise TypeError, "Optional parameter must contain variable of ideal generator."
  3372. vi = variables.index(v)
  3373. V[vi] = v,mi,ma
  3374. # now check whether we should find boundaries
  3375. for var_index in range(2):
  3376. if V[var_index][1] is None:
  3377. v, mi, ma = variables[var_index], -10, 10
  3378. for i in range(mi, ma):
  3379. roots = f.subs({v:i}).univariate_polynomial().change_ring(RR).roots()
  3380. if len(roots) > 0:
  3381. mi = i - 1
  3382. break
  3383. for i in range(ma, mi, -1):
  3384. roots = f.subs({v:i}).univariate_polynomial().change_ring(RR).roots()
  3385. if len(roots) > 0:
  3386. ma = i + 1
  3387. break
  3388. V[var_index] = variables[var_index], mi, ma
  3389. kwds.setdefault("plot_points",200)
  3390. kwds.pop('algorithm', '')
  3391. return implicit_plot(f, V[0], V[1], **kwds)
  3392. elif len(variables) == 3 or kwds.get('algorithm','') == 'surf':
  3393. MPolynomialIdeal_singular_repr.plot(self, kwds.get("singular",singular_default))
  3394. else:
  3395. raise TypeError, "Ideal generator may not have either 2 or 3 variables."
  3396. @require_field
  3397. def weil_restriction(self):
  3398. """
  3399. Compute the Weil restriction of this ideal over some extension
  3400. field.
  3401. A Weil restriction of scalars - denoted `Res_{L/k}` - is a
  3402. functor which, for any finite extension of fields `L/k` and
  3403. any algebraic variety `X` over `L`, produces another
  3404. corresponding variety `Res_{L/k}(X)`, defined over `k`. It is
  3405. useful for reducing questions about varieties over large
  3406. fields to questions about more complicated varieties over
  3407. smaller fields.
  3408. This function does not compute this Weil restriction directly
  3409. but computes on generating sets of polynomial ideals:
  3410. Let `d` be the degree of the field extension `L/k`, let `a` a
  3411. generator of `L/k` and `p` the minimal polynomial of
  3412. `L/k`. Denote this ideal by `I`.
  3413. Specifically, this function first maps each variable `x` to
  3414. its representation over `k`: `\sum_{i=0}^{d-1} a^i x_i`. Then
  3415. each generator of `I` is evaluated over these representations
  3416. and reduced modulo the minimal polynomial `p`. The result is
  3417. interpreted as a univariate polynomial in `a` and its
  3418. coefficients are the new generators of the returned ideal.
  3419. If the input and the output ideals are radical, this is
  3420. equivalent to the statement about algebraic varieties above.
  3421. EXAMPLE::
  3422. sage: k.<a> = GF(2^2)
  3423. sage: P.<x,y> = PolynomialRing(k,2)
  3424. sage: I = Ideal([x*y + 1, a*x + 1])
  3425. sage: I.variety()
  3426. [{y: a, x: a + 1}]
  3427. sage: J = I.weil_restriction()
  3428. sage: J
  3429. Ideal (x1*y0 + x0*y1 + x1*y1, x0*y0 + x1*y1 + 1, x0 + x1, x1 + 1) of
  3430. Multivariate Polynomial Ring in x0, x1, y0, y1 over Finite Field of size 2
  3431. sage: J += sage.rings.ideal.FieldIdeal(J.ring()) # ensure radical ideal
  3432. sage: J.variety()
  3433. [{y1: 1, x1: 1, x0: 1, y0: 0}]
  3434. sage: J.weil_restriction() # returns J
  3435. Ideal (x1*y0 + x0*y1 + x1*y1, x0*y0 + x1*y1 + 1, x0 + x1, x1 + 1, x0^2 + x0,
  3436. x1^2 + x1, y0^2 + y0, y1^2 + y1)
  3437. of Multivariate Polynomial Ring in x0, x1, y0, y1 over Finite Field of size 2
  3438. sage: k.<a> = GF(3^5)
  3439. sage: P.<x,y,z> = PolynomialRing(k)
  3440. sage: I = sage.rings.ideal.Katsura(P)
  3441. sage: I.dimension()
  3442. 0
  3443. sage: I.variety()
  3444. [{y: 0, z: 0, x: 1}]
  3445. sage: J = I.weil_restriction(); J
  3446. Ideal (x4 - y4 - z4, x3 - y3 - z3, x2 - y2 - z2, x1 - y1 - z1, x0 - y0 - z0 - 1,
  3447. x2^2 - x1*x3 - x0*x4 + x4^2 - y2^2 + y1*y3 + y0*y4 - y4^2 - z2^2 + z1*z3 + z0*z4 - z4^2 - x4,
  3448. -x1*x2 - x0*x3 - x3*x4 - x4^2 + y1*y2 + y0*y3 + y3*y4 + y4^2 + z1*z2 + z0*z3 + z3*z4 + z4^2 - x3,
  3449. x1^2 - x0*x2 + x3^2 - x2*x4 + x3*x4 - y1^2 + y0*y2 - y3^2 + y2*y4 - y3*y4 - z1^2 + z0*z2 - z3^2 + z2*z4 - z3*z4 - x2,
  3450. -x0*x1 - x2*x3 - x3^2 - x1*x4 + x2*x4 + y0*y1 + y2*y3 + y3^2 + y1*y4 - y2*y4 + z0*z1 + z2*z3 + z3^2 + z1*z4 - z2*z4 - x1,
  3451. x0^2 + x2*x3 + x1*x4 - y0^2 - y2*y3 - y1*y4 - z0^2 - z2*z3 - z1*z4 - x0,
  3452. -x4*y0 - x3*y1 - x2*y2 - x1*y3 - x0*y4 - x4*y4 - y4*z0 - y3*z1 - y2*z2 - y1*z3 - y0*z4 - y4*z4 - y4,
  3453. -x3*y0 - x2*y1 - x1*y2 - x0*y3 - x4*y3 - x3*y4 + x4*y4 - y3*z0 - y2*z1 - y1*z2 - y0*z3 - y4*z3 - y3*z4 + y4*z4 - y3,
  3454. -x2*y0 - x1*y1 - x0*y2 - x4*y2 - x3*y3 + x4*y3 - x2*y4 + x3*y4 - y2*z0 - y1*z1 - y0*z2 - y4*z2 - y3*z3 + y4*z3 - y2*z4 + y3*z4 - y2,
  3455. -x1*y0 - x0*y1 - x4*y1 - x3*y2 + x4*y2 - x2*y3 + x3*y3 - x1*y4 + x2*y4 - y1*z0 - y0*z1 - y4*z1 - y3*z2 + y4*z2 - y2*z3 + y3*z3 - y1*z4 + y2*z4 - y1,
  3456. -x0*y0 + x4*y1 + x3*y2 + x2*y3 + x1*y4 - y0*z0 + y4*z1 + y3*z2 + y2*z3 + y1*z4 - y0) of Multivariate Polynomial Ring in
  3457. x0, x1, x2, x3, x4, y0, y1, y2, y3, y4, z0, z1, z2, z3, z4 over Finite Field of size 3
  3458. sage: J += sage.rings.ideal.FieldIdeal(J.ring()) # ensure radical ideal
  3459. sage: J.variety()
  3460. [{y1: 0, y4: 0, x4: 0, y2: 0, y3: 0, y0: 0, x2: 0, z4: 0, z3: 0, z2: 0, x1: 0, z1: 0, z0: 0, x0: 1, x3: 0}]
  3461. Weil restrictions are often used to study elliptic curves over
  3462. extension fields so we give a simple example involving those::
  3463. sage: K.<a> = QuadraticField(1/3)
  3464. sage: E = EllipticCurve(K,[1,2,3,4,5])
  3465. We pick a point on ``E``::
  3466. sage: p = E.lift_x(1); p
  3467. (1 : 2 : 1)
  3468. sage: I = E.defining_ideal(); I
  3469. Ideal (-x^3 - 2*x^2*z + x*y*z + y^2*z - 4*x*z^2 + 3*y*z^2 - 5*z^3)
  3470. of Multivariate Polynomial Ring in x, y, z over Number Field in a with defining polynomial x^2 - 1/3
  3471. Of course, the point ``p`` is a root of all generators of ``I``::
  3472. sage: I.subs(x=1,y=2,z=1)
  3473. Ideal (0) of Multivariate Polynomial Ring in x, y, z over
  3474. Number Field in a with defining polynomial x^2 - 1/3
  3475. ``I`` is also radical::
  3476. sage: I.radical() == I
  3477. True
  3478. So we compute its Weil restriction::
  3479. sage: J = I.weil_restriction()
  3480. sage: J
  3481. Ideal (-3*x0^2*x1 - 1/3*x1^3 - 4*x0*x1*z0 + x1*y0*z0 + x0*y1*z0 + 2*y0*y1*z0 - 4*x1*z0^2 + 3*y1*z0^2 - 2*x0^2*z1
  3482. - 2/3*x1^2*z1 + x0*y0*z1 + y0^2*z1 + 1/3*x1*y1*z1 + 1/3*y1^2*z1 - 8*x0*z0*z1 + 6*y0*z0*z1 - 15*z0^2*z1 - 4/3*x1*z1^2 + y1*z1^2 - 5/3*z1^3,
  3483. -x0^3 - x0*x1^2 - 2*x0^2*z0 - 2/3*x1^2*z0 + x0*y0*z0 + y0^2*z0 + 1/3*x1*y1*z0 + 1/3*y1^2*z0 - 4*x0*z0^2 + 3*y0*z0^2 - 5*z0^3 - 4/3*x0*x1*z1
  3484. + 1/3*x1*y0*z1 + 1/3*x0*y1*z1 + 2/3*y0*y1*z1 - 8/3*x1*z0*z1 + 2*y1*z0*z1 - 4/3*x0*z1^2 + y0*z1^2 - 5*z0*z1^2)
  3485. of Multivariate Polynomial Ring in x0, x1, y0, y1, z0, z1 over Rational Field
  3486. We can check that the point ``p`` is still a root of all generators of ``J``::
  3487. sage: J.subs(x0=1,y0=2,z0=1,x1=0,y1=0,z1=0)
  3488. Ideal (0, 0) of Multivariate Polynomial Ring in x0, x1, y0, y1, z0, z1 over Rational Field
  3489. .. note::
  3490. Based on a Singular implementation by Michael Brickenstein
  3491. """
  3492. from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
  3493. R = self.ring()
  3494. nvars = R.ngens()
  3495. L = R.base_ring()
  3496. k = L.prime_subfield()
  3497. if L.degree() == 1:
  3498. return self
  3499. helper = PolynomialRing(L.prime_subfield(), nvars + 1, (L.variable_name(),) + R.variable_names(), order='lex')
  3500. myminpoly = L.polynomial().subs(helper.gen(0))
  3501. l = [helper(str(f)) for f in self.gens()]
  3502. r = myminpoly.degree()
  3503. intermediate_ring = PolynomialRing(k, nvars*r+1, 'x')
  3504. a = intermediate_ring.gen(0)
  3505. # map e.g. x -> a^2*x_2 + a*x_1 + x_0, where x_0,..,x_2
  3506. # represent the components of x if viewed as a vector in k^r
  3507. map_ideal = [a]
  3508. variables = iter(intermediate_ring.gens()[1:])
  3509. for _ in xrange(nvars):
  3510. map_ideal.append(sum([a**i * variables.next() for i in range(r)]))
  3511. myminpoly = myminpoly(*map_ideal)
  3512. l = [f(*map_ideal).reduce([myminpoly]) for f in l]
  3513. result = []
  3514. # split e.g. a^2*x0+a*x1+x2 to x0,x1,x2
  3515. for f in l:
  3516. for i in reversed(range(r)):
  3517. g = f.coefficient(a**i)
  3518. f = f - a**i * g
  3519. result.append(g)
  3520. # eliminate parameter
  3521. new_var_names = [str(var)+"%d"%i for var in R.gens() for i in range(r)]
  3522. result_ring = PolynomialRing(k, nvars*r, new_var_names)
  3523. map_ideal = (0,) + result_ring.gens()
  3524. result = [f(*map_ideal) for f in result]
  3525. return result_ring.ideal(result)