Sequential Quantum Gate Decomposer  v1.9.3
Powerful decomposition of general unitarias into one- and two-qubit gates gates
CROT.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 "CROT.h"
26 
27 static double M_PIOver2 = M_PI/2;
28 
29 //static tbb::spin_mutex my_mutex;
34 
35  // A string describing the type of the gate
37 
39 
40  // number of qubits spanning the matrix of the gate
41  qbit_num = -1;
42  // the size of the matrix
43  matrix_size = -1;
44 
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  parameter_num = 0;
49 
50  name = "CROT";
51 
52 }
53 
54 
55 
64 CROT::CROT(int qbit_num_in, int target_qbit_in, int control_qbit_in, crot_type subtype_in) {
65 
66  name = "CROT";
67 
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
73 
74  // A string describing the type of the gate
76 
77  subtype = subtype_in;
78 
79 
80  if (control_qbit_in >= qbit_num) {
81  std::stringstream sstream;
82  sstream << "The index of the control qubit is larger than the number of qubits in CROT gate." << std::endl;
83  print(sstream, 0);
84  throw sstream.str();
85  }
86 
87  // The index of the qubit which acts as a control qubit (control_qbit >= 0) in controlled gates
88  control_qbit = control_qbit_in;
89 
90 
91  // The index of the qubit on which the gate acts (target_qbit >= 0)
92  target_qbit = target_qbit_in;
93 
95  parameter_num=2;
96  }
97  else if (subtype == CONTROL_INDEPENDENT){
98  parameter_num = 4;
99  }
100  else{
101  std::stringstream sstream2;
102  sstream2 << "ERROR: CROT subtype not implemented" << std::endl;
103  print(sstream2, 0);
104  throw sstream2.str();
105  }
107 }
108 
113 
114 }
115 
116 
122 void
123 CROT::apply_to_list( Matrix_real& parameters_mtx, std::vector<Matrix>& input ) {
124 
125 
126  for ( std::vector<Matrix>::iterator it=input.begin(); it != input.end(); it++ ) {
127  apply_to( parameters_mtx, *it, 0);
128  }
129 
130 }
131 
138 void
139 CROT::apply_to_list( Matrix_real& parameters_mtx, std::vector<Matrix>& inputs, int parallel ) {
140 
141  int work_batch = 1;
142  if ( parallel == 0 ) {
143  work_batch = inputs.size();
144  }
145  else {
146  work_batch = 1;
147  }
148 
149 
150  tbb::parallel_for( tbb::blocked_range<int>(0,inputs.size(),work_batch), [&](tbb::blocked_range<int> r) {
151  for (int idx=r.begin(); idx<r.end(); ++idx) {
152 
153  Matrix* input = &inputs[idx];
154 
155  apply_to( parameters_mtx, *input, parallel );
156 
157  }
158 
159  });
160 
161 }
162 
169 void
170 CROT::apply_to( Matrix_real& parameters_mtx, Matrix& input, int parallel ) {
171 
172 
173  if (input.rows != matrix_size ) {
174  std::stringstream sstream;
175  sstream << "Wrong matrix size in CROT gate apply" << std::endl;
176  print(sstream, 0);
177  exit(-1);
178  }
179 
180 
181  double Theta0Over2, Theta1Over2, Phi0, Phi1;
182 
183  if (subtype == CONTROL_R){
184  Theta0Over2 = parameters_mtx[0];
185  Phi0 = parameters_mtx[1];
186  }
187  else if (subtype == CONTROL_OPPOSITE){
188  Theta0Over2 = parameters_mtx[0];
189  Theta1Over2 = -1.*parameters_mtx[0];
190  Phi0 = parameters_mtx[1];
191  Phi1 = parameters_mtx[1];
192  }
193  else if (subtype == CONTROL_INDEPENDENT){
194  Theta0Over2 = parameters_mtx[0];
195  Theta1Over2 = parameters_mtx[2];
196  Phi0 = parameters_mtx[1];
197  Phi1 = parameters_mtx[3];
198  }
199  else {
200  Theta0Over2 = 0.0;
201  Theta1Over2 = 0.0;
202  Phi0 = 0.0;
203  Phi1 = 0.0;
204  }
205 
206 
207 
208  if (subtype == CONTROL_R){
209  Matrix U3_matrix = calc_one_qubit_rotation(Theta0Over2,Phi0);
210  apply_kernel_to( U3_matrix, input, false, parallel );
211  }
212  else{
213  if (input.cols==1){
214 
215  Matrix U_2qbit(4,4);
216  memset(U_2qbit.get_data(),0.0,(U_2qbit.size()*2)*sizeof(double));
217  U_2qbit[0].real = std::cos(Theta0Over2);
218  U_2qbit[2].real = std::sin(Theta0Over2)*std::sin(Phi0);
219  U_2qbit[2].imag = std::sin(Theta0Over2)*std::cos(Phi0);
220  U_2qbit[1*4+3].real = -1.*std::sin(Theta1Over2)*std::sin(Phi1);
221  U_2qbit[1*4+3].imag = -1.*std::sin(Theta1Over2)*std::cos(Phi1);
222  U_2qbit[1*4+1].real = std::cos(Theta1Over2);
223  U_2qbit[2*4+2].real = std::cos(Theta0Over2);
224  U_2qbit[2*4].real = -1.*std::sin(Theta0Over2)*std::sin(Phi0);
225  U_2qbit[2*4].imag = std::sin(Theta0Over2)*std::cos(Phi0);
226  U_2qbit[3*4+3].real = std::cos(Theta1Over2);
227  U_2qbit[3*4+1].real = std::sin(Theta1Over2)*std::sin(Phi1);
228  U_2qbit[3*4+1].imag = -1.*std::sin(Theta1Over2)*std::cos(Phi1);
229  //U_2qbit[0].real =1.;U_2qbit[7].real =1.;U_2qbit[10].real =1.;U_2qbit[13].real =1.;
230  // apply the computing kernel on the matrix
231  std::vector<int> involved_qbits = {control_qbit,target_qbit};
232  if (parallel){
233  apply_large_kernel_to_input_AVX(U_2qbit,input,involved_qbits,input.size());
234  }
235  else{
236  apply_large_kernel_to_input(U_2qbit,input,involved_qbits,input.size());
237  }
238 
239  }
240 
241  else{
242 
243  Matrix U3_matrix = calc_one_qubit_rotation(Theta0Over2,Phi0);
244  Matrix U3_matrix2 = calc_one_qubit_rotation(Theta1Over2,Phi1);
245  if(parallel){
246  apply_crot_kernel_to_matrix_input_AVX_parallel(U3_matrix2,U3_matrix, input, target_qbit, control_qbit, input.rows);
247  }
248  else{
249  apply_crot_kernel_to_matrix_input_AVX(U3_matrix2,U3_matrix, input, target_qbit, control_qbit, input.rows);
250  }
251  }
252 
253  }
254 
255 }
256 
257 
258 
264 void
266 
267 
268 
269 }
270 
271 
277 std::vector<Matrix>
278 CROT::apply_derivate_to( Matrix_real& parameters_mtx, Matrix& input, int parallel ) {
279 
280  if (input.rows != matrix_size ) {
281  std::stringstream sstream;
282  sstream << "Wrong matrix size in CROT gate apply" << std::endl;
283  print(sstream, 0);
284  exit(-1);
285  }
286 
287  std::vector<Matrix> ret;
288 
289  double Theta0Over2, Theta1Over2, Phi0, Phi1;
290 
291  if (subtype == CONTROL_R){
292  Theta0Over2 = parameters_mtx[0];
293  Phi0 = parameters_mtx[1];
294  }
295  else if (subtype == CONTROL_OPPOSITE){
296  Theta0Over2 = parameters_mtx[0];
297  Theta1Over2 = -1.*(parameters_mtx[0]);
298  Phi0 = parameters_mtx[1];
299  Phi1 = parameters_mtx[1];
300  }
301  else if (subtype == CONTROL_INDEPENDENT){
302  Theta0Over2 = parameters_mtx[0];
303  Theta1Over2 = parameters_mtx[2];
304  Phi0 = parameters_mtx[1];
305  Phi1 = parameters_mtx[3];
306  }
307  else {
308  Theta0Over2 = 0.0;
309  Theta1Over2 = 0.0;
310  Phi0 = 0.0;
311  Phi1 = 0.0;
312  }
313 
314 
315 
316  // the resulting matrix
317  if (subtype == CONTROL_R){
318 
319 
320 
321  Matrix res_mtx = input.copy();
322  Matrix u3_1qbit = calc_one_qubit_rotation(Theta0Over2 +M_PIOver2 ,Phi0);
323  apply_kernel_to( u3_1qbit, res_mtx, true, parallel );
324  ret.push_back(res_mtx);
325  Matrix res_mtx2 = input.copy();
326  u3_1qbit = calc_one_qubit_rotation_deriv_Phi(Theta0Over2,Phi0+M_PIOver2 );
327  apply_kernel_to( u3_1qbit, res_mtx2, true, parallel );
328  ret.push_back(res_mtx2);
329  }
330  else{
331 
332  if (input.cols==1){
333  if ( subtype == CONTROL_OPPOSITE){
334  double Theta0Over2_shifted = Theta0Over2 + M_PIOver2;
335  double Theta1Over2_shifted;
336 
337  Theta1Over2_shifted = -1.*Theta0Over2_shifted;
338 
339  double Phi0_shifted = Phi0 + M_PIOver2;
340  double Phi1_shifted = Phi1 + M_PIOver2;
341 
342  //Theta derivative
343  Matrix res_mtx = input.copy();
344  Matrix U_2qbit(4,4);
345  memset(U_2qbit.get_data(),0.0,(U_2qbit.size()*2)*sizeof(double));
346 
347  U_2qbit[0].real = std::cos(Theta0Over2_shifted);
348  U_2qbit[2].real = std::sin(Theta0Over2_shifted)*std::sin(Phi0);
349  U_2qbit[2].imag = std::sin(Theta0Over2_shifted)*std::cos(Phi0);
350 
351  U_2qbit[2*4+2].real = std::cos(Theta0Over2_shifted);
352  U_2qbit[2*4].real = -1.*std::sin(Theta0Over2_shifted)*std::sin(Phi0);
353  U_2qbit[2*4].imag = std::sin(Theta0Over2_shifted)*std::cos(Phi0);
354 
355  U_2qbit[1*4+3].real = -1.*std::sin(Theta1Over2_shifted)*std::sin(Phi1);
356  U_2qbit[1*4+3].imag = -1.*std::sin(Theta1Over2_shifted)*std::cos(Phi1);
357  U_2qbit[1*4+1].real = std::cos(Theta1Over2_shifted);
358 
359  U_2qbit[3*4+3].real = std::cos(Theta1Over2_shifted);
360  U_2qbit[3*4+1].real = std::sin(Theta1Over2_shifted)*std::sin(Phi1);
361  U_2qbit[3*4+1].imag = -1.*std::sin(Theta1Over2_shifted)*std::cos(Phi1);
362 
363 
364  std::vector<int> involved_qbits = {control_qbit,target_qbit};
365 
366  apply_large_kernel_to_input(U_2qbit,res_mtx,involved_qbits,res_mtx.size());
367  ret.push_back(res_mtx);
368 
369  //Phi derivative
370  Matrix res_mtx1 = input.copy();
371  memset(U_2qbit.get_data(),0.0,(U_2qbit.size()*2)*sizeof(double));
372 
373  U_2qbit[2].real = std::sin(Theta0Over2)*std::sin(Phi0_shifted);
374  U_2qbit[2].imag = std::sin(Theta0Over2)*std::cos(Phi0_shifted);
375 
376  U_2qbit[2*4].real = -1.*std::sin(Theta0Over2)*std::sin(Phi0_shifted);
377  U_2qbit[2*4].imag = std::sin(Theta0Over2)*std::cos(Phi0_shifted);
378 
379  U_2qbit[1*4+3].real = -1.*std::sin(Theta1Over2)*std::sin(Phi1_shifted);
380  U_2qbit[1*4+3].imag = -1.*std::sin(Theta1Over2)*std::cos(Phi1_shifted);
381 
382  U_2qbit[3*4+1].real = std::sin(Theta1Over2)*std::sin(Phi1_shifted);
383  U_2qbit[3*4+1].imag = -1.*std::sin(Theta1Over2)*std::cos(Phi1_shifted);
384 
385  apply_large_kernel_to_input(U_2qbit,res_mtx1,involved_qbits,res_mtx1.size());
386  ret.push_back(res_mtx1);
387 
388  }
389  else{
390  double Theta0Over2_shifted = Theta0Over2 + M_PIOver2;
391  double Theta1Over2_shifted = Theta1Over2 + M_PIOver2;
392  double Phi0_shifted = Phi0 + M_PIOver2;
393  double Phi1_shifted = Phi1 + M_PIOver2;
394 
395  //theta0 derivative
396  Matrix res_mtx = input.copy();
397  Matrix U_2qbit(4,4);
398  memset(U_2qbit.get_data(),0.0,(U_2qbit.size()*2)*sizeof(double));
399  U_2qbit[0].real = std::cos(Theta0Over2_shifted);
400  U_2qbit[2].real = std::sin(Theta0Over2_shifted)*std::sin(Phi0);
401  U_2qbit[2].imag = std::sin(Theta0Over2_shifted)*std::cos(Phi0);
402 
403  U_2qbit[2*4+2].real = std::cos(Theta0Over2_shifted);
404  U_2qbit[2*4].real = -1.*std::sin(Theta0Over2_shifted)*std::sin(Phi0);
405  U_2qbit[2*4].imag = std::sin(Theta0Over2_shifted)*std::cos(Phi0);
406 
407  std::vector<int> involved_qbits = {control_qbit,target_qbit};
408 
409  apply_large_kernel_to_input(U_2qbit,res_mtx,involved_qbits,res_mtx.size());
410  ret.push_back(res_mtx);
411 
412  //Phi0 derivative
413  Matrix res_mtx1 = input.copy();
414  memset(U_2qbit.get_data(),0.0,(U_2qbit.size()*2)*sizeof(double));
415 
416  U_2qbit[2].real = std::sin(Theta0Over2)*std::sin(Phi0_shifted);
417  U_2qbit[2].imag = std::sin(Theta0Over2)*std::cos(Phi0_shifted);
418 
419  U_2qbit[2*4].real = -1.*std::sin(Theta0Over2)*std::sin(Phi0_shifted);
420  U_2qbit[2*4].imag = std::sin(Theta0Over2)*std::cos(Phi0_shifted);
421 
422  apply_large_kernel_to_input(U_2qbit,res_mtx1,involved_qbits,res_mtx1.size());
423  ret.push_back(res_mtx1);
424 
425  //theta1 derivative
426  Matrix res_mtx2 = input.copy();
427  memset(U_2qbit.get_data(),0.0,(U_2qbit.size()*2)*sizeof(double));
428 
429  U_2qbit[1*4+3].real = -1.*std::sin(Theta1Over2_shifted)*std::sin(Phi1);
430  U_2qbit[1*4+3].imag = -1.*std::sin(Theta1Over2_shifted)*std::cos(Phi1);
431  U_2qbit[1*4+1].real = std::cos(Theta1Over2_shifted);
432 
433  U_2qbit[3*4+3].real = std::cos(Theta1Over2_shifted);
434  U_2qbit[3*4+1].real = std::sin(Theta1Over2_shifted)*std::sin(Phi1);
435  U_2qbit[3*4+1].imag = -1.*std::sin(Theta1Over2_shifted)*std::cos(Phi1);
436 
437  apply_large_kernel_to_input(U_2qbit,res_mtx2,involved_qbits,res_mtx2.size());
438  ret.push_back(res_mtx2);
439 
440  //Phi1 derivative
441  Matrix res_mtx3 = input.copy();
442  memset(U_2qbit.get_data(),0.0,(U_2qbit.size()*2)*sizeof(double));
443 
444  U_2qbit[1*4+3].real = -1.*std::sin(Theta1Over2)*std::sin(Phi1_shifted);
445  U_2qbit[1*4+3].imag = -1.*std::sin(Theta1Over2)*std::cos(Phi1_shifted);
446 
447  U_2qbit[3*4+1].real = std::sin(Theta1Over2)*std::sin(Phi1_shifted);
448  U_2qbit[3*4+1].imag = -1.*std::sin(Theta1Over2)*std::cos(Phi1_shifted);
449 
450  apply_large_kernel_to_input(U_2qbit,res_mtx3,involved_qbits,res_mtx3.size());
451  ret.push_back(res_mtx3);
452  }
453  }
454  else{
455  if (subtype == CONTROL_OPPOSITE){
456  double Theta0Over2_shifted = Theta0Over2 + M_PIOver2;
457  double Theta1Over2_shifted;
458 
459  Theta1Over2_shifted = -1.*Theta0Over2_shifted;
460 
461  //Theta derivative
462  Matrix res_mtx = input.copy();
463  Matrix U3_matrix = calc_one_qubit_rotation(Theta0Over2_shifted,Phi0);
464  Matrix U3_matrix2 = calc_one_qubit_rotation(Theta1Over2_shifted,Phi1);
465 
466  apply_crot_kernel_to_matrix_input_AVX(U3_matrix2, U3_matrix, res_mtx, target_qbit, control_qbit, res_mtx.rows);
467  ret.push_back(res_mtx);
469  double Phi0_shifted = Phi0 + M_PIOver2;
470  double Phi1_shifted = Phi1 + M_PIOver2;
471  Matrix res_mtx1 = input.copy();
472  U3_matrix = calc_one_qubit_rotation_deriv_Phi(Theta0Over2,Phi0_shifted);
473  U3_matrix2 = calc_one_qubit_rotation_deriv_Phi(Theta1Over2,Phi1_shifted);
474  apply_crot_kernel_to_matrix_input_AVX(U3_matrix2, U3_matrix, res_mtx1, target_qbit, control_qbit, res_mtx1.rows);
475  ret.push_back(res_mtx1);
476  }
477  else if (subtype == CONTROL_INDEPENDENT){
478 
480  double Theta0Over2_shifted = Theta0Over2 + M_PIOver2;
481  Matrix res_mtx = input.copy();
482  Matrix U3_matrix = calc_one_qubit_rotation(Theta0Over2_shifted,Phi0);
483  Matrix U3_matrix2(2,2);
484  memset(U3_matrix2.get_data(),0.0,U3_matrix2.size()*sizeof(QGD_Complex16));
485  apply_crot_kernel_to_matrix_input_AVX(U3_matrix2, U3_matrix, res_mtx, target_qbit, control_qbit, res_mtx.rows);
486  ret.push_back(res_mtx);
487 
489  double Phi0_shifted = Phi0 + M_PIOver2;
490  Matrix res_mtx1 = input.copy();
491  U3_matrix = calc_one_qubit_rotation_deriv_Phi(Theta0Over2,Phi0_shifted);
492  memset(U3_matrix2.get_data(),0.0,U3_matrix2.size()*sizeof(QGD_Complex16));
493  apply_crot_kernel_to_matrix_input_AVX(U3_matrix2, U3_matrix, res_mtx1, target_qbit, control_qbit, res_mtx1.rows);
494  ret.push_back(res_mtx1);
495 
497  double Theta1Over2_shifted = Theta1Over2 + M_PIOver2;
498  Matrix res_mtx2 = input.copy();
499  U3_matrix2 = calc_one_qubit_rotation(Theta1Over2_shifted,Phi1);
500  memset(U3_matrix.get_data(),0.0,U3_matrix.size()*sizeof(QGD_Complex16));
501  apply_crot_kernel_to_matrix_input_AVX(U3_matrix2, U3_matrix, res_mtx2, target_qbit, control_qbit, res_mtx2.rows);
502  ret.push_back(res_mtx2);
503 
505  double Phi1_shifted = Phi1 + M_PIOver2;
506  Matrix res_mtx3 = input.copy();
507  U3_matrix2 = calc_one_qubit_rotation_deriv_Phi(Theta1Over2,Phi1_shifted);
508  memset(U3_matrix.get_data(),0.0,U3_matrix.size()*sizeof(QGD_Complex16));
509  apply_crot_kernel_to_matrix_input_AVX(U3_matrix2, U3_matrix, res_mtx3, target_qbit, control_qbit, res_mtx3.rows);
510  ret.push_back(res_mtx3);
511 
512  }
513  else{
514  std::stringstream sstream;
515  sstream << "Subtype not implemented for gradient" << std::endl;
516  print(sstream, 1);
517  exit(-1);
518  }
519 
520  }
521  }
522 
523  return ret;
524 
525 
526 }
528  return subtype;
529  }
530 
535 void CROT::set_qbit_num(int qbit_num_in) {
536 
537  // setting the number of qubits
538  Gate::set_qbit_num(qbit_num_in);
539 }
540 
541 
542 
547 void CROT::reorder_qubits( std::vector<int> qbit_list) {
548 
549  Gate::reorder_qubits(qbit_list);
550 
551 }
552 
553 
554 
560 
562 
564 
565  return ret;
566 
567 }
568 
569 Matrix CROT::calc_one_qubit_rotation(double ThetaOver2, double Phi) {
570  Matrix u3_1qbit = Matrix(2,2);
571  u3_1qbit[0].real = std::cos(ThetaOver2);
572  u3_1qbit[0].imag = 0;
573 
574  u3_1qbit[1].real = -1.*std::sin(ThetaOver2)*std::sin(Phi);
575  u3_1qbit[1].imag = -1.*std::sin(ThetaOver2)*std::cos(Phi);
576 
577  u3_1qbit[2].real = std::sin(ThetaOver2)*std::sin(Phi);
578  u3_1qbit[2].imag = -1.*std::sin(ThetaOver2)*std::cos(Phi);
579 
580  u3_1qbit[3].real = std::cos(ThetaOver2);
581  u3_1qbit[3].imag = 0;
582 
583  return u3_1qbit;
584 }
585 
587  Matrix u3_1qbit = Matrix(2,2);
588  u3_1qbit[0].real = 0;
589  u3_1qbit[0].imag = 0;
590 
591  u3_1qbit[1].real = -1.*std::sin(ThetaOver2)*std::sin(Phi);
592  u3_1qbit[1].imag = -1.*std::sin(ThetaOver2)*std::cos(Phi);
593 
594  u3_1qbit[2].real = std::sin(ThetaOver2)*std::sin(Phi);
595  u3_1qbit[2].imag = -1.*std::sin(ThetaOver2)*std::cos(Phi);
596 
597  u3_1qbit[3].real = 0;
598  u3_1qbit[3].imag = 0;
599 
600  return u3_1qbit;
601 }
602 
610 
611  if ( get_parameter_start_idx() + get_parameter_num() > parameters.size() ) {
612  std::string err("CROT::extract_parameters: Cant extract parameters, since the dinput arary has not enough elements.");
613  throw err;
614  }
616  Matrix_real extracted_parameters(1,2);
617 
618  extracted_parameters[0] = std::fmod( 2*parameters[ get_parameter_start_idx() ], 4*M_PI);
619  extracted_parameters[1] = std::fmod( parameters[ get_parameter_start_idx() + 1 ], 2*M_PI);
620  return extracted_parameters;
621  }
622  else if (subtype == CONTROL_INDEPENDENT){
623  Matrix_real extracted_parameters(1,4);
624 
625  extracted_parameters[0] = std::fmod( 2*parameters[ get_parameter_start_idx() ], 4*M_PI);
626  extracted_parameters[1] = std::fmod( parameters[ get_parameter_start_idx() + 1 ], 2*M_PI);
627  extracted_parameters[2] = std::fmod( 2*parameters[ get_parameter_start_idx() +2 ], 4*M_PI);
628  extracted_parameters[3] = std::fmod( parameters[ get_parameter_start_idx() + 3 ], 2*M_PI);
629  return extracted_parameters;
630  }
631  Matrix_real extracted_parameters(1,1);
632  return extracted_parameters;
633 
634 }
virtual Matrix_real extract_parameters(Matrix_real &parameters)
Call to extract parameters from the parameter array corresponding to the circuit, in which the gate i...
Definition: CROT.cpp:609
crot_type get_subtype()
Definition: CROT.cpp:527
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
virtual void apply_from_right(Matrix_real &parameters, Matrix &input)
Call to apply the gate on the input array/matrix by input*CROT.
Definition: CROT.cpp:265
int control_qbit
The index of the qubit which acts as a control qubit (control_qbit >= 0) in controlled operations...
Definition: Gate.h:87
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 a controlled rotation gate around the Y axis.
int target_qbit
The index of the qubit on which the operation acts (target_qbit >= 0)
Definition: Gate.h:85
void apply_large_kernel_to_input(Matrix &unitary, Matrix &input, std::vector< int > involved_qbits, const int &matrix_size)
int matrix_size
The size N of the NxN matrix associated with the operations.
Definition: Gate.h:89
scalar * get_data() const
Call to get the pointer to the stored data.
A class representing a CROT gate.
Definition: CROT.h:39
void apply_to_list(Matrix_real &parameters_mtx, std::vector< Matrix > &input)
Call to apply the gate on the input array/matrix by U3*input.
Definition: CROT.cpp:123
void apply_large_kernel_to_input_AVX(Matrix &unitary, Matrix &input, std::vector< int > involved_qbits, const int &matrix_size)
virtual void reorder_qubits(std::vector< int > qbit_list)
Call to reorder the qubits in the matrix of the gate.
Definition: CROT.cpp:547
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 calc_one_qubit_rotation_deriv_Phi(double ThetaOver2, double Phi)
Definition: CROT.cpp:586
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
Matrix calc_one_qubit_rotation(double ThetaOver2, double Phi)
Definition: CROT.cpp:569
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
Structure type representing complex numbers in the SQUANDER package.
Definition: QGDTypes.h:38
virtual void apply_to(Matrix_real &parameters_mtx, Matrix &input, int parallel)
Call to apply the gate on the input array/matrix by CROT3*input.
Definition: CROT.cpp:170
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
int size() const
Call to get the number of the allocated elements.
int get_parameter_num()
Call to get the number of free parameters.
Definition: Gate.cpp:486
void apply_crot_kernel_to_matrix_input_AVX_parallel(Matrix &u3_1qbit1, Matrix &u3_1qbit2, Matrix &input, const int &target_qbit, const int &control_qbit, const int &matrix_size)
static double M_PIOver2
Definition: CROT.cpp:27
std::string name
A string labeling the gate operation.
Definition: Gate.h:79
Matrix_real parameters
Definition: CROT.h:46
void apply_crot_kernel_to_matrix_input_AVX(Matrix &u3_1qbit1, Matrix &u3_1qbit2, Matrix &input, const int &target_qbit, const int &control_qbit, const int &matrix_size)
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
int parameter_num
the number of free parameters of the operation
Definition: Gate.h:91
virtual void set_qbit_num(int qbit_num_in)
Call to set the number of qubits spanning the matrix of the gate.
Definition: CROT.cpp:535
virtual CROT * clone()
Call to create a clone of the present class.
Definition: CROT.cpp:559
Definition: CROT.h:34
CROT()
Nullary constructor of the class.
Definition: CROT.cpp:33
Matrix copy()
Call to create a copy of the matrix.
Definition: matrix.cpp:105
virtual ~CROT()
Destructor of the class.
Definition: CROT.cpp:112
int qbit_num
number of qubits spanning the matrix of the operation
Definition: Gate.h:81
crot_type subtype
Definition: CROT.h:44
virtual std::vector< Matrix > apply_derivate_to(Matrix_real &parameters_mtx, Matrix &input, int parallel)
Call to evaluate the derivate of the circuit on an inout with respect to all of the free parameters...
Definition: CROT.cpp:278
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
crot_type
Definition: CROT.h:34