Ticket #4539: trac4539_fix_docs.patch
| File trac4539_fix_docs.patch, 42.1 KB (added by SimonKing, 20 months ago) |
|---|
-
sage/libs/singular/function.pyx
# HG changeset patch # User Simon King <simon.king@uni-jena.de> # Date 1317313679 -7200 # Node ID d129c0622eb94d3871297ccb39de1edbf44eb729 # Parent 9f95d173ac536e34aa7c6f711843b4aa1632f166 #4539: Fix doc string format; fix doc test errors left over by the previous patches. diff --git a/sage/libs/singular/function.pyx b/sage/libs/singular/function.pyx
a b 405 405 406 406 def is_singular_poly_wrapper(p): 407 407 """ 408 Checks if p is some data type corresponding to some singular ``poly`` `.409 408 Checks if p is some data type corresponding to some singular ``poly``. 409 410 410 EXAMPLE:: 411 411 412 sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural413 sage: from sage.matrix.constructor import Matrix414 412 sage: from sage.libs.singular.function import is_singular_poly_wrapper 415 sage: c=Matrix(2) 416 sage: c[0,1]=-1 417 sage: P = NCPolynomialRing_plural(QQ, 2, 'x,y', c=c, d=Matrix(2)) 418 sage: (x,y)=P.gens() 413 sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 414 sage: H.<x,y,z> = A.g_algebra({z*x:x*z+2*x, z*y:y*z-2*y}) 419 415 sage: is_singular_poly_wrapper(x+y) 420 416 True 421 417 422 418 """ 423 419 return PY_TYPE_CHECK(p, MPolynomial_libsingular) or PY_TYPE_CHECK(p, NCPolynomial_plural) 424 420 … … 1640 1636 <Resolution> 1641 1637 sage: singular_list(resolution) 1642 1638 [[(-2*y, 2, y + 1, 0), (0, -2, x - 1, 0), (x*y - y, -y + 1, 1, -y), (x^2 + 1, -x - 1, -1, -x)], [(-x - 1, y - 1, 2*x, -2*y)], [(0)]] 1643 sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural 1644 sage: from sage.matrix.constructor import Matrix 1645 sage: c=Matrix(2) 1646 sage: c[0,1]=-1 1647 sage: P = NCPolynomialRing_plural(QQ, 2, 'x,y', c=c, d=Matrix(2)) 1648 sage: (x,y)=P.gens() 1649 sage: I= Sequence([x*y,x+y], check=False, immutable=True)#P.ideal(x*y,x+y) 1639 1640 sage: A.<x,y> = FreeAlgebra(QQ, 2) 1641 sage: P.<x,y> = A.g_algebra({y*x:-x*y}) 1642 sage: I= Sequence([x*y,x+y], check=False, immutable=True) 1650 1643 sage: twostd = singular_function("twostd") 1651 1644 sage: twostd(I) 1652 1645 [x + y, y^2] -
sage/libs/singular/groebner_strategy.pyx
diff --git a/sage/libs/singular/groebner_strategy.pyx b/sage/libs/singular/groebner_strategy.pyx
a b 299 299 300 300 EXAMPLES:: 301 301 302 sage: from sage.libs.singular.groebner_strategy import GroebnerStrategy303 sage: P.<x,y,z> = PolynomialRing(QQ)304 sage: I = Ideal([x+z,y+z+1])305 sage: strat = GroebnerStrategy(I); strat306 Groebner Strategy for ideal generated by 2 elements307 over Multivariate Polynomial Ring in x, y, z over Rational Field302 sage: from sage.libs.singular.groebner_strategy import NCGroebnerStrategy 303 sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 304 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}) 305 sage: I = H.ideal([y^2, x^2, z^2-H.one_element()]) 306 sage: NCGroebnerStrategy(I) 307 Groebner Strategy for ideal generated by 3 elements over 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} 308 308 309 309 TESTS:: 310 310 311 sage: from sage.libs.singular.groebner_strategy import GroebnerStrategy 312 sage: strat = GroebnerStrategy(None) 311 sage: strat = NCGroebnerStrategy(None) 313 312 Traceback (most recent call last): 314 313 ... 315 TypeError: First parameter must be a multivariate polynomial ideal.314 TypeError: First parameter must be an ideal in a g-algebra. 316 315 317 sage: P.<x,y,z> = PolynomialRing( QQ,order='neglex')316 sage: P.<x,y,z> = PolynomialRing(CC,order='neglex') 318 317 sage: I = Ideal([x+z,y+z+1]) 319 sage: strat = GroebnerStrategy(I)318 sage: strat = NCGroebnerStrategy(I) 320 319 Traceback (most recent call last): 321 320 ... 322 NotImplementedError: The local case is not implemented yet. 323 324 sage: P.<x,y,z> = PolynomialRing(CC,order='neglex') 325 sage: I = Ideal([x+z,y+z+1]) 326 sage: strat = GroebnerStrategy(I) 327 Traceback (most recent call last): 328 ... 329 TypeError: First parameter's ring must be multivariate polynomial ring via libsingular. 321 TypeError: First parameter must be an ideal in a g-algebra. 330 322 331 sage: P.<x,y,z> = PolynomialRing(ZZ)332 sage: I = Ideal([x+z,y+z+1])333 sage: strat = GroebnerStrategy(I)334 Traceback (most recent call last):335 ...336 NotImplementedError: Only coefficient fields are implemented so far.337 338 323 """ 339 324 if not isinstance(L, NCPolynomialIdeal): 340 325 raise TypeError("First parameter must be an ideal in a g-algebra.") 341 326 342 327 if not isinstance(L.ring(), NCPolynomialRing_plural): 343 raise TypeError("First parameter's ring must be multivariate polynomial ring via libsingular.")328 raise TypeError("First parameter's ring must be a g-algebra.") 344 329 345 330 self._ideal = L 346 331 … … 381 366 """ 382 367 TEST:: 383 368 384 sage: from sage.libs.singular.groebner_strategy import GroebnerStrategy 385 sage: P.<x,y,z> = PolynomialRing(GF(32003)) 386 sage: I = Ideal([x + z, y + z]) 387 sage: strat = GroebnerStrategy(I) 388 sage: del strat 369 sage: from sage.libs.singular.groebner_strategy import NCGroebnerStrategy 370 sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 371 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}) 372 sage: I = H.ideal([y^2, x^2, z^2-H.one_element()]) 373 sage: strat = NCGroebnerStrategy(I) 374 sage: del strat # indirect doctest 389 375 """ 390 376 cdef ring *oldRing = NULL 391 377 if self._strat: … … 412 398 """ 413 399 TEST:: 414 400 415 sage: from sage.libs.singular.groebner_strategy import GroebnerStrategy 416 sage: P.<x,y,z> = PolynomialRing(GF(32003)) 417 sage: I = Ideal([x + z, y + z]) 418 sage: strat = GroebnerStrategy(I) 401 sage: from sage.libs.singular.groebner_strategy import NCGroebnerStrategy 402 sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 403 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}) 404 sage: I = H.ideal([y^2, x^2, z^2-H.one_element()]) 405 sage: strat = NCGroebnerStrategy(I) 419 406 sage: strat # indirect doctest 420 Groebner Strategy for ideal generated by 2 elements over 421 Multivariate Polynomial Ring in x, y, z over Finite Field of size 32003 407 Groebner Strategy for ideal generated by 3 elements over 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} 422 408 """ 423 409 return "Groebner Strategy for ideal generated by %d elements over %s"%(self._ideal.ngens(),self._parent) 424 410 … … 428 414 429 415 EXAMPLE:: 430 416 431 sage: from sage.libs.singular.groebner_strategy import GroebnerStrategy 432 sage: P.<x,y,z> = PolynomialRing(GF(32003)) 433 sage: I = Ideal([x + z, y + z]) 434 sage: strat = GroebnerStrategy(I) 435 sage: strat.ideal() 436 Ideal (x + z, y + z) of Multivariate Polynomial Ring in x, y, z over Finite Field of size 32003 417 sage: from sage.libs.singular.groebner_strategy import NCGroebnerStrategy 418 sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 419 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}) 420 sage: I = H.ideal([y^2, x^2, z^2-H.one_element()]) 421 sage: strat = NCGroebnerStrategy(I) 422 sage: strat.ideal() == I 423 True 424 437 425 """ 438 426 return self._ideal 439 427 … … 443 431 444 432 EXAMPLE:: 445 433 446 sage: from sage.libs.singular.groebner_strategy import GroebnerStrategy 447 sage: P.<x,y,z> = PolynomialRing(GF(32003)) 448 sage: I = Ideal([x + z, y + z]) 449 sage: strat = GroebnerStrategy(I) 450 sage: strat.ring() 451 Multivariate Polynomial Ring in x, y, z over Finite Field of size 32003 434 sage: from sage.libs.singular.groebner_strategy import NCGroebnerStrategy 435 sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 436 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}) 437 sage: I = H.ideal([y^2, x^2, z^2-H.one_element()]) 438 sage: strat = NCGroebnerStrategy(I) 439 sage: strat.ring() is H 440 True 452 441 """ 453 442 return self._parent 454 443 … … 456 445 """ 457 446 EXAMPLE:: 458 447 459 sage: from sage.libs.singular.groebner_strategy import GroebnerStrategy 460 sage: P.<x,y,z> = PolynomialRing(GF(19)) 461 sage: I = Ideal([P(0)]) 462 sage: strat = GroebnerStrategy(I) 463 sage: strat == GroebnerStrategy(I) 448 sage: from sage.libs.singular.groebner_strategy import NCGroebnerStrategy 449 sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 450 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}) 451 sage: I = H.ideal([y^2, x^2, z^2-H.one_element()]) 452 sage: strat = NCGroebnerStrategy(I) 453 sage: strat == NCGroebnerStrategy(I) 464 454 True 465 sage: I = Ideal([x+1,y+z])466 sage: strat == GroebnerStrategy(I)455 sage: I = H.ideal([y^2, x^2, z^2-H.one_element()], side='twosided') 456 sage: strat == NCGroebnerStrategy(I) 467 457 False 468 458 """ 469 459 if not isinstance(other, NCGroebnerStrategy): 470 460 return cmp(type(self),other(type)) 471 461 else: 472 return cmp(self._ideal.gens(),(<NCGroebnerStrategy>other)._ideal.gens()) 462 return cmp((self._ideal.gens(),self._ideal.side()), 463 ((<NCGroebnerStrategy>other)._ideal.gens(), 464 (<NCGroebnerStrategy>other)._ideal.side())) 473 465 474 466 def __reduce__(self): 475 467 """ 476 468 EXAMPLE:: 477 469 478 sage: from sage.libs.singular.groebner_strategy import GroebnerStrategy 479 sage: P.<x,y,z> = PolynomialRing(GF(32003)) 480 sage: I = Ideal([x + z, y + z]) 481 sage: strat = GroebnerStrategy(I) 470 sage: from sage.libs.singular.groebner_strategy import NCGroebnerStrategy 471 sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 472 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}) 473 sage: I = H.ideal([y^2, x^2, z^2-H.one_element()]) 474 sage: strat = NCGroebnerStrategy(I) 482 475 sage: loads(dumps(strat)) == strat 483 476 True 484 477 """ … … 491 484 492 485 EXAMPLE:: 493 486 494 sage: from sage.libs.singular.groebner_strategy import GroebnerStrategy 495 sage: P.<x,y,z> = PolynomialRing(QQ) 496 sage: I = Ideal([x + z, y + z]) 497 sage: strat = GroebnerStrategy(I) 498 sage: strat.normal_form(x*y) # indirect doctest 499 z^2 500 sage: strat.normal_form(x + 1) 501 -z + 1 487 sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 488 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}) 489 sage: JL = H.ideal([x^3, y^3, z^3 - 4*z]) 490 sage: JT = H.ideal([x^3, y^3, z^3 - 4*z], side='twosided') 491 sage: from sage.libs.singular.groebner_strategy import NCGroebnerStrategy 492 sage: SL = NCGroebnerStrategy(JL.std()) 493 sage: ST = NCGroebnerStrategy(JT.std()) 494 sage: SL.normal_form(x*y^2) 495 x*y^2 496 sage: ST.normal_form(x*y^2) 497 y*z 502 498 503 TESTS::504 505 sage: from sage.libs.singular.groebner_strategy import GroebnerStrategy506 sage: P.<x,y,z> = PolynomialRing(QQ)507 sage: I = Ideal([P(0)])508 sage: strat = GroebnerStrategy(I)509 sage: strat.normal_form(x)510 x511 sage: strat.normal_form(P(0))512 0513 499 """ 514 500 if unlikely(p._parent is not self._parent): 515 501 raise TypeError("parent(p) must be the same as this object's parent.") … … 526 512 """ 527 513 EXAMPLE:: 528 514 529 sage: from sage.libs.singular.groebner_strategy import GroebnerStrategy 530 sage: P.<x,y,z> = PolynomialRing(GF(32003)) 531 sage: I = Ideal([x + z, y + z]) 532 sage: strat = GroebnerStrategy(I) 533 sage: loads(dumps(strat)) == strat # indirect doctest 515 sage: from sage.libs.singular.groebner_strategy import NCGroebnerStrategy 516 sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 517 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}) 518 sage: I = H.ideal([y^2, x^2, z^2-H.one_element()]) 519 sage: strat = NCGroebnerStrategy(I) 520 sage: loads(dumps(strat)) == strat # indirect doctest 534 521 True 535 522 """ 536 523 return NCGroebnerStrategy(I) -
sage/rings/ideal_monoid.py
diff --git a/sage/rings/ideal_monoid.py b/sage/rings/ideal_monoid.py
a b 81 81 82 82 sage: R.<a> = QuadraticField(-23) 83 83 sage: M = sage.rings.ideal_monoid.IdealMonoid(R) 84 sage: M(a) 84 sage: M(a) # indirect doctest 85 85 Fractional ideal (a) 86 86 sage: M([a-4, 13]) 87 87 Fractional ideal (13, 1/2*a + 9/2) 88 88 """ 89 #print x, type(x) 90 if isinstance(x, ideal.Ideal_generic): 89 try: 90 side = x.side() 91 except (AttributeError,TypeError): 92 side = None 93 try: 91 94 x = x.gens() 92 y = self.__R.ideal(x) 95 except AttributeError: 96 pass 97 if side is None: 98 y = self.__R.ideal(x) 99 else: 100 y = self.__R.ideal(x,side=side) 93 101 y._set_parent(self) 94 102 return y 95 103 -
sage/rings/polynomial/multi_polynomial_ideal.py
diff --git a/sage/rings/polynomial/multi_polynomial_ideal.py b/sage/rings/polynomial/multi_polynomial_ideal.py
a b 2957 2957 Apparently, ``x*y^2-y*z`` should be in the two-sided, but not 2958 2958 in the left ideal:: 2959 2959 2960 sage: x*y^2-y*z in JL 2960 sage: x*y^2-y*z in JL #indirect doctest 2961 2961 False 2962 2962 sage: x*y^2-y*z in JT 2963 2963 True -
sage/rings/polynomial/plural.pxd
diff --git a/sage/rings/polynomial/plural.pxd b/sage/rings/polynomial/plural.pxd
a b 21 21 # cdef NCPolynomial_plural _one_element 22 22 # cdef NCPolynomial_plural _zero_element 23 23 24 cdef public object _relations 24 cdef public object _relations,_relations_commutative 25 25 pass 26 26 27 27 cdef class ExteriorAlgebra_plural(NCPolynomialRing_plural): -
sage/rings/polynomial/plural.pyx
diff --git a/sage/rings/polynomial/plural.pyx b/sage/rings/polynomial/plural.pyx
a b 22 22 23 23 - Alexander Dreyer (2010-07): noncommutative ring functionality and documentation 24 24 25 - Simon King (2011-09): left and two-sided ideals; normal forms; pickling; 26 documentation 27 25 28 The underlying libSINGULAR interface was implemented by 26 29 27 - Martin Albrecht (2007-01): initial implementation28 29 - Joel Mohler (2008-01): misc improvements, polishing30 31 - Martin Albrecht (2008-08): added `\QQ(a)` and `\ZZ` support32 33 - Simon King (2009-04): improved coercion34 35 - Martin Albrecht (2009-05): added `\ZZ/n\ZZ` support, refactoring36 37 - Martin Albrecht (2009-06): refactored the code to allow better38 re-use30 - Martin Albrecht (2007-01): initial implementation 31 32 - Joel Mohler (2008-01): misc improvements, polishing 33 34 - Martin Albrecht (2008-08): added `\QQ(a)` and `\ZZ` support 35 36 - Simon King (2009-04): improved coercion 37 38 - Martin Albrecht (2009-05): added `\ZZ/n\ZZ` support, refactoring 39 40 - Martin Albrecht (2009-06): refactored the code to allow better 41 re-use 39 42 40 43 TODO: 41 44 … … 46 49 We show how to construct various noncommutative polynomial rings:: 47 50 48 51 sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 49 sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 50 sage: P.inject_variables() 51 Defining x, y, z 52 sage: P.<x,y,z> = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 52 53 53 54 sage: P 54 55 Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -x*y} … … 57 58 -x*y + 1/2 58 59 59 60 sage: A.<x,y,z> = FreeAlgebra(GF(17), 3) 60 sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 61 sage: P.inject_variables() 62 Defining x, y, z 63 61 sage: P.<x,y,z> = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 64 62 sage: P 65 63 Noncommutative Multivariate Polynomial Ring in x, y, z over Finite Field of size 17, nc-relations: {y*x: -x*y} 66 64 … … 68 66 -x*y + 7 69 67 70 68 71 Raw use of this class:: 69 Raw use of this class; *this is not the intended use!* 70 :: 71 72 72 sage: from sage.matrix.constructor import Matrix 73 73 sage: c = Matrix(3) 74 74 sage: c[0,1] = -2 … … 77 77 78 78 sage: d = Matrix(3) 79 79 sage: d[0, 1] = 17 80 sage: P = QQ['x','y','z'] 81 sage: c = c.change_ring(P) 82 sage: d = d.change_ring(P) 80 83 81 84 sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural 82 sage: R.<x,y,z> = NCPolynomialRing_plural(QQ, 3, c = c, d = d, order='lex')85 sage: R.<x,y,z> = NCPolynomialRing_plural(QQ, c = c, d = d, order=TermOrder('lex',3),category=Algebras(QQ)) 83 86 sage: R 84 87 Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -2*x*y + 17} 85 88 … … 90 93 sage: f = 57 * a^2*b + 43 * c + 1; f 91 94 57*x^2*y + 43*z + 1 92 95 93 sage: R.term_order()94 Lexicographic term order95 96 96 TESTS:: 97 97 98 98 sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 99 99 sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 100 sage: P.inject_variables() 101 Defining x, y, z 102 103 sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural, NCPolynomial_plural 104 sage: TestSuite(NCPolynomialRing_plural).run() 105 sage: TestSuite(NCPolynomial_plural).run() 100 sage: TestSuite(P).run() 101 sage: loads(dumps(P)) is P 102 True 103 106 104 """ 107 105 include "sage/ext/stdsage.pxi" 108 106 include "sage/ext/interrupt.pxi" … … 198 196 sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 199 197 sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}) 200 198 sage: H is A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}) # indirect doctest 199 True 201 200 202 201 """ 203 202 if names is None: … … 241 240 Category of algebras over Rational Field 242 241 sage: TestSuite(H).run() 243 242 243 Note that two variables commute if they are not part of the given 244 relations:: 245 246 sage: H.<x,y,z> = A.g_algebra({z*x:x*z+2*x, z*y:y*z-2*y}) 247 sage: x*y == y*x 248 True 249 244 250 """ 245 251 def __init__(self, base_ring, names, c, d, order, category, check = True): 246 252 """ … … 258 264 259 265 ``self.gen(j)*self.gen(i) == c[i, j] * self.gen(i)*self.gen(j) + d[i, j],`` 260 266 261 where ``0 <= i < j < self.ngens()``. 267 where ``0 <= i < j < self.ngens()``. Note that two variables 268 commute if they are not part of one of these relations. 262 269 - ``order`` - term order 263 270 - ``check`` - check the noncommutative conditions (default: ``True``) 264 271 265 EXAMPLES:: 272 TESTS: 273 274 It is strongly recommended to construct a g-algebra using 275 :class:`G_AlgFactory`. The following is just for documenting 276 the arguments of the ``__init__`` method:: 266 277 267 278 sage: from sage.matrix.constructor import Matrix 268 sage: c = Matrix(3) 269 sage: c[0,1] = -1 270 sage: c[0,2] = 1 271 sage: c[1,2] = 1 272 273 sage: d = Matrix(3) 274 sage: d[0, 1] = 17 279 sage: c0 = Matrix(3) 280 sage: c0[0,1] = -1 281 sage: c0[0,2] = 1 282 sage: c0[1,2] = 1 283 284 sage: d0 = Matrix(3) 285 sage: d0[0, 1] = 17 286 sage: P = QQ['x','y','z'] 287 sage: c = c0.change_ring(P) 288 sage: d = d0.change_ring(P) 275 289 276 290 sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural 277 sage: P.<x,y,z> = NCPolynomialRing_plural(QQ, c = c, d = d, order= 'lex')291 sage: P.<x,y,z> = NCPolynomialRing_plural(QQ, c = c, d = d, order=TermOrder('lex',3), category=Algebras(QQ)) 278 292 279 293 sage: P # indirect doctest 280 294 Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -x*y + 17} … … 289 303 Lexicographic term order 290 304 291 305 sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural 292 sage: P.<x,y,z> = NCPolynomialRing_plural(GF(7), 3, c = c, d = d, order='degrevlex') 306 sage: P = GF(7)['x','y','z'] 307 sage: c = c0.change_ring(P) 308 sage: d = d0.change_ring(P) 309 sage: P.<x,y,z> = NCPolynomialRing_plural(GF(7), c = c, d = d, order=TermOrder('degrevlex',3), category=Algebras(GF(7))) 293 310 294 311 sage: P # indirect doctest 295 312 Noncommutative Multivariate Polynomial Ring in x, y, z over Finite Field of size 7, nc-relations: {y*x: -x*y + 3} … … 323 340 self.__ngens = n 324 341 self.__term_order = order 325 342 326 Ring.__init__(self, base_ring, names, category )343 Ring.__init__(self, base_ring, names, category=category) 327 344 self._populate_coercion_lists_() 328 345 329 346 #MPolynomialRing_generic.__init__(self, base_ring, n, names, order) … … 364 381 collection). 365 382 366 383 TESTS: 384 367 385 This example caused a segmentation fault with a previous version 368 of this method: 386 of this method:: 387 369 388 sage: import gc 370 389 sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural 371 390 sage: from sage.algebras.free_algebra import FreeAlgebra … … 394 413 Make sure element is a valid member of self, and return the constructed element. 395 414 396 415 EXAMPLES:: 416 397 417 sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 398 399 418 sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 400 419 401 420 We can construct elements from the base ring:: … … 403 422 sage: P(1/2) 404 423 1/2 405 424 406 407 425 and all kinds of integers:: 408 426 409 427 sage: P(17) 410 428 17 411 412 429 sage: P(int(19)) 413 430 19 414 415 431 sage: P(long(19)) 416 432 19 417 418 TESTS: :433 434 TESTS: 419 435 420 436 Check conversion from self:: 437 421 438 sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 422 sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 423 sage: P.inject_variables() 424 Defining x, y, z 439 sage: P.<x,y,z> = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 425 440 426 441 sage: P._element_constructor_(1/2) 427 442 1/2 … … 432 447 sage: P._element_constructor_(y*x) 433 448 -x*y 434 449 435 Raw use of this class::436 sage: from sage.matrix.constructor import Matrix437 sage: c = Matrix(3)438 sage: c[0,1] = -2439 sage: c[0,2] = 1440 sage: c[1,2] = 1441 442 sage: d = Matrix(3)443 sage: d[0, 1] = 17444 445 sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural446 sage: R.<x,y,z> = NCPolynomialRing_plural(QQ, 3, c = c, d = d, order='lex')447 sage: R._element_constructor_(x*y)448 x*y449 450 sage: P._element_constructor_(17)451 17452 453 sage: P._element_constructor_(int(19))454 19455 456 450 Testing special cases:: 451 457 452 sage: P._element_constructor_(1) 458 453 1 459 454 … … 536 531 cpdef _coerce_map_from_(self, S): 537 532 """ 538 533 The only things that coerce into this ring are: 539 - the integer ring 540 - other localizations away from fewer primes 541 542 EXAMPLES:: 534 535 - the integer ring 536 - other localizations away from fewer primes 537 538 EXAMPLES:: 539 543 540 sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 544 541 sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 545 546 542 sage: P._coerce_map_from_(ZZ) 547 543 True 548 544 """ … … 553 549 554 550 555 551 def __hash__(self): 556 """ 557 Return a hash for this noncommutative ring, that is, a hash of the string 558 representation of this polynomial ring. 559 560 EXAMPLES:: 561 sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 562 sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 563 sage: hash(P) # somewhat random output 564 ... 565 566 TESTS:: 567 568 Check conversion from self:: 569 sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 570 sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 571 sage: from sage.matrix.constructor import Matrix 572 sage: c = Matrix(3) 573 sage: c[0,1] = -1 574 sage: c[0,2] = 1 575 sage: c[1,2] = 1 576 577 sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural 578 sage: R.<x,y,z> = NCPolynomialRing_plural(QQ, 3, c = c, d = Matrix(3), order='lex') 579 sage: hash(R) == hash(P) 580 True 581 """ 582 return hash(str(self.__repr__()) + str(self.term_order()) ) 583 584 585 def __cmp__(self, right): 586 r""" 587 Non-commutative polynomial rings are said to be equal if: 588 589 - their base rings match, 590 - their generator names match, 591 - their term orderings match, and 592 - their relations match. 552 """ 553 Return a hash for this noncommutative ring, that is, a hash of the string 554 representation of this polynomial ring. 555 556 NOTE: 557 558 G-algebras are unique parents, provided that the g-algebra constructor 559 is used. Thus, the hash simply is the memory address of the g-algebra 560 (so, it is a session hash, but no stable hash). It is possible to 561 destroy uniqueness of g-algebras on purpose, but that's your own 562 problem if you do those things. 593 563 594 564 EXAMPLES:: 595 565 596 sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 597 sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 598 599 sage: P == P 600 True 601 sage: Q = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 602 sage: Q == P 603 True 604 605 sage: from sage.matrix.constructor import Matrix 606 sage: c = Matrix(3) 607 sage: c[0,1] = -1 608 sage: c[0,2] = 1 609 sage: c[1,2] = 1 610 sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural 611 sage: R.<x,y,z> = NCPolynomialRing_plural(QQ, 3, c = c, d = Matrix(3), order='lex') 612 sage: R == P 613 True 614 615 sage: c[0,1] = -2 616 sage: R.<x,y,z> = NCPolynomialRing_plural(QQ, 3, c = c, d = Matrix(3), order='lex') 617 sage: P == R 618 False 566 sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 567 sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 568 sage: {P:2}[P] # indirect doctest 569 2 570 619 571 """ 620 621 if PY_TYPE_CHECK(right, NCPolynomialRing_plural): 622 623 return cmp( (self.base_ring(), map(str, self.gens()), 624 self.term_order(), self._c, self._d), 625 (right.base_ring(), map(str, right.gens()), 626 right.term_order(), 627 (<NCPolynomialRing_plural>right)._c, 628 (<NCPolynomialRing_plural>right)._d) 629 ) 630 else: 631 return cmp(type(self),type(right)) 572 return id(self) 632 573 633 574 def __pow__(self, n, _): 634 575 """ 635 576 Return the free module of rank `n` over this ring. 636 577 578 NOTE: 579 580 This is not properly implemented yet. Thus, there is 581 a warning. 582 637 583 EXAMPLES:: 584 638 585 sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 639 sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 640 sage: P.inject_variables() 641 Defining x, y, z 642 643 sage: f = x^3 + y 644 sage: f^2 645 x^6 + y^2 586 sage: P.<x,y,z> = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 587 sage: P^3 588 d...: UserWarning: You are constructing a free module 589 over a noncommutative ring. Sage does not have a concept 590 of left/right and both sided modules, so be careful. 591 It's also not guaranteed that all multiplications are 592 done from the right side. 593 d...: UserWarning: You are constructing a free module 594 over a noncommutative ring. Sage does not have a concept 595 of left/right and both sided modules, so be careful. 596 It's also not guaranteed that all multiplications are 597 done from the right side. 598 Ambient free module of rank 3 over Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -x*y} 599 646 600 """ 647 601 import sage.modules.all 648 602 return sage.modules.all.FreeModule(self, n) … … 653 607 654 608 EXAMPLES:: 655 609 656 sage: A.<x,y,z> = FreeAlgebra(QQ, 3)657 sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex')658 sage: P.term_order()659 Lexicographic term order660 661 sage: P = A.g_algebra(relations={y*x:-x*y})662 sage: P.term_order()663 Degree reverse lexicographic term order610 sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 611 sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 612 sage: P.term_order() 613 Lexicographic term order 614 615 sage: P = A.g_algebra(relations={y*x:-x*y}) 616 sage: P.term_order() 617 Degree reverse lexicographic term order 664 618 """ 665 619 return self.__term_order 666 620 … … 668 622 """ 669 623 Return False. 670 624 625 .. todo:: Provide a mathematically correct answer. 626 671 627 EXAMPLES:: 672 628 673 sage: A.<x,y,z> = FreeAlgebra(QQ, 3)674 sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex')675 sage: P.is_commutative()676 False629 sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 630 sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 631 sage: P.is_commutative() 632 False 677 633 """ 678 634 return False 679 635 … … 683 639 684 640 EXAMPLES:: 685 641 686 sage: A.<x,y,z> = FreeAlgebra(QQ, 3)687 sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex')688 sage: P.is_field()689 False642 sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 643 sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 644 sage: P.is_field() 645 False 690 646 """ 691 647 return False 692 648 693 649 def _repr_(self): 694 650 """ 695 EXAMPLE: 696 sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural 697 sage: from sage.matrix.constructor import Matrix 698 sage: c=Matrix(2) 699 sage: c[0,1]=-1 700 sage: P.<x,y> = NCPolynomialRing_plural(QQ, 2, c=c, d=Matrix(2)) 701 sage: P # indirect doctest 651 EXAMPLE:: 652 653 sage: A.<x,y> = FreeAlgebra(QQ, 2) 654 sage: H.<x,y> = A.g_algebra({y*x:-x*y}) 655 sage: H # indirect doctest 702 656 Noncommutative Multivariate Polynomial Ring in x, y over Rational Field, nc-relations: {y*x: -x*y} 703 657 sage: x*y 704 658 x*y … … 715 669 Return an internal list representation of the noncummutative ring. 716 670 717 671 EXAMPLES:: 718 sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 719 sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 720 sage: P._ringlist() 721 [0, ['x', 'y', 'z'], [['lp', (1, 1, 1)], ['C', (0,)]], [0], [ 0 -1 1] 722 [ 0 0 1] 723 [ 0 0 0], [0 0 0] 724 [0 0 0] 725 [0 0 0]] 672 673 sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 674 sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 675 sage: P._ringlist() 676 [0, ['x', 'y', 'z'], [['lp', (1, 1, 1)], ['C', (0,)]], [0], [ 0 -1 1] 677 [ 0 0 1] 678 [ 0 0 0], [0 0 0] 679 [0 0 0] 680 [0 0 0]] 726 681 """ 727 682 cdef ring* _ring = self._ring 728 683 if(_ring != currRing): rChangeCurrRing(_ring) 729 684 from sage.libs.singular.function import singular_function 730 685 ringlist = singular_function('ringlist') 731 686 result = ringlist(self, ring=self) 732 733 734 735 736 687 return result 737 688 738 689 739 690 def relations(self, add_commutative = False): 740 691 """ 692 Return the relations of this g-algebra. 693 694 INPUT: 695 696 ``add_commutative`` (optional bool, default False) 697 698 OUTPUT: 699 700 The defining relations. There are some implicit relations: 701 Two generators commute if they are not part of any given 702 relation. The implicit relations are not provided, unless 703 ``add_commutative==True``. 704 741 705 EXAMPLE:: 742 706 743 sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural 744 sage: from sage.matrix.constructor import Matrix 745 sage: c=Matrix(2) 746 sage: c[0,1]=-1 747 sage: P = NCPolynomialRing_plural(QQ, 2, 'x,y', c=c, d=Matrix(2)) 748 sage: P # indirect doctest 749 Noncommutative Multivariate Polynomial Ring in x, y over Rational Field, nc-relations: ... 707 sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 708 sage: H.<x,y,z> = A.g_algebra({z*x:x*z+2*x, z*y:y*z-2*y}) 709 sage: x*y == y*x 710 True 711 sage: H.relations() 712 {z*y: y*z - 2*y, z*x: x*z + 2*x} 713 sage: H.relations(add_commutative=True) 714 {y*x: x*y, z*y: y*z - 2*y, z*x: x*z + 2*x} 715 750 716 """ 717 if add_commutative: 718 if self._relations_commutative is not None: 719 return self._relations_commutative 720 721 from sage.algebras.free_algebra import FreeAlgebra 722 A = FreeAlgebra( self.base_ring(), self.ngens(), self.gens() ) 723 724 res = {} 725 n = self.ngens() 726 for r in range(0, n-1, 1): 727 for c in range(r+1, n, 1): 728 res[ A.gen(c) * A.gen(r) ] = self.gen(c) * self.gen(r) # C[r, c] * P.gen(r) * P.gen(c) + D[r, c] 729 self._relations_commutative = res 730 return res 731 751 732 if self._relations is not None: 752 733 return self._relations 753 734 … … 758 739 n = self.ngens() 759 740 for r in range(0, n-1, 1): 760 741 for c in range(r+1, n, 1): 761 if (self.gen(c) * self.gen(r) != self.gen(r) * self.gen(c)) or add_commutative:742 if (self.gen(c) * self.gen(r) != self.gen(r) * self.gen(c)): 762 743 res[ A.gen(c) * A.gen(r) ] = self.gen(c) * self.gen(r) # C[r, c] * P.gen(r) * P.gen(c) + D[r, c] 763 764 744 765 745 self._relations = res 766 746 return self._relations 767 747 … … 772 752 EXAMPLES:: 773 753 774 754 sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 775 sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 776 sage: P.inject_variables() 777 Defining x, y, z 778 755 sage: P.<x,y,z> = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 779 756 sage: P.ngens() 780 757 3 781 758 """ … … 797 774 sage: P.gen(),P.gen(1) 798 775 (x, y) 799 776 800 sage: P.gen(1) 801 y 777 Note that the generators are not cached:: 778 779 sage: P.gen(1) is P.gen(1) 780 False 781 802 782 """ 803 783 cdef poly *_p 804 784 cdef ring *_ring = self._ring … … 820 800 INPUT: 821 801 822 802 - ``*gens`` - list or tuple of generators (or several input arguments) 823 824 803 - ``coerce`` - bool (default: ``True``); this must be a 825 804 keyword argument. Only set it to ``False`` if you are certain 826 805 that each generator is already in the ring. 806 - ``side`` - string (either "left", which is the default, or "twosided") 807 Must be a keyword argument. Defines whether the ideal is a left ideal 808 or a two-sided ideal. Right ideals are not implemented. 827 809 828 810 EXAMPLES:: 811 829 812 sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 830 sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 831 sage: P.inject_variables() 832 Defining x, y, z 813 sage: P.<x,y,z> = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 833 814 834 815 sage: P.ideal([x + 2*y + 2*z-1, 2*x*y + 2*y*z-y, x^2 + 2*y^2 + 2*z^2-x]) 835 Ideal (x + 2*y + 2*z - 1, 2*x*y + 2*y*z - y, x^2 - x + 2*y^2 + 2*z^2) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -x*y} 816 Left Ideal (x + 2*y + 2*z - 1, 2*x*y + 2*y*z - y, x^2 - x + 2*y^2 + 2*z^2) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -x*y} 817 sage: P.ideal([x + 2*y + 2*z-1, 2*x*y + 2*y*z-y, x^2 + 2*y^2 + 2*z^2-x], side="twosided") 818 Twosided Ideal (x + 2*y + 2*z - 1, 2*x*y + 2*y*z - y, x^2 - x + 2*y^2 + 2*z^2) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -x*y} 819 836 820 """ 837 # from sage.rings.polynomial.multi_polynomial_ideal import \838 # NCPolynomialIdeal839 821 coerce = kwds.get('coerce', True) 840 822 if len(gens) == 1: 841 823 gens = gens[0] … … 872 854 ring = singular_function('ring') 873 855 return ring(L, ring=self) 874 856 857 # TODO: Implement this properly! 875 858 # def quotient(self, I): 876 859 # """ 877 860 # Construct quotient ring of ``self`` and the two-sided Groebner basis of `ideal` … … 943 926 2/3 944 927 945 928 TESTS:: 929 946 930 sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 947 931 sage: R = A.g_algebra(relations={y*x:-x*y}, order='lex') 948 932 sage: R.inject_variables() … … 1037 1021 False 1038 1022 1039 1023 TESTS:: 1024 1040 1025 sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 1041 1026 sage: Q = A.g_algebra(relations={y*x:-x*y}, order='lex') 1042 1027 sage: Q.inject_variables() … … 1164 1149 (y, 1/4*x*y + 2/7) 1165 1150 1166 1151 TESTS:: 1152 1167 1153 sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 1168 1154 sage: Q = A.g_algebra(relations={y*x:-x*y}, order='lex') 1169 1155 sage: Q.inject_variables() … … 1314 1300 return M 1315 1301 1316 1302 def unpickle_NCPolynomial_plural(NCPolynomialRing_plural R, d): 1303 """ 1304 Auxiliary function to unpickle a non-commutative polynomial. 1305 1306 TEST:: 1307 1308 sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 1309 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}) 1310 sage: p = x*y+2*z+4*x*y*z*x 1311 sage: loads(dumps(p)) == p # indirect doctest 1312 True 1313 1314 """ 1317 1315 cdef ring *r = R._ring 1318 1316 cdef poly *m, *p 1319 1317 cdef int _i, _e … … 1703 1701 1704 1702 sage: (x*z).reduce(I) 1705 1703 -x 1706 sage: I.twostd() 1704 1705 The Groebner basis shows that the result is correct:: 1706 1707 sage: I.std() 1707 1708 Left Ideal (z^2 - 1, y*z - y, x*z + x, y^2, 2*x*y - z - 1, x^2) of 1708 1709 Noncommutative Multivariate Polynomial Ring in x, y, z over Rational 1709 1710 Field, nc-relations: {y*x: x*y - z, z*y: y*z - 2*y, z*x: x*z + 2*x} … … 1833 1834 degree, which is the maximum degree of any monomial. 1834 1835 1835 1836 OUTPUT: 1836 integer 1837 1838 integer 1837 1839 1838 1840 EXAMPLES:: 1839 1841 … … 1970 1972 - a monomial (very fast, but not as flexible) 1971 1973 1972 1974 OUTPUT: 1973 element of the parent of this element. 1975 1976 element of the parent of this element. 1974 1977 1975 1978 .. note:: 1976 1979 … … 2089 2092 - ``mon`` - a monomial 2090 2093 2091 2094 OUTPUT: 2092 coefficient in base ring 2095 2096 coefficient in base ring 2093 2097 2094 2098 SEE ALSO: 2095 For coefficients in a base ring of fewer variables, look at ``coefficient``. 2099 2100 For coefficients in a base ring of fewer variables, look at ``coefficient``. 2096 2101 2097 2102 EXAMPLES:: 2098 2103 … … 2212 2217 INPUT: 2213 2218 2214 2219 - ``x`` - a tuple or, in case of a single-variable MPolynomial 2215 ring x can also be an integer.2220 ring x can also be an integer. 2216 2221 2217 2222 EXAMPLES:: 2218 2223 … … 2276 2281 INPUT: 2277 2282 2278 2283 - ``as_ETuples`` - (default: ``True``) if true returns the result as an list of ETuples 2279 otherwise returns a list of tuples2284 otherwise returns a list of tuples 2280 2285 2281 2286 2282 2287 EXAMPLES:: … … 2660 2665 2661 2666 EXAMPLES:: 2662 2667 2663 2668 sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 2669 sage: H = A.g_algebra({z*x:x*z+2*x, z*y:y*z-2*y}) 2670 sage: H.gen(2) # indirect doctest 2671 z 2672 2664 2673 """ 2665 2674 cdef NCPolynomial_plural p = PY_NEW(NCPolynomial_plural) 2666 2675 p._parent = <ParentWithBase>parent … … 2676 2685 Construct MPolynomialRing_libsingular from ringWrap, assumming the ground field to be base_ring 2677 2686 2678 2687 EXAMPLES:: 2688 2679 2689 sage: H.<x,y,z> = PolynomialRing(QQ, 3) 2680 2690 sage: from sage.libs.singular.function import singular_function 2681 2691 … … 2720 2730 Construct NCPolynomialRing_plural from ringWrap, assumming the ground field to be base_ring 2721 2731 2722 2732 EXAMPLES:: 2723 EXAMPLES::2724 2733 2725 2734 sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 2726 2735 sage: H = A.g_algebra({y*x:x*y-1}) … … 2872 2881 if (r in alt_vars) and (c in alt_vars): 2873 2882 relations[ A.gen(c) * A.gen(r) ] = - A.gen(r) * A.gen(c) 2874 2883 2875 H = A.g_algebra(relations=relations, order=order)2884 cdef NCPolynomialRing_plural H = A.g_algebra(relations=relations, order=order) 2876 2885 I = H.ideal([H.gen(i) *H.gen(i) for i in alt_vars]).twostd() 2877 return H.quotient(I) 2886 L = H._ringlist() 2887 L[3] = I 2888 W = H._list_to_ring(L) 2889 return new_NRing(W, H.base_ring()) 2878 2890 2879 2891 cdef poly *addwithcarry(poly *tempvector, poly *maxvector, int pos, ring *_ring): 2880 2892 if p_GetExp(tempvector, pos, _ring) < p_GetExp(maxvector, pos, _ring):
