Sequential Quantum Gate Decomposer  v1.9.3
Powerful decomposition of general unitarias into one- and two-qubit gates gates
custom_gate_structure_test.cpp
Go to the documentation of this file.
1 
2 /*
3 Created on Fri Jun 26 14:14:12 2020
4 Copyright 2020 Peter Rakyta, Ph.D.
5 
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
9 
10  http://www.apache.org/licenses/LICENSE-2.0
11 
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.
17 
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/.
20 
21 @author: Peter Rakyta, Ph.D.
22 */
27 #include <iostream>
28 #include <stdio.h>
29 #include <map>
30 
31 
33 #include "common.h"
34 #include "N_Qubit_Decomposition.h"
35 #include "Random_Unitary.h"
36 #include "logging.h"
38 
39 using namespace std;
40 
41 
42 
49 
51  // creating an instance of the wrapper class Gates_block
52  Gates_block* gates_block = new Gates_block( qbit_num );
54 
56  int disentangle_qubit = qbit_num - 1;
58 
59 
61  for ( int qbit=0; qbit< disentangle_qubit; qbit++ ) {
62 
63  // creating an instance of the wrapper class Gates_block
64  Gates_block* layer = new Gates_block( qbit_num );
65 
66  if (qbit == 1) {
67 
68  int target_qbit = 0;
69  int control_qbit = 1;
70 
71  // add U3 gate to the block
72  bool Theta = true;
73  bool Phi = false;
74  bool Lambda = true;
75  layer->add_u3( 0, Theta, Phi, Lambda );
76  layer->add_u3( 1, Theta, Phi, Lambda );
77 
78  // add CNOT gate to the block
79  layer->add_cnot( target_qbit, control_qbit );
80 
81 
82  }
83  else {
84 
85  int target_qbit = qbit;
86  int control_qbit = disentangle_qubit;
87 
88  // add U3 gate to the block
89  bool Theta = true;
90  bool Phi = false;
91  bool Lambda = true;
92  layer->add_u3( qbit, Theta, Phi, Lambda );
93  layer->add_u3( disentangle_qubit, Theta, Phi, Lambda );
94 
95  // add CNOT gate to the block
96  layer->add_cnot( target_qbit, control_qbit );
97  }
98 
99  gates_block->add_gate( (Gate*)layer );
100 
101  }
103 
104  return gates_block;
105 
106 
107 }
108 
112 int main() {
113 
114 
115 
117  std::stringstream sstream;
118 
120  logging output;
121 
123  int verbose_level;
124 
125  //Setting the verbosity level of the Test of N qubit decomposition with custom gate structure
126  verbose_level=1;
127  sstream << std::endl << std::endl << "****************************************" << std::endl;
128  sstream << "Test of N qubit decomposition with custom gate structure" << std::endl;
129  sstream << "****************************************"<< std::endl << std::endl << std::endl;
130  output.print(sstream,verbose_level);
131 
133  // The number of qubits spanning the random unitary
134  int qbit_num = 3;
135  // the number of rows of the random unitary
136  int matrix_size = Power_of_2(qbit_num);
137  // creating class to generate general random unitary
138  Random_Unitary ru = Random_Unitary(matrix_size);
139  // create general random unitary
141 
142 
143 
144 
145  // construct the complex transpose of the random unitary
146  Matrix Umtx_adj = Matrix(matrix_size, matrix_size);
147  for (int element_idx=0; element_idx<matrix_size*matrix_size; element_idx++) {
148  // determine the row and column index of the element to be filled.
149  int col_idx = element_idx % matrix_size;
150  int row_idx = int((element_idx-col_idx)/matrix_size);
151 
152  // setting the complex conjugate of the element in the adjungate matrix
153  QGD_Complex16 element = Umtx[col_idx*matrix_size + row_idx];
154  Umtx_adj[element_idx].real = element.real;
155  Umtx_adj[element_idx].imag = -element.imag;
156  }
158 
160  // creating the class for the decomposition. Here Umtx_adj is the complex transposition of unitary Umtx
161  N_Qubit_Decomposition cDecomposition =
162  N_Qubit_Decomposition( Umtx_adj, qbit_num, /* optimize_layer_num= */ false, /* initial_guess= */ RANDOM );
164 
165 
166 
168  // creating custom gate structure for the decomposition
169  std::map<int, Gates_block*> gate_structure;
170  gate_structure.insert( pair<int, Gates_block*>(qbit_num, create_custom_gate_structure( qbit_num ) ) );
171  gate_structure.insert( pair<int, Gates_block*>(qbit_num-1, create_custom_gate_structure( qbit_num-1 ) ) );
172 
173  // setting the custom gate structure in the decomposition class
174  cDecomposition.set_custom_gate_structure( gate_structure);
175 
176  // release the custom gate structure since it was cloned by cDecomposition
177  delete gate_structure[qbit_num];
178  delete gate_structure[qbit_num-1];
180 
181 
182  // setting the verbosity level of the decomposition
183  verbose_level=1;
184  sstream << "Starting the decompsition" << std::endl;
185  output.print(sstream,verbose_level);
186 
188  // starting the decomposition
189  cDecomposition.start_decomposition(/* finalize_decomposition = */ true, /* prepare_export= */ true);
190 
191  cDecomposition.list_gates(1);
193 
194 
195 
196 
197  return 0;
198 
199 };
200 
void print(const std::stringstream &sstream, int verbose_level=1) const
Call to print output messages in the function of the verbosity level.
Definition: logging.cpp:55
void add_gate(Gate *gate)
Append a general gate to the list of gates.
Gates_block * create_custom_gate_structure(int qbit_num)
Function to create custom gate structure for the decomposition.
void add_cnot(int target_qbit, int control_qbit)
Append a CNOT gate gate to the list of gates.
Header file for a class containing basic methods for setting up the verbosity level.
A class containing basic methods for setting up the verbosity level.
Definition: logging.h:43
matrix_size
[load Umtx]
Definition: example.py:58
Umtx
The unitary to be decomposed.
Definition: example.py:53
void add_u3(int target_qbit)
Append a U3 gate to the list of gates.
Structure type representing complex numbers in the SQUANDER package.
Definition: QGDTypes.h:38
int Power_of_2(int n)
Calculates the n-th power of 2.
Definition: common.cpp:117
Class to store data of complex arrays and its properties.
Definition: matrix.h:38
int main()
Decomposition of general random unitary matrix into a custom structure of U3 and CNOT gates...
A class responsible for grouping two-qubit (CNOT,CZ,CH) and one-qubit gates into layers.
Definition: Gates_block.h:41
A class to cerate general random unitary matrix according to arXiv:1303:5904v1.
Base class for the representation of general gate operations.
Definition: Gate.h:73
Header file for commonly used functions and wrappers to CBLAS functions.
double real
the real part of a complex number
Definition: QGDTypes.h:40
Matrix Construct_Unitary_Matrix()
Call to create a random unitary.
Header file for a class to determine the decomposition of an N-qubit unitary into a sequence of CNOT ...
double imag
the imaginary part of a complex number
Definition: QGDTypes.h:42