macaulay2.eval("""
K = toField(QQ[zet]/(zet^8 - zet^7 +zet^5 - zet^4 +zet^3 -zet + 1))
A=matrix{{zet^1,0},{0,zet^13}}
needsPackage "InvariantRing"
G=generateGroup({A},K)
P = molienSeries G
""")macaulay2.eval("""
needsPackage "Points";
M = matrix{{1,2,3},{4,5,6}}
R = QQ[x,y,MonomialOrder=>Lex];
(Q,inG,G) = points(M,R)
G#0
ring G#0
""")
G0 = macaulay2('G#0').to_sage(); G0 3 2
y - 15y + 74y - 120
I convert this to a sage object, G0, and it appears as:y^3 - 15*y^2 + 74*y - 120
The part that I really need is where Sage changes M2's two-line display for exponents on variables to just the standard Sage notation. I'm looking at the to_sage()
method in the source code but I can't seem to figure out how it's doing it. Am I missing something obvious? G#0 is a polynomial ring I believe, and here
is the code in the to_sage function for PolynomialRings:
elif cls_str == "PolynomialRing":
from sage.rings.all import PolynomialRing
from sage.rings.polynomial.term_order import inv_macaulay2_name_mapping
#Get the base ring
base_ring = self.coefficientRing().to_sage()
#Get a string list of generators
gens = str(self.gens())[1:-1]
# Check that we are dealing with default degrees, i.e. 1's.
if self.degrees().any("x -> x != {1}").to_sage():
raise ValueError("cannot convert Macaulay2 polynomial ring with non-default degrees to Sage")
#Handle the term order
external_string = self.external_string()
order = None
if "MonomialOrder" not in external_string:
order = "degrevlex"
else:
for order_name in inv_macaulay2_name_mapping:
if order_name in external_string:
order = inv_macaulay2_name_mapping[order_name]
if len(gens) > 1 and order is None:
raise ValueError("cannot convert Macaulay2's term order to a Sage term order")
return PolynomialRing(base_ring, order=order, names=gens)
Where in this code does that conversion happen? It's like parsing ascii art...Hey everyone:
I was hoping some of you could provide some insight where my knowledge is lacking. I'm trying to add to the M2/Sage interface by adding a conversion for the M2 Divide class. Sage can already convert polynomials, so my hope was to just have it treat the Divide class as two polynomials, one in the numerator and the other in the denominator.
Here is an example of an object in the divide class:macaulay2.eval("""
K = toField(QQ[zet]/(zet^8 - zet^7 +zet^5 - zet^4 +zet^3 -zet + 1))
A=matrix{{zet^1,0},{0,zet^13}}
needsPackage "InvariantRing"
G=generateGroup({A},K)
P = molienSeries G
""")
elif cls_str == "Divide":
self_Div = self
div_Numerator = macaulay2('numerator self_Div')
div_Denominator = macaulay2('denominator self_Div')
div_Numerator = div_Numerator.sage_polystring()
div_Denominator = div_Denominator.sage_polystring()
sage_Div = div_Numerator/div_Denominator
return sage_Div
sage: macaulay2.eval("""
....: K = toField(QQ[zet]/(zet^8 - zet^7 +zet^5 - zet^4 +zet^3 -zet + 1))
....: A=matrix{{zet^1,0},{0,zet^14}}
....: needsPackage "InvariantRing"
....: G=generateGroup({A},K)
....: P = molienSeries G
....: """)
K
PolynomialRing
| zet 0 |
| 0 -zet^7+zet^6-zet^4+zet^3-zet^2+1 |
2 2
Matrix K <--- K
InvariantRing
Package
{| 1 0 |, | -zet^7-zet^2 0 |, | zet^7 0 |, | zet^7-zet^6-zet^3+zet^2-1 0 |, | -zet^7+zet^6-zet^4+zet^3-zet^2+1 0 |, | zet 0 |, | -zet^6-zet 0 |, | zet^5 0 |, | zet^2 0 |, | zet^6 0 |, | zet^7-zet^5+zet^4-zet^3+zet-1 0 |, | zet^4 0 |, | -zet^7+zet^5-zet^4-zet+1 0 |, | zet^3 0 |, | -zet^5-1 0 |}
| 0 1 | | 0 zet^3 | | 0 zet^7-zet^5+zet^4-zet^3+zet-1 | | 0 zet^6 | | 0 zet | | 0 -zet^7+zet^6-zet^4+zet^3-zet^2+1 | | 0 zet^4 | | 0 -zet^5-1 | | 0 -zet^7+zet^5-zet^4-zet+1 | | 0 zet^7-zet^6-zet^3+zet^2-1 | | 0 zet^7 | | 0 -zet^6-zet | | 0 zet^2 | | 0 -zet^7-zet^2 | | 0 zet^5 |
List
2 3 4 5 6 7 8 9 10 11 12 13 14
1 - T + T - T + T - T + T - T + T - T + T - T + T - T + T
---------------------------------------------------------------------------
2 3 4 5 7 8 2 2 3 4
(1 - T) (1 - T + T - T + T - T + T )(1 + T + T )(1 + T + T + T + T )
Expression of class Divide
sage: G = macaulay2('P').to_sage()
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/home/saad/sage/local/lib/python2.7/site-packages/sage/all_cmdline.pyc in <module>()
----> 1 G = macaulay2('P').to_sage()
/home/saad/sage/local/lib/python2.7/site-packages/sage/interfaces/macaulay2.pyc in to_sage(self)
1151 elif cls_str == "Divide":
1152 self_Div = self
-> 1153 div_Numerator = macaulay2('numerator self_Div')
1154 div_Denominator = macaulay2('denominator self_Div')
1155 div_Numerator = div_Numerator.sage_polystring()
/home/saad/sage/local/lib/python2.7/site-packages/sage/interfaces/interface.pyc in __call__(self, x, name)
241
242 if isinstance(x, six.string_types):
--> 243 return cls(self, x, name=name)
244 try:
245 return self._coerce_from_special_method(x)
/home/saad/sage/local/lib/python2.7/site-packages/sage/interfaces/expect.pyc in __init__(self, parent, value, is_name, name)
1379 except (RuntimeError, ValueError) as x:
1380 self._session_number = -1
-> 1381 raise_(TypeError, x, sys.exc_info()[2])
1382 except BaseException:
1383 self._session_number = -1
/home/saad/sage/local/lib/python2.7/site-packages/sage/interfaces/expect.pyc in __init__(self, parent, value, is_name, name)
1374 else:
1375 try:
-> 1376 self._name = parent._create(value, name=name)
1377 # Convert ValueError and RuntimeError to TypeError for
1378 # coercion to work properly.
/home/saad/sage/local/lib/python2.7/site-packages/sage/interfaces/interface.pyc in _create(self, value, name)
431 def _create(self, value, name=None):
432 name = self._next_var_name() if name is None else name
--> 433 self.set(name, value)
434 return name
435
/home/saad/sage/local/lib/python2.7/site-packages/sage/interfaces/macaulay2.pyc in set(self, var, value)
318 ans = Expect.eval(self, cmd)
319 if ans.find("stdio:") != -1:
--> 320 raise RuntimeError("Error evaluating Macaulay2 code.\nIN:%s\nOUT:%s"%(cmd, ans))
321
322 def _object_class(self):
TypeError: Error evaluating Macaulay2 code.
IN:sage1=numerator self_Div;
OUT:stdio:13:7:(3): error: no method found for applying numerator to:
argument : self (of class IndexedVariable)
Div
Well, here's what i tried and it doesn't seem to work after I build sage again. I added this code to the to_sage() function,elif cls_str == "Divide":
self_Div = self
div_Numerator = macaulay2('numerator self_Div')
div_Denominator = macaulay2('denominator self_Div')
div_Numerator = div_Numerator.sage_polystring()
div_Denominator = div_Denominator.sage_polystring()
sage_Div = div_Numerator/div_Denominator
return sage_Div
On Sunday, July 3, 2016 at 1:21:18 AM UTC+1, saad khalid wrote:Well, here's what i tried and it doesn't seem to work after I build sage again. I added this code to the to_sage() function,elif cls_str == "Divide":
self_Div = self
div_Numerator = macaulay2('numerator self_Div')
div_Denominator = macaulay2('denominator self_Div')
div_Numerator = div_Numerator.sage_polystring()
div_Denominator = div_Denominator.sage_polystring()
sage_Div = div_Numerator/div_Denominator
return sage_Divself_Div is not known to M2 in any way, yet you try calling in M2 'numerator self_Div'.You need a way to get the counterpart of 'self' in M2 somehow.
elif cls_str == "Divide":
div_Str = repr_str
div_Numerator = macaulay2('numerator div_Str')
div_Denominator = macaulay2('denominator div_Str')
div_Numerator = div_Numerator.sage_polystring()
div_Denominator = div_Denominator.sage_polystring()
sage_Div = div_Numerator/div_Denominator
return sage_Div
def sage_prodstring(self):
"""
If this Macaulay2 element is a Product, return a string
representation of this Product that is suitable for
evaluation in Python. Needed internally for using to_sage on objects of class Divide.
EXAMPLES::
"""
external_string = self.external_String()
prod_String = re.findall("new Power from \{(.+?),(.+?)\}", external_string)
final_Prod = ""
for i in range(0, len(prod_String)):
final_Prod += "(" + prod_String[i][0] + ")" + '^' + prod_String[i][1] + "*"
final_Prod = final_Prod[:-1]
return final_Prod elif cls_str == "Divide":
div_Numerator = self.numerator()
div_Denominator = self.denominator()
div_Numerator = div_Numerator.sage_polystring()
div_Denominator = div_Denominator.sage_prodstring()
sage_Div = "(" + div_Numerator ")" + "/" + "(" + div_Denominator + ")"
return sage_Divsage: macaulay2.eval("""
....: K = toField(QQ[zet]/(zet^8 - zet^7 +zet^5 - zet^4 +zet^3 -zet + 1))
....: A=matrix{{zet^1,0},{0,zet^14}}
....: needsPackage "InvariantRing"
....: G=generateGroup({A},K)
....: P = molienSeries G
....: """)
sage: macaulay2('P').to_sage()
macaulay2('P').to_sage().taylor()" or something, but I'm not sure how to convert the string. So, after fixing a small typo, here is the output from an example:sage: macaulay2.eval("""
....: K = toField(QQ[zet]/(zet^8 - zet^7 +zet^5 - zet^4 +zet^3 -zet + 1))
....: A=matrix{{zet^1,0},{0,zet^14}}
....: needsPackage "InvariantRing"
....: G=generateGroup({A},K)
....: P = molienSeries G
....: """)
sage: macaulay2('P').to_sage()
'(1-T+T**2-T**3+T**4-T**5+T**6-T**7+T**8-T**9+T**10-T**11+T**12-T**13+T**14)/((1-T)^2*(1-T+T^3-T^4+T^5-T^7+T^8)^1*(1+T+T^2)^1*(1+T+T^2+T^3+T^4)^1)'
Side note: Never use += on a string in a loop. Here it's even worse,
since you are concatenating strings on the right hand side as well.