In the following pdf, I gave a brief pedagogical introduction to the Trotter-Suzuki (TS) approximation
http://www.ar-tiste.com/trotter-suzuki-intro.pdf
In this notebook, I use the same notation that is used in that pdf.
The purpose of this notebook is to give some simple Python functions that print out the formulas for TS in the first 3 orders of approximation $S_2$, $S_4$ and $S_6$. TS is defined by Suzuki recursively $S_6=S_6(S_4)$ and $S_4 = S_4(S_2)$. So I could have written these printing functions recursively too, but I wanted to write them non-recursively, in such a way that the formulas for $S_2$, $S_4$ and $S_6$ don't call each other. This can be done using nested loops:
Nested loops can of course be represented by trees. In this case, the each branch sprouts 3 branches until the last branch, which has no branches.
This notebook suggests that a quantum circuit that implements the TS approximation can be expressed in terms of nested loops, with quantum gates being performed inside the loops. The notebook suggests one possible application of nested loops (and also of loop dependent evaluation of placeholder variables), for quantum languages (such as Qubiter, IBM qiskit, Rigetti Pyquil, and Google Cirq, etc.)
M = ['A', 'B', 'A']
time = 't'
factors0 = ['(1/2)', '', '(1/2)']
factors1 = ['a_2', '(1-4a_2)', 'a_2']
factors2 = ['a_4', '(1-4a_4)', 'a_4']
powers = ['2', '1', '2']
def S2():
S = ''
for j0 in range(3):
scaled_time = factors0[j0] + time
S += 'exp(' + scaled_time + M[j0] + ')'
return(S)
print(S2())
exp((1/2)tA)exp(tB)exp((1/2)tA)
def S4():
S = ''
for j1 in range(3):
S += '\n[\n'
for j0 in range(3):
scaled_time = factors1[j1] + factors0[j0] + time
S += 'exp(' + scaled_time + M[j0] + ')'
S += '\n]**' + powers[j1]
return S
print(S4())
[ exp(a_2(1/2)tA)exp(a_2tB)exp(a_2(1/2)tA) ]**2 [ exp((1-4a_2)(1/2)tA)exp((1-4a_2)tB)exp((1-4a_2)(1/2)tA) ]**1 [ exp(a_2(1/2)tA)exp(a_2tB)exp(a_2(1/2)tA) ]**2
def S6():
S = ''
for j2 in range(3):
S += '\n['
for j1 in range(0, 3):
S += '\n[\n'
for j0 in range(3):
scaled_time = factors2[j2] + factors1[j1] + factors0[j0] + time
S += 'exp(' + scaled_time + M[j0] + ')'
S += '\n]**' + powers[j1]
S += '\n]**' + powers[j2]
return S
print(S6())
[ [ exp(a_4a_2(1/2)tA)exp(a_4a_2tB)exp(a_4a_2(1/2)tA) ]**2 [ exp(a_4(1-4a_2)(1/2)tA)exp(a_4(1-4a_2)tB)exp(a_4(1-4a_2)(1/2)tA) ]**1 [ exp(a_4a_2(1/2)tA)exp(a_4a_2tB)exp(a_4a_2(1/2)tA) ]**2 ]**2 [ [ exp((1-4a_4)a_2(1/2)tA)exp((1-4a_4)a_2tB)exp((1-4a_4)a_2(1/2)tA) ]**2 [ exp((1-4a_4)(1-4a_2)(1/2)tA)exp((1-4a_4)(1-4a_2)tB)exp((1-4a_4)(1-4a_2)(1/2)tA) ]**1 [ exp((1-4a_4)a_2(1/2)tA)exp((1-4a_4)a_2tB)exp((1-4a_4)a_2(1/2)tA) ]**2 ]**1 [ [ exp(a_4a_2(1/2)tA)exp(a_4a_2tB)exp(a_4a_2(1/2)tA) ]**2 [ exp(a_4(1-4a_2)(1/2)tA)exp(a_4(1-4a_2)tB)exp(a_4(1-4a_2)(1/2)tA) ]**1 [ exp(a_4a_2(1/2)tA)exp(a_4a_2tB)exp(a_4a_2(1/2)tA) ]**2 ]**2