81 std::stringstream sstream;
82 sstream <<
"The index of the control qubit is larger than the number of qubits in CROT gate." << std::endl;
101 std::stringstream sstream2;
102 sstream2 <<
"ERROR: CROT subtype not implemented" << std::endl;
104 throw sstream2.str();
126 for ( std::vector<Matrix>::iterator it=input.begin(); it != input.end(); it++ ) {
142 if ( parallel == 0 ) {
143 work_batch = inputs.size();
150 tbb::parallel_for( tbb::blocked_range<int>(0,inputs.size(),work_batch), [&](tbb::blocked_range<int> r) {
151 for (
int idx=r.begin(); idx<r.end(); ++idx) {
153 Matrix* input = &inputs[idx];
155 apply_to( parameters_mtx, *input, parallel );
174 std::stringstream sstream;
175 sstream <<
"Wrong matrix size in CROT gate apply" << std::endl;
181 double Theta0Over2, Theta1Over2, Phi0, Phi1;
184 Theta0Over2 = parameters_mtx[0];
185 Phi0 = parameters_mtx[1];
188 Theta0Over2 = parameters_mtx[0];
189 Theta1Over2 = -1.*parameters_mtx[0];
190 Phi0 = parameters_mtx[1];
191 Phi1 = parameters_mtx[1];
194 Theta0Over2 = parameters_mtx[0];
195 Theta1Over2 = parameters_mtx[2];
196 Phi0 = parameters_mtx[1];
197 Phi1 = parameters_mtx[3];
216 memset(U_2qbit.
get_data(),0.0,(U_2qbit.
size()*2)*
sizeof(
double));
217 U_2qbit[0].real = std::cos(Theta0Over2);
218 U_2qbit[2].real = std::sin(Theta0Over2)*std::sin(Phi0);
219 U_2qbit[2].imag = std::sin(Theta0Over2)*std::cos(Phi0);
220 U_2qbit[1*4+3].real = -1.*std::sin(Theta1Over2)*std::sin(Phi1);
221 U_2qbit[1*4+3].imag = -1.*std::sin(Theta1Over2)*std::cos(Phi1);
222 U_2qbit[1*4+1].real = std::cos(Theta1Over2);
223 U_2qbit[2*4+2].real = std::cos(Theta0Over2);
224 U_2qbit[2*4].real = -1.*std::sin(Theta0Over2)*std::sin(Phi0);
225 U_2qbit[2*4].imag = std::sin(Theta0Over2)*std::cos(Phi0);
226 U_2qbit[3*4+3].real = std::cos(Theta1Over2);
227 U_2qbit[3*4+1].real = std::sin(Theta1Over2)*std::sin(Phi1);
228 U_2qbit[3*4+1].imag = -1.*std::sin(Theta1Over2)*std::cos(Phi1);
281 std::stringstream sstream;
282 sstream <<
"Wrong matrix size in CROT gate apply" << std::endl;
287 std::vector<Matrix> ret;
289 double Theta0Over2, Theta1Over2, Phi0, Phi1;
292 Theta0Over2 = parameters_mtx[0];
293 Phi0 = parameters_mtx[1];
296 Theta0Over2 = parameters_mtx[0];
297 Theta1Over2 = -1.*(parameters_mtx[0]);
298 Phi0 = parameters_mtx[1];
299 Phi1 = parameters_mtx[1];
302 Theta0Over2 = parameters_mtx[0];
303 Theta1Over2 = parameters_mtx[2];
304 Phi0 = parameters_mtx[1];
305 Phi1 = parameters_mtx[3];
324 ret.push_back(res_mtx);
328 ret.push_back(res_mtx2);
334 double Theta0Over2_shifted = Theta0Over2 +
M_PIOver2;
335 double Theta1Over2_shifted;
337 Theta1Over2_shifted = -1.*Theta0Over2_shifted;
345 memset(U_2qbit.
get_data(),0.0,(U_2qbit.
size()*2)*
sizeof(
double));
347 U_2qbit[0].real = std::cos(Theta0Over2_shifted);
348 U_2qbit[2].real = std::sin(Theta0Over2_shifted)*std::sin(Phi0);
349 U_2qbit[2].imag = std::sin(Theta0Over2_shifted)*std::cos(Phi0);
351 U_2qbit[2*4+2].real = std::cos(Theta0Over2_shifted);
352 U_2qbit[2*4].real = -1.*std::sin(Theta0Over2_shifted)*std::sin(Phi0);
353 U_2qbit[2*4].imag = std::sin(Theta0Over2_shifted)*std::cos(Phi0);
355 U_2qbit[1*4+3].real = -1.*std::sin(Theta1Over2_shifted)*std::sin(Phi1);
356 U_2qbit[1*4+3].imag = -1.*std::sin(Theta1Over2_shifted)*std::cos(Phi1);
357 U_2qbit[1*4+1].real = std::cos(Theta1Over2_shifted);
359 U_2qbit[3*4+3].real = std::cos(Theta1Over2_shifted);
360 U_2qbit[3*4+1].real = std::sin(Theta1Over2_shifted)*std::sin(Phi1);
361 U_2qbit[3*4+1].imag = -1.*std::sin(Theta1Over2_shifted)*std::cos(Phi1);
367 ret.push_back(res_mtx);
371 memset(U_2qbit.
get_data(),0.0,(U_2qbit.
size()*2)*
sizeof(
double));
373 U_2qbit[2].real = std::sin(Theta0Over2)*std::sin(Phi0_shifted);
374 U_2qbit[2].imag = std::sin(Theta0Over2)*std::cos(Phi0_shifted);
376 U_2qbit[2*4].real = -1.*std::sin(Theta0Over2)*std::sin(Phi0_shifted);
377 U_2qbit[2*4].imag = std::sin(Theta0Over2)*std::cos(Phi0_shifted);
379 U_2qbit[1*4+3].real = -1.*std::sin(Theta1Over2)*std::sin(Phi1_shifted);
380 U_2qbit[1*4+3].imag = -1.*std::sin(Theta1Over2)*std::cos(Phi1_shifted);
382 U_2qbit[3*4+1].real = std::sin(Theta1Over2)*std::sin(Phi1_shifted);
383 U_2qbit[3*4+1].imag = -1.*std::sin(Theta1Over2)*std::cos(Phi1_shifted);
386 ret.push_back(res_mtx1);
390 double Theta0Over2_shifted = Theta0Over2 +
M_PIOver2;
391 double Theta1Over2_shifted = Theta1Over2 +
M_PIOver2;
398 memset(U_2qbit.
get_data(),0.0,(U_2qbit.
size()*2)*
sizeof(
double));
399 U_2qbit[0].real = std::cos(Theta0Over2_shifted);
400 U_2qbit[2].real = std::sin(Theta0Over2_shifted)*std::sin(Phi0);
401 U_2qbit[2].imag = std::sin(Theta0Over2_shifted)*std::cos(Phi0);
403 U_2qbit[2*4+2].real = std::cos(Theta0Over2_shifted);
404 U_2qbit[2*4].real = -1.*std::sin(Theta0Over2_shifted)*std::sin(Phi0);
405 U_2qbit[2*4].imag = std::sin(Theta0Over2_shifted)*std::cos(Phi0);
410 ret.push_back(res_mtx);
414 memset(U_2qbit.
get_data(),0.0,(U_2qbit.
size()*2)*
sizeof(
double));
416 U_2qbit[2].real = std::sin(Theta0Over2)*std::sin(Phi0_shifted);
417 U_2qbit[2].imag = std::sin(Theta0Over2)*std::cos(Phi0_shifted);
419 U_2qbit[2*4].real = -1.*std::sin(Theta0Over2)*std::sin(Phi0_shifted);
420 U_2qbit[2*4].imag = std::sin(Theta0Over2)*std::cos(Phi0_shifted);
423 ret.push_back(res_mtx1);
427 memset(U_2qbit.
get_data(),0.0,(U_2qbit.
size()*2)*
sizeof(
double));
429 U_2qbit[1*4+3].real = -1.*std::sin(Theta1Over2_shifted)*std::sin(Phi1);
430 U_2qbit[1*4+3].imag = -1.*std::sin(Theta1Over2_shifted)*std::cos(Phi1);
431 U_2qbit[1*4+1].real = std::cos(Theta1Over2_shifted);
433 U_2qbit[3*4+3].real = std::cos(Theta1Over2_shifted);
434 U_2qbit[3*4+1].real = std::sin(Theta1Over2_shifted)*std::sin(Phi1);
435 U_2qbit[3*4+1].imag = -1.*std::sin(Theta1Over2_shifted)*std::cos(Phi1);
438 ret.push_back(res_mtx2);
442 memset(U_2qbit.
get_data(),0.0,(U_2qbit.
size()*2)*
sizeof(
double));
444 U_2qbit[1*4+3].real = -1.*std::sin(Theta1Over2)*std::sin(Phi1_shifted);
445 U_2qbit[1*4+3].imag = -1.*std::sin(Theta1Over2)*std::cos(Phi1_shifted);
447 U_2qbit[3*4+1].real = std::sin(Theta1Over2)*std::sin(Phi1_shifted);
448 U_2qbit[3*4+1].imag = -1.*std::sin(Theta1Over2)*std::cos(Phi1_shifted);
451 ret.push_back(res_mtx3);
456 double Theta0Over2_shifted = Theta0Over2 +
M_PIOver2;
457 double Theta1Over2_shifted;
459 Theta1Over2_shifted = -1.*Theta0Over2_shifted;
467 ret.push_back(res_mtx);
475 ret.push_back(res_mtx1);
480 double Theta0Over2_shifted = Theta0Over2 +
M_PIOver2;
486 ret.push_back(res_mtx);
494 ret.push_back(res_mtx1);
497 double Theta1Over2_shifted = Theta1Over2 +
M_PIOver2;
502 ret.push_back(res_mtx2);
510 ret.push_back(res_mtx3);
514 std::stringstream sstream;
515 sstream <<
"Subtype not implemented for gradient" << std::endl;
571 u3_1qbit[0].real = std::cos(ThetaOver2);
572 u3_1qbit[0].imag = 0;
574 u3_1qbit[1].real = -1.*std::sin(ThetaOver2)*std::sin(Phi);
575 u3_1qbit[1].imag = -1.*std::sin(ThetaOver2)*std::cos(Phi);
577 u3_1qbit[2].real = std::sin(ThetaOver2)*std::sin(Phi);
578 u3_1qbit[2].imag = -1.*std::sin(ThetaOver2)*std::cos(Phi);
580 u3_1qbit[3].real = std::cos(ThetaOver2);
581 u3_1qbit[3].imag = 0;
588 u3_1qbit[0].real = 0;
589 u3_1qbit[0].imag = 0;
591 u3_1qbit[1].real = -1.*std::sin(ThetaOver2)*std::sin(Phi);
592 u3_1qbit[1].imag = -1.*std::sin(ThetaOver2)*std::cos(Phi);
594 u3_1qbit[2].real = std::sin(ThetaOver2)*std::sin(Phi);
595 u3_1qbit[2].imag = -1.*std::sin(ThetaOver2)*std::cos(Phi);
597 u3_1qbit[3].real = 0;
598 u3_1qbit[3].imag = 0;
612 std::string err(
"CROT::extract_parameters: Cant extract parameters, since the dinput arary has not enough elements.");
620 return extracted_parameters;
629 return extracted_parameters;
632 return extracted_parameters;
virtual Matrix_real extract_parameters(Matrix_real ¶meters)
Call to extract parameters from the parameter array corresponding to the circuit, in which the gate i...
void print(const std::stringstream &sstream, int verbose_level=1) const
Call to print output messages in the function of the verbosity level.
virtual void apply_from_right(Matrix_real ¶meters, Matrix &input)
Call to apply the gate on the input array/matrix by input*CROT.
int control_qbit
The index of the qubit which acts as a control qubit (control_qbit >= 0) in controlled operations...
virtual void set_qbit_num(int qbit_num_in)
Set the number of qubits spanning the matrix of the operation.
Header file for a class representing a controlled rotation gate around the Y axis.
int target_qbit
The index of the qubit on which the operation acts (target_qbit >= 0)
int matrix_size
The size N of the NxN matrix associated with the operations.
scalar * get_data() const
Call to get the pointer to the stored data.
A class representing a CROT gate.
void apply_to_list(Matrix_real ¶meters_mtx, std::vector< Matrix > &input)
Call to apply the gate on the input array/matrix by U3*input.
virtual void reorder_qubits(std::vector< int > qbit_list)
Call to reorder the qubits in the matrix of the gate.
gate_type type
The type of the operation (see enumeration gate_type)
int rows
The number of rows.
int cols
The number of columns.
Matrix calc_one_qubit_rotation_deriv_Phi(double ThetaOver2, double Phi)
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 ...
Matrix calc_one_qubit_rotation(double ThetaOver2, double Phi)
int get_parameter_start_idx()
Call to get the starting index of the parameters in the parameter array corresponding to the circuit ...
Structure type representing complex numbers in the SQUANDER package.
virtual void apply_to(Matrix_real ¶meters_mtx, Matrix &input, int parallel)
Call to apply the gate on the input array/matrix by CROT3*input.
int Power_of_2(int n)
Calculates the n-th power of 2.
Class to store data of complex arrays and its properties.
int size() const
Call to get the number of the allocated elements.
int get_parameter_num()
Call to get the number of free parameters.
std::string name
A string labeling the gate operation.
void apply_kernel_to(Matrix &u3_1qbit, Matrix &input, bool deriv=false, int parallel=0)
Call to apply the gate kernel on the input state or unitary with optional AVX support.
int parameter_num
the number of free parameters of the operation
virtual void set_qbit_num(int qbit_num_in)
Call to set the number of qubits spanning the matrix of the gate.
virtual CROT * clone()
Call to create a clone of the present class.
CROT()
Nullary constructor of the class.
Matrix copy()
Call to create a copy of the matrix.
virtual ~CROT()
Destructor of the class.
int qbit_num
number of qubits spanning the matrix of the operation
virtual std::vector< Matrix > apply_derivate_to(Matrix_real ¶meters_mtx, Matrix &input, int parallel)
Call to evaluate the derivate of the circuit on an inout with respect to all of the free parameters...
virtual void reorder_qubits(std::vector< int > qbit_list)
Call to reorder the qubits in the matrix of the operation.
Class to store data of complex arrays and its properties.