Testing bra-ket notation capabilities of sneg.m
Part of SNEG package, http://nrgljubljana.ijs.si/sneg
Rok Zitko, rok.zitko@ijs.si, May 2006, March 2007

<< sneg`sneg`;

snegfermionoperators[a, b]
snegrealconstants[J]

Empty bra and ket

bra[]
ket[]

Simple bras and kets

bra[1]
2  bra[1]
bra[1] + bra[2]
ket[1]
2  ket[1]
ket[1] + ket[2]
nc[ket[1], bra[1]]

Simple cases for brakets

nc[bra[1], ket[1]]
nc[bra[1], ket[2]]
nc[bra[x], ket[y]]
nc[bra[x], ket[y], bra[w], ket[z]]

Cases with several quantum numbers. Null is a placeholder representing an undefined value.

bra[1, 2]
bra[1, Null]
bra[Null, 2]
bra[1, 2, 3]
bra[1, Null, 3]

In evaluating brakets, paired Null elements are ignored.

nc[bra[Null], ket[Null]]
nc[bra[Null, Null], ket[Null, Null]]
nc[bra[Null, Null, x, Null], 
      ket[Null, Null, y, Null]]
nc[bra[Null, Null, x, Null], 
      ket[Null, Null, y, 1]]
nc[bra[1, Null], ket[Null, 2]]

Scalar product is evaluated only when bra and ket have compatible pair pattern.

nc[bra[x, Null], ket[y, 1]]
nc[bra[Null, x1], %]

Bras and kets are shifted to the right of operator expressions

operatorQ[a]
nc[ket[], bra[], a[]]
nc[bra[], a[]]
nc[a[], bra[], b[]]
nc[bra[1], a[], ket[1]]

Test concatenation of indeces: do nothing if the patterns are no compatible!

a1 = nc[ket[x1], ket[y1]]
a2 = nc[bra[y2], bra[x2]]

These are allowes and are suitably concatenated

nc[ket[Null, y1], ket[x1, Null]]
nc[ket[x1, Null], ket[Null, y1]]
nc[bra[Null, y2], bra[x2, Null]]
nc[bra[x2, Null], bra[Null, y2]]

k1 = ket[Null, y1]~nc~ket[x1, Null]
b1 = bra[x2, Null]~nc~bra[Null, y2]
nc[b1, k1]

spinket[1/2]
spinbra[1/2]

Spin operators in ket/bra representation

sz = spinketbraZ[1/2]
sp = spinketbraP[1/2]
sm = spinketbraM[1/2]
sx = spinketbraX[1/2]
sy = spinketbraY[1/2]

nc[sz, ket[1/2]]
nc[sz, ket[-1/2]]

ops = {a[], b[]};
makebasis[ops]
v = vacuum[]
MatrixForm[bz = qsbasis[ops]]
MatrixForm[
      bvc = Map[{#[[1]], ap[#[[2]], v]} &, bz]]

We now override default formatting rules for bras and kets

PrettyOutputBraKetRule = { 
Null -> "\
∘",  
1/2  -> 
            StyleBox["↑", 
              FontColor -> Red], 
-1/2 -> 
            StyleBox["↓", 
              FontColor -> Blue]};

Basis for spin 1/2 operator represented by pseudospin a[]

baza = QSpseudospin[bvc, a[]];
baza // MatrixForm

Operator Sz.sz

oz = 
      nc[sz, 1/2 (number[b[], UP] - number[b[], DO])] // 
        Expand

op = nc[sp, b[CR, DO]~nc~b[AN, UP]]
om = nc[sm, b[CR, UP]~nc~b[AN, DO]]

spinspin[a[], b[]] // Expand

ss = oz + 1/2 (op + om) // Expand

spinbasis[1/2]

ket[x1]
conj[%]

{ket[x1],  ket[x2]}
conj[%]

ap[Null, vc[]]

ap[ket[1], vc[]]

ap[ket[1],  vc[0, 0]]

ap[bra[x],  %]

Consecutive additing of quantum numbers

ap[ket[1, Null, Null],  vc[0, 0]]
ap[ket[Null, 2, Null], %]
xx = ap[ket[Null, Null, 3], %]

Do nothing!

ap[ket[1], vc[0, 0]]
ap[ket[2], %]

xx
ap[bra[x1, x2, x3], xx]
ap[bra[x1, Null, Null], xx]

baza // MatrixForm

Normalisation

b1 = baza[[2, 2, 1]]
c1 = conj[b1]
c1~nc~b1
vev[%]

Heisenberg Hamiltonian

H = J ss

b1 = baza[[2, 2, 1]]
c1 = conj[b1]
nc[c1, H, b1] // Simplify
vev[%]

b1 = baza[[3, 2, 1]]
c1 = conj[b1]
nc[c1, H, b1] // Simplify
vev[%]

sb = baza[[4, 2]]
matrixrepresentationop[H, sb, sb]

x = nc[a[CR, UP], ket[1/2]]
ap[x, v]

MatrixForm[baza]
MatrixForm[
      bazavc = Map[{#[[1]], ap[#[[2]], v]} &, baza]]

sb = bazavc[[2, 2]]
matrixrepresentationvc[H, sb]