37 gen = std::mt19937(
rd());
59 gen = std::mt19937(
rd());
86 memset( parameters.
get_data(), 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 =
static_cast<int8_t
>(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;
268 int stride_kernel = index_pair_distance * Umtx.
stride;
273 col_idx = col_idx << (target_qbit+1);
278 col_idx = col_idx + tmp;
280 int col_idx_pair = col_idx ^ index_pair_distance;
286 Matrix_real chanels_kernel( chanels_reshaped.get_data() + idx*chanels_reshaped.stride + 4*jdx, 1, 4, chanels_reshaped.stride);
309 std::string err(
"The unitary must be a square matrix.");
313 if ( Umtx.
rows <= 0 ) {
314 std::string err(
"The unitary must be larger than 0x0.");
323 if ( chanels.
size() != dim_over_2*dim_over_2*4*
qbit_num ) {
324 chanels =
Matrix_real( dim_over_2, dim_over_2*4*qbit_num );
348 row_idx = row_idx << (target_qbit+1);
350 int tmp_idx = (idx & ( (1 << (
target_qbit)) - 1 ) );
353 row_idx = row_idx + tmp_idx;
357 int stride_kernel = index_pair_distance * Umtx.
stride;
363 col_idx = col_idx << (target_qbit+1);
365 int tmp_jdx = (jdx & ( (1 << (
target_qbit)) - 1 ) );
368 col_idx = col_idx + tmp_jdx;
370 int col_idx_pair = col_idx ^ index_pair_distance;
376 Matrix_real chanels_kernel( chanels_reshaped.get_data() + idx*chanels_reshaped.stride + 4*qbit_num*jdx + 4*
target_qbit, 1, 4, chanels_reshaped.stride);
406 std::map<std::string, Config_Element> config_int;
413 for(
int idx=0; idx<
levels; idx++) {
461 #if BLAS==0 // undefined BLAS 466 MKL_Set_Num_Threads(1);
467 #elif BLAS==2 //OpenBLAS 469 openblas_set_num_threads(1);
474 if ( samples_num == 1 ) {
475 get_nn_chanels(qbit_num, levels, chanels, nontrivial_adaptive_layers);
479 if ( samples_num < 1 ) {
480 std::string err(
"Number of samples must be greater than 0.");
489 get_nn_chanels(qbit_num, levels, chanels_1, nontrivial_adaptive_layers_1);
495 memset( chanels.
get_data(), 0, chanels.
size()*
sizeof(double) );
496 memset( nontrivial_adaptive_layers.
get_data(), 0, nontrivial_adaptive_layers.
size()*
sizeof(int8_t) );
501 memcpy( nontrivial_adaptive_layers.
get_data(), nontrivial_adaptive_layers_1.
get_data(), nontrivial_adaptive_layers_1.
size()*
sizeof(int8_t) );
505 tbb::parallel_for( tbb::blocked_range<int>(1,samples_num), [&](tbb::blocked_range<int> r) {
507 for (
int idx=r.begin(); idx<r.end(); idx++) {
514 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() );
516 get_nn_chanels(qbit_num, levels, chanels_idx, nontrivial_adaptive_layers_idx);
538 #if BLAS==0 // undefined BLAS 542 #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
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 rows
The number of rows.
int cols
The number of columns.
Umtx
The unitary to be decomposed.
Matrix get_matrix(Matrix_real ¶meters) override
Call to retrieve the gate matrix (Which is the product of all the gate matrices stored in the gate bl...
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...
Double-precision complex matrix (float64).
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.
int get_parameter_num() override
Call to get the number of free parameters.
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