Ask Your Question

Can attributes of sage classes be changed?

asked 2020-10-13 19:37:51 +0200

more_weight gravatar image

I want to change the way vectors are rendered in sagetex. For example, consider v = vector([1, 2, 3]). In sagetex, the command $v=\sage{v}$ renders as $$ v=(1, 2, 3) $$ Instead, I want my vectors to take the form $$ v=\left[\begin{array}{rrr}1&2&3\end{array}\right]^\intercal $$ I thought I could do this by resetting the _latex_ method of the sage.modules.free_module_element.FreeModuleElement class as follows.

def my_vector_latex(self):
    return matrix(v)._latex_() + r'^\intercal'

setattr(sage.modules.free_module_element.FreeModuleElement, '_latex_', my_vector_latex)

However, this code throws the following error:

TypeError: can't set attributes of built-in/extension type 'sage.modules.free_module_element.FreeModuleElement'

So, it looks like I can't modify the methods of FreeModuleElement in this way. Is there anything else I could do?

edit retag flag offensive close merge delete


The problem is that FreeModuleElementis a Cython class, and attributes of those can't be modified, I believe. See

John Palmieri gravatar imageJohn Palmieri ( 2020-10-14 05:15:03 +0200 )edit

Are there any workarounds?

more_weight gravatar imagemore_weight ( 2020-10-14 06:03:32 +0200 )edit

Cython classes can't be monkey-patched, indeed. ISTR to have tried that, unsuccessfully...


You might try creating a subclass of the relevant base class (in your case sage.modules.vector_integer_dense.Vector_integer_dense), with updated latex-related methods.But that should be done for any vector class you wish to use...


Or propose a patch allowing setting _latex_ attribute of vectors at run time, as it is done for var and function. But that could be (run time) costly...

Emmanuel Charpentier gravatar imageEmmanuel Charpentier ( 2020-10-14 08:14:51 +0200 )edit

1 Answer

Sort by ยป oldest newest most voted

answered 2020-10-15 01:17:19 +0200

updated 2020-10-16 00:16:20 +0200

I haven't tried this in sagetex, but it works in a Sage session:

sage: v = vector([1,2,3])
sage: latex(v)

That's not what you want, so use latex.vector_delimiters to change the parentheses to what you want:

sage: latex.vector_delimiters("[", "]^{\\intercal}")
sage: latex(v)

Edit: An alternative is to modify your sagetex.sty file: change the line




Or maybe better, create an .sty file with this change, with a new name and use that instead of sagetex.sty.

Then the first thing in your LaTeX file (after "\begin{document}") should be

def my_print(v):
    if isinstance(v, sage.modules.free_module_element.FreeModuleElement):
        return matrix(v)._latex_() + r'^\intercal'
        return latex(v)

Then you can customize the output for each class, however you want.

edit flag offensive delete link more


This isn't quite what I want. The commas are still there and the numbers are not inside an array.

more_weight gravatar imagemore_weight ( 2020-10-15 20:46:05 +0200 )edit

I added an alternative in the edit.

John Palmieri gravatar imageJohn Palmieri ( 2020-10-16 00:16:42 +0200 )edit

Really cool idea! Thanks!

more_weight gravatar imagemore_weight ( 2020-10-16 16:56:00 +0200 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower


Asked: 2020-10-13 19:37:51 +0200

Seen: 299 times

Last updated: Oct 16 '20