Interface to Macaulay2

Note

You must have Macaulay2 installed on your computer for this interface to work. Macaulay2 is not included with Sage, but you can obtain it from <http://www.math.uiuc.edu/Macaulay2/>. Note additional optional Sage packages are required.

Sage provides an interface to the Macaulay2 computational algebra system. This system provides extensive functionality for commutative algebra. You do not have to install any optional packages.

The Macaulay2 interface offers three pieces of functionality:

  • Macaulay2_console() – A function that dumps you into an interactive command-line Macaulay2 session.
  • Macaulay2(expr) – Evaluation of arbitrary Macaulay2 expressions, with the result returned as a string.
  • Macaulay2.new(expr) – Creation of a Sage object that wraps a Macaulay2 object. This provides a Pythonic interface to Macaulay2. For example, if f=Macaulay2.new(10), then f.gcd(25) returns the GCD of \(10\) and \(25\) computed using Macaulay2.

EXAMPLES:

sage: print(macaulay2('3/5 + 7/11')) # optional - macaulay2
68
--
55
sage: f = macaulay2('f = i -> i^3') # optional - macaulay2
sage: f                             # optional - macaulay2
f
sage: f(5)                          # optional - macaulay2
125

sage: R = macaulay2('ZZ/5[x,y,z]')  # optional - macaulay2
sage: print(R)                       # optional - macaulay2
ZZ
--[x..z, Degrees => {3:1}, Heft => {1}, MonomialOrder => {MonomialSize => 32}, DegreeRank => 1]
 5                                                       {GRevLex => {3:1}  }
                                                         {Position => Up    }
sage: x = macaulay2('x')            # optional - macaulay2
sage: y = macaulay2('y')            # optional - macaulay2
sage: print((x+y)^5)                # optional - macaulay2
 5    5
x  + y
sage: parent((x+y)^5)               # optional - macaulay2
Macaulay2

sage: R = macaulay2('QQ[x,y,z,w]')  # optional - macaulay2
sage: f = macaulay2('x^4 + 2*x*y^3 + x*y^2*w + x*y*z*w + x*y*w^2 + 2*x*z*w^2 + y^4 + y^3*w + 2*y^2*z*w + z^4 + w^4') # optional - macaulay2
sage: print(f)                      # optional - macaulay2
 4       3    4    4      2     3                2           2         2    4
x  + 2x*y  + y  + z  + x*y w + y w + x*y*z*w + 2y z*w + x*y*w  + 2x*z*w  + w
sage: g = f * macaulay2('x+y^5')    # optional - macaulay2
sage: print(g.factor())             # optional - macaulay2
  4       3    4    4      2     3                2           2         2    4   5
(x  + 2x*y  + y  + z  + x*y w + y w + x*y*z*w + 2y z*w + x*y*w  + 2x*z*w  + w )(y  + x)

AUTHORS:

  • Kiran Kedlaya and David Roe (2006-02-05, during Sage coding sprint)
  • William Stein (2006-02-09): inclusion in Sage; prompt uses regexp, calling of Macaulay2 functions via __call__.
  • William Stein (2006-02-09): fixed bug in reading from file and improved output cleaning.
  • Kiran Kedlaya (2006-02-12): added ring and ideal constructors, list delimiters, is_Macaulay2Element, sage_polystring, __floordiv__, __mod__, __iter__, __len__; stripped extra leading space and trailing newline from output.

Todo

Get rid of all numbers in output, e.g., in ideal function below.

class sage.interfaces.macaulay2.Macaulay2(maxread=None, script_subdirectory=None, logfile=None, server=None, server_tmpdir=None)

Bases: sage.interfaces.tab_completion.ExtraTabCompletion, sage.interfaces.expect.Expect

Interface to the Macaulay2 interpreter.

console()

Spawn a new M2 command-line session.

EXAMPLES:

sage: macaulay2.console()                    # not tested
Macaulay 2, version 1.1
with packages: Classic, Core, Elimination, IntegralClosure, LLLBases, Parsing, PrimaryDecomposition, SchurRings, TangentCone
...
cputime(t=None)

EXAMPLES:

sage: R = macaulay2("QQ[x,y]")  # optional - macaulay2
sage: x,y = R.gens()            # optional - macaulay2
sage: a = (x+y+1)^20            # optional - macaulay2
sage: macaulay2.cputime()       # optional - macaulay2; random
0.48393700000000001
eval(code, strip=True, **kwds)

Send the code x to the Macaulay2 interpreter and return the output as a string suitable for input back into Macaulay2, if possible.

INPUT:

  • code – str
  • strip – ignored

EXAMPLES:

sage: macaulay2.eval("2+2") # optional - macaulay2
4
get(var)

Get the value of the variable var.

EXAMPLES:

sage: macaulay2.set("a", "2") # optional - macaulay2
sage: macaulay2.get("a")      # optional - macaulay2
2
help(s)

EXAMPLES:

sage: macaulay2.help("load")  # optional - macaulay2
load ...
****...
...
  * "input" -- read Macaulay2 commands and echo
  * "notify" -- whether to notify the user when a file is loaded
ideal(*gens)

Return the ideal generated by gens.

INPUT:

  • gens – list or tuple of Macaulay2 objects (or objects that can be made into Macaulay2 objects via evaluation)

OUTPUT:

the Macaulay2 ideal generated by the given list of gens

EXAMPLES:

sage: R2 = macaulay2.ring('QQ', '[x, y]'); R2            # optional - macaulay2
QQ[x..y, Degrees => {2:1}, Heft => {1}, MonomialOrder => {MonomialSize => 16}, DegreeRank => 1]
                                                         {Lex => 2          }
                                                         {Position => Up    }
sage: I = macaulay2.ideal( ('y^2 - x^3', 'x - y') ); I   # optional - macaulay2
          3    2
ideal (- x  + y , x - y)
sage: J = I^3; J.gb().gens().transpose()                 # optional - macaulay2
{-9} | y9-3y8+3y7-y6             |
{-7} | xy6-2xy5+xy4-y7+2y6-y5    |
{-5} | x2y3-x2y2-2xy4+2xy3+y5-y4 |
{-3} | x3-3x2y+3xy2-y3           |
new_from(type, value)

Return a new Macaulay2Element of type type constructed from value.

EXAMPLES:

sage: l = macaulay2.new_from("MutableList", [1,2,3]) # optional - macaulay2
sage: l                                              # optional - macaulay2
MutableList{...3...}
sage: list(l)                                        # optional - macaulay2
[1, 2, 3]
restart()

Restart Macaulay2 interpreter.

ring(base_ring='ZZ', vars='[x]', order='Lex')

Create a Macaulay2 ring.

INPUT:

  • base_ring – base ring (see examples below)
  • vars – a tuple or string that defines the variable names
  • order – string – the monomial order (default: ‘Lex’)

OUTPUT:

  • a Macaulay2 ring (with base ring ZZ)

EXAMPLES:

This is a ring in variables named a through d over the finite field of order 7, with graded reverse lex ordering:

sage: R1 = macaulay2.ring('ZZ/7', '[a..d]', 'GRevLex');  R1  # optional - macaulay2
ZZ
--[a..d, Degrees => {4:1}, Heft => {1}, MonomialOrder => {MonomialSize => 16}, DegreeRank => 1]
 7                                                       {GRevLex => {4:1}  }
                                                         {Position => Up    }
sage: R1.char()                                             # optional - macaulay2
7

This is a polynomial ring over the rational numbers:

sage: R2 = macaulay2.ring('QQ', '[x, y]'); R2               # optional - macaulay2
QQ[x..y, Degrees => {2:1}, Heft => {1}, MonomialOrder => {MonomialSize => 16}, DegreeRank => 1]
                                                         {Lex => 2          }
                                                         {Position => Up    }
set(var, value)

Set the variable var to the given value.

EXAMPLES:

sage: macaulay2.set("a", "2")  # optional - macaulay2
sage: macaulay2.get("a")       # optional - macaulay2
2
use(R)

Use the Macaulay2 ring R.

EXAMPLES:

sage: R = macaulay2("QQ[x,y]")                  # optional - macaulay2
sage: P = macaulay2("ZZ/7[symbol x, symbol y]") # optional - macaulay2
sage: macaulay2("x").cls()                      # optional - macaulay2
ZZ
--[x..y, Degrees => {2:1}, Heft => {1}, MonomialOrder => {MonomialSize => 32}, DegreeRank => 1]
 7                                                       {GRevLex => {2:1}  }
                                                         {Position => Up    }
sage: macaulay2.use(R)                          # optional - macaulay2
sage: macaulay2("x").cls()                      # optional - macaulay2
QQ[x..y, Degrees => {2:1}, Heft => {1}, MonomialOrder => {MonomialSize => 32}, DegreeRank => 1]
                                                         {GRevLex => {2:1}  }
                                                         {Position => Up    }
version()

Returns the version of Macaulay2.

EXAMPLES:

sage: macaulay2.version() # optional - macaulay2
(1, 1...
class sage.interfaces.macaulay2.Macaulay2Element(parent, value, is_name=False, name=None)

Bases: sage.interfaces.tab_completion.ExtraTabCompletion, sage.interfaces.expect.ExpectElement

cls()

Since class is a keyword in Python, we have to use cls to call Macaulay2’s class. In Macaulay2, class corresponds to Sage’s notion of parent.

EXAMPLES:

sage: macaulay2(ZZ).cls()  # optional - macaulay2
Ring
dot(x)

EXAMPLES:

sage: d = macaulay2.new("MutableHashTable") # optional - macaulay2
sage: d["k"] = 4                            # optional - macaulay2
sage: d.dot("k")                            # optional - macaulay2
4
external_string()

EXAMPLES:

sage: R = macaulay2("QQ[symbol x, symbol y]")  # optional - macaulay2
sage: R.external_string()                      # optional - macaulay2
'QQ(monoid[x..y, Degrees => {2:1}, Heft => {1}, MonomialOrder => VerticalList{MonomialSize => 32, GRevLex => {2:1}, Position => Up}, DegreeRank => 1])'
repr()

EXAMPLES:

sage: R = macaulay2("QQ[x,y,z]/(x^3-y^3-z^3)") # optional - macaulay2
sage: x = macaulay2('x')                       # optional - macaulay2
sage: y = macaulay2('y')                       # optional - macaulay2
sage: print(x+y)                               # optional - macaulay2
x + y
sage: print(macaulay2("QQ[x,y,z]"))            # optional - macaulay2
QQ[x..z, Degrees => {3:1}, Heft => {1}, MonomialOrder => {MonomialSize => 32}, DegreeRank => 1]
                                                         {GRevLex => {3:1}  }
                                                         {Position => Up    }
sage: print(macaulay2("QQ[x,y,z]/(x+y+z)"))    # optional - macaulay2
QQ[x, y, z]
-----------
 x + y + z
sage_polystring()

If this Macaulay2 element is a polynomial, return a string representation of this polynomial that is suitable for evaluation in Python. Thus * is used for multiplication and ** for exponentiation. This function is primarily used internally.

EXAMPLES:

sage: R = macaulay2.ring('QQ','(x,y)')               # optional - macaulay2
sage: f = macaulay2('x^3 + 3*y^11 + 5')              # optional - macaulay2
sage: print(f)                                       # optional - macaulay2
 3     11
x  + 3y   + 5
sage: f.sage_polystring()                            # optional - macaulay2
'x**3+3*y**11+5'
sharp(x)

EXAMPLES:

sage: a = macaulay2([1,2,3]) # optional - macaulay2
sage: a.sharp(0)             # optional - macaulay2
1
starstar(x)

The binary operator ** in Macaulay2 is usually used for tensor or Cartesian power.

EXAMPLES:

sage: a = macaulay2([1,2]).set()  # optional - macaulay2
sage: a.starstar(a)               # optional - macaulay2
set {(1, 1), (1, 2), (2, 1), (2, 2)}
structure_sheaf()

EXAMPLES:

sage: S = macaulay2('QQ[a..d]')                     # optional - macaulay2
sage: R = S/macaulay2('a^3+b^3+c^3+d^3')            # optional - macaulay2
sage: X = R.Proj()                                  # optional - macaulay2
sage: print(X.structure_sheaf())                    # optional - macaulay2
OO
  sage...
subs(*args, **kwds)

Note that we have to override the substitute method so that we get the default one from Macaulay2 instead of the one provided by Element.

EXAMPLES:

sage: R = macaulay2("QQ[x]")            # optional - macaulay2
sage: P = macaulay2("ZZ/7[symbol x]")   # optional - macaulay2
sage: x, = R.gens()                     # optional - macaulay2
sage: a = x^2 + 1                       # optional - macaulay2
sage: a = a.substitute(P)               # optional - macaulay2
sage: a.to_sage().parent()              # optional - macaulay2
Univariate Polynomial Ring in x over Finite Field of size 7
substitute(*args, **kwds)

Note that we have to override the substitute method so that we get the default one from Macaulay2 instead of the one provided by Element.

EXAMPLES:

sage: R = macaulay2("QQ[x]")            # optional - macaulay2
sage: P = macaulay2("ZZ/7[symbol x]")   # optional - macaulay2
sage: x, = R.gens()                     # optional - macaulay2
sage: a = x^2 + 1                       # optional - macaulay2
sage: a = a.substitute(P)               # optional - macaulay2
sage: a.to_sage().parent()              # optional - macaulay2
Univariate Polynomial Ring in x over Finite Field of size 7
to_sage()

EXAMPLES:

sage: macaulay2(ZZ).to_sage()      # optional - macaulay2
Integer Ring
sage: macaulay2(QQ).to_sage()      # optional - macaulay2
Rational Field

sage: macaulay2(2).to_sage()       # optional - macaulay2
2
sage: macaulay2(1/2).to_sage()     # optional - macaulay2
1/2
sage: macaulay2(2/1).to_sage()     # optional - macaulay2
2
sage: _.parent()                   # optional - macaulay2
Rational Field
sage: macaulay2([1,2,3]).to_sage() # optional - macaulay2
[1, 2, 3]

sage: m = matrix([[1,2],[3,4]])
sage: macaulay2(m).to_sage()       # optional - macaulay2
[1 2]
[3 4]

sage: macaulay2(QQ['x,y']).to_sage()    # optional - macaulay2
Multivariate Polynomial Ring in x, y over Rational Field
sage: macaulay2(QQ['x']).to_sage()      # optional - macaulay2
Univariate Polynomial Ring in x over Rational Field
sage: macaulay2(GF(7)['x,y']).to_sage() # optional - macaulay2
Multivariate Polynomial Ring in x, y over Finite Field of size 7

sage: macaulay2(GF(7)).to_sage()       # optional - macaulay2
Finite Field of size 7
sage: macaulay2(GF(49, 'a')).to_sage() # optional - macaulay2
Finite Field in a of size 7^2

sage: R.<x,y> = QQ[]
sage: macaulay2(x^2+y^2+1).to_sage()   # optional - macaulay2
x^2 + y^2 + 1

sage: R = macaulay2("QQ[x,y]")         # optional - macaulay2
sage: I = macaulay2("ideal (x,y)")     # optional - macaulay2
sage: I.to_sage()                      # optional - macaulay2
Ideal (x, y) of Multivariate Polynomial Ring in x, y over Rational Field

sage: macaulay2("x = symbol x")           # optional - macaulay2
x
sage: macaulay2("QQ[x_0..x_2]").to_sage() # optional - macaulay2
Multivariate Polynomial Ring in x_0, x_1, x_2 over Rational Field

sage: X = R/I       # optional - macaulay2
sage: X.to_sage()   # optional - macaulay2
Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x, y)

sage: R = macaulay2("QQ^2")  # optional - macaulay2
sage: R.to_sage()            # optional - macaulay2
Vector space of dimension 2 over Rational Field

sage: m = macaulay2('"hello"')  # optional - macaulay2
sage: m.to_sage()               # optional - macaulay2
'hello'
underscore(x)

EXAMPLES:

sage: a = macaulay2([1,2,3])  # optional - macaulay2
sage: a.underscore(0)         # optional - macaulay2
1
class sage.interfaces.macaulay2.Macaulay2Function(parent, name)

Bases: sage.interfaces.expect.ExpectFunction

sage.interfaces.macaulay2.is_Macaulay2Element(x)

EXAMPLES:

sage: from sage.interfaces.macaulay2 import is_Macaulay2Element
sage: is_Macaulay2Element(2)              # optional - macaulay2
False
sage: is_Macaulay2Element(macaulay2(2))   # optional - macaulay2
True
sage.interfaces.macaulay2.macaulay2_console()

Spawn a new M2 command-line session.

EXAMPLES:

sage: macaulay2_console()                    # not tested
Macaulay 2, version 1.1
with packages: Classic, Core, Elimination, IntegralClosure, LLLBases, Parsing, PrimaryDecomposition, SchurRings, TangentCone
...
sage.interfaces.macaulay2.reduce_load_macaulay2()

Used for reconstructing a copy of the Macaulay2 interpreter from a pickle.

EXAMPLES:

sage: from sage.interfaces.macaulay2 import reduce_load_macaulay2
sage: reduce_load_macaulay2()
Macaulay2
sage.interfaces.macaulay2.remove_output_labels(s)

Remove output labels of Macaulay2 from a string.

  • s: output of Macaulay2
  • s: string

Returns: the input string with \(n\) symbols removed from the beginning of each line, where \(n\) is the minimal number of spaces or symbols of Macaulay2 output labels (looking like ‘o39 = ‘) present on every non-empty line.

Return type: string

Note

If s consists of several outputs and their lables have different width, it is possible that some strings will have leading spaces (or maybe even pieces of output labels). However, this function will try not cut any messages.

EXAMPLES:

sage: from sage.interfaces.macaulay2 import remove_output_labels
sage: output = 'o1 = QQ [x, y]\n\no1 : PolynomialRing\n'
sage: remove_output_labels(output)
'QQ [x, y]\n\nPolynomialRing\n'