Sequential Quantum Gate Decomposer  v1.9.3
Powerful decomposition of general unitarias into one- and two-qubit gates gates
Composite.cpp
Go to the documentation of this file.
1 /*
2 Created on Fri Jun 26 14:13:26 2020
3 Copyright 2020 Peter Rakyta, Ph.D.
4 
5 Licensed under the Apache License, Version 2.0 (the "License");
6 you may not use this file except in compliance with the License.
7 You may obtain a copy of the License at
8 
9  http://www.apache.org/licenses/LICENSE-2.0
10 
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
16 
17 @author: Peter Rakyta, Ph.D.
18 */
24 #include "Composite.h"
25 #include "common.h"
26 #include "dot.h"
27 #include "Random_Unitary.h"
28 
29 
30 
36 
37  // A string labeling the gate operation
38  name = "COMPOSITE";
39 
40  // number of qubits spanning the matrix of the operation
41  qbit_num = -1;
42  // The size N of the NxN matrix associated with the operations.
43  matrix_size = -1;
44  // The type of the operation (see enumeration gate_type)
46  // The index of the qubit on which the operation acts (target_qbit >= 0)
47  target_qbit = -1;
48  // The index of the qubit which acts as a control qubit (control_qbit >= 0) in controlled operations
49  control_qbit = -1;
50  // the number of free parameters of the operation
51  parameter_num = 0;
52 }
53 
54 
55 
61 Composite::Composite(int qbit_num_in) {
62 
63  // A string labeling the gate operation
64  name = "COMPOSITE";
65 
66  // number of qubits spanning the matrix of the operation
67  qbit_num = qbit_num_in;
68  // the size of the matrix
70  // A string describing the type of the operation
72  // The index of the qubit on which the operation acts (target_qbit >= 0)
73  target_qbit = -1;
74  // The index of the qubit which acts as a control qubit (control_qbit >= 0) in controlled operations
75  control_qbit = -1;
76  // The number of parameters
78 }
79 
80 
85 }
86 
91 void Composite::set_qbit_num( int qbit_num_in ) {
92  // setting the number of qubits
93  qbit_num = qbit_num_in;
94 
95  // update the size of the matrix
97 
98  // Update the number of the parameters
100 
101 
102 }
103 
109 Matrix
111 
112  return get_matrix( parameters, false );
113 }
114 
115 
116 
123 Matrix
125 
126 
127  // create array of random parameters to construct random unitary
128  double* vartheta = parameters.get_data();//(double*) qgd_calloc( int(dim*(dim-1)/2),sizeof(double), 64);
129  double* varphi = parameters.get_data()+int((matrix_size*(matrix_size-1))/2);//(double*) qgd_calloc( int(dim*(dim-1)/2),sizeof(double), 64);
130  double* varkappa = parameters.get_data()+matrix_size*(matrix_size-1);//(double*) qgd_calloc( (dim-1),sizeof(double), 64);
131 
133  Matrix com_matrix = ru.Construct_Unitary_Matrix( vartheta, varphi, varkappa );
134 //com_matrix.print_matrix();
135 #ifdef DEBUG
136  if (com_matrix.isnan()) {
137  std::stringstream sstream;
138  sstream << "Composite::get_matrix: UN_matrix contains NaN." << std::endl;
139  print(sstream, 1);
140  }
141 #endif
142 
143  return com_matrix;
144 }
145 
146 
152 void
154 
155 
156  if (input.rows != matrix_size ) {
157  std::string err("Composite::apply_to: Wrong matrix size in Composite gate apply.");
158  throw err;
159  }
160 
161  if (parameters.size() < parameter_num) {
162  std::stringstream sstream;
163  sstream << "Not enough parameters given for the Composite gate" << std::endl;
164  print(sstream, 0);
165  exit(-1);
166  }
167 
168 
169  Matrix com_matrix = get_matrix( parameters );
170  Matrix transformed = dot( com_matrix, input );
171  memcpy( input.get_data(), transformed.get_data(), input.size()*sizeof(QGD_Complex16) );
172 
173 //std::cout << "Composite::apply_to" << std::endl;
174 //exit(-1);
175 }
176 
177 
182 void
184 
185 
186  if (input.rows != matrix_size ) {
187  std::stringstream sstream;
188  sstream << "Wrong matrix size in Composite gate apply" << std::endl;
189  print(sstream, 0);
190  exit(-1);
191  }
192 
193  if (parameters.size() < parameter_num) {
194  std::stringstream sstream;
195  sstream << "Not enough parameters given for the Composite gate" << std::endl;
196  print(sstream, 0);
197  exit(-1);
198  }
199 
200  Matrix com_matrix = get_matrix( parameters );
201  Matrix transformed = dot( input, com_matrix );
202  memcpy( input.get_data(), transformed.get_data(), input.size()*sizeof(QGD_Complex16) );
203 
204 //std::cout << "Composite::apply_to" << std::endl;
205 //exit(-1);
206 
207 }
208 
209 
210 
211 
216 void Composite::reorder_qubits( std::vector<int> qbit_list ) {
217 
218  // check the number of qubits
219  if ((int)qbit_list.size() != qbit_num ) {
220  std::stringstream sstream;
221  sstream << "Wrong number of qubits" << std::endl;
222  print(sstream, 0);
223  exit(-1);
224  }
225 
226 
227  int control_qbit_new = control_qbit;
228  int target_qbit_new = target_qbit;
229 
230  // setting the new value for the target qubit
231  for (int idx=0; idx<qbit_num; idx++) {
232  if (target_qbit == qbit_list[idx]) {
233  target_qbit_new = qbit_num-1-idx;
234  }
235  if (control_qbit == qbit_list[idx]) {
236  control_qbit_new = qbit_num-1-idx;
237  }
238  }
239 
240  control_qbit = control_qbit_new;
241  target_qbit = target_qbit_new;
242 }
243 
244 
249 int
251  return parameter_num;
252 }
253 
254 
259 gate_type
261  return type;
262 }
263 
264 
269 int
271  return qbit_num;
272 }
273 
274 
280 
281  Composite* ret = new Composite( qbit_num );
282 
284  ret->set_parents( parents );
285  ret->set_children( children );
286 
287  return ret;
288 
289 }
290 
291 
292 
std::vector< Gate * > parents
list of parent gates to be applied in the circuit prior to this current gate
Definition: Gate.h:95
bool isnan()
Call to check the array for NaN entries.
Definition: matrix.cpp:128
void apply_to(Matrix_real &parameters, Matrix &input, int parallel)
Call to apply the gate on the input array/matrix.
Definition: Composite.cpp:153
Matrix dot(Matrix &A, Matrix &B)
Call to calculate the product of two complex matrices by calling method zgemm3m from the CBLAS librar...
Definition: dot.cpp:38
Base class for the representation of general gate operations.
Definition: Composite.h:47
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
Header file for a class for a composite gate operation.
virtual Matrix get_matrix()
Call to retrieve the operation matrix.
Definition: Gate.cpp:129
Composite()
Default constructor of the class.
Definition: Composite.cpp:35
int control_qbit
The index of the qubit which acts as a control qubit (control_qbit >= 0) in controlled operations...
Definition: Gate.h:87
void set_children(std::vector< Gate *> &children_)
Call to set the children of the current gate.
Definition: Gate.cpp:802
int target_qbit
The index of the qubit on which the operation acts (target_qbit >= 0)
Definition: Gate.h:85
Composite * clone()
Call to create a clone of the present class.
Definition: Composite.cpp:279
int matrix_size
The size N of the NxN matrix associated with the operations.
Definition: Gate.h:89
scalar * get_data() const
Call to get the pointer to the stored data.
virtual ~Composite()
Destructor of the class.
Definition: Composite.cpp:84
void apply_from_right(Matrix_real &parameters, Matrix &input)
Call to apply the gate on the input array/matrix by input*Gate.
Definition: Composite.cpp:183
gate_type type
The type of the operation (see enumeration gate_type)
Definition: Gate.h:83
int rows
The number of rows.
Definition: matrix_base.hpp:42
virtual void set_qbit_num(int qbit_num_in)
Set the number of qubits spanning the matrix of the operation.
Definition: Composite.cpp:91
void set_parameter_start_idx(int start_idx)
Call to set the starting index of the parameters in the parameter array corresponding to the circuit ...
Definition: Gate.cpp:779
int get_parameter_start_idx()
Call to get the starting index of the parameters in the parameter array corresponding to the circuit ...
Definition: Gate.cpp:814
gate_type get_type()
Call to get the type of the operation.
Definition: Composite.cpp:260
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 size() const
Call to get the number of the allocated elements.
A class to cerate general random unitary matrix according to arXiv:1303:5904v1.
std::string name
A string labeling the gate operation.
Definition: Gate.h:79
std::vector< Gate * > children
list of child gates to be applied after this current gate
Definition: Gate.h:97
int get_parameter_num()
Call to get the number of free parameters.
Definition: Composite.cpp:250
int parameter_num
the number of free parameters of the operation
Definition: Gate.h:91
Header file for commonly used functions and wrappers to CBLAS functions.
void set_parents(std::vector< Gate *> &parents_)
Call to set the parents of the current gate.
Definition: Gate.cpp:790
int qbit_num
number of qubits spanning the matrix of the operation
Definition: Gate.h:81
gate_type
Type definition of operation types (also generalized for decomposition classes derived from the class...
Definition: Gate.h:34
int get_qbit_num()
Call to get the number of qubits composing the unitary.
Definition: Composite.cpp:270
Matrix_real parameters
Parameters theta, phi, lambda of the U3 gate after the decomposition of the unitary is done...
Definition: Composite.h:53
virtual void reorder_qubits(std::vector< int > qbit_list)
Call to reorder the qubits in the matrix of the operation.
Definition: Composite.cpp:216
Class to store data of complex arrays and its properties.
Definition: matrix_real.h:39