Sequential Quantum Gate Decomposer  v1.9.3
Powerful decomposition of general unitarias into one- and two-qubit gates gates
X.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 */
23 #include "X.h"
24 
25 
26 
27 //static tbb::spin_mutex my_mutex;
31 X::X() {
32 
33  // A string labeling the gate operation
34  name = "X";
35 
36  // number of qubits spanning the matrix of the gate
37  qbit_num = -1;
38  // the size of the matrix
39  matrix_size = -1;
40  // A string describing the type of the gate
41  type = X_OPERATION;
42 
43  // The index of the qubit on which the gate acts (target_qbit >= 0)
44  target_qbit = -1;
45  // The index of the qubit which acts as a control qubit (control_qbit >= 0) in controlled gates
46  control_qbit = -1;
47 
48  parameter_num = 0;
49 
50 
51 
52 }
53 
54 
55 
64 X::X(int qbit_num_in, int target_qbit_in) {
65 
66  // A string labeling the gate operation
67  name = "X";
68 
69  // number of qubits spanning the matrix of the gate
70  qbit_num = qbit_num_in;
71  // the size of the matrix
73  // A string describing the type of the gate
74  type = X_OPERATION;
75 
76 
77  if (target_qbit_in >= qbit_num) {
78  std::stringstream sstream;
79  sstream << "The index of the target qubit is larger than the number of qubits" << std::endl;
80  print(sstream, 0);
81 
82  throw "The index of the target qubit is larger than the number of qubits";
83  }
84 
85  // The index of the qubit on which the gate acts (target_qbit >= 0)
86  target_qbit = target_qbit_in;
87  // The index of the qubit which acts as a control qubit (control_qbit >= 0) in controlled gates
88  control_qbit = -1;
89 
90  parameter_num = 0;
91 }
92 
93 
97 X::~X() {
98 
99 }
100 
101 
106 Matrix
108 
109 
110 
111  return get_matrix( false );
112 
113 }
114 
115 
121 Matrix
122 X::get_matrix( int parallel ) {
123 
124  Matrix X_matrix = create_identity(matrix_size);
125  apply_to(X_matrix, parallel);
126 
127 #ifdef DEBUG
128  if (X_matrix.isnan()) {
129  std::stringstream sstream;
130  sstream << "X::get_matrix: X_matrix contains NaN." << std::endl;
131  print(sstream, 1);
132  }
133 #endif
134 
135  return X_matrix;
136 
137 }
138 
139 
140 
147 void
148 X::apply_to( Matrix& input, int parallel ) {
149 
150  if (input.rows != matrix_size ) {
151  std::string err("X::apply_to: Wrong input size in X gate apply");
152  throw(err);
153  }
154 
155  Matrix u3_1qbit = calc_one_qubit_u3();
156 
157  //apply_kernel_to function to X gate
158  apply_kernel_to( u3_1qbit, input, false, parallel );
159 
160 
161 
162 }
163 
164 
165 
171 void
173 
174  //The stringstream input to store the output messages.
175  std::stringstream sstream;
176 
177  if (input.cols != matrix_size ) {
178  std::stringstream sstream;
179  sstream << "Wrong matrix size in U3 apply_from_right" << std::endl;
180  print(sstream, 0);
181  exit(-1);
182  }
183 
184  Matrix u3_1qbit = calc_one_qubit_u3();
185 
186  //apply_kernel_from_right function to X gate
187  apply_kernel_from_right(u3_1qbit, input);
188 
189 
190  /* int index_step = Power_of_2(target_qbit);
191  int current_idx = 0;
192  int current_idx_pair = current_idx+index_step;
193 
194 //std::cout << "target qbit: " << target_qbit << std::endl;
195 
196  while ( current_idx_pair < matrix_size ) {
197 
198 
199  tbb::parallel_for(0, index_step, 1, [&](int idx) {
200 
201  int current_idx_loc = current_idx + idx;
202  int current_idx_pair_loc = current_idx_pair + idx;
203 
204 
205  for ( int row_idx=0; row_idx<matrix_size; row_idx++) {
206 
207  int row_offset = row_idx*input.stride;
208 
209 
210  int index = row_offset+current_idx_loc;
211  int index_pair = row_offset+current_idx_pair_loc;
212 
213  QGD_Complex16 element = input[index];
214  QGD_Complex16 element_pair = input[index_pair];
215 
216  input[index] = element_pair;
217  input[index_pair] = element;
218 
219  };
220 
221 //std::cout << current_idx << " " << current_idx_pair << std::endl;
222 
223  });
224 
225 
226  current_idx = current_idx + 2*index_step;
227  current_idx_pair = current_idx_pair + 2*index_step;
228 
229 
230  }
231 
232 */
233 
234 }
235 
236 
237 
243 
244  X* ret = new X(qbit_num, target_qbit);
245 
247  ret->set_parents( parents );
248  ret->set_children( children );
249 
250  return ret;
251 
252 }
253 
254 
255 
256 
261 void X::reorder_qubits( std::vector<int> qbit_list) {
262 
263  Gate::reorder_qubits(qbit_list);
264 
265 }
266 
267 
272 void X::set_qbit_num(int qbit_num_in) {
273 
274  // setting the number of qubits
275  Gate::set_qbit_num(qbit_num_in);
276 }
277 
283 Matrix
285 
286  Matrix u3_1qbit = Matrix(2,2);
287  u3_1qbit[0].real = 0.0; u3_1qbit[0].imag = 0.0;
288  u3_1qbit[1].real = 1.0; u3_1qbit[1].imag = 0.0;
289  u3_1qbit[2].real = 1.0; u3_1qbit[2].imag = 0.0;
290  u3_1qbit[3].real = 0.0;u3_1qbit[3].imag = 0.0;
291  return u3_1qbit;
292 
293 }
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
A class representing a U3 gate.
Definition: X.h:36
Matrix calc_one_qubit_u3()
Set static values for matrix of the gates.
Definition: X.cpp:284
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 representing the X gate.
int control_qbit
The index of the qubit which acts as a control qubit (control_qbit >= 0) in controlled operations...
Definition: Gate.h:87
X()
NullaRX constructor of the class.
Definition: X.cpp:31
void apply_to(Matrix &input, int parallel)
Call to apply the gate on the input array/matrix by U3*input.
Definition: X.cpp:148
void set_children(std::vector< Gate *> &children_)
Call to set the children of the current gate.
Definition: Gate.cpp:802
virtual void set_qbit_num(int qbit_num_in)
Set the number of qubits spanning the matrix of the operation.
Definition: Gate.cpp:102
int target_qbit
The index of the qubit on which the operation acts (target_qbit >= 0)
Definition: Gate.h:85
void apply_kernel_from_right(Matrix &u3_1qbit, Matrix &input)
Call to apply the gate kernel on the input state or unitary from right (no AVX support) ...
Definition: Gate.cpp:613
int matrix_size
The size N of the NxN matrix associated with the operations.
Definition: Gate.h:89
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
int cols
The number of columns.
Definition: matrix_base.hpp:44
Matrix get_matrix()
Call to retrieve the gate matrix.
Definition: X.cpp:107
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
void reorder_qubits(std::vector< int > qbit_list)
Call to reorder the qubits in the matrix of the gate.
Definition: X.cpp:261
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
~X()
Destructor of the class.
Definition: X.cpp:97
int Power_of_2(int n)
Calculates the n-th power of 2.
Definition: common.cpp:117
X * clone()
Call to create a clone of the present class.
Definition: X.cpp:242
Class to store data of complex arrays and its properties.
Definition: matrix.h:38
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
void apply_kernel_to(Matrix &u3_1qbit, Matrix &input, bool deriv=false, int parallel=0)
Call to apply the gate kernel on the input state or unitary with optional AVX support.
Definition: Gate.cpp:537
Matrix create_identity(int matrix_size)
Call to create an identity matrix.
Definition: common.cpp:164
int parameter_num
the number of free parameters of the operation
Definition: Gate.h:91
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
void apply_from_right(Matrix &input)
Call to apply the gate on the input array/matrix by input*U3.
Definition: X.cpp:172
void set_qbit_num(int qbit_num_in)
Call to set the number of qubits spanning the matrix of the gate.
Definition: X.cpp:272
virtual void reorder_qubits(std::vector< int > qbit_list)
Call to reorder the qubits in the matrix of the operation.
Definition: Gate.cpp:339