Sequential Quantum Gate Decomposer  v1.9.6
Powerful decomposition of general unitarias into one- and two-qubit gates gates
U2.cpp
Go to the documentation of this file.
2 #include "U2.h"
3 
4 static const double M_PIOver4 = M_PI / 4.0;
5 
6 U2::U2() : U2(-1, -1) {}
7 
8 U2::U2(int qbit_num_in, int target_qbit_in) : U3(qbit_num_in, target_qbit_in) {
9  name = "U2";
11  parameter_num = 2;
12  control_qbit = -1;
13 }
14 
15 U2::~U2() {}
16 
18  U2* ret = new U2(qbit_num, target_qbit);
20  ret->set_parents(parents);
21  ret->set_children(children);
22  return ret;
23 }
24 
25 std::vector<double> U2::get_parameter_multipliers() const {
26  return {1.0, 1.0};
27 }
28 
29 Matrix U2::gate_kernel(const Matrix_real& precomputed_sincos) {
30  const int phi_offset = 0 * precomputed_sincos.stride;
31  const int lambda_offset = 1 * precomputed_sincos.stride;
32  const double s_phi = precomputed_sincos[phi_offset + 0];
33  const double c_phi = precomputed_sincos[phi_offset + 1];
34  const double s_lambda = precomputed_sincos[lambda_offset + 0];
35  const double c_lambda = precomputed_sincos[lambda_offset + 1];
36  return u2_gate_kernel_from_trig<Matrix, double>(s_phi, c_phi, s_lambda, c_lambda);
37 }
38 
39 Matrix_float U2::gate_kernel(const Matrix_real_float& precomputed_sincos) {
40  const int phi_offset = 0 * precomputed_sincos.stride;
41  const int lambda_offset = 1 * precomputed_sincos.stride;
42  const float s_phi = precomputed_sincos[phi_offset + 0];
43  const float c_phi = precomputed_sincos[phi_offset + 1];
44  const float s_lambda = precomputed_sincos[lambda_offset + 0];
45  const float c_lambda = precomputed_sincos[lambda_offset + 1];
46  return u2_gate_kernel_from_trig<Matrix_float, float>(s_phi, c_phi, s_lambda, c_lambda);
47 }
48 
49 Matrix U2::inverse_gate_kernel(const Matrix_real& precomputed_sincos) {
50  const int phi_offset = 0 * precomputed_sincos.stride;
51  const int lambda_offset = 1 * precomputed_sincos.stride;
52  const double s_phi = precomputed_sincos[phi_offset + 0];
53  const double c_phi = precomputed_sincos[phi_offset + 1];
54  const double s_lambda = precomputed_sincos[lambda_offset + 0];
55  const double c_lambda = precomputed_sincos[lambda_offset + 1];
56  return u2_inverse_gate_kernel_from_trig<Matrix, double>(s_phi, c_phi, s_lambda, c_lambda);
57 }
58 
60  const int phi_offset = 0 * precomputed_sincos.stride;
61  const int lambda_offset = 1 * precomputed_sincos.stride;
62  const float s_phi = precomputed_sincos[phi_offset + 0];
63  const float c_phi = precomputed_sincos[phi_offset + 1];
64  const float s_lambda = precomputed_sincos[lambda_offset + 0];
65  const float c_lambda = precomputed_sincos[lambda_offset + 1];
66  return u2_inverse_gate_kernel_from_trig<Matrix_float, float>(s_phi, c_phi, s_lambda, c_lambda);
67 }
68 
69 Matrix U2::derivative_kernel(const Matrix_real& precomputed_sincos, int param_idx) {
70  const int phi_offset = 0 * precomputed_sincos.stride;
71  const int lambda_offset = 1 * precomputed_sincos.stride;
72  const double s_phi = precomputed_sincos[phi_offset + 0];
73  const double c_phi = precomputed_sincos[phi_offset + 1];
74  const double s_lambda = precomputed_sincos[lambda_offset + 0];
75  const double c_lambda = precomputed_sincos[lambda_offset + 1];
76 
77  if (param_idx == 0) {
78  return u2_derivative_kernel_phi_from_trig<Matrix, double>(s_phi, c_phi, s_lambda, c_lambda);
79  }
80  if (param_idx == 1) {
81  return u2_derivative_kernel_lambda_from_trig<Matrix, double>(s_phi, c_phi, s_lambda, c_lambda);
82  }
83 
84  return Matrix();
85 }
86 
87 Matrix_float U2::derivative_kernel(const Matrix_real_float& precomputed_sincos, int param_idx) {
88  const int phi_offset = 0 * precomputed_sincos.stride;
89  const int lambda_offset = 1 * precomputed_sincos.stride;
90  const float s_phi = precomputed_sincos[phi_offset + 0];
91  const float c_phi = precomputed_sincos[phi_offset + 1];
92  const float s_lambda = precomputed_sincos[lambda_offset + 0];
93  const float c_lambda = precomputed_sincos[lambda_offset + 1];
94 
95  if (param_idx == 0) {
96  return u2_derivative_kernel_phi_from_trig<Matrix_float, float>(s_phi, c_phi, s_lambda, c_lambda);
97  }
98  if (param_idx == 1) {
99  return u2_derivative_kernel_lambda_from_trig<Matrix_float, float>(s_phi, c_phi, s_lambda, c_lambda);
100  }
101 
102  return Matrix_float();
103 }
104 
105 void U2::gate_kernel_to(const Matrix_real& precomputed_sincos, Matrix& output) {
106  const int lambda_offset = precomputed_sincos.stride;
107  u2_gate_kernel_from_trig_to<Matrix, double>(
108  output,
109  precomputed_sincos[0],
110  precomputed_sincos[1],
111  precomputed_sincos[lambda_offset + 0],
112  precomputed_sincos[lambda_offset + 1]
113  );
114 }
115 
116 void U2::gate_kernel_to(const Matrix_real_float& precomputed_sincos, Matrix_float& output) {
117  const int lambda_offset = precomputed_sincos.stride;
118  u2_gate_kernel_from_trig_to<Matrix_float, float>(
119  output,
120  precomputed_sincos[0],
121  precomputed_sincos[1],
122  precomputed_sincos[lambda_offset + 0],
123  precomputed_sincos[lambda_offset + 1]
124  );
125 }
126 
127 void U2::inverse_gate_kernel_to(const Matrix_real& precomputed_sincos, Matrix& output) {
128  const int lambda_offset = precomputed_sincos.stride;
129  u2_inverse_gate_kernel_from_trig_to<Matrix, double>(
130  output,
131  precomputed_sincos[0],
132  precomputed_sincos[1],
133  precomputed_sincos[lambda_offset + 0],
134  precomputed_sincos[lambda_offset + 1]
135  );
136 }
137 
139  const int lambda_offset = precomputed_sincos.stride;
140  u2_inverse_gate_kernel_from_trig_to<Matrix_float, float>(
141  output,
142  precomputed_sincos[0],
143  precomputed_sincos[1],
144  precomputed_sincos[lambda_offset + 0],
145  precomputed_sincos[lambda_offset + 1]
146  );
147 }
148 
149 void U2::derivative_kernel_to(const Matrix_real& precomputed_sincos, int param_idx, Matrix& output) {
150  const int lambda_offset = precomputed_sincos.stride;
151  const double s_phi = precomputed_sincos[0];
152  const double c_phi = precomputed_sincos[1];
153  const double s_lambda = precomputed_sincos[lambda_offset + 0];
154  const double c_lambda = precomputed_sincos[lambda_offset + 1];
155 
156  if (param_idx == 0) {
157  u2_derivative_kernel_phi_from_trig_to<Matrix, double>(output, s_phi, c_phi, s_lambda, c_lambda);
158  return;
159  }
160  if (param_idx == 1) {
161  u2_derivative_kernel_lambda_from_trig_to<Matrix, double>(output, s_phi, c_phi, s_lambda, c_lambda);
162  return;
163  }
164  output = Matrix();
165 }
166 
167 void U2::derivative_kernel_to(const Matrix_real_float& precomputed_sincos, int param_idx, Matrix_float& output) {
168  const int lambda_offset = precomputed_sincos.stride;
169  const float s_phi = precomputed_sincos[0];
170  const float c_phi = precomputed_sincos[1];
171  const float s_lambda = precomputed_sincos[lambda_offset + 0];
172  const float c_lambda = precomputed_sincos[lambda_offset + 1];
173 
174  if (param_idx == 0) {
175  u2_derivative_kernel_phi_from_trig_to<Matrix_float, float>(output, s_phi, c_phi, s_lambda, c_lambda);
176  return;
177  }
178  if (param_idx == 1) {
179  u2_derivative_kernel_lambda_from_trig_to<Matrix_float, float>(output, s_phi, c_phi, s_lambda, c_lambda);
180  return;
181  }
182  output = Matrix_float();
183 }
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
Class to store single-precision real arrays and properties.
virtual U2 * clone() override
Call to create a clone of the present class.
Definition: U2.cpp:17
Definition: U2.h:11
U2()
Definition: U2.cpp:6
int control_qbit
The index of the qubit which acts as a control qubit (control_qbit >= 0) in controlled operations...
Definition: Gate.h:100
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
~U2() override
Definition: U2.cpp:15
virtual void gate_kernel_to(const Matrix_real &precomputed_sincos, Matrix &output) override
Definition: U2.cpp:105
gate_type type
The type of the operation (see enumeration gate_type)
Definition: Gate.h:96
static const double M_PIOver4
Definition: U2.cpp:4
virtual Matrix inverse_gate_kernel(const Matrix_real &precomputed_sincos) override
Definition: U2.cpp:49
virtual void inverse_gate_kernel_to(const Matrix_real &precomputed_sincos, Matrix &output) override
Definition: U2.cpp:127
#define M_PI
Definition: qgd_math.h:42
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
virtual void derivative_kernel_to(const Matrix_real &precomputed_sincos, int param_idx, Matrix &output) override
Definition: U2.cpp:149
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
std::vector< Gate * > children
list of child gates to be applied after this current gate
Definition: Gate.h:114
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 gate_kernel(const Matrix_real &precomputed_sincos) override
Compute the gate kernel matrix from precomputed trigonometric values.
Definition: U2.cpp:29
virtual std::vector< double > get_parameter_multipliers() const override
Returns the per-parameter multipliers relative to 2π used by extract_parameters. ...
Definition: U2.cpp:25
Class to store data of complex arrays and its properties.
Definition: matrix_real.h:41
virtual Matrix derivative_kernel(const Matrix_real &precomputed_sincos, int param_idx) override
Definition: U2.cpp:69