78 N_Qubit_Decomposition_Tabu_Search::N_Qubit_Decomposition_Tabu_Search(
Matrix Umtx_in,
int qbit_num_in,
int level_limit_in, std::vector<
matrix_base<int>> topology_in, std::map<std::string, Config_Element>&
config,
int accelerator_num ) :
N_Qubit_Decomposition_Tree_Search( Umtx_in, qbit_num_in, level_limit_in, topology_in, config, accelerator_num ) {
104 double optimization_tolerance_loc;
106 if (
config.count(
"optimization_tolerance") > 0 ) {
107 config[
"optimization_tolerance"].get_property( optimization_tolerance_loc );
114 if (
config.count(
"tree_level_max") > 0 ){
115 std::cout <<
"lefut\n";
116 config[
"tree_level_max"].get_property( level_max );
128 std::stringstream sstream;
129 sstream <<
"Decomposition did not reached prescribed high numerical precision." << std::endl;
148 double optimization_tolerance_loc;
149 if (
config.count(
"optimization_tolerance") > 0 ) {
150 config[
"optimization_tolerance"].get_property( optimization_tolerance_loc );
175 GrayCode gcode_best_solution = gcode;
178 std::uniform_real_distribution<double> unif(0.0,1.0);
179 std::default_random_engine re;
181 double inverz_temperature = 1.0;
182 std::vector<GrayCode> possible_gate_structures;
195 std::stringstream sstream;
196 sstream <<
"Starting optimization with " << gate_structure_loc->
get_gate_num() <<
" decomposing layers." << std::endl;
201 delete( gate_structure_loc );
202 gate_structure_loc = NULL;
209 sstream <<
"Optimization with " << gcode.
size() <<
" levels converged to " << current_minimum_tmp;
228 gcode_best_solution = gcode;
231 possible_gate_structures.clear();
238 double random_double = unif(re);
239 double number_to_test = exp( -inverz_temperature*(current_minimum_tmp-
current_minimum) );
241 if( random_double < number_to_test ) {
245 gcode_best_solution = gcode;
248 possible_gate_structures.clear();
261 if( possible_gate_structures.size() == 0 ) {
269 if( possible_gate_structures.size() == 0 ) {
276 gcode_best_solution = std::get<0>(pair);
281 if( possible_gate_structures.size() > 0 ||
best_solutions.size() == 0 ) {
289 if ( possible_gate_structures.size() == 0 ) {
290 std::cout <<
"tttttttttttttttttttttttttttttt " <<
best_solutions.size() << std::endl;
320 return gcode_best_solution;
342 double minimum = std::get<1>( *it );
344 if( minimum > minimum_) {
365 std::vector<GrayCode>
369 std::vector<GrayCode> possible_structures_list;
370 int n_ary_limit_max =
topology.size();
379 for(
int gcode_idx=0; gcode_idx<gcode.
size(); gcode_idx++ ) {
381 for(
int gcode_element=0; gcode_element<n_ary_limit_max; gcode_element++ ) {
384 gcode_modified[gcode_idx] = gcode_element;
388 possible_structures_list.push_back( gcode_modified );
397 for(
int gcode_idx=0; gcode_idx<gcode.
size(); gcode_idx++ ) {
403 possible_structures_list.push_back( gcode_modified );
411 return possible_structures_list;
418 for(
int gcode_element=0; gcode_element<n_ary_limit_max; gcode_element++ ) {
421 gcode_modified[ gcode_extended.
size()-1 ] = gcode_element;
425 possible_structures_list.push_back( gcode_modified );
430 return possible_structures_list;
444 if ( gcodes.size() == 0 ) {
445 std::string err(
"N_Qubit_Decomposition_Tabu_Search::draw_gate_structure_from_list: The list of gates structure is empty." );
459 for(
int gcode_idx=0; gcode_idx<gcodes.size(); gcode_idx++ ) {
461 gcode = gcodes[ gcode_idx ];
462 weights[ gcode_idx ] = fact*(
levels);
464 for(
int gcode_element_idx=0; gcode_element_idx<gcode.
size(); gcode_element_idx++ ) {
465 if( gcode[gcode_element_idx] > -1 ) {
466 weights[ gcode_idx ] = weights[ gcode_idx ] - fact;
478 for(
int idx=0; idx<weights.size(); idx++ ) {
479 weight_sum = weight_sum + weights[idx];
483 std::random_device dev;
484 std::mt19937 rng(dev());
485 std::uniform_int_distribution<std::mt19937::result_type> dist(0,weight_sum);
487 int random_num = dist(rng);
488 int weight_sum_partial = 0;
490 for(
int idx=0; idx<weights.size(); idx++ ) {
492 weight_sum_partial = weight_sum_partial + weights[idx];
494 if( random_num < weight_sum_partial ) {
503 GrayCode chosen_gcode = gcodes[ chosen_idx ];
504 gcodes.erase( gcodes.begin() + chosen_idx );
Gates_block * determine_gate_structure(Matrix_real &optimized_parameters_mtx)
Call determine the gate structrue of the decomposing circuit.
void print(const std::stringstream &sstream, int verbose_level=1) const
Call to print output messages in the function of the verbosity level.
GrayCode draw_gate_structure_from_list(std::vector< GrayCode > &gcodes)
Call to sample a gate structure from a list of gate structures to test in the optimization process...
Copyright 2021 Budapest Quantum Computing Group.
int get_num_iters()
Get the number of processed iterations during the optimization process.
Header file for a class representing the X gate.
std::vector< GrayCode > determine_mutated_structures(const GrayCode &gcode)
Call to generate a list of mutated gate structures.
double current_minimum
The current minimum of the optimization problem.
std::vector< std::pair< GrayCode, double > > best_solutions
A base class to determine the decomposition of an N-qubit unitary into a sequence of CNOT and U3 gate...
int levels
[creating decomp class]
double get_current_minimum()
Call to get the obtained minimum of the cost function.
N_Qubit_Decomposition_Tabu_Search()
Nullary constructor of the class.
N_Qubit_Decomposition_custom perform_optimization(Gates_block *gate_structure_loc)
Call to perform the optimization on the given gate structure.
GrayCode tabu_search_over_gate_structures()
Perform tabu serach over gate structures.
int level_limit
The maximal number of adaptive layers used in the decomposition.
int get_gate_num()
Call to get the number of gates grouped in the class.
A base class to determine the decomposition of an N-qubit unitary into a sequence of CNOT and U3 gate...
double optimization_tolerance
The maximal allowed error of the optimization problem (The error of the decomposition would scale wit...
GrayCode_base remove_Digit(const int idx) const
Call to add a new digit to the Gray code.
int accelerator_num
number of utilized accelerators
std::vector< matrix_base< int > > topology
A vector of index pairs encoding the connectivity between the qubits.
int number_of_iters
number of iterations
Matrix_real get_optimized_parameters()
Call to get the optimized parameters.
virtual ~N_Qubit_Decomposition_Tabu_Search()
Destructor of the class.
void insert_into_best_solution(const GrayCode &gcode_, double minimum_)
Call to store a given solution among the best ones.
GrayCode_base add_Digit(const intType n_ary_limit) const
Call to add a new digit to the Gray code.
Class to store data of complex arrays and its properties.
int size() const
Call to get the number of the allocated elements.
GrayCode_base copy() const
Call to create a copy of the state.
A class responsible for grouping two-qubit (CNOT,CZ,CH) and one-qubit gates into layers.
Header file for a class implementing the adaptive gate decomposition algorithm of arXiv:2203...
std::string name
A string labeling the gate operation.
std::map< std::string, Config_Element > config
config metadata utilized during the optimization
std::unordered_set< GrayCode, GrayCodeHash > tested_gate_structures
the set of already examined gate structures (mapped to n-ary Gray codes)
Header file for the paralleized calculation of the cost function of the final optimization problem (s...
Header file for DFE support in unitary simulation.
Matrix_real optimized_parameters_mtx
The optimized parameters for the gates.
Gates_block * construct_gate_structure_from_Gray_code(const GrayCode &gcode)
Call to construct a gate structure corresponding to the configuration of the two-qubit gates describe...
Class to store data of complex arrays and its properties.