# 1D Simple Harmonic Oscillator

## Imports


```python
from IPython.display import display, display_pretty
```


```python
from sympy import init_printing
init_printing(use_latex=True)
```


```python
from sympy import *
from sympy.physics.quantum import *
from sympy.physics.quantum.sho1d import *
from sympy.physics.quantum.tests.test_sho1d import *
```

## Printing Of Operators

Create a raising and lowering operator and make sure they print correctly


```python
ad = RaisingOp('a')
ad
```


```python
a = LoweringOp('a')
a
```


```python
print(latex(ad))
print(latex(a))
```

    a^{\dag}
    a



```python
display_pretty(ad)
display_pretty(a)
```


     †
    a 



    a



```python
print(srepr(ad))
print(srepr(a))
```

    RaisingOp(Symbol('a'))
    LoweringOp(Symbol('a'))



```python
print(repr(ad))
print(repr(a))
```

    RaisingOp(a)
    a


## Printing of States

Create a simple harmonic state and check its printing


```python
k = SHOKet('k')
k
```


```python
b = SHOBra('b')
b
```


```python
print(pretty(k))
print(pretty(b))
```

    ❘k⟩
    ⟨b❘



```python
print(latex(k))
print(latex(b))
```

    {\left|k\right\rangle }
    {\left\langle b\right|}



```python
print(srepr(k))
print(srepr(b))
```

    SHOKet(Symbol('k'))
    SHOBra(Symbol('b'))


## Properties

Take the dagger of the raising and lowering operators. They should return each other:


```python
Dagger(ad)
```


```python
Dagger(a)
```

Check commutators of the raising and lowering operators


```python
Commutator(ad,a).doit()
```


```python
Commutator(a,ad).doit()
```

Take a look at the dual states of the bra and ket


```python
k.dual
```


```python
b.dual
```

Taking the inner product of the bra and ket will return the Kronecker delta function


```python
InnerProduct(b,k).doit()
```

Take a look at how the raising and lowering operators act on states. We use qapply to apply an operator to a state


```python
qapply(ad*k)
```


```python
qapply(a*k)
```

But the states may have an explicit energy level. Let's look at the ground and first excited states


```python
kg = SHOKet(0)
kf = SHOKet(1)
```


```python
qapply(ad*kg)
```


```python
qapply(ad*kf)
```


```python
qapply(a*kg)
```


```python
qapply(a*kf)
```

## Number operator and Hamiltonian

Let's look at the number operator and Hamiltonian operator:


```python
k = SHOKet('k')
ad = RaisingOp('a')
a = LoweringOp('a')
N = NumberOp('N')
H = Hamiltonian('H')
```

The number operator is simply expressed as `ad*a`:


```python
N.rewrite('a').doit()
```

The number operator expressed in terms of the position and momentum operators:


```python
N.rewrite('xp').doit()
```

It can also be expressed in terms of the Hamiltonian operator:


```python
N.rewrite('H').doit()
```

The Hamiltonian operator can be expressed in terms of the raising and lowering operators, position and momentum operators, and the number operator:


```python
H.rewrite('a').doit()
```


```python
H.rewrite('xp').doit()
```


```python
H.rewrite('N').doit()
```

The raising and lowering operators can also be expressed in terms of the position and momentum operators


```python
ad.rewrite('xp').doit()
```


```python
a.rewrite('xp').doit()
```

### Properties

Let's take a look at how the number operator and Hamiltonian act on states:


```python
qapply(N*k)
```

Apply the number operator to a state returns the state times the ket:


```python
ks = SHOKet(2)
qapply(N*ks)
```


```python
qapply(H*k)
```

Let's see how the operators commute with each other:


```python
Commutator(N,ad).doit()
```


```python
Commutator(N,a).doit()
```


```python
Commutator(N,H).doit()
```

## Representation

We can express the operators in number operator basis. There are different ways to create a matrix in Python, we will use 3 different ways.

Sympy:


```python
represent(ad, basis=N, ndim=4, format='sympy')
```

Numpy:


```python
represent(ad, basis=N, ndim=5, format='numpy')
```




    array([[ 0.        ,  0.        ,  0.        ,  0.        ,  0.        ],
           [ 1.        ,  0.        ,  0.        ,  0.        ,  0.        ],
           [ 0.        ,  1.41421356,  0.        ,  0.        ,  0.        ],
           [ 0.        ,  0.        ,  1.73205081,  0.        ,  0.        ],
           [ 0.        ,  0.        ,  0.        ,  2.        ,  0.        ]])



`scipy.sparse`:


```python
sparse_rep = represent(ad, basis=N, ndim=4, format='scipy.sparse', spmatrix='lil')
sparse_rep
```




    <4x4 sparse matrix of type '<class 'numpy.float64'>'
    	with 3 stored elements in Compressed Sparse Row format>




```python
print(sparse_rep)
```

      (1, 0)	1.0
      (2, 1)	1.41421356237
      (3, 2)	1.73205080757


The same can be done for the other operators


```python
represent(a, basis=N, ndim=4, format='sympy')
```


```python
represent(N, basis=N, ndim=4, format='sympy')
```


```python
represent(H, basis=N, ndim=4, format='sympy')
```

Bras and kets can also be represented:


```python
k0 = SHOKet(0)
k1 = SHOKet(1)
b0 = SHOBra(0)
b1 = SHOBra(1)
```


```python
represent(k0, basis=N, ndim=5, format='sympy')
```


```python
represent(k1, basis=N, ndim=5, format='sympy')
```


```python
represent(b0, basis=N, ndim=5, format='sympy')
```


```python
represent(b1, basis=N, ndim=5, format='sympy')
```

2a40f7b2003b28851d633659ef1bbe219ec0dc86
ipynb
Jupyter Notebook
notebooks/sho1d.ipynb
gvvynplaine/quantum_notebooks
58783823596465fe2d6c494c2cc3a53ae69a9752
BSD-3-Clause
2017-10-17T22:44:27.000Z
2022-03-28T06:26:46.000Z
notebooks/sho1d.ipynb
gvvynplaine/quantum_notebooks
58783823596465fe2d6c494c2cc3a53ae69a9752
BSD-3-Clause
2017-10-09T05:16:41.000Z
2018-09-22T03:08:29.000Z
notebooks/sho1d.ipynb
gvvynplaine/quantum_notebooks
58783823596465fe2d6c494c2cc3a53ae69a9752
BSD-3-Clause
2017-10-09T04:22:19.000Z
2022-03-28T06:25:21.000Z
Qwen/Qwen-72B
1. YES
2. YES