I'm having difficulty getting properly formatted latex output for notation in the sage notebook. I am using sympy for sympy.physics.quantum.Bra and Ket, but cant seem to get proper latex behaviour out of them.
for instance, I want to show the symbol psi in a ket.
sage: p = var('Psi')
sage: show(p)
displays the greek character {\Psi}
but using sympy
sage: k = Ket(p)
sage: show(k)
displays plain text |Psi>
I have searched, tested and experimented to try and get formatted output, to no avail.
sage: latex(k)
{\left|\Psi\right\rangle} - plain text
creating a custom latex macro:
sage: from sage.misc.latex import latex_extra_preamble
sage: latex.add_macro("\\newcommand{\\ket}[1]{\\left|{#1}\\right\\rangle}")
sage: var("myket", latex_name=r"\ket{\alpha}")
sage: show(myket)
gives the output i want! latex style ket with the symbol for alpha... however, as soon as I try to apply this method to the sympy Ket, it fails
sage: k = Ket('k', latex_name=r"\left|{\Psi}\right\rangle")
sage: show(k)
and other variants, all spit out plain-text |k>
I have a feeling that there is a simple solution for this, some flag that i'm missing to get sympy to behave properly in sage notebook.
Here is a solution. It is probably not very robust but it could probably be adapted to your need. They are two problems here:
1 - You need to tell sage how to latex Bra and Ket. This can be done using latex_table
which is a dict associating type to latex type-setting functions:
from sympy.physics.quantum import Bra, Ket
def latexBra(x):
if len(x.args) == 1: # x.args contains the argument of the Bra
res = latex(x.args[0])
else:
res = ",".join(latex(i) for i in x.args)
return r"{\left|%s\right\rangle}"%res
from sage.misc.latex import latex_table
latex_table[Bra] = latexBra
Of course you have to do the same for Ket. You probably want to do that also for
sympy.physics.quantum.operator.OuterProduct
sympy.physics.quantum.operator.InnerProduct
...
However, this only solve part of the problem: latexing the Bra. Note that Phi isn't latexed.
sage: bPhi = Bra(var('Phi'))
sage: print latex(bPhi)
{\left|\text{\texttt{Phi}}\right\rangle}
2 - The reason is that Sympy bPhi
argument bPhi.args[0]
is not exactly the Sage variable Phi
but a Sympy Symbol
object:
sage: type(bPhi.args[0])
<class 'sympy.core.symbol.Symbol'>
However one can get back Sage's Phi
by coercing the Symbol
object back to Sage's symbolic ring (SR
):
sage: SR(bPhi.args[0]) is Phi
True
So you can do tell Sage to to that for latexing Sympy's Symbol
:
from sympy.core.symbol import Symbol
latex_table[Symbol] = lambda x : latex(SR(x))
And then:
sage: bPhi = Bra(var('Phi'))
sage: print latex(bPhi)
{\left|\Phi\right\rangle}