I implementd QAOA on cuTensorNet to use the power of tensor network.
opt_einsum is a library to use the TN easily. This time i used it only to get simbols.
import opt_einsum as oe
from cuquantum import contract
import numpy as np
kanji = [oe.get_symbol(i) for i in range(118)]
l2 = [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 10], [10, 11], [11, 12], [12, 13], [13, 14], [14, 15], [15, 0], [5, 8], [7, 12], [0, 3], [2, 14], [7, 9], [7, 11], [0, 14], [6, 13], [13, 15], [8, 12], [7, 10], [10, 13], [6, 8], [2, 7], [7, 14], [1, 14], [11, 15], [1, 9], [9, 13]]
#number of qubits
N = 16
#initial state
psi = np.array([1,0], dtype="complex128")
arr_tensor = []
arr_arm = []
#simbols
n_kanji = 0
for i in range(N):
arr_arm.append(kanji[i])
arr_tensor.append(psi)
#make a state for arms on time evolutions
arr_state = []
for i in range(N):
arr_state.append(arr_arm[i])
n_kanji += 1
#apply H for making superposition of eigenstate of mixer X
H = np.array([[1,1],[1,-1]], dtype="complex128")/np.sqrt(2)
for i in range(N):
arr_tensor.append(H)
arr_arm.append(arr_state[i] + kanji[n_kanji])
arr_state[i] = kanji[n_kanji]
n_kanji += 1
#ZZ for time evolution of cost hamiltonian
theta = np.random.rand()np.pi2
#converting 4x4 matrix to 2x2x2x2 tensor to connect the arms
ZZ = np.array([[np.exp(-11jtheta/2),0,0,0],[0,np.exp(-11jtheta/2),0,0],[0,0,np.exp(1jtheta/2),0],[0,0,0,np.exp(-11jtheta/2)]], dtype="complex128").reshape(2,2,2,2)
for item in l2:
in1 = item[0]
in2 = item[1]
arr_tensor.append(ZZ)
arr_arm.append(arr_state[in1] + arr_state[in2] + kanji[n_kanji] + kanji[n_kanji+1])
arr_state[in1] = kanji[n_kanji]
arr_state[in2] = kanji[n_kanji+1]
n_kanji += 2
#time evolution of transvers filed X mixer
theta2 = np.random.rand()np.pi2
RX = np.array([[np.cos(theta2/2),-1jnp.sin(theta2/2)],[-1j*np.sin(theta2/2),np.cos(theta2/2)]], dtype="complex128")
for i in range(N):
arr_tensor.append(RX)
arr_arm.append(arr_state[i] + kanji[n_kanji])
arr_state[i] = kanji[n_kanji]
n_kanji += 1
#execute
r = contract(','.join(arr_arm), *arr_tensor)
#get the state vec
r.reshape(2**N)