89 max_layer_num.insert( std::pair<int, int>(it->first, it->second) );
125 std::stringstream sstream;
126 sstream <<
"Sub-disentaglement already done." << std::endl;
131 std::stringstream sstream;
132 sstream << std::endl <<
"Disentagling submatrices." << std::endl;
142 std::stringstream sstream;
143 sstream <<
"Disentanglig not needed" << std::endl;
155 tbb::tick_count
start_time = tbb::tick_count::now();
158 int max_layer_num_loc;
163 std::stringstream sstream;
164 sstream <<
"Layer number not given" << std::endl;
169 while (
layer_num < max_layer_num_loc ) {
191 tbb::tick_count current_time = tbb::tick_count::now();
193 std::stringstream sstream;
194 sstream <<
"--- " << (current_time -
start_time).seconds() <<
" seconds elapsed during the decomposition ---" << std::endl << std::endl;
202 std::stringstream sstream;
203 sstream <<
"Sub-disentaglement was succesfull." << std::endl << std::endl;
207 std::stringstream sstream;
208 sstream <<
"Sub-disentaglement did not reach the tolerance limit." << std::endl << std::endl;
237 int identical_blocks_loc;
240 if (identical_blocks_loc==0) {
241 identical_blocks_loc = 1;
245 identical_blocks_loc=1;
251 for (std::vector<Gate*>::iterator gates_it = gates.begin(); gates_it != gates.end(); gates_it++ ) {
254 Gate* gate = *gates_it;
256 for (
int idx=0; idx<identical_blocks_loc; idx++) {
275 int identical_blocks_loc;
278 if (identical_blocks_loc==0) {
279 identical_blocks_loc = 1;
283 identical_blocks_loc=1;
287 for (
int target_qbit_loc = 0; target_qbit_loc<control_qbit_loc; target_qbit_loc++ ) {
289 for (
int idx=0; idx<identical_blocks_loc; idx++) {
295 block->
add_u3(target_qbit_loc);
296 block->
add_u3(control_qbit_loc);
300 block->
add_cnot(target_qbit_loc, control_qbit_loc);
335 if (
gates.size() == 0 ) {
340 if (solution_guess.
size() == 0 ) {
352 int iteration_loops_max;
357 iteration_loops_max = 1;
361 long long max_inner_iterations_loc;
362 if (
config.count(
"max_inner_iterations") > 0 ) {
363 config[
"max_inner_iterations"].get_property( max_inner_iterations_loc );
370 std::uniform_real_distribution<> distrib_real(0.0, 2*M_PI);
373 for (
long long idx=0; idx<iteration_loops_max; idx++) {
383 solution_guess[jdx] = solution_guess[jdx] + distrib_real(
gen)/100;
388 solution_guess[jdx] = solution_guess[jdx] + distrib_real(
gen);
416 apply_to( parameters_mtx, matrix_new );
419 if (matrix_new.
isnan()) {
420 std::stringstream sstream;
421 sstream <<
"Sub_Matrix_Decomposition::optimization_problem: matrix_new contains NaN a. Exiting" << std::endl;
429 return cost_function;
442 std::vector<Gate*> gates_loc = instance->
get_gates();
444 Matrix Umtx_loc, matrix_new;
450 matrix_new = Umtx_loc.
copy();
451 instance->
apply_to( parameters, matrix_new );
454 if (matrix_new.
isnan()) {
455 std::stringstream sstream;
456 sstream <<
"Sub_Matrix_Decomposition::optimization_problem matrix_new contains NaN b." << std::endl;
467 return cost_function;
509 double dparam = 1e-8;
512 tbb::parallel_for(0, parameter_num_loc+1, 1, [&](
int i) {
514 if (i == (
int)parameters.
size()) {
521 parameters_d[i] = parameters_d[i] + dparam;
540 for (
int idx=0; idx<parameter_num_loc; idx++) {
543 if (isnan(f->data[idx])) {
544 std::string err(
"Sub_Matrix_Decomposition::optimization_problem_combined: f->data[i] is NaN.");
548 grad[idx] = (f[idx]-(*f0))/dparam;
592 for ( std::map<int,int>::iterator it=identical_blocks_in.begin(); it!= identical_blocks_in.end(); it++ ) {
618 std::string err(
"Sub_Matrix_Decomposition::clone(): extracting gates was not succesfull.");
bool optimize_layer_num
logical value. Set true to optimize the minimum number of gate layers required in the decomposition...
bool isnan()
Call to check the array for NaN entries.
Sub_Matrix_Decomposition()
Nullary constructor of the class.
static void optimization_problem_grad(Matrix_real parameters, void *void_instance, Matrix_real &grad)
Calculate the approximate derivative (f-f0)/(x-x0) of the cost function with respect to the free para...
void set_custom_gate_layers(Gates_block *block_in)
Call to set custom layers to the gate structure that are intended to be used in the subdecomposition...
void print(const std::stringstream &sstream, int verbose_level=1) const
Call to print output messages in the function of the verbosity level.
Gates_block * unit_gate_structure
Custom gate structure describing the gate structure used in the decomposition. The gate structure is ...
Matrix get_Umtx()
Call to retrive a pointer to the unitary to be transformed.
void disentangle_submatrices()
Start the optimization process to disentangle the most significant qubit from the others...
Matrix_real copy() const
Call to create a copy of the matrix.
double current_minimum
The current minimum of the optimization problem.
virtual Gate * clone()
Call to create a clone of the present class.
void add_gate(Gate *gate)
Append a general gate to the list of gates.
long long max_inner_iterations
maximal number of inner iterations
int set_max_layer_num(int n, int max_layer_num_in)
Set the maximal number of layers used in the subdecomposition of the n-th qubit.
std::vector< Gate * > get_gates()
Call to get the gates stored in the class.
int layer_num
number of gate layers
void add_cnot(int target_qbit, int control_qbit)
Append a CNOT gate gate to the list of gates.
std::map< int, int > max_layer_num
A map of <int n: int num> indicating that how many layers should be used in the subdecomposition proc...
virtual void apply_to(Matrix_real ¶meters_mtx, Matrix &input, int parallel=0)
Call to apply the gate on the input array/matrix Gates_block*input.
scalar * get_data() const
Call to get the pointer to the stored data.
guess_type initial_guess
type to guess the initial values for the optimization. Possible values: ZEROS=0, RANDOM=1, CLOSE_TO_ZERO=2
std::map< int, int > identical_blocks
A map of <int n: int num> indicating that how many identical succesive blocks should be used in the d...
double get_submatrix_cost_function(Matrix &matrix)
Call to calculate the cost function of a given matrix during the submatrix decomposition process...
int set_identical_blocks(int qbit, int identical_blocks_in)
Set the number of identical successive blocks during the subdecomposition of the qbit-th qubit...
std::vector< Gate * > gates
The list of stored gates.
int max_outer_iterations
Maximal number of iterations allowed in the optimization process.
A class implementing the BFGS optimizer based on conjugate gradient direction method of M...
gate_type type
The type of the operation (see enumeration gate_type)
int get_parameter_num()
Call to get the number of free parameters.
double Start_Optimization(Matrix_real &x, long maximal_iterations_in=5001)
Call this method to start the optimization.
void add_u3(int target_qbit)
Append a U3 gate to the list of gates.
bool subdisentaglement_done
logical value indicating whether the disentamglement of a qubit from the othetrs was done or not ...
virtual void add_gate_layers()
Call to add further layer to the gate structure used in the subdecomposition.
Sub_Matrix_Decomposition * clone()
Call to create a clone of the present class.
std::map< int, int > iteration_loops
A map of <int n: int num> indicating the number of iteration in each step of the decomposition.
~Sub_Matrix_Decomposition()
Destructor of the class.
void add_default_gate_layers()
Call to add default gate layers to the gate structure used in the subdecomposition.
A class containing basic methods for the decomposition process.
int extract_gates(Gates_block *op_block)
Call to extract the gates stored in the class.
virtual Gates_block * clone()
Create a clone of the present class.
Class to store data of complex arrays and its properties.
int size() const
Call to get the number of the allocated elements.
Gates_block()
Default constructor of the class.
A class responsible for grouping two-qubit (CNOT,CZ,CH) and one-qubit gates into layers.
Matrix subdecomposed_mtx
The subdecomposed matrix.
guess_type
Type definition of the types of the initial guess.
std::map< std::string, Config_Element > config
config metadata utilized during the optimization
Base class for the representation of general gate operations.
static void optimization_problem_combined(Matrix_real parameters, void *void_instance, double *f0, Matrix_real &grad)
Call to calculate both the cost function and the its gradient components.
Header file for a class responsible for the disentanglement of one qubit from the others...
int parameter_num
the number of free parameters of the operation
double optimization_problem(double *parameters)
The optimization problem of the final optimization.
void solve_optimization_problem(double *solution_guess, int solution_guess_num)
This method can be used to solve the main optimization problem which is devidid into sub-layer optimi...
Matrix Umtx
The unitary to be decomposed.
Matrix copy()
Call to create a copy of the matrix.
static std::map< int, int > max_layer_num_def
A map of <int n: int num> indicating that how many layers should be used in the subdecomposition proc...
int qbit_num
number of qubits spanning the matrix of the operation
void set_max_iteration(int max_outer_iterations_in)
Call to set the maximal number of the iterations in the optimization process.
bool check_optimization_solution()
check_optimization_solution
A class responsible for the disentanglement of one qubit from the others.
int optimization_block
number of gate blocks used in one shot of the optimization process
int set_iteration_loops(int n, int iteration_loops_in)
Set the number of iteration loops during the subdecomposition of the n-th qubit.
Matrix_real optimized_parameters_mtx
The optimized parameters for the gates.
double global_target_minimum
The global target minimum of the optimization problem.
Header file for the paralleized calculation of the cost function of the subdecomposition (supporting ...
void set_optimization_blocks(int optimization_block_in)
Call to set the number of gate blocks to be optimized in one shot.
Class to store data of complex arrays and its properties.
std::mt19937 gen
Standard mersenne_twister_engine seeded with rd()
void solve_layer_optimization_problem(int num_of_parameters, Matrix_real solution_guess_gsl)
Call to solve layer by layer the optimization problem.