Sequential Quantum Gate Decomposer  v1.9.6
Powerful decomposition of general unitarias into one- and two-qubit gates gates
R.cpp
Go to the documentation of this file.
2 #include "R.h"
3 
4 R::R() : R(-1, -1) {}
5 
6 R::R(int qbit_num_in, int target_qbit_in) : U3(qbit_num_in, target_qbit_in) {
7  name = "R";
9  parameter_num = 2;
10  control_qbit = -1;
11 }
12 
13 R::~R() {}
14 
15 R* R::clone() {
16  R* ret = new R(qbit_num, target_qbit);
18  ret->set_parents(parents);
19  ret->set_children(children);
20  return ret;
21 }
22 
23 std::vector<double> R::get_parameter_multipliers() const {
24  return {2.0, 1.0};
25 }
26 
27 Matrix R::gate_kernel(const Matrix_real& precomputed_sincos) {
28  const int theta_offset = 0 * precomputed_sincos.stride;
29  const int phi_offset = 1 * precomputed_sincos.stride;
30  const double s_theta = precomputed_sincos[theta_offset + 0];
31  const double c_theta = precomputed_sincos[theta_offset + 1];
32  const double s_phi = precomputed_sincos[phi_offset + 0];
33  const double c_phi = precomputed_sincos[phi_offset + 1];
34  return r_gate_kernel_from_trig<Matrix, double>(s_theta, c_theta, s_phi, c_phi);
35 }
36 
37 Matrix_float R::gate_kernel(const Matrix_real_float& precomputed_sincos) {
38  const int theta_offset = 0 * precomputed_sincos.stride;
39  const int phi_offset = 1 * precomputed_sincos.stride;
40  const float s_theta = precomputed_sincos[theta_offset + 0];
41  const float c_theta = precomputed_sincos[theta_offset + 1];
42  const float s_phi = precomputed_sincos[phi_offset + 0];
43  const float c_phi = precomputed_sincos[phi_offset + 1];
44  return r_gate_kernel_from_trig<Matrix_float, float>(s_theta, c_theta, s_phi, c_phi);
45 }
46 
47 Matrix R::inverse_gate_kernel(const Matrix_real& precomputed_sincos) {
48  const int theta_offset = 0 * precomputed_sincos.stride;
49  const int phi_offset = 1 * precomputed_sincos.stride;
50  const double s_theta = precomputed_sincos[theta_offset + 0];
51  const double c_theta = precomputed_sincos[theta_offset + 1];
52  const double s_phi = precomputed_sincos[phi_offset + 0];
53  const double c_phi = precomputed_sincos[phi_offset + 1];
54  return r_inverse_gate_kernel_from_trig<Matrix, double>(s_theta, c_theta, s_phi, c_phi);
55 }
56 
58  const int theta_offset = 0 * precomputed_sincos.stride;
59  const int phi_offset = 1 * precomputed_sincos.stride;
60  const float s_theta = precomputed_sincos[theta_offset + 0];
61  const float c_theta = precomputed_sincos[theta_offset + 1];
62  const float s_phi = precomputed_sincos[phi_offset + 0];
63  const float c_phi = precomputed_sincos[phi_offset + 1];
64  return r_inverse_gate_kernel_from_trig<Matrix_float, float>(s_theta, c_theta, s_phi, c_phi);
65 }
66 
67 Matrix R::derivative_kernel(const Matrix_real& precomputed_sincos, int param_idx) {
68  const int theta_offset = 0 * precomputed_sincos.stride;
69  const int phi_offset = 1 * precomputed_sincos.stride;
70  const double s_theta = precomputed_sincos[theta_offset + 0];
71  const double c_theta = precomputed_sincos[theta_offset + 1];
72  const double s_phi = precomputed_sincos[phi_offset + 0];
73  const double c_phi = precomputed_sincos[phi_offset + 1];
74 
75  if (param_idx == 0) {
76  return r_derivative_kernel_theta_from_trig<Matrix, double>(s_theta, c_theta, s_phi, c_phi);
77  }
78  if (param_idx == 1) {
79  return r_derivative_kernel_phi_from_trig<Matrix, double>(s_theta, s_phi, c_phi);
80  }
81 
82  return Matrix();
83 }
84 
85 Matrix_float R::derivative_kernel(const Matrix_real_float& precomputed_sincos, int param_idx) {
86  const int theta_offset = 0 * precomputed_sincos.stride;
87  const int phi_offset = 1 * precomputed_sincos.stride;
88  const float s_theta = precomputed_sincos[theta_offset + 0];
89  const float c_theta = precomputed_sincos[theta_offset + 1];
90  const float s_phi = precomputed_sincos[phi_offset + 0];
91  const float c_phi = precomputed_sincos[phi_offset + 1];
92 
93  if (param_idx == 0) {
94  return r_derivative_kernel_theta_from_trig<Matrix_float, float>(s_theta, c_theta, s_phi, c_phi);
95  }
96  if (param_idx == 1) {
97  return r_derivative_kernel_phi_from_trig<Matrix_float, float>(s_theta, s_phi, c_phi);
98  }
99 
100  return Matrix_float();
101 }
102 
103 void R::gate_kernel_to(const Matrix_real& precomputed_sincos, Matrix& output) {
104  const int phi_offset = precomputed_sincos.stride;
105  r_gate_kernel_from_trig_to<Matrix, double>(
106  output,
107  precomputed_sincos[0],
108  precomputed_sincos[1],
109  precomputed_sincos[phi_offset + 0],
110  precomputed_sincos[phi_offset + 1]
111  );
112 }
113 
114 void R::gate_kernel_to(const Matrix_real_float& precomputed_sincos, Matrix_float& output) {
115  const int phi_offset = precomputed_sincos.stride;
116  r_gate_kernel_from_trig_to<Matrix_float, float>(
117  output,
118  precomputed_sincos[0],
119  precomputed_sincos[1],
120  precomputed_sincos[phi_offset + 0],
121  precomputed_sincos[phi_offset + 1]
122  );
123 }
124 
125 void R::inverse_gate_kernel_to(const Matrix_real& precomputed_sincos, Matrix& output) {
126  const int phi_offset = precomputed_sincos.stride;
127  r_inverse_gate_kernel_from_trig_to<Matrix, double>(
128  output,
129  precomputed_sincos[0],
130  precomputed_sincos[1],
131  precomputed_sincos[phi_offset + 0],
132  precomputed_sincos[phi_offset + 1]
133  );
134 }
135 
137  const int phi_offset = precomputed_sincos.stride;
138  r_inverse_gate_kernel_from_trig_to<Matrix_float, float>(
139  output,
140  precomputed_sincos[0],
141  precomputed_sincos[1],
142  precomputed_sincos[phi_offset + 0],
143  precomputed_sincos[phi_offset + 1]
144  );
145 }
146 
147 void R::derivative_kernel_to(const Matrix_real& precomputed_sincos, int param_idx, Matrix& output) {
148  const int phi_offset = precomputed_sincos.stride;
149  const double s_theta = precomputed_sincos[0];
150  const double c_theta = precomputed_sincos[1];
151  const double s_phi = precomputed_sincos[phi_offset + 0];
152  const double c_phi = precomputed_sincos[phi_offset + 1];
153 
154  if (param_idx == 0) {
155  r_derivative_kernel_theta_from_trig_to<Matrix, double>(output, s_theta, c_theta, s_phi, c_phi);
156  return;
157  }
158  if (param_idx == 1) {
159  r_derivative_kernel_phi_from_trig_to<Matrix, double>(output, s_theta, s_phi, c_phi);
160  return;
161  }
162  output = Matrix();
163 }
164 
165 void R::derivative_kernel_to(const Matrix_real_float& precomputed_sincos, int param_idx, Matrix_float& output) {
166  const int phi_offset = precomputed_sincos.stride;
167  const float s_theta = precomputed_sincos[0];
168  const float c_theta = precomputed_sincos[1];
169  const float s_phi = precomputed_sincos[phi_offset + 0];
170  const float c_phi = precomputed_sincos[phi_offset + 1];
171 
172  if (param_idx == 0) {
173  r_derivative_kernel_theta_from_trig_to<Matrix_float, float>(output, s_theta, c_theta, s_phi, c_phi);
174  return;
175  }
176  if (param_idx == 1) {
177  r_derivative_kernel_phi_from_trig_to<Matrix_float, float>(output, s_theta, s_phi, c_phi);
178  return;
179  }
180  output = Matrix_float();
181 }
std::vector< Gate * > parents
list of parent gates to be applied in the circuit prior to this current gate
Definition: Gate.h:112
Copyright (C) Miklos Maroti, 2021 SPDX-License-Identifier: Apache-2.0.
Definition: U3.h:19
virtual void derivative_kernel_to(const Matrix_real &precomputed_sincos, int param_idx, Matrix &output) override
Definition: R.cpp:147
Class to store single-precision real arrays and properties.
int control_qbit
The index of the qubit which acts as a control qubit (control_qbit >= 0) in controlled operations...
Definition: Gate.h:100
virtual Matrix gate_kernel(const Matrix_real &precomputed_sincos) override
Compute the gate kernel matrix from precomputed trigonometric values.
Definition: R.cpp:27
int stride
The column stride of the array. (The array elements in one row are a_0, a_1, ... a_{cols-1}, 0, 0, 0, 0. The number of zeros is stride-cols)
Definition: matrix_base.hpp:46
void set_children(std::vector< Gate *> &children_)
Call to set the children of the current gate.
Definition: Gate.cpp:2523
int target_qbit
The index of the qubit on which the operation acts (target_qbit >= 0)
Definition: Gate.h:98
virtual void inverse_gate_kernel_to(const Matrix_real &precomputed_sincos, Matrix &output) override
Definition: R.cpp:125
gate_type type
The type of the operation (see enumeration gate_type)
Definition: Gate.h:96
virtual R * clone() override
Call to create a clone of the present class.
Definition: R.cpp:15
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:2500
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:2535
R()
Definition: R.cpp:4
~R() override
Definition: R.cpp:13
Double-precision complex matrix (float64).
Definition: matrix.h:38
std::string name
A string labeling the gate operation.
Definition: Gate.h:92
Single-precision complex matrix (float32).
Definition: matrix_float.h:41
Definition: R.h:11
std::vector< Gate * > children
list of child gates to be applied after this current gate
Definition: Gate.h:114
virtual void gate_kernel_to(const Matrix_real &precomputed_sincos, Matrix &output) override
Definition: R.cpp:103
virtual Matrix derivative_kernel(const Matrix_real &precomputed_sincos, int param_idx) override
Definition: R.cpp:67
int parameter_num
the number of free parameters of the operation
Definition: Gate.h:108
void set_parents(std::vector< Gate *> &parents_)
Call to set the parents of the current gate.
Definition: Gate.cpp:2511
int qbit_num
number of qubits spanning the matrix of the operation
Definition: Gate.h:94
virtual Matrix inverse_gate_kernel(const Matrix_real &precomputed_sincos) override
Definition: R.cpp:47
Class to store data of complex arrays and its properties.
Definition: matrix_real.h:41
virtual std::vector< double > get_parameter_multipliers() const override
Returns the per-parameter multipliers relative to 2π used by extract_parameters. ...
Definition: R.cpp:23