37 gen = std::mt19937(
rd());
59 gen = std::mt19937(
rd());
86 memset( parameters.
get_data(), 0.0, parameters.
size()*
sizeof(double) );
91 int num_of_adaptive_layers = qbit_num*(qbit_num-1)/2 * levels;
93 if ( nontrivial_adaptive_layers.
size() != num_of_adaptive_layers ) {
104 std::uniform_int_distribution<int16_t> distrib(0, 1);
105 std::uniform_real_distribution<> distrib_real(0.0, 2*M_PI);
106 std::uniform_real_distribution<> distrib_real2(0.0, M_PI);
111 for(
int idx = 0; idx < 3*
qbit_num; idx++) {
112 if ( idx % 3 == 0 ) {
113 parameters[idx] = distrib_real2(
gen);
116 parameters[idx] = distrib_real(
gen);
121 for(
int layer_idx=0; layer_idx<num_of_adaptive_layers; layer_idx++) {
123 int8_t nontrivial_adaptive_layer = distrib(
gen);
124 nontrivial_adaptive_layers[layer_idx] = nontrivial_adaptive_layer;
126 if (nontrivial_adaptive_layer) {
129 int start_idx = qbit_num*3 + layer_idx*7;
131 int end_idx = start_idx + 7;
134 for(
int jdx = start_idx; jdx < end_idx; jdx++) {
135 if ( (jdx-start_idx) % 3 == 0 ) {
136 parameters[jdx] = distrib_real2(
gen);
139 parameters[jdx] = distrib_real(
gen);
184 double phi1 = std::atan2( Y0, X0 );
185 phi1 = phi1 < 0 ? 2*M_PI + phi1 : phi1;
186 double phi2 = std::atan2( Y1, X1 ) + M_PI;
187 phi2 = phi2 < 0 ? 2*M_PI + phi2 : phi2;
191 if ( std::abs(X0) > 1e-8 ) {
192 theta1 = std::atan2( X0/cos(phi1), Z0 )/2 ;
195 theta1 = std::atan2( Y0/sin(phi1), Z0 )/2;
200 if ( std::abs(X1) > 1e-8 ) {
201 theta2 = (M_PI + atan2( X1/cos(phi2), Z1 ))/2;
204 theta2 = (M_PI + atan2( Y1/sin(phi2), Z1 ))/2;
226 std::string err(
"The unitary must be a square matrix.");
230 if ( Umtx.
rows <= 0 ) {
231 std::string err(
"The unitary must be larger than 0x0.");
240 if ( chanels.
size() != dim_over_2*dim_over_2*4 ) {
259 row_idx = row_idx << (target_qbit+1);
264 row_idx = row_idx + tmp;
266 int row_idx_pair = row_idx ^ index_pair_distance;
269 int stride_kernel = index_pair_distance * Umtx.
stride;
274 col_idx = col_idx << (target_qbit+1);
279 col_idx = col_idx + tmp;
281 int col_idx_pair = col_idx ^ index_pair_distance;
287 Matrix_real chanels_kernel( chanels_reshaped.get_data() + idx*chanels_reshaped.stride + 4*jdx, 1, 4, chanels_reshaped.stride);
310 std::string err(
"The unitary must be a square matrix.");
314 if ( Umtx.
rows <= 0 ) {
315 std::string err(
"The unitary must be larger than 0x0.");
324 if ( chanels.
size() != dim_over_2*dim_over_2*4*
qbit_num ) {
325 chanels =
Matrix_real( dim_over_2, dim_over_2*4*qbit_num );
349 row_idx = row_idx << (target_qbit+1);
351 int tmp_idx = (idx & ( (1 << (
target_qbit)) - 1 ) );
354 row_idx = row_idx + tmp_idx;
356 int row_idx_pair = row_idx ^ index_pair_distance;
359 int stride_kernel = index_pair_distance * Umtx.
stride;
365 col_idx = col_idx << (target_qbit+1);
367 int tmp_jdx = (jdx & ( (1 << (
target_qbit)) - 1 ) );
370 col_idx = col_idx + tmp_jdx;
372 int col_idx_pair = col_idx ^ index_pair_distance;
378 Matrix_real chanels_kernel( chanels_reshaped.get_data() + idx*chanels_reshaped.stride + 4*qbit_num*jdx + 4*
target_qbit, 1, 4, chanels_reshaped.stride);
412 std::map<std::string, Config_Element> config_int;
419 for(
int idx=0; idx<
levels; idx++) {
467 #if BLAS==0 // undefined BLAS 472 MKL_Set_Num_Threads(1);
473 #elif BLAS==2 //OpenBLAS 475 openblas_set_num_threads(1);
480 if ( samples_num == 1 ) {
481 get_nn_chanels(qbit_num, levels, chanels, nontrivial_adaptive_layers);
485 if ( samples_num < 1 ) {
486 std::string err(
"Number of samples must be greater than 0.");
495 get_nn_chanels(qbit_num, levels, chanels_1, nontrivial_adaptive_layers_1);
501 memset( chanels.
get_data(), 0.0, chanels.
size()*
sizeof(double) );
502 memset( nontrivial_adaptive_layers.
get_data(), 0, nontrivial_adaptive_layers.
size()*
sizeof(int8_t) );
507 memcpy( nontrivial_adaptive_layers.
get_data(), nontrivial_adaptive_layers_1.
get_data(), nontrivial_adaptive_layers_1.
size()*
sizeof(int8_t) );
511 tbb::parallel_for( tbb::blocked_range<int>(1,samples_num), [&](tbb::blocked_range<int> r) {
513 for (
int idx=r.begin(); idx<r.end(); idx++) {
520 matrix_base<int8_t> nontrivial_adaptive_layers_idx( nontrivial_adaptive_layers.
get_data()+idx*nontrivial_adaptive_layers_1.
size(), 1, nontrivial_adaptive_layers_1.
size() );
522 get_nn_chanels(qbit_num, levels, chanels_idx, nontrivial_adaptive_layers_idx);
544 #if BLAS==0 // undefined BLAS 548 #elif BLAS==2 //OpenBLAS NN()
Nullary constructor of the class.
std::mt19937 gen
Standard mersenne_twister_engine seeded with rd()
void add_adaptive_layers()
Call to add adaptive layers to the gate structure stored by the class.
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)
void add_finalyzing_layer()
Call to add finalyzing layer (single qubit rotations on all of the qubits) to the gate structure stor...
cDecompose
[create decomposition class] creating a class to decompose the unitary
int levels
[creating decomp class]
int num_threads
Store the number of OpenMP threads. (During the calculations OpenMP multithreading is turned off...
std::vector< matrix_base< int > > topology
connectivity between the wubits
Matrix get_matrix(Matrix_real ¶meters)
Call to retrieve the gate matrix (Which is the product of all the gate matrices stored in the gate bl...
void get_nn_chanels_from_kernel(Matrix &kernel_up, Matrix &kernel_down, Matrix_real &chanels)
call retrieve the channels for the neural network associated with a single 2x2 kernel ...
scalar * get_data() const
Call to get the pointer to the stored data.
void create_randomized_parameters(int num_of_parameters, int qbit_num, int levels, Matrix_real ¶meters, matrix_base< int8_t > &nontrivial_adaptive_layers)
Call to construct random parameter, with limited number of non-trivial adaptive layers.
int get_parameter_num()
Call to get the number of free parameters.
int rows
The number of rows.
int cols
The number of columns.
Umtx
The unitary to be decomposed.
Structure type representing complex numbers in the SQUANDER package.
A base class to determine the decomposition of an N-qubit unitary into a sequence of CNOT and U3 gate...
Class to store data of complex arrays and its properties.
int size() const
Call to get the number of the allocated elements.
void omp_set_num_threads(int num_threads)
Set the number of threads on runtime in MKL.
double real
the real part of a complex number
Header file for a class implementing the adaptive gate decomposition algorithm of arXiv:2203...
void get_nn_chanels(const Matrix &Umtx, const int &target_qbit, Matrix_real &chanels)
call retrieve the channels for the neural network associated with a single unitary ...
std::random_device rd
Will be used to obtain a seed for the random number engine.
Class to store data of complex arrays and its properties.
double imag
the imaginary part of a complex number
int omp_get_max_threads()
get the number of threads in MKL