Question

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.

Was it helpful?

Solution

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}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top