Sequential Quantum Gate Decomposer  v1.9.3
Powerful decomposition of general unitarias into one- and two-qubit gates gates
test_State_Preparation.py
Go to the documentation of this file.
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3 """
4 Created on Fri Jun 26 14:42:56 2020
5 Copyright 2020 Peter Rakyta, Ph.D.
6 
7 Licensed under the Apache License, Version 2.0 (the "License");
8 you may not use this file except in compliance with the License.
9 You may obtain a copy of the License at
10 
11  http://www.apache.org/licenses/LICENSE-2.0
12 
13 Unless required by applicable law or agreed to in writing, software
14 distributed under the License is distributed on an "AS IS" BASIS,
15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 See the License for the specific language governing permissions and
17 limitations under the License.
18 
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see http://www.gnu.org/licenses/.
21 
22 @author: Peter Rakyta, Ph.D.
23 """
24 
25 
27 
28 
29 from scipy.stats import unitary_group
30 import numpy as np
31 import pytest
32 from squander import utils
33 
34 try:
35  from mpi4py import MPI
36  MPI_imported = True
37 except ModuleNotFoundError:
38  MPI_imported = False
39 
40 
41 import qiskit
42 qiskit_version = qiskit.version.get_version_info()
43 
44 from qiskit import QuantumCircuit
45 
46 
47 if qiskit_version[0] == '1' or qiskit_version[0] == '2':
48  from qiskit import transpile
49  import qiskit_aer as Aer
50 else :
51  from qiskit import execute
52  from qiskit import Aer
53 
54 
56 
58  r"""
59  This method is called by pytest.
60  Test to decompose a 4-qubit unitary State
61 
62  """
63 
64  from squander.decomposition.qgd_N_Qubit_State_Preparation_adaptive import qgd_N_Qubit_State_Preparation_adaptive
65  from scipy.io import loadmat
66 
67  # load the unitary from file
68 
69  data = loadmat('data/Umtx.mat')
70 
71  # The unitary to be decomposed
72 
73  Umtx = data['Umtx'].conj().T
74 
75  # creating a class to decompose the unitary
76 
77  with pytest.raises(Exception):
78  cDecompose = qgd_N_Qubit_State_Preparation_adaptive(Umtx,
79  level_limit_max=5, level_limit_min=0)
80 
81  def State_Preparation_adaptive_base(self, optimizer, cost_func, compression_enabled=1):
82 
83  from squander.decomposition.qgd_N_Qubit_State_Preparation_adaptive import qgd_N_Qubit_State_Preparation_adaptive
84  from scipy.io import loadmat
85 
86  # load the unitary from file
87 
88  data = loadmat('data/Umtx.mat')
89 
90  # The unitary to be decomposed
91 
92  Umtx = data['Umtx']
93  State = Umtx[:, 0].reshape(16, 1)
94  norm = np.sqrt( State.conj().T @ State )
95  State = State/norm
96 
97 
98  config = { 'max_outer_iterations': 1,
99  'max_inner_iterations': 10000,
100  'max_inner_iterations_compression': 10000,
101  'max_inner_iterations_final': 1000,
102  'randomization_threshold': int(1e4),
103  'Randomized_Radius': 0.3,
104  'randomized_adaptive_layers': 1,
105  'optimization_tolerance_agent': 1e-4,
106  'optimization_tolerance': 1e-4,
107  'compression_enabled': compression_enabled,
108  'number_of_agents': 4}
109 
110 
111  # creating a class to decompose the unitary
112 
113  cDecompose = qgd_N_Qubit_State_Preparation_adaptive(State,
114  level_limit_max=5, level_limit_min=0, config = config)
115 
116  # setting the verbosity of the decomposition
117 
118  cDecompose.set_Verbose(3)
119 
120  # setting the verbosity of the decomposition
121 
122  cDecompose.set_Cost_Function_Variant(cost_func)
123 
124  #set Optimizer
125 
126  cDecompose.set_Optimizer(optimizer)
127 
128  # starting the decomposition
129 
130  cDecompose.Start_Decomposition()
131 
132  # list the decomposing operations
133 
134  cDecompose.List_Gates()
135 
136  # get the decomposing operations
137 
138  circuit_qiskit = cDecompose.get_Qiskit_Circuit()
139 
140  # print the quantum circuit
141 
142  print (circuit_qiskit)
143  # the unitary matrix from the result object
144 
145  decomp_error = cDecompose.Optimization_Problem_Combined(cDecompose.get_Optimized_Parameters())[0]
146  assert decomp_error < 1e-4
147  print(f"DECOMPOSITION ERROR: {decomp_error} ")
148 
149  # Execute and get the state vector
150  if qiskit_version[0] == '1' or qiskit_version[0] == '2':
151 
152  circuit_qiskit.save_statevector()
153 
154  backend = Aer.AerSimulator(method='statevector')
155  compiled_circuit = transpile(circuit_qiskit, backend)
156  result = backend.run(compiled_circuit).result()
157 
158  transformed_state = result.get_statevector(compiled_circuit)
159 
160 
161  elif qiskit_version[0] == '0':
162 
163  # Select the StatevectorSimulator from the Aer provider
164  simulator = Aer.get_backend('statevector_simulator')
165 
166  backend = Aer.get_backend('aer_simulator')
167  result = execute(circuit_qiskit, simulator).result()
168 
169  transformed_state = result.get_statevector(circuit_qiskit)
170 
171  overlap = np.abs( np.asarray(transformed_state).conj().T @ State )
172 
173  print( 'Overlap integral with the initial state: ', overlap )
174  assert( np.abs(overlap - 1) < 1e-4 )
175 
176 
177 
178 
180  r"""
181  This method is called by pytest.
182  Test for a 4 qubit state preparation using the BFGS optimizer
183 
184  """
185 
186  self.State_Preparation_adaptive_base('BFGS', 0)
187 
189  r"""
190  This method is called by pytest.
191  Test for a 4 qubit state preparation using the Hilbert Schmidt test
192 
193  """
194 
195  self.State_Preparation_adaptive_base('BFGS', 3)
def State_Preparation_adaptive_base(self, optimizer, cost_func, compression_enabled=1)
result
the result of the Qiskit job