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