Sequential Quantum Gate Decomposer  v1.9.6
Powerful decomposition of general unitarias into one- and two-qubit gates gates
SYC.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 "SYC.h"
24 
25 #include <cmath>
26 
27 
28 
29 using namespace std;
30 
31 
36 
37  // A string labeling the gate operation
38  name = "SYC";
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  // A string describing the type of the gate
45  type = SYC_OPERATION;
46  // The number of free parameters
47  parameter_num = 0;
48 
49  // The index of the qubit on which the gate acts (target_qbit >= 0)
50  target_qbit = -1;
51 
52  // The index of the qubit which acts as a control qubit (control_qbit >= 0) in controlled gate
53  control_qbit = -1;
54 
55 
56 }
57 
58 
65 SYC::SYC(int qbit_num_in, int target_qbit_in, int control_qbit_in) {
66 
67  // A string labeling the gate operation
68  name = "SYC";
69 
70  // number of qubits spanning the matrix of the gate
71  qbit_num = qbit_num_in;
72  // the size of the matrix
74  // A string describing the type of the gate
75  type = SYC_OPERATION;
76  // The number of free parameters
77  parameter_num = 0;
78 
79  if (target_qbit_in >= qbit_num) {
80  std::stringstream sstream;
81  sstream << "The index of the target qubit is larger than the number of qubits" << std::endl;
82  print(sstream, 0);
83  throw "The index of the target qubit is larger than the number of qubits";
84  }
85 
86  // The index of the qubit on which the gate acts (target_qbit >= 0)
87  target_qbit = target_qbit_in;
88 
89 
90  if (control_qbit_in >= qbit_num) {
91  std::stringstream sstream;
92  sstream << "The index of the control qubit is larger than the number of qubits" << std::endl;
93  print(sstream, 0);
94  throw "The index of the control qubit is larger than the number of qubits";
95  }
96 
97  // The index of the qubit which acts as a control qubit (control_qbit >= 0) in controlled gate
98  control_qbit = control_qbit_in;
99 
100 }
101 
106 }
107 
108 namespace {
109 
110 template<typename MT, typename CT, typename RT>
111 MT build_syc_kernel_impl(bool inverse) {
112  MT m(4, 4);
113  for (int idx = 0; idx < m.size(); ++idx) {
114  m[idx] = CT();
115  }
116 
117  m[0 * m.stride + 0].real = static_cast<RT>(1);
118 
119  const RT i_sign = inverse ? static_cast<RT>(1) : static_cast<RT>(-1);
120  m[1 * m.stride + 2].imag = i_sign;
121  m[2 * m.stride + 1].imag = i_sign;
122 
123  const RT phase_real = static_cast<RT>(std::sqrt(3.0) / 2.0);
124  const RT phase_imag = inverse ? static_cast<RT>(0.5) : static_cast<RT>(-0.5);
125  m[3 * m.stride + 3].real = phase_real;
126  m[3 * m.stride + 3].imag = phase_imag;
127 
128  return m;
129 }
130 
131 } // namespace
132 
133 
134 Matrix
135 SYC::gate_kernel(const Matrix_real& /*precomputed_sincos*/) {
136  return build_syc_kernel_impl<Matrix, QGD_Complex16, double>(false);
137 }
138 
139 
141 SYC::gate_kernel(const Matrix_real_float& /*precomputed_sincos*/) {
142  return build_syc_kernel_impl<Matrix_float, QGD_Complex8, float>(false);
143 }
144 
145 
146 Matrix
147 SYC::inverse_gate_kernel(const Matrix_real& /*precomputed_sincos*/) {
148  return build_syc_kernel_impl<Matrix, QGD_Complex16, double>(true);
149 }
150 
151 
153 SYC::inverse_gate_kernel(const Matrix_real_float& /*precomputed_sincos*/) {
154  return build_syc_kernel_impl<Matrix_float, QGD_Complex8, float>(true);
155 }
156 
157 
158 
164 
165  SYC* ret = new SYC( qbit_num, target_qbit, control_qbit );
166 
167  ret->set_parameter_start_idx( get_parameter_start_idx() );
168  ret->set_parents( parents );
169  ret->set_children( children );
170 
171  return ret;
172 
173 }
174 
parameter_num
[set adaptive gate structure]
Class to store single-precision real arrays and properties.
void set_children(std::vector< Gate *> &children_)
Call to set the children of the current gate.
Definition: Gate.cpp:2523
SYC()
Nullary constructor of the class.
Definition: SYC.cpp:35
Matrix inverse_gate_kernel(const Matrix_real &precomputed_sincos) override
Definition: SYC.cpp:147
matrix_size
[load Umtx]
Definition: example.py:58
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
~SYC()
Destructor of the class.
Definition: SYC.cpp:105
SYC * clone() override
Call to create a clone of the present class.
Definition: SYC.cpp:163
int Power_of_2(int n)
Calculates the n-th power of 2.
Definition: common.cpp:136
Double-precision complex matrix (float64).
Definition: matrix.h:38
Single-precision complex matrix (float32).
Definition: matrix_float.h:41
Matrix gate_kernel(const Matrix_real &precomputed_sincos) override
Return the fixed 4x4 SYC two-qubit kernel.
Definition: SYC.cpp:135
void set_parents(std::vector< Gate *> &parents_)
Call to set the parents of the current gate.
Definition: Gate.cpp:2511
A class representing a SYC operation.
Definition: SYC.h:36
Class to store data of complex arrays and its properties.
Definition: matrix_real.h:41
Header file for a class representing a Sycamore gate.