Sequential Quantum Gate Decomposer  v1.9.3
Powerful decomposition of general unitarias into one- and two-qubit gates gates
H.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 "H.h"
24 
25 
26 
27 //static tbb::spin_mutex my_mutex;
31 H::H() {
32 
33  // A string labeling the gate operation
34  name = "H";
35 
36  // number of qubits spanning the matrix of the gate
37  qbit_num = -1;
38 
39  // the size of the matrix
40  matrix_size = -1;
41 
42  // A string describing the type of the gate
43  type = H_OPERATION;
44 
45  // The index of the qubit on which the gate acts (target_qbit >= 0)
46  target_qbit = -1;
47 
48  // The index of the qubit which acts as a control qubit (control_qbit >= 0) in controlled gates
49  control_qbit = -1;
50 
51  parameter_num = 0;
52 
53 
54 
55 }
56 
57 
58 
67 H::H(int qbit_num_in, int target_qbit_in) {
68 
69  // A string labeling the gate operation
70  name = "H";
71 
72  // number of qubits spanning the matrix of the gate
73  qbit_num = qbit_num_in;
74 
75  // the size of the matrix
77 
78  // A string describing the type of the gate
79  type = H_OPERATION;
80 
81 
82  if (target_qbit_in >= qbit_num) {
83  std::stringstream sstream;
84  sstream << "The index of the target qubit is larger than the number of qubits" << std::endl;
85  print(sstream, 0);
86  throw "The index of the target qubit is larger than the number of qubits";
87  }
88 
89  // The index of the qubit on which the gate acts (target_qbit >= 0)
90  target_qbit = target_qbit_in;
91 
92  // The index of the qubit which acts as a control qubit (control_qbit >= 0) in controlled gates
93  control_qbit = -1;
94 
95  parameter_num = 0;
96 
97 
98 }
99 
100 
104 H::~H() {
105 
106 }
107 
108 
113 Matrix
115 
116 
117 
118  return get_matrix( false );
119 
120 }
121 
122 
128 Matrix
129 H::get_matrix( int parallel ) {
130 
131  Matrix H_matrix = create_identity(matrix_size);
132  apply_to(H_matrix, parallel);
133 
134 #ifdef DEBUG
135  if (H_matrix.isnan()) {
136  std::stringstream sstream;
137  sstream << "H::get_matrix: H_matrix contains NaN." << std::endl;
138  print(sstream, 1);
139  }
140 #endif
141 
142  return H_matrix;
143 
144 }
145 
146 
147 
154 void
155 H::apply_to( Matrix& input, int parallel ) {
156 
157  if (input.rows != matrix_size ) {
158  std::string err("H::apply_to: Wrong input size in H gate apply.");
159  throw err;
160  }
161 
162  Matrix u3_1qbit = calc_one_qubit_u3();
163 
164  //apply_kernel_to function to X gate
165  apply_kernel_to( u3_1qbit, input, false, parallel );
166 
167 
168 
169 }
170 
171 
172 
178 void
180 
181  //The stringstream input to store the output messages.
182  std::stringstream sstream;
183 
184  if (input.cols != matrix_size ) {
185  std::stringstream sstream;
186  sstream << "Wrong matrix size in U3 apply_from_right" << std::endl;
187  print(sstream, 0);
188  exit(-1);
189  }
190 
191  Matrix u3_1qbit = calc_one_qubit_u3();
192 
193  //apply_kernel_from_right function to X gate
194  apply_kernel_from_right(u3_1qbit, input);
195 
196 
197  /* int index_step = Power_of_2(target_qbit);
198  int current_idx = 0;
199  int current_idx_pair = current_idx+index_step;
200 
201 //std::cout << "target qbit: " << target_qbit << std::endl;
202 
203  while ( current_idx_pair < matrix_size ) {
204 
205 
206  tbb::parallel_for(0, index_step, 1, [&](int idx) {
207 
208  int current_idx_loc = current_idx + idx;
209  int current_idx_pair_loc = current_idx_pair + idx;
210 
211 
212  for ( int row_idx=0; row_idx<matrix_size; row_idx++) {
213 
214  int row_offset = row_idx*input.stride;
215 
216 
217  int index = row_offset+current_idx_loc;
218  int index_pair = row_offset+current_idx_pair_loc;
219 
220  QGD_Complex16 element = input[index];
221  QGD_Complex16 element_pair = input[index_pair];
222 
223  input[index] = element_pair;
224  input[index_pair] = element;
225 
226  };
227 
228 //std::cout << current_idx << " " << current_idx_pair << std::endl;
229 
230  });
231 
232 
233  current_idx = current_idx + 2*index_step;
234  current_idx_pair = current_idx_pair + 2*index_step;
235 
236 
237  }
238 
239 */
240 
241 }
242 
243 
244 
250 
251  H* ret = new H(qbit_num, target_qbit);
252 
254  ret->set_parents( parents );
255  ret->set_children( children );
256 
257  return ret;
258 
259 }
260 
261 
262 
263 
268 void H::reorder_qubits( std::vector<int> qbit_list) {
269 
270  Gate::reorder_qubits(qbit_list);
271 
272 }
273 
274 
279 void H::set_qbit_num(int qbit_num_in) {
280 
281  // setting the number of qubits
282  Gate::set_qbit_num(qbit_num_in);
283 }
284 
290 Matrix
292 
293  Matrix u3_1qbit = Matrix(2,2);
294  u3_1qbit[0].real = 1.0/sqrt(2.0); u3_1qbit[0].imag = 0.0;
295  u3_1qbit[1].real = 1.0/sqrt(2.0); u3_1qbit[1].imag = 0.0;
296  u3_1qbit[2].real = 1.0/sqrt(2.0); u3_1qbit[2].imag = 0.0;
297  u3_1qbit[3].real = -1.0/sqrt(2.0);u3_1qbit[3].imag = 0.0;
298  return u3_1qbit;
299 
300 }
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 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
Matrix calc_one_qubit_u3()
Set static values for matrix of the gates.
Definition: H.cpp:291
void set_qbit_num(int qbit_num_in)
Call to set the number of qubits spanning the matrix of the gate.
Definition: H.cpp:279
~H()
Destructor of the class.
Definition: H.cpp:104
void reorder_qubits(std::vector< int > qbit_list)
Call to reorder the qubits in the matrix of the gate.
Definition: H.cpp:268
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
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
void apply_from_right(Matrix &input)
Call to apply the gate on the input array/matrix by input*U3.
Definition: H.cpp:179
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
H()
Nullary constructor of the class.
Definition: H.cpp:31
Header file for a class representing the Hadamard gate.
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 apply_to(Matrix &input, int parallel)
Call to apply the gate on the input array/matrix by U3*input.
Definition: H.cpp:155
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
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
A class representing a Hadamard gate.
Definition: H.h:36
Matrix get_matrix()
Call to retrieve the gate matrix.
Definition: H.cpp:114
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
H * clone()
Call to create a clone of the present class.
Definition: H.cpp:249
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
virtual void reorder_qubits(std::vector< int > qbit_list)
Call to reorder the qubits in the matrix of the operation.
Definition: Gate.cpp:339