Quantum Gate Decomposer  v1.3
Powerful decomposition of almost any unitary into U3 and CNOT gates
Operation_block (copy).cpp
Go to the documentation of this file.
1 /*
2 Created on Fri Jun 26 14:13:26 2020
3 Copyright (C) 2020 Peter Rakyta, Ph.D.
4 
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see http://www.gnu.org/licenses/.
17 
18 @author: Peter Rakyta, Ph.D.
19 */
25 #include "qgd/CNOT.h"
26 #include "qgd/U3.h"
27 #include "qgd/Operation_block.h"
28 
29 using namespace std;
30 
35 
36  // A string describing the type of the operation
38  // number of operation layers
39  layer_num = 0;
40 }
41 
42 
43 
48 Operation_block::Operation_block(int qbit_num_in) : Operation(qbit_num_in) {
49 
50  // A string describing the type of the operation
52  // number of operation layers
53  layer_num = 0;
54 }
55 
56 
61 
63 }
64 
69 
70  //free the alloctaed memory of the stored operations
71  for(std::vector<Operation*>::iterator it = operations.begin(); it != operations.end(); ++it) {
72 
73  Operation* operation = *it;
74 
75  if (operation->get_type() == CNOT_OPERATION) {
76  CNOT* cnot_operation = static_cast<CNOT*>(operation);
77  delete cnot_operation;
78  }
79  else if (operation->get_type() == U3_OPERATION) {
80 
81  U3* u3_operation = static_cast<U3*>(operation);
82  delete u3_operation;
83 
84  }
85  else if (operation->get_type() == BLOCK_OPERATION) {
86 
87  Operation_block* block_operation = static_cast<Operation_block*>(operation);
88  delete block_operation;
89 
90  }
91  else if (operation->get_type() == GENERAL_OPERATION) {
92  delete operation;
93  }
94  }
95 
96  operations.clear();
97 
98 }
99 
100 
106 Matrix Operation_block::get_matrix( const double* parameters ) {
107 
108  // get the matrices of the operations grouped in the block
109  vector<Matrix> operation_mtxs = get_matrices( parameters );
110 
111  // calculate the product of the matrices
112  Matrix block_matrix = reduce_zgemm( operation_mtxs );
113 
114  operation_mtxs.clear();
115 
116  return block_matrix;
117 }
118 
119 
125 QGD_Complex16* Operation_block::matrix( const double* parameters ) {
126 
127  // get the matrices of the operations grouped in the block
128  vector<Matrix> operation_mtxs = get_matrices( parameters );
129 
130  // calculate the product of the matrices
131  Matrix block_matrix = reduce_zgemm( operation_mtxs );
132 
133  operation_mtxs.clear();
134 
135  block_matrix.set_owner(false);
136  return block_matrix.get_data();
137 }
138 
139 
140 
147 int Operation_block::matrix( const double* parameters, QGD_Complex16* block_mtx ) {
148 
149  // get the matrices of the operations grouped in the block
150  vector<Matrix> operation_mtxs = get_matrices( parameters );
151 
152  // calculate the product of the matrices
153  Matrix block_matrix = reduce_zgemm( operation_mtxs );
154 
155  operation_mtxs.clear();
156 
157  memcpy(block_mtx, block_matrix.get_data(), block_matrix.size()*sizeof(QGD_Complex16));
158 
159 
160  return 0;
161 
162 
163 
164 }
165 
166 
167 
168 
174 std::vector<Matrix> Operation_block::get_matrices( const double* parameters ) {
175 
176  std::vector<Matrix> matrices;
177  Matrix operation_mtx;
178 
179  for(std::vector<Operation*>::iterator it = operations.begin(); it != operations.end(); ++it) {
180 
181  Operation* operation = *it;
182 
183 
184  if (operation->get_type() == CNOT_OPERATION) {
185  CNOT* cnot_operation = static_cast<CNOT*>(operation);
186  operation_mtx = cnot_operation->get_matrix();
187 
188  }
189  else if (operation->get_type() == U3_OPERATION) {
190 
191  U3* u3_operation = static_cast<U3*>(operation);
192 
193  if (u3_operation->get_parameter_num() == 1 ) {
194  operation_mtx = u3_operation->get_matrix( parameters );
195  parameters = parameters + 1;
196  }
197  else if (u3_operation->get_parameter_num() == 2 ) {
198  operation_mtx = u3_operation->get_matrix( parameters );
199  parameters = parameters + 2;
200  }
201  else if (u3_operation->get_parameter_num() == 3 ) {
202  operation_mtx = u3_operation->get_matrix( parameters );
203  parameters = parameters + 3;
204  }
205  else {
206  printf("The U3 operation has wrong number of parameters");
207  throw "The U3 operation has wrong number of parameters";
208  }
209 
210  }
211  else if (operation->get_type() == GENERAL_OPERATION) {
212  operation_mtx = operation->get_matrix();
213  }
214 
215  matrices.push_back(operation_mtx);
216 
217 
218  }
219 
220  return matrices;
221 
222 }
223 
224 
225 
233 void Operation_block::add_u3_to_end(int target_qbit, bool Theta, bool Phi, bool Lambda) {
234 
235  // create the operation
236  Operation* operation = static_cast<Operation*>(new U3( qbit_num, target_qbit, Theta, Phi, Lambda ));
237 
238  // adding the operation to the end of the list of operations
239  add_operation_to_end( operation );
240 }
241 
249 void Operation_block::add_u3_to_front(int target_qbit, bool Theta, bool Phi, bool Lambda) {
250 
251  // create the operation
252  Operation* operation = static_cast<Operation*>(new U3( qbit_num, target_qbit, Theta, Phi, Lambda ));
253 
254  // adding the operation to the front of the list of operations
255  add_operation_to_front( operation );
256 
257 }
258 
264 void Operation_block::add_cnot_to_end( int control_qbit, int target_qbit) {
265 
266  // new cnot operation
267  Operation* operation = static_cast<Operation*>(new CNOT(qbit_num, control_qbit, target_qbit ));
268 
269  // append the operation to the list
270  add_operation_to_end(operation);
271 
272 }
273 
274 
275 
281 void Operation_block::add_cnot_to_front( int control_qbit, int target_qbit) {
282 
283  // new cnot operation
284  Operation* operation = static_cast<Operation*>(new CNOT(qbit_num, control_qbit, target_qbit ));
285 
286  // put the operation to tghe front of the list
287  add_operation_to_front(operation);
288 
289 }
290 
295 void Operation_block::add_operations_to_end( vector<Operation*> operations_in) {
296 
297  for(std::vector<Operation*>::iterator it = operations_in.begin(); it != operations_in.end(); ++it) {
298  add_operation_to_end( *it );
299  }
300 
301 }
302 
303 
308 void Operation_block::add_operations_to_front( vector<Operation*> operations_in) {
309 
310  // adding operations in reversed order!!
311  for(std::vector<Operation*>::iterator it = operations_in.end(); it != operations_in.begin(); --it) {
312  add_operation_to_front( *it );
313  }
314 
315 }
316 
317 
323 
324  //set the number of qubit in the operation
325  operation->set_qbit_num( qbit_num );
326 
327  // append the operation to the list
328  operations.push_back(operation);
329 
330 
331  // increase the number of parameters by the number of parameters
333 
334  // increase the number of layers if necessary
335  if (operation->get_type() == BLOCK_OPERATION) {
336  layer_num = layer_num + 1;
337  }
338 
339 }
340 
346 
347 
348  // set the number of qubit in the operation
349  operation->set_qbit_num( qbit_num );
350 
351  operations.insert( operations.begin(), operation);
352 
353  // increase the number of U3 gate parameters by the number of parameters
355 
356  // increase the number of layers if necessary
357  if (operation->get_type() == BLOCK_OPERATION) {
358  layer_num = layer_num + 1;
359  }
360 
361 }
362 
363 
364 
370 
371  gates_num gate_nums;
372 
373  gate_nums.u3 = 0;
374  gate_nums.cnot = 0;
375  gate_nums.general = 0;
376 
377  for(std::vector<Operation*>::iterator it = operations.begin(); it != operations.end(); ++it) {
378  // get the specific operation or block of operations
379  Operation* operation = *it;
380 
381  if (operation->get_type() == BLOCK_OPERATION) {
382  Operation_block* block_operation = static_cast<Operation_block*>(operation);
383  gates_num gate_nums_loc = block_operation->get_gate_nums();
384  gate_nums.u3 = gate_nums.u3 + gate_nums_loc.u3;
385  gate_nums.cnot = gate_nums.cnot + gate_nums_loc.cnot;
386  }
387  else if (operation->get_type() == U3_OPERATION) {
388  gate_nums.u3 = gate_nums.u3 + 1;
389  }
390  else if (operation->get_type() == CNOT_OPERATION) {
391  gate_nums.cnot = gate_nums.cnot + 1;
392  }
393  else if (operation->get_type() == GENERAL_OPERATION) {
394  gate_nums.general = gate_nums.general + 1;
395  }
396 
397  }
398 
399 
400  return gate_nums;
401 
402 }
403 
404 
410  return parameter_num;
411 }
412 
413 
419  return operations.size();
420 }
421 
422 
428 void Operation_block::list_operations( const double* parameters, int start_index ) {
429 
430  printf( "\nThe operations in the list of operations:\n" );
431 
432  int operation_idx = start_index;
433  int parameter_idx = parameter_num;
434 
435  for(int op_idx = operations.size()-1; op_idx>=0; op_idx--) {
436 
437  Operation* operation = operations[op_idx];
438 
439  if (operation->get_type() == CNOT_OPERATION) {
440  CNOT* cnot_operation = static_cast<CNOT*>(operation);
441 
442  printf( "%dth operation: CNOT with control qubit: %d and target qubit: %d\n", operation_idx, cnot_operation->get_control_qbit(), cnot_operation->get_target_qbit() );
443  operation_idx = operation_idx + 1;
444  }
445  else if (operation->get_type() == U3_OPERATION) {
446 
447  // definig the U3 parameters
448  double vartheta;
449  double varphi;
450  double varlambda;
451 
452  // get the inverse parameters of the U3 rotation
453 
454  U3* u3_operation = static_cast<U3*>(operation);
455 
456  if ((u3_operation->get_parameter_num() == 1) && u3_operation->is_theta_parameter()) {
457  vartheta = std::fmod( parameters[parameter_idx-1], 4*M_PI);
458  varphi = 0;
459  varlambda =0;
460  parameter_idx = parameter_idx - 1;
461 
462  }
463  else if ((u3_operation->get_parameter_num() == 1) && u3_operation->is_phi_parameter()) {
464  vartheta = 0;
465  varphi = std::fmod( parameters[ parameter_idx-1 ], 2*M_PI);
466  varlambda =0;
467  parameter_idx = parameter_idx - 1;
468  }
469  else if ((u3_operation->get_parameter_num() == 1) && u3_operation->is_lambda_parameter()) {
470  vartheta = 0;
471  varphi = 0;
472  varlambda = std::fmod( parameters[ parameter_idx-1 ], 2*M_PI);
473  parameter_idx = parameter_idx - 1;
474  }
475  else if ((u3_operation->get_parameter_num() == 2) && u3_operation->is_theta_parameter() && u3_operation->is_phi_parameter() ) {
476  vartheta = std::fmod( parameters[ parameter_idx-2 ], 4*M_PI);
477  varphi = std::fmod( parameters[ parameter_idx-1 ], 2*M_PI);
478  varlambda = 0;
479  parameter_idx = parameter_idx - 2;
480  }
481  else if ((u3_operation->get_parameter_num() == 2) && u3_operation->is_theta_parameter() && u3_operation->is_lambda_parameter() ) {
482  vartheta = std::fmod( parameters[ parameter_idx-2 ], 4*M_PI);
483  varphi = 0;
484  varlambda = std::fmod( parameters[ parameter_idx-1 ], 2*M_PI);
485  parameter_idx = parameter_idx - 2;
486  }
487  else if ((u3_operation->get_parameter_num() == 2) && u3_operation->is_phi_parameter() && u3_operation->is_lambda_parameter() ) {
488  vartheta = 0;
489  varphi = std::fmod( parameters[ parameter_idx-2], 2*M_PI);
490  varlambda = std::fmod( parameters[ parameter_idx-1 ], 2*M_PI);
491  parameter_idx = parameter_idx - 2;
492  }
493  else if ((u3_operation->get_parameter_num() == 3)) {
494  vartheta = std::fmod( parameters[ parameter_idx-3 ], 4*M_PI);
495  varphi = std::fmod( parameters[ parameter_idx-2 ], 2*M_PI);
496  varlambda = std::fmod( parameters[ parameter_idx-1 ], 2*M_PI);
497  parameter_idx = parameter_idx - 3;
498  }
499 
500 // message = message + "U3 on target qubit %d with parameters theta = %f, phi = %f and lambda = %f";
501  printf("%dth operation: U3 on target qubit: %d and with parameters theta = %f, phi = %f and lambda = %f\n", operation_idx, u3_operation->get_target_qbit(), vartheta, varphi, varlambda );
502  operation_idx = operation_idx + 1;
503 
504  }
505  else if (operation->get_type() == BLOCK_OPERATION) {
506  Operation_block* block_operation = static_cast<Operation_block*>(operation);
507  const double* parameters_layer = parameters + parameter_idx - operation->get_parameter_num();
508  block_operation->list_operations( parameters_layer, operation_idx );
509  parameter_idx = parameter_idx - block_operation->get_parameter_num();
510  operation_idx = operation_idx + block_operation->get_operation_num();
511  }
512 
513  }
514 
515 }
516 
517 
522 void Operation_block::reorder_qubits( vector<int> qbit_list) {
523 
524  for(std::vector<Operation*>::iterator it = operations.begin(); it != operations.end(); ++it) {
525 
526  Operation* operation = *it;
527 
528  if (operation->get_type() == CNOT_OPERATION) {
529  CNOT* cnot_operation = static_cast<CNOT*>(operation);
530  cnot_operation->reorder_qubits( qbit_list );
531  }
532  else if (operation->get_type() == U3_OPERATION) {
533  U3* u3_operation = static_cast<U3*>(operation);
534  u3_operation->reorder_qubits( qbit_list );
535  }
536  else if (operation->get_type() == BLOCK_OPERATION) {
537  Operation_block* block_operation = static_cast<Operation_block*>(operation);
538  block_operation->reorder_qubits( qbit_list );
539  }
540 
541 
542  }
543 
544 }
545 
546 
547 
553 
554  std::vector<int> involved_qbits;
555 
556  int qbit;
557 
558 
559  for(std::vector<Operation*>::iterator it = operations.begin(); it != operations.end(); ++it) {
560 
561  Operation* operation = *it;
562 
563  qbit = operation->get_target_qbit();
564  if (qbit != -1) {
565  add_unique_elelement( involved_qbits, qbit );
566  }
567 
568 
569  qbit = operation->get_control_qbit();
570  if (qbit != -1) {
571  add_unique_elelement( involved_qbits, qbit );
572  }
573 
574  }
575 
576  return involved_qbits;
577 }
578 
579 
584 std::vector<Operation*> Operation_block::get_operations() {
585  return operations;
586 }
587 
588 
594 
595  // getting the list of operations
596  std::vector<Operation*> operations_in = op_block->get_operations();
597 
598  for(std::vector<Operation*>::iterator it = (operations_in).begin(); it != (operations_in).end(); ++it) {
599  Operation* op = *it;
600 
601  if (op->get_type() == CNOT_OPERATION) {
602  CNOT* cnot_op = static_cast<CNOT*>( op );
603  CNOT* cnot_op_cloned = cnot_op->clone();
604  Operation* op_cloned = static_cast<Operation*>( cnot_op_cloned );
605  add_operation_to_end(op_cloned);
606  }
607  else if (op->get_type() == U3_OPERATION) {
608  U3* u3_op = static_cast<U3*>( op );
609  U3* u3_op_cloned = u3_op->clone();
610  Operation* op_cloned = static_cast<Operation*>( u3_op_cloned );
611  add_operation_to_end( op_cloned );
612  }
613  else if (op->get_type() == BLOCK_OPERATION) {
614  Operation_block* block_op = static_cast<Operation_block*>( op );
615  Operation_block* block_op_cloned = block_op->clone();
616  Operation* op_cloned = static_cast<Operation*>( block_op_cloned );
617  add_operation_to_end( op_cloned );
618  }
619  else if (op->get_type() == GENERAL_OPERATION) {
620  Operation* op_cloned = op->clone();
621  add_operation_to_end( op_cloned );
622  }
623 
624  }
625 
626 }
627 
628 
633 void Operation_block::set_qbit_num( int qbit_num_in ) {
634 
635  // setting the number of qubits
636  Operation::set_qbit_num(qbit_num_in);
637 
638  // setting the number of qubit in the operations
639  for(std::vector<Operation*>::iterator it = operations.begin(); it != operations.end(); ++it) {
640  Operation* op = *it;
641 
642  if (op->get_type() == CNOT_OPERATION) {
643  CNOT* cnot_op = static_cast<CNOT*>( op );
644  cnot_op->set_qbit_num( qbit_num_in );
645  }
646  else if (op->get_type() == U3_OPERATION) {
647  U3* u3_op = static_cast<U3*>( op );
648  u3_op->set_qbit_num( qbit_num_in );
649  }
650  else if (op->get_type() == BLOCK_OPERATION) {
651  Operation_block* block_op = static_cast<Operation_block*>( op );
652  block_op->set_qbit_num( qbit_num_in );
653  }
654  else if (op->get_type() == GENERAL_OPERATION) {
655  op->set_qbit_num( qbit_num_in );
656  }
657  }
658 }
659 
660 
666 
667  // creatign new instance of class Operation_block
669 
670  // extracting the operations from the current class
671  if (extract_operations( ret ) != 0 ) {
672  printf("Operation_block::clone(): extracting operations was not succesfull\n");
673  exit(-1);
674  };
675 
676  return ret;
677 
678 }
679 
680 
687 
688  op_block->release_operations();
689 
690  for ( std::vector<Operation*>::iterator it=operations.begin(); it != operations.end(); ++it ) {
691  Operation* op = *it;
692 
693  if (op->get_type() == CNOT_OPERATION) {
694  CNOT* cnot_op = static_cast<CNOT*>( op );
695  CNOT* cnot_op_cloned = cnot_op->clone();
696  Operation* op_cloned = static_cast<Operation*>( cnot_op_cloned );
697  op_block->add_operation_to_end( op_cloned );
698  }
699  else if (op->get_type() == U3_OPERATION) {
700  U3* u3_op = static_cast<U3*>( op );
701  U3* u3_op_cloned = u3_op->clone();
702  Operation* op_cloned = static_cast<Operation*>( u3_op_cloned );
703  op_block->add_operation_to_end( op_cloned );
704  }
705  else if (op->get_type() == BLOCK_OPERATION) {
706  Operation_block* block_op = static_cast<Operation_block*>( op );
707  Operation_block* block_op_cloned = block_op->clone();
708  Operation* op_cloned = static_cast<Operation*>( block_op_cloned );
709  op_block->add_operation_to_end( op_cloned );
710  }
711  else if (op->get_type() == GENERAL_OPERATION) {
712  Operation* op_cloned = op->clone();
713  op_block->add_operation_to_end( op_cloned );
714  }
715 
716  }
717 
718  return 0;
719 
720 }
721 
722 
723 
724 
Operation * clone()
Call to create a clone of the present class.
Definition: Operation.cpp:192
A class representing a U3 operation.
Definition: U3.h:35
void reorder_qubits(std::vector< int > qbit_list)
Call to reorder the qubits in the matrix of the operations.
void add_operations_to_end(std::vector< Operation * > operations_in)
Append a list of operations to the list of operations.
std::vector< Operation * > get_operations()
Call to get the operations stored in the class.
int extract_operations(Operation_block *op_block)
Call to extract the operations stored in the class.
Base class for the representation of one- and two-qubit operations.
Definition: Operation.h:40
int target_qbit
The index of the qubit on which the operation acts (target_qbit >= 0)
Definition: Operation.h:50
int control_qbit
The index of the qubit which acts as a control qubit (control_qbit >= 0) in controlled operations.
Definition: Operation.h:52
int get_parameter_num()
Call to get the number of free parameters.
Operation_block * clone()
Create a clone of the present class.
std::vector< Matrix > get_matrices(const double *parameters)
Call to get the list of matrix representation of the operations grouped in the block.
int get_target_qbit()
Call to get the index of the target qubit.
Definition: Operation.cpp:149
Structure type conatining numbers of gates.
Definition: QGDTypes.h:47
scalar * get_data()
Call to get the pointer to the stored data.
Definition: matrix_base.h:221
void list_operations(const double *parameters, int start_index)
Call to print the list of operations stored in the block of operations for a specific set of paramete...
void combine(Operation_block *op_block)
Call to append the operations of an operation block to the current block.
bool is_theta_parameter()
Call to check whether theta is a free parameter of the gate.
Definition: U3.cpp:402
void reorder_qubits(std::vector< int > qbit_list)
Call to reorder the qubits in the matrix of the operation.
Definition: U3.cpp:387
Header file for a class representing a CNOT operation.
U3 * clone()
Call to create a clone of the present class.
Definition: U3.cpp:462
operation_type type
The type of the operation (see enumeration operation_type)
Definition: Operation.h:48
Matrix reduce_zgemm(std::vector< Matrix > &mtxs)
Calculate the product of several square shaped complex matrices stored in a vector.
Definition: common.cpp:297
int u3
The number of U3 gates.
Definition: QGDTypes.h:49
int general
The number of general gates.
Definition: QGDTypes.h:53
void reorder_qubits(std::vector< int > qbit_list)
Call to reorder the qubits in the matrix of the operation.
Definition: CNOT.cpp:180
int qbit_num
number of qubits spanning the matrix of the operation
Definition: Operation.h:46
std::vector< int > get_involved_qubits()
Call to get the qubits involved in the operations stored in the block of operations.
void release_operations()
Call to release the stored operations.
A class responsible for grouping CNOT and U3 operations into layers.
Operation_block()
Deafult constructor of the class.
CNOT * clone()
Call to create a clone of the present class.
Definition: CNOT.cpp:192
virtual ~Operation_block()
Destructor of the class.
unsigned int parameter_num
the number of free parameters of the operation
Definition: Operation.h:56
void set_owner(bool owner_in)
Call to set the current class instance to be (or not to be) the owner of the stored data array.
Definition: matrix_base.h:295
gates_num get_gate_nums()
Call to get the number of the individual gate types in the list of operations.
Structure type representing complex numbers in the QGD package.
Definition: QGDTypes.h:39
A class representing a CNOT operation.
Definition: CNOT.h:36
int layer_num
number of operation layers
void set_qbit_num(int qbit_num)
Call to set the number of qubits spanning the matrix of the operation.
Definition: CNOT.cpp:168
Matrix get_matrix()
Call to retrieve the operation matrix.
Definition: Operation.cpp:97
Class to store data of complex arrays and its properties.
Definition: matrix.h:12
std::vector< Operation * > operations
The list of stored operations.
unsigned int get_parameter_num()
Call to get the number of free parameters.
Definition: Operation.cpp:165
Header file for a class representing a U3 operation.
void add_u3_to_end(int target_qbit, bool Theta, bool Phi, bool Lambda)
Append a U3 gate to the list of operations.
void add_operation_to_end(Operation *operation)
Append a general operation to the list of operations.
void add_operation_to_front(Operation *operation)
Add an operation to the front of the list of operations.
operation_type get_type()
Call to get the type of the operation.
Definition: Operation.cpp:174
bool is_lambda_parameter()
Call to check whether Lambda is a free parameter of the gate.
Definition: U3.cpp:419
bool is_phi_parameter()
Call to check whether Phi is a free parameter of the gate.
Definition: U3.cpp:411
Matrix get_matrix(const double *parameters)
Call to retrieve the operation matrix.
Definition: U3.cpp:138
virtual void set_qbit_num(int qbit_num_in)
Set the number of qubits spanning the matrix of the operation.
Definition: Operation.cpp:82
void add_unique_elelement(std::vector< int > &involved_qbits, int qbit)
Add an integer to a vector of integers if the integer is not already an element of the vector.
Definition: common.cpp:95
int get_operation_num()
Call to get the number of operations grouped in the class.
Matrix get_matrix()
Call to retrieve the operation matrix.
Definition: CNOT.cpp:79
void set_qbit_num(int qbit_num_in)
Call to set the number of qubits spanning the matrix of the operation.
Definition: U3.cpp:372
int get_control_qbit()
Call to get the index of the control qubit.
Definition: Operation.cpp:157
Header file for a class responsible for grouping CNOT and U3 operations into layers.
void add_cnot_to_end(int control_qbit, int target_qbit)
Append a C_NOT gate operation to the list of operations.
int cnot
The number of CNOT gates.
Definition: QGDTypes.h:51
size_t size()
Call to get the number of the allocated elements.
Definition: matrix_base.h:374
void set_qbit_num(int qbit_num_in)
Set the number of qubits spanning the matrix of the operations stored in the block of operations.
void add_cnot_to_front(int control_qbit, int target_qbit)
Add a C_NOT gate operation to the front of the list of operations.
void add_u3_to_front(int target_qbit, bool Theta, bool Phi, bool Lambda)
Add a U3 gate to the front of the list of operations.
void add_operations_to_front(std::vector< Operation * > operations_in)
Add an array of operations to the front of the list of operations.