Sequential Quantum Gate Decomposer  v1.9.3
Powerful decomposition of general unitarias into one- and two-qubit gates gates
vqe_utils.py
Go to the documentation of this file.
1 '''
2 Copyright 2020 Peter Rakyta, Ph.D.
3 
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7 
8  http://www.apache.org/licenses/LICENSE-2.0
9 
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 
16 '''
17 
18 from qiskit import QuantumCircuit, transpile
19 import numpy as np
20 
21 from pauli_exponent import pauli_exponent
22 
23 from qiskit import execute
24 from qiskit import Aer
25 
26 from qgd_python.decomposition.qgd_N_Qubit_Decomposition_custom import qgd_N_Qubit_Decomposition_custom
27 from qgd_python.utils import get_unitary_from_qiskit_circuit
28 
29 from scipy.interpolate import interp1d
30 
31 
32 
33 
34 backend = Aer.get_backend('unitary_simulator')
35 
36 
37 #
38 optimized_parameters_mtx = None
39 alpha_vec = None
40 
41 
42 
46 def load_preconstructed_data( filename1, filename2 ):
47  global alpha_vec
48  global optimized_parameters_mtx
49 
50  optimized_parameters_mtx = np.loadtxt(filename1)
51  alpha_vec = np.loadtxt(filename2)
52 
53 
54 
55 
56 
61 def get_unitary_distance( Umtx1, Umtx2 ):
62 
63  product_matrix = np.dot(Umtx1, Umtx2.conj().T)
64  phase = np.angle(product_matrix[0,0])
65  product_matrix = product_matrix*np.exp(-1j*phase)
66  product_matrix = np.eye(len(Umtx1))*2 - product_matrix - product_matrix.conj().T
67  distance = (np.real(np.trace(product_matrix)))/2
68 
69  return distance
70 
71 
72 
75 def get_optimized_circuit( alpha, optimized_parameters_in=None ):
76 
77  filename = '19CNOT.qasm'
78  qc_trial = QuantumCircuit.from_qasm_file( filename )
79  qc_trial = transpile(qc_trial, optimization_level=3, basis_gates=['cz', 'cx', 'u3'], layout_method='sabre')
80  #print(qc_trial)
81 
82 
83  qc_orig = pauli_exponent(alpha )
84  qc_orig = transpile(qc_orig, optimization_level=3, basis_gates=['cx', 'u3'], layout_method='sabre')
85  #print('global phase: ', qc_orig.global_phase)
86 
87  Umtx_orig = get_unitary_from_qiskit_circuit( qc_orig )
88 
89  iteration_max = 10
90  for jdx in range(iteration_max):
91 
92  cDecompose = qgd_N_Qubit_Decomposition_custom( Umtx_orig.conj().T )
93 
94  # setting the tolerance of the optimization process. The final error of the decomposition would scale with the square root of this value.
95  cDecompose.set_Optimization_Tolerance( 1e-8 )
96 
97  # importing the quantum circuit
98  cDecompose.import_Qiskit_Circuit(qc_trial)
99 
100  #if isinstance(optimized_parameters_in, (np.ndarray, np.generic) ) :
101  # cDecompose.set_Optimized_Parameters( optimized_parameters_in )
102 
103  # set the number of successive identical blocks in the optimalization of disentanglement of the n-th qubits
104  cDecompose.set_Optimization_Blocks( 200 )
105 
106  # turning off verbosity
107  cDecompose.set_Verbose( False )
108 
109  # starting the decomposition
110  cDecompose.Start_Decomposition()
111 
112  # getting the new optimized parameters
113  optimized_parameters_loc = cDecompose.get_Optimized_Parameters()
114 
115  qc_final = cDecompose.get_Quantum_Circuit()
116 
117  # get the unitary of the final circuit
118  Umtx_recheck = get_unitary_from_qiskit_circuit( qc_final )
119 
120  # get the decomposition error
121  decomposition_error = get_unitary_distance(Umtx_orig, Umtx_recheck)
122  print('recheck decomposition error: ',decomposition_error)
123 
124  if decomposition_error < 1e-6:
125  break
126 
127  if decomposition_error < 1e-6:
128  return qc_final, optimized_parameters_loc
129  else:
130  return None, None
131 
132 
133 
137 
138  # interpolate the optimized parameters to obtain the best initial set of parameters to be furthe roptimized
139  itp = interp1d(alpha_vec, optimized_parameters_mtx, axis=0, kind='linear')
140  initial_optimized_parameters = itp(alpha)
141 
142  qc = get_optimized_circuit( alpha, initial_optimized_parameters )
143  return qc
144 
def load_preconstructed_data(filename1, filename2)
Call load precosntructed data for inerpolated optimization.
Definition: vqe_utils.py:46
def get_interpolated_circuit(alpha)
???????????
Definition: vqe_utils.py:136
def get_unitary_from_qiskit_circuit
Call to retrieve the unitary from QISKIT circuit.
Definition: utils.py:52
def get_optimized_circuit(alpha, optimized_parameters_in=None)
???????????
Definition: vqe_utils.py:75
def get_unitary_distance(Umtx1, Umtx2)
Calcuates the distance between two unitaries according to Eq.
Definition: vqe_utils.py:61