Sequential Quantum Gate Decomposer  v1.9.3
Powerful decomposition of general unitarias into one- and two-qubit gates gates
CZ_NU.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 "CZ_NU.h"
24 
25 
26 
27 using namespace std;
28 
29 
34 
35  // A string labeling the gate operation
36  name = "CZ_NU";
37 
38  // number of qubits spanning the matrix of the gate
39  qbit_num = -1;
40  // the size of the matrix
41  matrix_size = -1;
42  // A string describing the type of the gate
44  // The number of free parameters
45  parameter_num = 0;
46 
47  // The index of the qubit on which the gate acts (target_qbit >= 0)
48  target_qbit = -1;
49 
50  // The index of the qubit which acts as a control qubit (control_qbit >= 0) in controlled gates
51  control_qbit = -1;
52 
53 
54 }
55 
56 
63 CZ_NU::CZ_NU(int qbit_num_in, int target_qbit_in, int control_qbit_in) {
64 
65 
66  // A string labeling the gate operation
67  name = "CZ_NU";
68  // number of qubits spanning the matrix of the gate
69  qbit_num = qbit_num_in;
70  // the size of the matrix
72  // A string describing the type of the gate
74  // The number of free parameters
75  parameter_num = 1;
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  throw sstream.str();
82  }
83  // The index of the qubit on which the gate acts (target_qbit >= 0)
84  target_qbit = target_qbit_in;
85 
86 
87  if (control_qbit_in >= qbit_num) {
88  std::stringstream sstream;
89  sstream << "The index of the control qubit is larger than the number of qubits" << std::endl;
90  print(sstream, 0);
91  throw sstream.str();
92  }
93  // The index of the qubit which acts as a control qubit (control_qbit >= 0) in controlled gates
94  control_qbit = control_qbit_in;
95 
96  // Parameter of the gate after the decomposition of the unitary is done
98 
99 }
100 
105 }
106 
111 Matrix
113 
114  return get_matrix( parameters, false );
115 }
116 
117 
123 Matrix
125 
126  Matrix CZ_matrix = create_identity(matrix_size);
127  apply_to( parameters, CZ_matrix, parallel);
128 
129  return CZ_matrix;
130 }
131 
132 
133 
134 
140 void
141 CZ_NU::apply_to( Matrix_real& parameters, Matrix& input, int parallel ) {
142 
143  if (input.rows != matrix_size ) {
144  std::string err("CZ_NU::apply_to: Wrong matrix size in CZ_NU gate apply.");
145  throw err;
146  }
147 
148  double param = parameters[0];
149 
150  Matrix u3_1qbit = calc_one_qubit_u3( param );
151  apply_kernel_to(u3_1qbit, input, false, parallel);
152 
153 }
154 
155 
156 
161 void
163 
164  if (input.cols != matrix_size ) {
165  std::stringstream sstream;
166  sstream << "Wrong matrix size in CRY apply_from_right" << std::endl;
167  print(sstream, 0);
168  throw "Wrong matrix size in CRY apply_from_right";
169  }
170 
171  double param = parameters[0];
172 
173  Matrix u3_1qbit = calc_one_qubit_u3( param );
174  apply_kernel_from_right(u3_1qbit, input);
175 
176 }
177 
178 
185 void
186 CZ_NU::apply_to_list( Matrix_real& parameters_mtx, std::vector<Matrix>& inputs, int parallel ) {
187 
188  int work_batch = 1;
189  if ( parallel == 0 ) {
190  work_batch = inputs.size();
191  }
192  else {
193  work_batch = 1;
194  }
195 
196 
197  tbb::parallel_for( tbb::blocked_range<int>(0,inputs.size(),work_batch), [&](tbb::blocked_range<int> r) {
198  for (int idx=r.begin(); idx<r.end(); ++idx) {
199 
200  Matrix* input = &inputs[idx];
201 
202  apply_to( parameters_mtx, *input, parallel );
203 
204  }
205 
206  });
207 
208 
209 }
210 
211 
218 std::vector<Matrix>
219 CZ_NU::apply_derivate_to( Matrix_real& parameters_mtx, Matrix& input, int parallel ) {
220 
221  if (input.rows != matrix_size ) {
222  std::stringstream sstream;
223  sstream << "Wrong matrix size in CRY gate apply" << std::endl;
224  print(sstream, 0);
225  throw "Wrong matrix size in CRY gate apply";
226  }
227 
228  std::vector<Matrix> ret;
229 
230  double param = parameters_mtx[0]+M_PI/2;
231 
232  // the resulting matrix
233  Matrix res_mtx = input.copy();
234 
235 
236  // get the gate kernel
237  Matrix u3_1qbit = calc_one_qubit_u3( param );
238 
239 
240  // apply the computing kernel on the matrix
241  bool deriv = true;
242  apply_kernel_to(u3_1qbit, res_mtx, deriv, parallel);
243 
244  ret.push_back(res_mtx);
245  return ret;
246 
247 
248 }
249 
250 
251 
252 
257 void CZ_NU::set_optimized_parameters(double param ) {
258 
260 
261  parameters[0] = param;
262 
263 }
264 
265 
271 
272  return parameters.copy();
273 
274 }
275 
276 
277 
283  // setting the number of qubits
284  Gate::set_qbit_num(qbit_num);
285 
286 }
287 
288 
289 
294 void CZ_NU::reorder_qubits( vector<int> qbit_list) {
295 
296  Gate::reorder_qubits(qbit_list);
297 
298 }
299 
304 Matrix
305 CZ_NU::calc_one_qubit_u3( double& param ){
306 
307  Matrix u3_1qbit = Matrix(2,2);
308  u3_1qbit[0].real = 1.0; u3_1qbit[0].imag = 0.0;
309  u3_1qbit[1].real = 0.0; u3_1qbit[1].imag = 0.0;
310  u3_1qbit[2].real = 0.0; u3_1qbit[2].imag = 0.0;
311  u3_1qbit[3].real = cos( param); u3_1qbit[3].imag = 0.0;
312  return u3_1qbit;
313 
314 }
315 
321 
322  CZ_NU* ret = new CZ_NU( qbit_num, target_qbit, control_qbit );
323 
324  return ret;
325 
326 }
327 
328 
329 
Matrix calc_one_qubit_u3()
Set static values for matrix of the gates.
Definition: CNOT.cpp:211
CZ_NU()
Nullary constructor of the class.
Definition: CZ_NU.cpp:33
parameter_num
[set adaptive gate structure]
void apply_to(Matrix_real &parameters, Matrix &input, int parallel)
Call to apply the gate on the input array/matrix CZ*input.
Definition: CZ_NU.cpp:141
void set_optimized_parameters(double param)
Call to set the final optimized parameters of the gate.
Definition: CZ_NU.cpp:257
virtual void set_qbit_num(int qbit_num_in)
Set the number of qubits spanning the matrix of the operation.
Definition: Gate.cpp:102
void apply_from_right(Matrix_real &parameters, Matrix &input)
Call to apply the gate on the input array/matrix by input*CZ.
Definition: CZ_NU.cpp:162
void apply_to_list(Matrix_real &parameters, std::vector< Matrix > &inputs, int parallel)
Call to apply the gate on the input array/matrix by CZ_NU*input.
Definition: CZ_NU.cpp:186
name
Definition: setup.py:33
int rows
The number of rows.
Definition: matrix_base.hpp:42
int cols
The number of columns.
Definition: matrix_base.hpp:44
matrix_size
[load Umtx]
Definition: example.py:58
~CZ_NU()
Destructor of the class.
Definition: CZ_NU.cpp:104
virtual CZ_NU * clone()
Call to create a clone of the present class.
Definition: CZ_NU.cpp:320
def apply_to(self, parameters_mtx, unitary_mtx, parallel=1)
Definition: qgd_Circuit.py:302
int Power_of_2(int n)
Calculates the n-th power of 2.
Definition: common.cpp:117
Matrix_real get_optimized_parameters()
Call to get the final optimized parameters of the gate.
Definition: CZ_NU.cpp:270
Class to store data of complex arrays and its properties.
Definition: matrix.h:38
A class representing a CZ operation.
Definition: CZ_NU.h:36
Matrix create_identity(int matrix_size)
Call to create an identity matrix.
Definition: common.cpp:164
void set_qbit_num(int qbit_num)
Call to set the number of qubits spanning the matrix of the operation.
Definition: CZ_NU.cpp:282
Matrix copy()
Call to create a copy of the matrix.
Definition: matrix.cpp:105
void reorder_qubits(std::vector< int > qbit_list)
Call to reorder the qubits in the matrix of the operation.
Definition: CZ_NU.cpp:294
Matrix get_matrix()
Call to retrieve the operation matrix.
Definition: CNOT.cpp:118
virtual void reorder_qubits(std::vector< int > qbit_list)
Call to reorder the qubits in the matrix of the operation.
Definition: Gate.cpp:339
Class to store data of complex arrays and its properties.
Definition: matrix_real.h:39
std::vector< Matrix > apply_derivate_to(Matrix_real &parameters_mtx, Matrix &input, int parallel)
Call to evaluate the derivate of the circuit on an input with respect to all of the free parameters...
Definition: CZ_NU.cpp:219