47 std::string err(
"Optimization_Interface::solve_layer_optimization_problem_COSINE: Only cost functions FROBENIUS_NORM and VQE are implemented for this strategy");
58 tbb::tick_count t0_CPU = tbb::tick_count::now();
60 if (
gates.size() == 0 ) {
65 double M_PI_quarter = M_PI/4;
66 double M_PI_half = M_PI/2;
67 double M_PI_double = M_PI*2;
69 if (solution_guess.
size() == 0 ) {
71 std::uniform_real_distribution<> distrib_real(0, M_PI_double);
73 solution_guess[idx] = distrib_real(
gen);
88 std::stringstream sstream;
89 double optimization_time = 0.0;
90 tbb::tick_count optimization_start = tbb::tick_count::now();
102 if (
config.count(
"batch_size_cosine") > 0 ) {
104 config[
"batch_size_cosine"].get_property( value );
105 batch_size = (
int) value;
107 else if (
config.count(
"batch_size") > 0 ) {
109 config[
"batch_size"].get_property( value );
110 batch_size = (
int) value;
117 if( batch_size > num_of_parameters ) {
118 std::string err(
"Optimization_Interface::solve_layer_optimization_problem_COSINE: batch size should be lower or equal to the number of free parameters");
123 long long max_inner_iterations_loc;
124 if (
config.count(
"max_inner_iterations_cosine") > 0 ) {
125 config[
"max_inner_iterations_cosine"].get_property( max_inner_iterations_loc );
127 else if (
config.count(
"max_inner_iterations") > 0 ) {
128 config[
"max_inner_iterations"].get_property( max_inner_iterations_loc );
135 long long export_circuit_2_binary_loc;
136 if (
config.count(
"export_circuit_2_binary_cosine") > 0 ) {
137 config[
"export_circuit_2_binary_cosine"].get_property( export_circuit_2_binary_loc );
139 else if (
config.count(
"export_circuit_2_binary") > 0 ) {
140 config[
"export_circuit_2_binary"].get_property( export_circuit_2_binary_loc );
143 export_circuit_2_binary_loc = 0;
147 double optimization_tolerance_loc;
148 if (
config.count(
"optimization_tolerance_cosine") > 0 ) {
149 config[
"optimization_tolerance_cosine"].get_property( optimization_tolerance_loc );
151 else if (
config.count(
"optimization_tolerance") > 0 ) {
153 config[
"optimization_tolerance"].get_property( optimization_tolerance_loc );
161 int output_periodicity;
162 if (
config.count(
"output_periodicity_cosine") > 0 ) {
164 config[
"output_periodicity_cosine"].get_property( value );
165 output_periodicity = (
int) value;
167 if (
config.count(
"output_periodicity") > 0 ) {
169 config[
"output_periodicity"].get_property( value );
170 output_periodicity = (
int) value;
173 output_periodicity = 0;
178 if ( output_periodicity>0 ) {
184 memset( f0_vec.
get_data(), 0.0, f0_vec.
size()*
sizeof(double) );
185 double f0_mean = 0.0;
194 std::vector<Matrix_real> parameters_mtx_vec(batch_size);
195 parameters_mtx_vec.reserve(batch_size);
201 bool three_point_line_search_double_period =
cost_fnc ==
VQE;
204 for (
unsigned long long iter_idx=0; iter_idx<max_inner_iterations_loc; iter_idx++) {
207 std::vector<int> indices(num_of_parameters);
208 indices.reserve(num_of_parameters);
213 for(
int idx=0; idx<batch_size; idx++ ) {
214 parameters_mtx_vec[idx] = solution_guess_tmp_mtx.
copy();
217 std::uniform_int_distribution<> distrib_int(0, indices.size()-1);
220 int chosen_idx = distrib_int(
gen);
221 param_idx_agents[ idx ] = indices[ chosen_idx ];
222 indices.erase( indices.begin()+chosen_idx );
227 MPI_Bcast( (
void*)param_idx_agents.
get_data(), batch_size, MPI_INT, 0, MPI_COMM_WORLD);
232 if ( three_point_line_search ) {
234 for(
int idx=0; idx<batch_size; idx++) {
235 Matrix_real& solution_guess_mtx_idx = parameters_mtx_vec[ idx ];
236 solution_guess_mtx_idx[ param_idx_agents[idx] ] += M_PI_half;
242 for(
int idx=0; idx<batch_size; idx++) {
243 Matrix_real& solution_guess_mtx_idx = parameters_mtx_vec[ idx ];
244 solution_guess_mtx_idx[ param_idx_agents[idx] ] += M_PI_half;
249 for(
int idx=0; idx<batch_size; idx++ ) {
251 double f0_shifted_pi = f0_shifted_pi_agents[idx];
252 double f0_shifted_pi2 = f0_shifted_pi2_agents[idx];
258 double A_times_sin = offset - f0_shifted_pi2;
260 double phi0 = atan2( A_times_sin, A_times_cos);
263 double parameter_shift = phi0 > 0 ? M_PI-phi0 : -phi0-M_PI;
266 param_update_mtx[ idx ] = parameter_shift;
269 Matrix_real& solution_guess_mtx_idx = parameters_mtx_vec[idx];
270 solution_guess_mtx_idx[ param_idx_agents[idx] ] = solution_guess_tmp_mtx[ param_idx_agents[idx] ];
275 else if ( three_point_line_search_double_period ) {
277 for(
int idx=0; idx<batch_size; idx++) {
278 Matrix_real& solution_guess_mtx_idx = parameters_mtx_vec[ idx ];
279 solution_guess_mtx_idx[ param_idx_agents[idx] ] += M_PI_quarter;
285 for(
int idx=0; idx<batch_size; idx++) {
286 Matrix_real& solution_guess_mtx_idx = parameters_mtx_vec[ idx ];
287 solution_guess_mtx_idx[ param_idx_agents[idx] ] += M_PI_quarter;
292 for(
int idx=0; idx<batch_size; idx++ ) {
294 double f0_shifted_pi = f0_shifted_pi2_agents[idx];
295 double f0_shifted_pi2 = f0_shifted_pi4_agents[idx];
301 double A_times_sin = offset - f0_shifted_pi2;
303 double phi0 = atan2( A_times_sin, A_times_cos);
306 double parameter_shift = phi0 > 0 ? M_PI_half-phi0/2 : -phi0/2-M_PI_half;
309 param_update_mtx[ idx ] = parameter_shift;
312 Matrix_real& solution_guess_mtx_idx = parameters_mtx_vec[idx];
313 solution_guess_mtx_idx[ param_idx_agents[idx] ] = solution_guess_tmp_mtx[ param_idx_agents[idx] ];
321 std::string err(
"solve_layer_optimization_problem_COSINE: Not implemented method.");
328 double interval_coeff = 2.0/(sqrt(5.0) + 1);
332 double point_a = 0.0;
333 double point_b = 1.0;
334 double epsilon = 1e-2;
336 double interval_length = point_b - point_a;
338 double x1 = point_a + interval_length*interval_coeff*interval_coeff;
343 for(
int idx=0; idx<batch_size; idx++ ) {
344 parameters_x1[ param_idx_agents[idx] ] += param_update_mtx[ idx ]*x1;
356 double current_best_point = point_a;
362 interval_length = point_b - point_a;
364 if ( interval_length < epsilon) {
368 if ( (x1-point_a) < (point_b-x1) ) {
370 x2 = point_a + interval_length*interval_coeff;
372 parameters_x2 = solution_guess_tmp_mtx.
copy();
374 for(
int idx=0; idx<batch_size; idx++ ) {
375 parameters_x2[ param_idx_agents[idx] ] += param_update_mtx[ idx ]*x2;
385 x1 = point_a + interval_length*interval_coeff*interval_coeff;
387 parameters_x1 = solution_guess_tmp_mtx.
copy();
389 for(
int idx=0; idx<batch_size; idx++ ) {
390 parameters_x1[ param_idx_agents[idx] ] += param_update_mtx[ idx ]*x1;
401 if ( val_x1 < val_x2 ) {
403 if ( current_best_value > val_x1 ) {
404 current_best_point = x1;
405 current_best_value = val_x1;
410 if ( current_best_value > val_x2 ) {
411 current_best_point = x2;
412 current_best_value = val_x2;
422 if ( iter > iter_max) {
423 std::cout <<
"line search not converged: interval length: " << interval_length <<
" " << interval_coeff << std::endl;
433 for (
int param_idx=0; param_idx<batch_size; param_idx++) {
434 solution_guess_tmp_mtx[ param_idx_agents[param_idx] ] += param_update_mtx[ param_idx ]*current_best_point;
487 if ( output_periodicity>0 && iter_idx % output_periodicity == 0 ) {
488 std::stringstream sstream;
489 sstream <<
"COSINE: processed iterations " << (double)iter_idx/max_inner_iterations_loc*100 <<
"\%, current minimum:" <<
current_minimum;
492 if ( export_circuit_2_binary_loc > 0 ) {
493 std::string
filename(
"initial_circuit_iteration.binary");
502 if ( output_periodicity>0 && iter_idx % output_periodicity == 0 ) {
517 f0_idx = (f0_idx + 1) % f0_vec.
size();
520 for (
int idx=0; idx<f0_vec.
size(); idx++) {
521 var_f0 = var_f0 + (f0_vec[idx]-f0_mean)*(f0_vec[idx]-f0_mean);
523 var_f0 = std::sqrt(var_f0)/f0_vec.
size();
527 if ( std::abs( f0_mean -
current_minimum) < 1e-7 && var_f0/f0_mean < 1e-7 ) {
528 std::stringstream sstream;
529 sstream <<
"COSINE: converged to minimum at iterations " << (double)iter_idx/max_inner_iterations_loc*100 <<
"\%, current minimum:" <<
current_minimum;
532 if ( export_circuit_2_binary_loc > 0 ) {
533 std::string
filename(
"initial_circuit_iteration.binary");
551 CPU_time += (tbb::tick_count::now() - t0_CPU).seconds();
557 tbb::tick_count optimization_end = tbb::tick_count::now();
558 optimization_time = optimization_time + (optimization_end-optimization_start).seconds();
void export_current_cost_fnc(double current_minimum)
Call to print out into a file the current cost function and the second Rényi entropy on the subsyste...
void print(const std::stringstream &sstream, int verbose_level=1) const
Call to print output messages in the function of the verbosity level.
Matrix_real copy() const
Call to create a copy of the matrix.
double current_minimum
The current minimum of the optimization problem.
cost_function_type cost_fnc
The chosen variant of the cost function.
int get_accelerator_num()
Get the number of accelerators to be reserved on DFEs on users demand.
double optimization_problem(double *parameters)
Evaluate the optimization problem of the optimization.
scalar * get_data() const
Call to get the pointer to the stored data.
std::vector< Gate * > gates
The list of stored gates.
std::string project_name
the name of the project
double optimization_tolerance
The maximal allowed error of the optimization problem (The error of the decomposition would scale wit...
double CPU_time
time spent on optimization
int verbose
Set the verbosity level of the output messages.
double circuit_simulation_time
Time spent on circuit simulation/cost function evaluation.
int size() const
Call to get the number of the allocated elements.
std::map< std::string, Config_Element > config
config metadata utilized during the optimization
Header file for the paralleized calculation of the cost function of the final optimization problem (s...
void solve_layer_optimization_problem_COSINE(int num_of_parameters, Matrix_real &solution_guess)
Call to solve layer by layer the optimization problem via the COSINE algorithm.
void export_gate_list_to_binary(Matrix_real ¶meters, Gates_block *gates_block, const std::string &filename, int verbosity)
?????????
int qbit_num
number of qubits spanning the matrix of the operation
Header file for DFE support in unitary simulation.
int max_inner_iterations
the maximal number of iterations for which an optimization engine tries to solve the optimization pro...
Matrix_real optimized_parameters_mtx
The optimized parameters for the gates.
Matrix_real optimization_problem_batched(std::vector< Matrix_real > ¶meters_vec)
The cost function of the optimization with batched input (implemented only for the Frobenius norm cos...
Class to store data of complex arrays and its properties.
std::mt19937 gen
Standard mersenne_twister_engine seeded with rd()