Sequential Quantum Gate Decomposer  v1.9.6
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 import 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 = 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 import 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 = 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  # set initial parameters
129  rng = np.random.default_rng( 42 )
130  num_of_parameters = cDecompose.get_Parameter_Num()
131  parameters = rng.random(num_of_parameters)*2*np.pi
132 
133  cDecompose.set_Optimized_Parameters( parameters )
134 
135  # starting the decomposition
136 
137  cDecompose.Start_Decomposition()
138 
139  # list the decomposing operations
140 
141  cDecompose.List_Gates()
142 
143  # get the decomposing operations
144 
145  circuit_qiskit = cDecompose.get_Qiskit_Circuit()
146 
147  # print the quantum circuit
148 
149  print (circuit_qiskit)
150  # the unitary matrix from the result object
151 
152  decomp_error = cDecompose.Optimization_Problem_Combined(cDecompose.get_Optimized_Parameters())[0]
153  assert decomp_error < 1e-4
154  print(f"DECOMPOSITION ERROR: {decomp_error} ")
155 
156  # Execute and get the state vector
157  if qiskit_version[0] == '1' or qiskit_version[0] == '2':
158 
159  circuit_qiskit.save_statevector()
160 
161  backend = Aer.AerSimulator(method='statevector')
162  compiled_circuit = transpile(circuit_qiskit, backend)
163  result = backend.run(compiled_circuit).result()
164 
165  transformed_state = result.get_statevector(compiled_circuit)
166 
167 
168  elif qiskit_version[0] == '0':
169 
170  # Select the StatevectorSimulator from the Aer provider
171  simulator = Aer.get_backend('statevector_simulator')
172 
173  backend = Aer.get_backend('aer_simulator')
174  result = execute(circuit_qiskit, simulator).result()
175 
176  transformed_state = result.get_statevector(circuit_qiskit)
177 
178  overlap = np.abs( np.asarray(transformed_state).conj().T @ State )
179 
180  print( 'Overlap integral with the initial state: ', overlap )
181  assert( np.abs(overlap - 1) < 1e-4 )
182 
183 
184 
185 
187  r"""
188  This method is called by pytest.
189  Test for a 4 qubit state preparation using the BFGS optimizer
190 
191  """
192 
193  self.State_Preparation_adaptive_base('BFGS', 0)
194 
196  r"""
197  This method is called by pytest.
198  Test for a 4 qubit state preparation using the Hilbert Schmidt test
199 
200  """
201 
202  self.State_Preparation_adaptive_base('BFGS', 3)
def State_Preparation_adaptive_base(self, optimizer, cost_func, compression_enabled=1)