Sequential Quantum Gate Decomposer  v1.9.6
Powerful decomposition of general unitarias into one- and two-qubit gates gates
RXX.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 "RXX.h"
24 #include "gate_kernel_templates.h"
25 using namespace std;
26 
27 // Build the 4x4 RXX kernel matrix for either float32 or float64 precision.
31 RXX::RXX() : Gate() {
32 
33  // A string labeling the gate operation
34  name = "RXX";
35 
36  // A string describing the type of the gate
38 
39  // Initialize target qubits vector (empty for nullary constructor)
40  target_qbits.clear();
41 
42  parameter_num = 1;
43 }
44 
50 RXX::RXX(int qbit_num_in, const std::vector<int>& target_qbits_in)
51  : Gate(qbit_num_in, target_qbits_in) {
52 
53  // A string labeling the gate operation
54  name = "RXX";
55 
56  // A string describing the type of the gate
58 
59  // Validate that we have exactly 2 target qubits
60  if (target_qbits_in.size() != 2) {
61  std::stringstream sstream;
62  sstream << "RXX gate requires exactly 2 target qubits, got " << target_qbits_in.size() << std::endl;
63  print(sstream, 0);
64  throw sstream.str();
65  }
66 
67  // Check that target qubits are unique
68  if (target_qbits_in[0] == target_qbits_in[1]) {
69  std::stringstream sstream;
70  sstream << "The two target qubits cannot be the same" << std::endl;
71  print(sstream, 0);
72  throw sstream.str();
73  }
74 
75  parameter_num = 1;
76 }
77 
82 
83 }
84 
95 Matrix RXX::gate_kernel(const Matrix_real& precomputed_sincos) {
96  Matrix ret;
97  gate_kernel_to(precomputed_sincos, ret);
98  return ret;
99 }
100 
101 Matrix_float RXX::gate_kernel(const Matrix_real_float& precomputed_sincos) {
102  Matrix_float ret;
103  gate_kernel_to(precomputed_sincos, ret);
104  return ret;
105 }
106 
107 Matrix RXX::inverse_gate_kernel(const Matrix_real& precomputed_sincos) {
108  Matrix ret;
109  inverse_gate_kernel_to(precomputed_sincos, ret);
110  return ret;
111 }
112 
114  Matrix_float ret;
115  inverse_gate_kernel_to(precomputed_sincos, ret);
116  return ret;
117 }
118 
119 Matrix RXX::derivative_kernel(const Matrix_real& precomputed_sincos, int param_idx) {
120  Matrix ret;
121  derivative_kernel_to(precomputed_sincos, param_idx, ret);
122  return ret;
123 }
124 
125 Matrix_float RXX::derivative_kernel(const Matrix_real_float& precomputed_sincos, int param_idx) {
126  Matrix_float ret;
127  derivative_kernel_to(precomputed_sincos, param_idx, ret);
128  return ret;
129 }
130 
131 void RXX::gate_kernel_to(const Matrix_real& precomputed_sincos, Matrix& output) {
132  const int theta_offset = 0 * precomputed_sincos.stride;
133  const double s_theta = precomputed_sincos[theta_offset + 0];
134  const double c_theta = precomputed_sincos[theta_offset + 1];
135  build_rxx_kernel_from_trig_to<Matrix, double>(output, s_theta, c_theta);
136 }
137 
138 void RXX::gate_kernel_to(const Matrix_real_float& precomputed_sincos, Matrix_float& output) {
139  const int theta_offset = 0 * precomputed_sincos.stride;
140  const float s_theta = precomputed_sincos[theta_offset + 0];
141  const float c_theta = precomputed_sincos[theta_offset + 1];
142  build_rxx_kernel_from_trig_to<Matrix_float, float>(output, s_theta, c_theta);
143 }
144 
145 void RXX::inverse_gate_kernel_to(const Matrix_real& precomputed_sincos, Matrix& output) {
146  const int theta_offset = 0 * precomputed_sincos.stride;
147  const double s_theta = precomputed_sincos[theta_offset + 0];
148  const double c_theta = precomputed_sincos[theta_offset + 1];
149  build_rxx_kernel_from_trig_to<Matrix, double>(output, -s_theta, c_theta);
150 }
151 
153  const int theta_offset = 0 * precomputed_sincos.stride;
154  const float s_theta = precomputed_sincos[theta_offset + 0];
155  const float c_theta = precomputed_sincos[theta_offset + 1];
156  build_rxx_kernel_from_trig_to<Matrix_float, float>(output, -s_theta, c_theta);
157 }
158 
159 void RXX::derivative_kernel_to(const Matrix_real& precomputed_sincos, int param_idx, Matrix& output) {
160  if (param_idx != 0) {
161  output = Matrix();
162  return;
163  }
164  const int theta_offset = 0 * precomputed_sincos.stride;
165  const double s_theta = precomputed_sincos[theta_offset + 0];
166  const double c_theta = precomputed_sincos[theta_offset + 1];
167  build_rxx_derivative_kernel_from_trig_to<Matrix, double>(output, s_theta, c_theta);
168 }
169 
170 void RXX::derivative_kernel_to(const Matrix_real_float& precomputed_sincos, int param_idx, Matrix_float& output) {
171  if (param_idx != 0) {
172  output = Matrix_float();
173  return;
174  }
175  const int theta_offset = 0 * precomputed_sincos.stride;
176  const float s_theta = precomputed_sincos[theta_offset + 0];
177  const float c_theta = precomputed_sincos[theta_offset + 1];
178  build_rxx_derivative_kernel_from_trig_to<Matrix_float, float>(output, s_theta, c_theta);
179 }
180 
186 
187  RXX* ret = new RXX(qbit_num, target_qbits);
188 
190  ret->set_parents(parents);
191  ret->set_children(children);
192 
193  return ret;
194 }
195 
196 std::vector<double>
198  return {2.0};
199 }
std::vector< Gate * > parents
list of parent gates to be applied in the circuit prior to this current gate
Definition: Gate.h:112
Gate()
Default constructor of the class.
Definition: Gate.cpp:121
A class representing a RXX gate.
Definition: RXX.h:34
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
Class to store single-precision real arrays and properties.
std::vector< int > target_qbits
Vector of target qubit indices (for multi-qubit gates)
Definition: Gate.h:102
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
Matrix inverse_gate_kernel(const Matrix_real &precomputed_sincos) override
Definition: RXX.cpp:107
~RXX()
Destructor of the class.
Definition: RXX.cpp:81
RXX * clone() override
Call to create a clone of the present class.
Definition: RXX.cpp:185
gate_type type
The type of the operation (see enumeration gate_type)
Definition: Gate.h:96
RXX()
Nullary constructor of the class.
Definition: RXX.cpp:31
void inverse_gate_kernel_to(const Matrix_real &precomputed_sincos, Matrix &output) override
Definition: RXX.cpp:145
Matrix gate_kernel(const Matrix_real &precomputed_sincos) override
Build and return the 4x4 RXX unitary for the given parameter.
Definition: RXX.cpp:95
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
void derivative_kernel_to(const Matrix_real &precomputed_sincos, int param_idx, Matrix &output) override
Definition: RXX.cpp:159
Double-precision complex matrix (float64).
Definition: matrix.h:38
std::vector< double > get_parameter_multipliers() const override
Call to extract parameters from the parameter array corresponding to the circuit, in which the gate i...
Definition: RXX.cpp:197
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
Matrix derivative_kernel(const Matrix_real &precomputed_sincos, int param_idx) override
Definition: RXX.cpp:119
void gate_kernel_to(const Matrix_real &precomputed_sincos, Matrix &output) override
Definition: RXX.cpp:131
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
Class to store data of complex arrays and its properties.
Definition: matrix_real.h:41