isQ examples
Now we will show you how to write isQ code with some examples
Bell State
import std;
qbit a, b;
procedure main(){
H(a);
CNOT(a, b);
int x = M(a);
int y = M(b);
print x;
print y;
}
Bernstein Vazirani
import std;
// support 3-bit s is 110
oracle g(3, 1) = [0, 0, 1, 1, 1, 1, 0, 0];
qbit q[3], anc;
procedure main(){
for i in 0:3{
H(q[i]);
}
X(anc);
H(anc);
g(q[0], q[1], q[2], anc);
for i in 0:3{
H(q[i]);
int a = M(q[i]);
print a;
}
}
Grover Search
import std;
defgate U = [
1, 0, 0, 0, 0, 0, 0, 0;
0, -1, 0, 0, 0, 0, 0, 0;
0, 0, -1, 0, 0, 0, 0, 0;
0, 0, 0, -1, 0, 0, 0, 0;
0, 0, 0, 0, -1, 0, 0, 0;
0, 0, 0, 0, 0, -1, 0, 0;
0, 0, 0, 0, 0, 0, -1, 0;
0, 0, 0, 0, 0, 0, 0, -1
];
oracle G(3,1) = [0,1,0,0,0,0,0,0];
qbit q[3];
qbit anc;
procedure hardmard(){
H(q[0]);
H(q[1]);
H(q[2]);
}
procedure init(){
hardmard();
X(anc);
H(anc);
}
procedure grover_search(){
G(q[0], q[1], q[2], anc);
hardmard();
U(q[0], q[1], q[2]);
hardmard();
}
procedure main(){
init();
int a = 2;
while a > 0{
grover_search();
a = a - 1;
}
H(anc);
for i in 0:3{
int x = M(q[i]);
print x;
}
}
Recursive Fourier Sampling
import std;
oracle A(4,1) = [0,1,1,0,0,0,0,0,0,0,1,1,0,1,0,1];
oracle g(2,1) = [0,1,1,0];
int a;
qbit q[4], p[3];
procedure hadamard_layer(int k){
H(q[2*k]);
H(q[2*k+1]);
}
procedure recursive_fourier_sampling(int k){
if (k == 2){
A(q[0], q[1], q[2], q[3], p[2]);
}else{
hadamard_layer(k);
X(p[k+1]);
H(p[k+1]);
recursive_fourier_sampling(k+1);
hadamard_layer(k);
g(q[2*k],q[2*k+1], p[k]);
hadamard_layer(k);
recursive_fourier_sampling(k+1);
hadamard_layer(k);
H(p[k+1]);
X(p[k+1]);
}
}
procedure main(){
a = 0;
recursive_fourier_sampling(a);
int g = M<p[0]>;
print g;
}
Variational Quantum Algorithm
isQ implements variational quantum algorithm through python. Take the ground state energy of hydrogen molecule as an example, we can first write circuits with parameters through isQ
import std;
procedure main(int i_par[], double d_par[]){
qbit q[2];
X(q[1]);
Ry(1.57, q[0]);
Rx(4.71, q[1]);
CNOT(q[0],q[1]);
Rz(d_par[0], q[1]);
CNOT(q[0],q[1]);
Ry(4.71, q[0]);
Rx(1.57, q[1]);
if(i_par[0] == 0){
M(q[0]);
}
if(i_par[0]==1){
M(q[1]);
}
if(i_par[0]==2){
M(q[0]);
M(q[1]);
}
if(i_par[0]==3){
Rx(1.57, q[0]);
Rx(1.57, q[1]);
M(q[0]);
M(q[1]);
}
if(i_par[0]==4){
H(q[0]);
H(q[1]);
M(q[0]);
M(q[1]);
}
}
Then, update parameters through python. In python, the compilation and simulation of isQ can be called through os.popen
# ground state energy of hydrogen molecule
from numpy.random import rand
from scipy.optimize import minimize
import os
import json
# compile "h2.isq" and generate the qir file "h2.so"
h2_isq = 'h2.isq'
compile_cmd = f"isqc compile {h2_isq}"
res = os.popen(compile_cmd).read()
if res:
print('compile error')
print(res)
else:
print('compile ok!')
h2_sim_file = 'h2.so'
def get_exception(theta) -> float:
'''
theta: Angle during preparation
e_n: E_N
get the expectation value of
the Hamiltonian for specific theta
'''
theta = float(theta) # float
hs = [-0.4804, +0.3435, -0.4347, +0.5716, +0.0910, +0.0910]
# coefficients of the Hamiltonian
# for more information, see `PHYS. REV. X 6, 031007 (2016)`
exceptions = list() # to store results in a List
exceptions.append(hs[0])
E_N = 5
# The first does not require quantum measurement, which is constant
# As a result, the other 5 coefficients need to be measured
# i.e. hs[1], hs[2], hs[3], hs[4], hs[5]
for e_n in range(E_N):
# simulate and get the result
simulate_cmd = f'isqc simulate -i {e_n} -d {theta} --shots 100 {h2_sim_file}'
res = os.popen(simulate_cmd).read()
try:
test_res = json.loads(res)
exception = 0 # initialize to 0
for measure_res in test_res: # test_res is Dict
frequency = test_res[measure_res]/100 # to get every frequency
# 频率代替概率
parity = (-1)**(measure_res.count('1') % 2) # to get every parity
# 奇偶校验
exception += parity * frequency # to accumulate every exception result
exceptions.append(hs[e_n+1]*exception) # The result is multiplied by coefficients
except:
print('simulate error') # error
print(res)
exit()
return sum(exceptions) # to get the final result of Hamiltonian with `hs`
# nelder-mead optimization of a convex function
# define range for theta
theta_min, theta_max = -3.14, 3.14
# define the starting point as a random sample from the domain
pt = theta_min + rand(1) * (theta_max - theta_min)
# perform the search
result = minimize(get_exception, pt, method='nelder-mead')
# summarize the result
print(f"Status : {result['message']}")
print(f"Total Evaluations: {result['nfev']}")
# evaluate solution
solution = result['x']
evaluation = get_exception(solution)
print(f"Solution: H_2({solution}) = {evaluation} Eh")