diff --git a/src/sage/interfaces/macaulay2.py b/src/sage/interfaces/macaulay2.py index 7042c460649..d32e5785a62 100644 --- a/src/sage/interfaces/macaulay2.py +++ b/src/sage/interfaces/macaulay2.py @@ -1357,6 +1357,11 @@ def _sage_(self): sage: R.sage() # optional - macaulay2 Vector space of dimension 2 over Rational Field + sage: macaulay2("vector {4_QQ, 2}").sage() # optional - macaulay2 + (4, 2) + sage: _.parent() # optional - macaulay2 + Vector space of dimension 2 over Rational Field + sage: m = macaulay2('"hello"') # optional - macaulay2 sage: m.sage() # optional - macaulay2 'hello' @@ -1377,10 +1382,8 @@ def _sage_(self): if cls_str == "List": return [entry._sage_() for entry in self] elif cls_str == "Matrix": - from sage.matrix.all import matrix base_ring = self.ring()._sage_() - entries = self.entries()._sage_() - return matrix(base_ring, entries) + return self._matrix_(base_ring) elif cls_str == 'HashTable': return {x._sage_(): y._sage_() for (x, y) in self.pairs()} elif cls_str == "Ideal": @@ -1468,6 +1471,9 @@ def _sage_(self): from sage.misc.sage_eval import sage_eval gens_dict = parent.gens_dict() return sage_eval(self.external_string(), gens_dict) + elif cls_cls_str == "Module": + entries = self.entries()._sage_() + return parent._element_constructor_(entries) from sage.misc.sage_eval import sage_eval try: @@ -1478,6 +1484,27 @@ def _sage_(self): from sage.misc.superseded import deprecated_function_alias to_sage = deprecated_function_alias(27848, ExpectElement.sage) + def _matrix_(self, R): + r""" + If ``self`` is a Macaulay2 matrix, return the corresponding Sage matrix + over the Sage ring ``R``. + + INPUT: + + - ``R`` - ring to coerce into + + OUTPUT: matrix + + EXAMPLES:: + + sage: A = macaulay2('matrix {{1,2},{3,4}}') # optional - macaulay2 + sage: matrix(QQ, A) # optional - macaulay2, indirect doctest + [1 2] + [3 4] + """ + from sage.matrix.all import matrix + return matrix(R, self.entries()._sage_()) + @instancedoc class Macaulay2Function(ExpectFunction): diff --git a/src/sage/matrix/matrix1.pyx b/src/sage/matrix/matrix1.pyx index e40239b0d26..6ddcf1cf7ba 100644 --- a/src/sage/matrix/matrix1.pyx +++ b/src/sage/matrix/matrix1.pyx @@ -440,10 +440,21 @@ cdef class Matrix(Matrix0): sage: macaulay2(m) #optional - macaulay2 | x y | | x+1 y+1 | + + TESTS: + + Entries of the matrix get promoted to the base ring (:trac:`28566`):: + + sage: R. = QQ[] + sage: m = macaulay2(matrix(R, [[1, 2], [3, 4]])) # optional - macaulay2 + sage: m.ring()._operator('===', R).sage() # optional - macaulay2 + True """ - base_ring = macaulay2(self.base_ring()) - entries = list(map(list, self)) - return macaulay2(entries).matrix() + if macaulay2 is None: + from sage.interfaces.macaulay2 import macaulay2 as m2_default + macaulay2 = m2_default + entries = [list(row) for row in self] + return macaulay2(self.base_ring()).matrix(entries) def _scilab_init_(self): diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index d47607707e8..0b3a62602ec 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -3485,6 +3485,41 @@ cdef class FreeModuleElement(Vector): # abstract base class """ return True + def _macaulay2_(self, macaulay2=None): + r""" + Convert this vector to a Macaulay2 vector. + + EXAMPLES:: + + sage: vector(QQ, [1, 2, 3])._macaulay2_() # optional - macaulay2 + | 1 | + | 2 | + | 3 | + sage: _.ring() # optional - macaulay2 + QQ + + :: + + sage: R. = QQ[] + sage: macaulay2(vector(R, [1, x+y])) # optional - macaulay2 + | 1 | + | x+y | + + TESTS: + + Entries of the vector get promoted to the base ring:: + + sage: R. = QQ[] + sage: v = macaulay2(vector(R, [1, 2])) # optional - macaulay2 + sage: v.ring()._operator('===', R).sage() # optional - macaulay2 + True + """ + if macaulay2 is None: + from sage.interfaces.macaulay2 import macaulay2 as m2_default + macaulay2 = m2_default + return (macaulay2(self.base_ring()).matrix([self.list()]).transpose() + .vector()) + def _mathematica_init_(self): """ Returns string representation of this vector as a Mathematica diff --git a/src/sage/rings/finite_rings/finite_field_base.pyx b/src/sage/rings/finite_rings/finite_field_base.pyx index 9c7eeecc3c6..a119ca8e9f2 100644 --- a/src/sage/rings/finite_rings/finite_field_base.pyx +++ b/src/sage/rings/finite_rings/finite_field_base.pyx @@ -251,14 +251,25 @@ cdef class FiniteField(Field): EXAMPLES:: sage: GF(97,'a')._macaulay2_init_() - 'GF 97' + 'GF(97,Variable=>symbol x)' sage: macaulay2(GF(97, 'a')) # optional - macaulay2 GF 97 sage: macaulay2(GF(49, 'a')) # optional - macaulay2 GF 49 + + TESTS: + + The variable name is preserved (:trac:`28566`):: + + sage: K = macaulay2(GF(49, 'b')) # optional - macaulay2 + sage: K.gens() # optional - macaulay2 + {b} + sage: K._sage_() # optional - macaulay2 + Finite Field in b of size 7^2 """ - return "GF %s"%(self.order()) + return "GF(%s,Variable=>symbol %s)" % (self.order(), + self.variable_name()) def _sage_input_(self, sib, coerced): r"""