# HG changeset patch
# User Simon King <simon.king@unijena.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 (20060518): added sage_poly. 
21  21  
 22   Simon King (20110606): 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 Clibrary 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^3x1^2*x2^2+x1*x2^3, 
127  135  x0*x1x0*x2x1*x2, 
128  136  x0^2*x2x0*x2^2x1*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^22*y^3,6*x^2*y6*x*y^2, 0, 
159  170  6*x^2*y6*x*y^2, 6*y+2*x^36*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^472*x^3*y+72*x*y^324*y^448*x^4*y^2+64*x^3*y^348*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) 