Sequential Quantum Gate Decomposer  v1.9.6
Powerful decomposition of general unitarias into one- and two-qubit gates gates
U3.cpp
Go to the documentation of this file.
1 
6 #include "U3.h"
7 
8 namespace {
9 
10 template <typename RealMatrixT, typename RealT>
11 void read_u3_trig(const RealMatrixT& precomputed_sincos, RealT& sin_theta, RealT& cos_theta, RealT& sin_phi, RealT& cos_phi, RealT& sin_lambda, RealT& cos_lambda) {
12  const int theta_offset = 0 * precomputed_sincos.stride;
13  const int phi_offset = 1 * precomputed_sincos.stride;
14  const int lambda_offset = 2 * precomputed_sincos.stride;
15  sin_theta = precomputed_sincos[theta_offset + 0];
16  cos_theta = precomputed_sincos[theta_offset + 1];
17  sin_phi = precomputed_sincos[phi_offset + 0];
18  cos_phi = precomputed_sincos[phi_offset + 1];
19  sin_lambda = precomputed_sincos[lambda_offset + 0];
20  cos_lambda = precomputed_sincos[lambda_offset + 1];
21 }
22 
23 }
24 
25 U3::U3() : U3(-1, -1) {}
26 
27 U3::U3(int qbit_num_in, int target_qbit_in) : Gate(qbit_num_in) {
28  name = "U3";
30  target_qbit = target_qbit_in;
31  control_qbit = -1;
32  parameter_num = 3;
33  if (qbit_num > 0 && target_qbit >= qbit_num) {
34  std::string err("U3: target qubit index out of range.");
35  throw err;
36  }
37 }
38 
39 U3::~U3() {}
40 
42  U3* ret = new U3(qbit_num, target_qbit);
44  ret->set_parents(parents);
45  ret->set_children(children);
46  return ret;
47 }
48 
49 std::vector<double> U3::get_parameter_multipliers() const {
50  return {2.0, 1.0, 1.0};
51 }
52 
53 Matrix U3::gate_kernel(const Matrix_real& precomputed_sincos) {
54  Matrix ret;
55  gate_kernel_to(precomputed_sincos, ret);
56  return ret;
57 }
58 
59 Matrix_float U3::gate_kernel(const Matrix_real_float& precomputed_sincos) {
60  Matrix_float ret;
61  gate_kernel_to(precomputed_sincos, ret);
62  return ret;
63 }
64 
65 Matrix U3::inverse_gate_kernel(const Matrix_real& precomputed_sincos) {
66  Matrix ret;
67  inverse_gate_kernel_to(precomputed_sincos, ret);
68  return ret;
69 }
70 
72  Matrix_float ret;
73  inverse_gate_kernel_to(precomputed_sincos, ret);
74  return ret;
75 }
76 
77 Matrix U3::derivative_kernel(const Matrix_real& precomputed_sincos, int param_idx) {
78  Matrix ret;
79  derivative_kernel_to(precomputed_sincos, param_idx, ret);
80  return ret;
81 }
82 
83 Matrix_float U3::derivative_kernel(const Matrix_real_float& precomputed_sincos, int param_idx) {
84  Matrix_float ret;
85  derivative_kernel_to(precomputed_sincos, param_idx, ret);
86  return ret;
87 }
88 
89 void U3::gate_kernel_to(const Matrix_real& precomputed_sincos, Matrix& output) {
90  double sin_theta, cos_theta, sin_phi, cos_phi, sin_lambda, cos_lambda;
91  read_u3_trig<Matrix_real, double>(precomputed_sincos, sin_theta, cos_theta, sin_phi, cos_phi, sin_lambda, cos_lambda);
92  calc_one_qubit_u3_from_trig_to<Matrix, double>(output, sin_theta, cos_theta, sin_phi, cos_phi, sin_lambda, cos_lambda);
93 }
94 
95 void U3::gate_kernel_to(const Matrix_real_float& precomputed_sincos, Matrix_float& output) {
96  float sin_theta, cos_theta, sin_phi, cos_phi, sin_lambda, cos_lambda;
97  read_u3_trig<Matrix_real_float, float>(precomputed_sincos, sin_theta, cos_theta, sin_phi, cos_phi, sin_lambda, cos_lambda);
98  calc_one_qubit_u3_from_trig_to<Matrix_float, float>(output, sin_theta, cos_theta, sin_phi, cos_phi, sin_lambda, cos_lambda);
99 }
100 
101 void U3::inverse_gate_kernel_to(const Matrix_real& precomputed_sincos, Matrix& output) {
102  double sin_theta, cos_theta, sin_phi, cos_phi, sin_lambda, cos_lambda;
103  read_u3_trig<Matrix_real, double>(precomputed_sincos, sin_theta, cos_theta, sin_phi, cos_phi, sin_lambda, cos_lambda);
104  calc_one_qubit_u3_inverse_from_trig_to<Matrix, double>(output, sin_theta, cos_theta, sin_phi, cos_phi, sin_lambda, cos_lambda);
105 }
106 
108  float sin_theta, cos_theta, sin_phi, cos_phi, sin_lambda, cos_lambda;
109  read_u3_trig<Matrix_real_float, float>(precomputed_sincos, sin_theta, cos_theta, sin_phi, cos_phi, sin_lambda, cos_lambda);
110  calc_one_qubit_u3_inverse_from_trig_to<Matrix_float, float>(output, sin_theta, cos_theta, sin_phi, cos_phi, sin_lambda, cos_lambda);
111 }
112 
113 void U3::derivative_kernel_to(const Matrix_real& precomputed_sincos, int param_idx, Matrix& output) {
114  double sin_theta, cos_theta, sin_phi, cos_phi, sin_lambda, cos_lambda;
115  read_u3_trig<Matrix_real, double>(precomputed_sincos, sin_theta, cos_theta, sin_phi, cos_phi, sin_lambda, cos_lambda);
116  if (param_idx == 0) {
117  u3_derivative_kernel_theta_from_trig_to<Matrix, double>(output, sin_theta, cos_theta, sin_phi, cos_phi, sin_lambda, cos_lambda);
118  return;
119  }
120  if (param_idx == 1) {
121  u3_derivative_kernel_phi_from_trig_to<Matrix, double>(output, sin_theta, cos_theta, sin_phi, cos_phi, sin_lambda, cos_lambda);
122  return;
123  }
124  if (param_idx == 2) {
125  u3_derivative_kernel_lambda_from_trig_to<Matrix, double>(output, sin_theta, cos_theta, sin_phi, cos_phi, sin_lambda, cos_lambda);
126  return;
127  }
128  output = Matrix();
129 }
130 
131 void U3::derivative_kernel_to(const Matrix_real_float& precomputed_sincos, int param_idx, Matrix_float& output) {
132  float sin_theta, cos_theta, sin_phi, cos_phi, sin_lambda, cos_lambda;
133  read_u3_trig<Matrix_real_float, float>(precomputed_sincos, sin_theta, cos_theta, sin_phi, cos_phi, sin_lambda, cos_lambda);
134  if (param_idx == 0) {
135  u3_derivative_kernel_theta_from_trig_to<Matrix_float, float>(output, sin_theta, cos_theta, sin_phi, cos_phi, sin_lambda, cos_lambda);
136  return;
137  }
138  if (param_idx == 1) {
139  u3_derivative_kernel_phi_from_trig_to<Matrix_float, float>(output, sin_theta, cos_theta, sin_phi, cos_phi, sin_lambda, cos_lambda);
140  return;
141  }
142  if (param_idx == 2) {
143  u3_derivative_kernel_lambda_from_trig_to<Matrix_float, float>(output, sin_theta, cos_theta, sin_phi, cos_phi, sin_lambda, cos_lambda);
144  return;
145  }
146  output = Matrix_float();
147 }
148 
149 Matrix u3_matrix_kernel(double ThetaOver2, double Phi, double Lambda) {
150  double sin_theta, cos_theta;
151  double sin_phi, cos_phi;
152  double sin_lambda, cos_lambda;
153  qgd_sincos<double>(ThetaOver2, &sin_theta, &cos_theta);
154  qgd_sincos<double>(Phi, &sin_phi, &cos_phi);
155  qgd_sincos<double>(Lambda, &sin_lambda, &cos_lambda);
156  return calc_one_qubit_u3_from_trig<Matrix, double>(sin_theta, cos_theta, sin_phi, cos_phi, sin_lambda, cos_lambda);
157 }
158 
159 Matrix_float u3_matrix_kernel_f(float ThetaOver2, float Phi, float Lambda) {
160  float sin_theta, cos_theta;
161  float sin_phi, cos_phi;
162  float sin_lambda, cos_lambda;
163  qgd_sincos<float>(ThetaOver2, &sin_theta, &cos_theta);
164  qgd_sincos<float>(Phi, &sin_phi, &cos_phi);
165  qgd_sincos<float>(Lambda, &sin_lambda, &cos_lambda);
166  return calc_one_qubit_u3_from_trig<Matrix_float, float>(sin_theta, cos_theta, sin_phi, cos_phi, sin_lambda, cos_lambda);
167 }
void qgd_sincos< float >(float x, float *s, float *c)
Definition: qgd_math.h:106
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.
void qgd_sincos< double >(double x, double *s, double *c)
Definition: qgd_math.h:118
virtual void gate_kernel_to(const Matrix_real &precomputed_sincos, Matrix &output) override
Definition: U3.cpp:89
int control_qbit
The index of the qubit which acts as a control qubit (control_qbit >= 0) in controlled operations...
Definition: Gate.h:100
void set_children(std::vector< Gate *> &children_)
Call to set the children of the current gate.
Definition: Gate.cpp:2523
U3()
Definition: U3.cpp:25
int target_qbit
The index of the qubit on which the operation acts (target_qbit >= 0)
Definition: Gate.h:98
virtual Matrix gate_kernel(const Matrix_real &precomputed_sincos) override
Compute the gate kernel matrix from precomputed trigonometric values.
Definition: U3.cpp:53
~U3() override
Definition: U3.cpp:39
virtual std::vector< double > get_parameter_multipliers() const override
Returns the per-parameter multipliers relative to 2π used by extract_parameters. ...
Definition: U3.cpp:49
gate_type type
The type of the operation (see enumeration gate_type)
Definition: Gate.h:96
virtual void derivative_kernel_to(const Matrix_real &precomputed_sincos, int param_idx, Matrix &output) override
Definition: U3.cpp:113
virtual Matrix inverse_gate_kernel(const Matrix_real &precomputed_sincos) override
Definition: U3.cpp:65
virtual void inverse_gate_kernel_to(const Matrix_real &precomputed_sincos, Matrix &output) override
Definition: U3.cpp:101
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
Double-precision complex matrix (float64).
Definition: matrix.h:38
virtual Matrix derivative_kernel(const Matrix_real &precomputed_sincos, int param_idx) override
Definition: U3.cpp:77
Matrix_float u3_matrix_kernel_f(float ThetaOver2, float Phi, float Lambda)
Definition: U3.cpp:159
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
Base class for the representation of general gate operations.
Definition: Gate.h:86
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
Matrix u3_matrix_kernel(double ThetaOver2, double Phi, double Lambda)
Definition: U3.cpp:149
int qbit_num
number of qubits spanning the matrix of the operation
Definition: Gate.h:94
virtual U3 * clone() override
Call to create a clone of the present class.
Definition: U3.cpp:41
Class to store data of complex arrays and its properties.
Definition: matrix_real.h:41