# HG changeset patch
# User Simon King <simon.king@uni-jena.de>
# Date 1307513795 -7200
# Node ID a17f68134769b084687b171b3a92d56bff0c75e8
# Parent 5687b1bb99be4e1154eb175ddce5b3b9273e6cee
#11431: Show examples of .sage() to the singular interface tutorial. Fix some details of the previous patch.
diff --git a/sage/interfaces/singular.py b/sage/interfaces/singular.py
a
|
b
|
|
19 | 19 | |
20 | 20 | - Martin Albrecht (2006-05-18): added sage_poly. |
21 | 21 | |
| 22 | - Simon King (2011-06-06): Make conversion from Singular to Sage more flexible. |
| 23 | |
22 | 24 | Introduction |
23 | 25 | ------------ |
24 | 26 | |
… |
… |
|
43 | 45 | #. ``singular.eval(expr)`` - Evaluation of arbitrary |
44 | 46 | Singular expressions, with the result returned as a string. |
45 | 47 | |
| 48 | Of course, there are polynomial rings and ideals in Sage as well |
| 49 | (often based on a C-library interface to Singular). One can convert |
| 50 | an object in the Singular interpreter interface to Sage by the |
| 51 | method ``sage()``. |
| 52 | |
46 | 53 | |
47 | 54 | Tutorial |
48 | 55 | -------- |
… |
… |
|
87 | 94 | |
88 | 95 | :: |
89 | 96 | |
90 | | sage: R.<x, y> = PolynomialRing(QQ,2) |
91 | | sage: g = eval(f.sage_polystring()); g |
| 97 | sage: g = f.sage(); g |
92 | 98 | 9*x^16 - 18*x^13*y^2 - 9*x^12*y^3 + 9*x^10*y^4 - 18*x^11*y^2 + 36*x^8*y^4 + 18*x^7*y^5 - 18*x^5*y^6 + 9*x^6*y^4 - 18*x^3*y^6 - 9*x^2*y^7 + 9*y^8 |
93 | | sage: eval(F[1][2].sage_polystring()) |
| 99 | sage: F[1][2].sage() |
94 | 100 | x^6 - 2*x^3*y^2 - x^2*y^3 + y^4 |
| 101 | sage: g.parent() |
| 102 | Multivariate Polynomial Ring in x, y over Rational Field |
95 | 103 | |
96 | 104 | This example illustrates polynomial GCD's:: |
97 | 105 | |
… |
… |
|
126 | 134 | x0*x2^3-x1^2*x2^2+x1*x2^3, |
127 | 135 | x0*x1-x0*x2-x1*x2, |
128 | 136 | x0^2*x2-x0*x2^2-x1*x2^2 |
| 137 | sage: I2.sage() |
| 138 | Ideal (x1^2*x2^2, x0*x2^3 - x1^2*x2^2 + x1*x2^3, x0*x1 - x0*x2 - x1*x2, x0^2*x2 - x0*x2^2 - x1*x2^2) of Multivariate Polynomial Ring in x0, x1, x2 over Rational Field |
| 139 | |
129 | 140 | |
130 | 141 | This example illustrates moving a polynomial from one ring to |
131 | 142 | another. It also illustrates calling a method of an object with an |
… |
… |
|
158 | 169 | 6*x+6*x*y^2-2*y^3,6*x^2*y-6*x*y^2, 0, |
159 | 170 | 6*x^2*y-6*x*y^2, 6*y+2*x^3-6*x^2*y,0, |
160 | 171 | 0, 0, 2 |
161 | | sage: H.det() |
| 172 | sage: H.sage() |
| 173 | [6*x + 6*x*y^2 - 2*y^3 6*x^2*y - 6*x*y^2 0] |
| 174 | [ 6*x^2*y - 6*x*y^2 6*y + 2*x^3 - 6*x^2*y 0] |
| 175 | [ 0 0 2] |
| 176 | sage: H.det() # This is a polynomial in Singular |
162 | 177 | 72*x*y+24*x^4-72*x^3*y+72*x*y^3-24*y^4-48*x^4*y^2+64*x^3*y^3-48*x^2*y^4 |
| 178 | sage: H.det().sage() # This is the corresponding polynomial in Sage |
| 179 | 72*x*y + 24*x^4 - 72*x^3*y + 72*x*y^3 - 24*y^4 - 48*x^4*y^2 + 64*x^3*y^3 - 48*x^2*y^4 |
163 | 180 | |
164 | 181 | The 1x1 and 2x2 minors:: |
165 | 182 | |
… |
… |
|
1329 | 1346 | """ |
1330 | 1347 | return str(self).replace('^','**') |
1331 | 1348 | |
1332 | | def sage_basering(self): |
| 1349 | def sage_global_ring(self): |
1333 | 1350 | """ |
1334 | 1351 | Return the current basering in Singular as a polynomial ring or quotient ring. |
1335 | 1352 | |
… |
… |
|
1337 | 1354 | |
1338 | 1355 | sage: singular.eval('ring r1 = (9,x),(a,b,c,d,e,f),(M((1,2,3,0)),wp(2,3),lp)') |
1339 | 1356 | 'ring r1 = (9,x),(a,b,c,d,e,f),(M((1,2,3,0)),wp(2,3),lp);' |
1340 | | sage: R = singular('r1').sage_basering() |
| 1357 | sage: R = singular('r1').sage_global_ring() |
1341 | 1358 | sage: R |
1342 | 1359 | Multivariate Polynomial Ring in a, b, c, d, e, f over Finite Field in x of size 3^2 |
1343 | 1360 | sage: R.term_order() |
… |
… |
|
1352 | 1369 | |
1353 | 1370 | sage: singular.eval('ring r2 = (0,x),(a,b,c),dp') |
1354 | 1371 | 'ring r2 = (0,x),(a,b,c),dp;' |
1355 | | sage: singular('r2').sage_basering() |
| 1372 | sage: singular('r2').sage_global_ring() |
1356 | 1373 | Multivariate Polynomial Ring in a, b, c over Fraction Field of Univariate Polynomial Ring in x over Rational Field |
1357 | 1374 | |
1358 | 1375 | :: |
… |
… |
|
1361 | 1378 | 'ring r3 = (3,z),(a,b,c),dp;' |
1362 | 1379 | sage: singular.eval('minpoly = 1+z+z2+z3+z4') |
1363 | 1380 | 'minpoly = 1+z+z2+z3+z4;' |
1364 | | sage: singular('r3').sage_basering() |
| 1381 | sage: singular('r3').sage_global_ring() |
1365 | 1382 | Multivariate Polynomial Ring in a, b, c over Univariate Quotient Polynomial Ring in z over Finite Field of size 3 with modulus z^4 + z^3 + z^2 + z + 1 |
1366 | 1383 | |
| 1384 | Real and complex fields in both Singular and Sage are defined with a precision. |
| 1385 | The precision in Singular is given in terms of digits, but in Sage it is given |
| 1386 | in terms of bits. So, the digit precision is internally converted to a reasonable |
| 1387 | bit precision:: |
| 1388 | |
| 1389 | sage: singular.eval('ring r4 = (real,20),(a,b,c),dp') |
| 1390 | 'ring r4 = (real,20),(a,b,c),dp;' |
| 1391 | sage: singular('r4').sage_global_ring() |
| 1392 | Multivariate Polynomial Ring in a, b, c over Real Field with 70 bits of precision |
| 1393 | |
1367 | 1394 | The case of complex coefficients is not fully supported, yet, since |
1368 | 1395 | the generator of a complex field in Sage is always called "I":: |
1369 | 1396 | |
1370 | | sage: singular.eval('ring r4 = (complex,15,j),(a,b,c),dp') |
1371 | | 'ring r4 = (complex,15,j),(a,b,c),dp;' |
1372 | | sage: R = singular('r4').sage_basering(); R |
| 1397 | sage: singular.eval('ring r5 = (complex,15,j),(a,b,c),dp') |
| 1398 | 'ring r5 = (complex,15,j),(a,b,c),dp;' |
| 1399 | sage: R = singular('r5').sage_global_ring(); R |
1373 | 1400 | Multivariate Polynomial Ring in a, b, c over Complex Field with 54 bits of precision |
1374 | 1401 | sage: R.base_ring()('j') |
1375 | 1402 | Traceback (most recent call last): |
… |
… |
|
1380 | 1407 | |
1381 | 1408 | In our last example, the base ring is a quotient ring:: |
1382 | 1409 | |
1383 | | sage: singular.eval('ring r5 = (9,a), (x,y,z),lp') |
1384 | | 'ring r5 = (9,a), (x,y,z),lp;' |
| 1410 | sage: singular.eval('ring r6 = (9,a), (x,y,z),lp') |
| 1411 | 'ring r6 = (9,a), (x,y,z),lp;' |
1385 | 1412 | sage: Q = singular('std(ideal(x^2,x+y^2+z^3))', type='qring') |
1386 | | sage: Q.sage_basering() |
| 1413 | sage: Q.sage_global_ring() |
1387 | 1414 | Quotient of Multivariate Polynomial Ring in x, y, z over Finite Field in a of size 3^2 by the ideal (y^4 - y^2*z^3 + z^6, x + y^2 + z^3) |
1388 | 1415 | |
1389 | 1416 | AUTHOR: |
… |
… |
|
1403 | 1430 | from sage.all import QQ |
1404 | 1431 | br = QQ |
1405 | 1432 | elif charstr[0]=='real': |
1406 | | from sage.all import RR |
1407 | | br = RR |
| 1433 | from sage.all import RealField, ceil, log |
| 1434 | prec = singular.eval('ringlist(basering)[1][2][1]') |
| 1435 | br = RealField(ceil((ZZ(prec)+1)/log(2,10))) |
1408 | 1436 | is_extension = False |
1409 | 1437 | elif charstr[0]=='complex': |
1410 | 1438 | from sage.all import ComplexField, ceil, log |
1411 | | prec, I = charstr[1].split(',') |
| 1439 | prec = singular.eval('ringlist(basering)[1][2][1]') |
| 1440 | I = singular.eval('ringlist(basering)[1][3]') |
1412 | 1441 | br = ComplexField(ceil((ZZ(prec)+1)/log(2,10))) |
1413 | 1442 | is_extension = False |
1414 | 1443 | else: |
… |
… |
|
1443 | 1472 | |
1444 | 1473 | # Now, we form the polynomial ring over BR with the given variables, |
1445 | 1474 | # using Singular's term order |
1446 | | from sage.rings.polynomial.term_order import TermOrder_from_Singular |
| 1475 | from sage.rings.polynomial.term_order import termorder_from_singular |
1447 | 1476 | from sage.all import PolynomialRing |
1448 | 1477 | if singular.eval('typeof(basering)')=='ring': |
1449 | | return PolynomialRing(BR, names=singular.eval('varstr(basering)'), order=TermOrder_from_Singular(singular)) |
1450 | | P = PolynomialRing(BR, names=singular.eval('varstr(basering)'), order=TermOrder_from_Singular(singular)) |
| 1478 | return PolynomialRing(BR, names=singular.eval('varstr(basering)'), order=termorder_from_singular(singular)) |
| 1479 | P = PolynomialRing(BR, names=singular.eval('varstr(basering)'), order=termorder_from_singular(singular)) |
1451 | 1480 | return P.quotient(singular('ringlist(basering)[4]')._sage_(P), names=singular.eval('varstr(basering)')) |
1452 | 1481 | |
1453 | 1482 | def sage_poly(self, R=None, kcache=None): |
… |
… |
|
1459 | 1488 | |
1460 | 1489 | |
1461 | 1490 | - ``R`` - (default: None); an optional polynomial ring. |
1462 | | If it is provided, then you *must* take care it |
| 1491 | If it is provided, then you have to make sure that it |
1463 | 1492 | matches the current singular ring as, e.g., returned by |
1464 | 1493 | singular.current_ring(). By default, the output of |
1465 | | :meth:`sage_basering` is used. |
| 1494 | :meth:`sage_global_ring` is used. |
1466 | 1495 | |
1467 | 1496 | - ``kcache`` - (default: None); an optional dictionary |
1468 | 1497 | for faster finite field lookups, this is mainly useful for finite |
… |
… |
|
1531 | 1560 | ring_is_fine = False |
1532 | 1561 | if R is None: |
1533 | 1562 | ring_is_fine = True |
1534 | | R = self.sage_basering() |
| 1563 | R = self.sage_global_ring() |
1535 | 1564 | |
1536 | 1565 | sage_repr = {} |
1537 | 1566 | k = R.base_ring() |
… |
… |
|
1643 | 1672 | |
1644 | 1673 | - ``R`` - (default: None); an optional ring, over which |
1645 | 1674 | the resulting matrix is going to be defined. |
1646 | | By default, the output of :meth:`sage_basering` is used. |
| 1675 | By default, the output of :meth:`sage_global_ring` is used. |
1647 | 1676 | |
1648 | 1677 | - ``sparse`` - (default: True); determines whether the |
1649 | 1678 | resulting matrix is sparse or not. |
… |
… |
|
1663 | 1692 | nrows, ncols = int(self.nrows()),int(self.ncols()) |
1664 | 1693 | |
1665 | 1694 | if R is None: |
1666 | | R = self.sage_basering() |
| 1695 | R = self.sage_global_ring() |
1667 | 1696 | A = Matrix(R, nrows, ncols, sparse=sparse) |
1668 | 1697 | #this is slow |
1669 | 1698 | for x in range(nrows): |
… |
… |
|
1770 | 1799 | elif typ == 'string': |
1771 | 1800 | return repr(self) |
1772 | 1801 | elif typ == 'ideal': |
1773 | | R = R or self.sage_basering() |
| 1802 | R = R or self.sage_global_ring() |
1774 | 1803 | return R.ideal([p.sage_poly(R) for p in self]) |
1775 | 1804 | elif typ in ['ring', 'qring']: |
1776 | 1805 | br = singular('basering') |
1777 | 1806 | self.set_ring() |
1778 | | R = self.sage_basering() |
| 1807 | R = self.sage_global_ring() |
1779 | 1808 | br.set_ring() |
1780 | 1809 | return R |
1781 | 1810 | raise NotImplementedError, "Coercion of this datatype not implemented yet" |
diff --git a/sage/rings/polynomial/term_order.py b/sage/rings/polynomial/term_order.py
a
|
b
|
|
1859 | 1859 | """ |
1860 | 1860 | return self._weights is not None |
1861 | 1861 | |
1862 | | def TermOrder_from_Singular(S): |
| 1862 | def termorder_from_singular(S): |
1863 | 1863 | """ |
1864 | 1864 | Return the Sage term order of the basering in the given Singular interface |
1865 | 1865 | |
… |
… |
|
1877 | 1877 | |
1878 | 1878 | sage: singular.eval('ring r1 = (9,x),(a,b,c,d,e,f),(M((1,2,3,0)),wp(2,3),lp)') |
1879 | 1879 | 'ring r1 = (9,x),(a,b,c,d,e,f),(M((1,2,3,0)),wp(2,3),lp);' |
1880 | | sage: from sage.rings.polynomial.term_order import TermOrder_from_Singular |
1881 | | sage: TermOrder_from_Singular(singular) |
| 1880 | sage: from sage.rings.polynomial.term_order import termorder_from_singular |
| 1881 | sage: termorder_from_singular(singular) |
1882 | 1882 | Block term order with blocks: |
1883 | 1883 | (Matrix term order with matrix |
1884 | 1884 | [1 2] |
… |
… |
|
1910 | 1910 | else: |
1911 | 1911 | order.append(TermOrder(inv_singular_name_mapping[blocktype], ZZ(singular.eval("size(%s[2])"%block.name())))) |
1912 | 1912 | if not order: |
1913 | | raise ValueError, "Invalid termorder in Singular" |
| 1913 | raise ValueError, "Invalid term order in Singular" |
1914 | 1914 | out = order.pop(0) |
1915 | 1915 | while order: |
1916 | 1916 | out = out + order.pop(0) |