3 Created on Fri Jun 26 14:42:56 2020 4 Copyright 2020 Peter Rakyta, Ph.D. 6 Licensed under the Apache License, Version 2.0 (the "License"); 7 you may not use this file except in compliance with the License. 8 You may obtain a copy of the License at 10 http://www.apache.org/licenses/LICENSE-2.0 12 Unless required by applicable law or agreed to in writing, software 13 distributed under the License is distributed on an "AS IS" BASIS, 14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 See the License for the specific language governing permissions and 16 limitations under the License. 18 You should have received a copy of the GNU General Public License 19 along with this program. If not, see http://www.gnu.org/licenses/. 21 @author: Peter Rakyta, Ph.D. 26 from squander
import Circuit
35 np.set_printoptions(linewidth=200)
45 random_initial_state =
False 50 execution_times_squander = {}
51 transformed_states_squander = {}
52 parameters_squander = {}
53 initial_state_squander = {}
55 for qbit_num
in range(qbit_num_min, qbit_num_max+1, 1):
58 matrix_size = 1 << qbit_num
60 if (random_initial_state ) :
61 initial_state_real = np.random.uniform(-1.0,1.0, (matrix_size,) )
62 initial_state_imag = np.random.uniform(-1.0,1.0, (matrix_size,) )
63 initial_state = initial_state_real + initial_state_imag*1j
64 initial_state = initial_state/np.linalg.norm(initial_state)
66 initial_state = np.zeros( (matrix_size), dtype=np.complex128 )
67 initial_state[0] = 1.0 + 0j
69 initial_state_squander[ qbit_num ] = initial_state.copy()
73 circuit_squander = Circuit( qbit_num )
76 for level
in range(levels):
79 for control_qbit
in range(qbit_num-1):
80 for target_qbit
in range(control_qbit+1, qbit_num):
82 circuit_squander.add_U3(target_qbit,
True,
True,
True )
83 circuit_squander.add_U3(control_qbit,
True,
True,
True )
85 circuit_squander.add_CRY( target_qbit=target_qbit, control_qbit=control_qbit )
86 gates_num = gates_num + 3
88 for target_qbit
in range(qbit_num):
89 circuit_squander.add_U3(target_qbit,
True,
True,
True )
90 gates_num = gates_num + 1
95 num_of_parameters = circuit_squander.get_Parameter_Num()
99 parameters = np.random.rand(num_of_parameters)*2*np.pi
102 circuit_squander.apply_to( parameters, initial_state )
103 t_SQUANDER = time.time() - t0
104 print(
"Time elapsed SQUANDER: ", t_SQUANDER,
" seconds at qbit_num = ", qbit_num,
' number of gates: ', gates_num )
106 execution_times_squander[ qbit_num ] = t_SQUANDER
107 transformed_states_squander[ qbit_num ] = np.reshape(initial_state, (initial_state.size,) )
108 parameters_squander[ qbit_num ] = parameters
111 print(
"SQUANDER execution times [s]:")
112 print( execution_times_squander )
118 execution_times_qiskit = {}
119 transformed_states_qiskit = {}
123 qiskit_version = qiskit.version.get_version_info()
125 from qiskit
import QuantumCircuit
126 import qiskit_aer
as Aer
128 if qiskit_version[0] ==
'1':
129 from qiskit
import transpile
131 from qiskit
import execute
136 for qbit_num
in range(qbit_num_min, qbit_num_max+1, 1):
139 matrix_size = 1 << qbit_num
141 initial_state = initial_state_squander[ qbit_num ]
143 parameters = parameters_squander[ qbit_num ]
149 circuit_qiskit = QuantumCircuit(qbit_num)
151 if random_initial_state:
152 circuit_qiskit.initialize( initial_state )
154 for level
in range(levels):
157 for control_qbit
in range(qbit_num-1):
158 for target_qbit
in range(control_qbit+1, qbit_num):
160 circuit_qiskit.u(parameters[parameter_idx]*2, parameters[parameter_idx+1], parameters[parameter_idx+2], target_qbit )
161 parameter_idx = parameter_idx+3
162 circuit_qiskit.u(parameters[parameter_idx]*2, parameters[parameter_idx+1], parameters[parameter_idx+2], control_qbit )
163 parameter_idx = parameter_idx+3
165 circuit_qiskit.cry( parameters[parameter_idx]*2, control_qbit, target_qbit )
166 parameter_idx = parameter_idx+1
168 for target_qbit
in range(qbit_num):
169 circuit_qiskit.u(parameters[parameter_idx]*2, parameters[parameter_idx+1], parameters[parameter_idx+2], target_qbit )
170 parameter_idx = parameter_idx+3
180 if qiskit_version[0] ==
'1' or qiskit_version[0] ==
'2':
182 circuit_qiskit.save_statevector()
184 backend = Aer.AerSimulator(method=
'statevector')
185 compiled_circuit = transpile(circuit_qiskit, backend)
186 result = backend.run(compiled_circuit).
result()
188 transformed_state = result.get_statevector(compiled_circuit)
191 elif qiskit_version[0] ==
'0':
194 simulator = Aer.get_backend(
'statevector_simulator')
196 backend = Aer.get_backend(
'aer_simulator')
197 result = execute(circuit_qiskit, simulator).
result()
199 transformed_state = result.get_statevector(circuit_qiskit)
203 t_qiskit = time.time() - t0
206 execution_times_qiskit[ qbit_num ] = t_qiskit
207 transformed_states_qiskit[ qbit_num ] = np.array(transformed_state)
209 print(
"QISKIT execution times [s]:")
210 print( execution_times_qiskit )
213 from qulacs
import Observable, QuantumCircuit, QuantumState
216 execution_times_qulacs = {}
217 transformed_states_qulacs = {}
220 for qbit_num
in range(qbit_num_min, qbit_num_max+1, 1):
223 matrix_size = 1 << qbit_num
225 initial_state = initial_state_squander[ qbit_num ]
227 parameters = parameters_squander[ qbit_num ]
233 state = QuantumState(qbit_num)
234 state.load( initial_state )
236 circuit_qulacs = QuantumCircuit(qbit_num)
238 for level
in range(levels):
241 for control_qbit
in range(qbit_num-1):
242 for target_qbit
in range(control_qbit+1, qbit_num):
244 circuit_qulacs.add_U3_gate(target_qbit, parameters[parameter_idx]*2, parameters[parameter_idx+1], parameters[parameter_idx+2] )
245 parameter_idx = parameter_idx+3
246 circuit_qulacs.add_U3_gate( control_qbit, parameters[parameter_idx]*2, parameters[parameter_idx+1], parameters[parameter_idx+2] )
247 parameter_idx = parameter_idx+3
251 RY_gate = qulacs.gate.RotY( target_qbit, parameters[parameter_idx]*2 )
252 RY_gate = qulacs.gate.to_matrix_gate( RY_gate )
253 RY_gate.add_control_qubit( control_qbit, 1)
254 circuit_qulacs.add_gate( RY_gate )
256 parameter_idx = parameter_idx+1
259 for target_qbit
in range(qbit_num):
260 circuit_qulacs.add_U3_gate( target_qbit, parameters[parameter_idx]*2, parameters[parameter_idx+1], parameters[parameter_idx+2] )
261 parameter_idx = parameter_idx+3
267 circuit_qulacs.update_quantum_state( state )
268 transformed_state = state.get_vector()
269 t_qulacs = time.time() - t0
272 execution_times_qulacs[ qbit_num ] = t_qulacs
273 transformed_states_qulacs[ qbit_num ] = np.array(transformed_state)
275 print(
"Qulacs execution times [s]:")
276 print( execution_times_qulacs )
280 print(
"Difference between the transformed state vectors:")
282 keys = transformed_states_qiskit.keys()
283 for qbit_num
in keys:
284 state_squander = transformed_states_squander[ qbit_num ]
285 state_qiskit = transformed_states_qiskit[ qbit_num ]
286 state_qulacs = transformed_states_qulacs[ qbit_num ]
288 print(
"Squander vs QISKIT: ", np.linalg.norm( state_squander-state_qiskit ) )
289 print(
"Squander vs Qulacs: ", np.linalg.norm( state_squander-state_qulacs ) )