Sequential Quantum Gate Decomposer  v1.9.6
Powerful decomposition of general unitarias into one- and two-qubit gates gates
COSINE.cpp
Go to the documentation of this file.
1 /*
2 Created on Fri Jun 26 14:13:26 2020
3 Copyright 2020 Peter Rakyta, Ph.D.
4 
5 Licensed under the Apache License, Version 2.0 (the "License");
6 you may not use this file except in compliance with the License.
7 You may obtain a copy of the License at
8 
9  http://www.apache.org/licenses/LICENSE-2.0
10 
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
16 
17 @author: Peter Rakyta, Ph.D.
18 */
24 #include "Optimization_Interface.h"
26 
27 
28 #include <fstream>
29 
30 
31 #ifdef __DFE__
32 #include "common_DFE.h"
33 #endif
34 
35 
36 
37 
44 
45 
46  if ( cost_fnc != FROBENIUS_NORM && cost_fnc != VQE && cost_fnc != GQML) {
47  std::string err("Optimization_Interface::solve_layer_optimization_problem_COSINE: Only cost functions FROBENIUS_NORM and VQE are implemented for this strategy");
48  throw err;
49  }
50 
51 
52 #ifdef __DFE__
53  if ( qbit_num >= 5 && get_accelerator_num() > 0 ) {
54  upload_Umtx_to_DFE();
55  }
56 #endif
57 
58  tbb::tick_count t0_CPU = tbb::tick_count::now();
59 
60  if (gates.size() == 0 ) {
61  return;
62  }
63 
64 
65  double M_PI_eight = M_PI/8;
66  double M_PI_quarter = M_PI/4;
67  double M_PI_half = M_PI/2;
68  double M_PI_double = M_PI*2;
69 
70  if (solution_guess.size() == 0 ) {
71  solution_guess = Matrix_real(num_of_parameters,1);
72  std::uniform_real_distribution<> distrib_real(0, M_PI_double);
73  for ( int idx=0; idx<num_of_parameters; idx++) {
74  solution_guess[idx] = distrib_real(gen);
75  }
76 
77  }
78 
79 
80 
81  if (optimized_parameters_mtx.size() == 0) {
82  optimized_parameters_mtx = Matrix_real(1, num_of_parameters);
83  memcpy(optimized_parameters_mtx.get_data(), solution_guess.get_data(), num_of_parameters*sizeof(double) );
84  }
85 
86 
87 
88 
89  std::stringstream sstream;
90  double optimization_time = 0.0;
91  tbb::tick_count optimization_start = tbb::tick_count::now();
92 
93 
94  // the current result
96 
97 
98  // the array storing the optimized parameters
99  Matrix_real solution_guess_tmp_mtx = Matrix_real( num_of_parameters, 1 );
100  memcpy(solution_guess_tmp_mtx.get_data(), optimized_parameters_mtx.get_data(), num_of_parameters*sizeof(double) );
101 
102  int batch_size;
103  if ( config.count("batch_size_cosine") > 0 ) {
104  long long value;
105  config["batch_size_cosine"].get_property( value );
106  batch_size = (int) value;
107  }
108  else if ( config.count("batch_size") > 0 ) {
109  long long value;
110  config["batch_size"].get_property( value );
111  batch_size = (int) value;
112  }
113  else {
114  batch_size = 64 <= num_of_parameters ? 64 : num_of_parameters;
115 
116  }
117 
118  if( batch_size > num_of_parameters ) {
119  std::string err("Optimization_Interface::solve_layer_optimization_problem_COSINE: batch size should be lower or equal to the number of free parameters");
120  throw err;
121  }
122 
123 
124 
125  unsigned long long max_inner_iterations_loc;
126  if ( config.count("max_inner_iterations_cosine") > 0 ) {
127  long long max_inner_iterations_loc_tmp;
128  config["max_inner_iterations_cosine"].get_property( max_inner_iterations_loc_tmp );
129  max_inner_iterations_loc = ( unsigned long long)max_inner_iterations_loc_tmp;
130  }
131  else if ( config.count("max_inner_iterations") > 0 ) {
132  long long max_inner_iterations_loc_tmp;
133  config["max_inner_iterations"].get_property( max_inner_iterations_loc_tmp );
134  max_inner_iterations_loc = ( unsigned long long)max_inner_iterations_loc_tmp;
135  }
136  else {
137  max_inner_iterations_loc = max_inner_iterations;
138  }
139 
140 
141  long long export_circuit_2_binary_loc;
142  if ( config.count("export_circuit_2_binary_cosine") > 0 ) {
143  config["export_circuit_2_binary_cosine"].get_property( export_circuit_2_binary_loc );
144  }
145  else if ( config.count("export_circuit_2_binary") > 0 ) {
146  config["export_circuit_2_binary"].get_property( export_circuit_2_binary_loc );
147  }
148  else {
149  export_circuit_2_binary_loc = 0;
150  }
151 
152  long long check_for_convergence;
153  if ( config.count("check_for_convergence") > 0 ) {
154  config["check_for_convergence"].get_property( check_for_convergence );
155  }
156  else if ( config.count("check_for_convergence_cosine") > 0 ) {
157  config["check_for_convergence_cosine"].get_property( check_for_convergence );
158  }
159  else {
160  check_for_convergence = 1;
161  }
162 
163 
164  double optimization_tolerance_loc;
165  if ( config.count("optimization_tolerance_cosine") > 0 ) {
166  config["optimization_tolerance_cosine"].get_property( optimization_tolerance_loc );
167  }
168  else if ( config.count("optimization_tolerance") > 0 ) {
169  config["optimization_tolerance"].get_property( optimization_tolerance_loc );
170  }
171  else {
172  optimization_tolerance_loc = optimization_tolerance;
173  }
174 
175 
176  // The number if iterations after which the current results are displed/exported
177  int output_periodicity;
178  if ( config.count("output_periodicity_cosine") > 0 ) {
179  long long value = 1;
180  config["output_periodicity_cosine"].get_property( value );
181  output_periodicity = (int) value;
182  }
183  if ( config.count("output_periodicity") > 0 ) {
184  long long value = 1;
185  config["output_periodicity"].get_property( value );
186  output_periodicity = (int) value;
187  }
188  else {
189  output_periodicity = 0;
190  }
191 
192 
193 
194  if ( output_periodicity>0 ) {
196  }
197 
198  // vector stroing the lates values of current minimums to identify convergence
199  Matrix_real f0_vec(1, 100);
200  memset( f0_vec.get_data(), 0, f0_vec.size()*sizeof(double) );
201  double f0_mean = 0.0;
202  int f0_idx = 0;
203 
204 
205 
206  Matrix_real param_update_mtx( batch_size, 1 );
207  matrix_base<int> param_idx_agents( batch_size, 1 );
208 
209 
210  std::vector<Matrix_real> parameters_mtx_vec(batch_size);
211  parameters_mtx_vec.reserve(batch_size);
212 
213 
214 
215  bool three_point_line_search = cost_fnc == FROBENIUS_NORM;
216  bool three_point_line_search_double_period = cost_fnc == VQE;
217  bool five_point_line_search_double_period = cost_fnc == GQML;
218 
219 
220  for (unsigned long long iter_idx=0; iter_idx<max_inner_iterations_loc; iter_idx++) {
221 
222  // build up a vector of indices providing a set from which we can draw random (but unique) choices
223  std::vector<int> indices(num_of_parameters);
224  indices.reserve(num_of_parameters);
225  for( int idx=0; idx<num_of_parameters; idx++ ) {
226  indices[idx] = idx;
227  }
228 
229  for( int idx=0; idx<batch_size; idx++ ) {
230  parameters_mtx_vec[idx] = solution_guess_tmp_mtx.copy();
231 
232  // random generator of integers
233  std::uniform_int_distribution<> distrib_int(0, static_cast<int>(indices.size()-1));
234 
235  // The index array of the chosen parameters
236  int chosen_idx = distrib_int(gen);
237  param_idx_agents[ idx ] = indices[ chosen_idx ];
238  indices.erase( indices.begin()+chosen_idx );
239  }
240 
241 
242 #ifdef __MPI__
243  MPI_Bcast( (void*)param_idx_agents.get_data(), batch_size, MPI_INT, 0, MPI_COMM_WORLD);
244 #endif
245 
246 
247 
248  if ( three_point_line_search ) {
249 
250  for(int idx=0; idx<batch_size; idx++) {
251  Matrix_real& solution_guess_mtx_idx = parameters_mtx_vec[ idx ];
252  solution_guess_mtx_idx[ param_idx_agents[idx] ] += M_PI_half;
253  }
254 
255  Matrix_real f0_shifted_pi2_agents = optimization_problem_batched( parameters_mtx_vec );
256 
257 
258  for(int idx=0; idx<batch_size; idx++) {
259  Matrix_real& solution_guess_mtx_idx = parameters_mtx_vec[ idx ];
260  solution_guess_mtx_idx[ param_idx_agents[idx] ] += M_PI_half;
261  }
262 
263  Matrix_real f0_shifted_pi_agents = optimization_problem_batched( parameters_mtx_vec );
264 
265  for( int idx=0; idx<batch_size; idx++ ) {
266 
267  double f0_shifted_pi = f0_shifted_pi_agents[idx];
268  double f0_shifted_pi2 = f0_shifted_pi2_agents[idx];
269 
270 
271  double A_times_cos = (current_minimum-f0_shifted_pi)/2;
272  double offset = (current_minimum+f0_shifted_pi)/2;
273 
274  double A_times_sin = offset - f0_shifted_pi2;
275 
276  double phi0 = atan2( A_times_sin, A_times_cos);
277 
278 
279  double parameter_shift = phi0 > 0 ? M_PI-phi0 : -phi0-M_PI;
280 
281 
282  param_update_mtx[ idx ] = parameter_shift;
283 
284  //revert the changed parameters
285  Matrix_real& solution_guess_mtx_idx = parameters_mtx_vec[idx];
286  solution_guess_mtx_idx[ param_idx_agents[idx] ] = solution_guess_tmp_mtx[ param_idx_agents[idx] ];
287 
288  }
289 
290  }
291  else if ( three_point_line_search_double_period ) {
292 
293  for(int idx=0; idx<batch_size; idx++) {
294  Matrix_real& solution_guess_mtx_idx = parameters_mtx_vec[ idx ];
295  solution_guess_mtx_idx[ param_idx_agents[idx] ] += M_PI_quarter;
296  }
297 
298  Matrix_real f0_shifted_pi4_agents = optimization_problem_batched( parameters_mtx_vec );
299 
300 
301  for(int idx=0; idx<batch_size; idx++) {
302  Matrix_real& solution_guess_mtx_idx = parameters_mtx_vec[ idx ];
303  solution_guess_mtx_idx[ param_idx_agents[idx] ] += M_PI_quarter;
304  }
305 
306  Matrix_real f0_shifted_pi2_agents = optimization_problem_batched( parameters_mtx_vec );
307 
308  for( int idx=0; idx<batch_size; idx++ ) {
309 
310  double f0_shifted_pi = f0_shifted_pi2_agents[idx];
311  double f0_shifted_pi2 = f0_shifted_pi4_agents[idx];
312 
313 
314  double A_times_cos = (current_minimum-f0_shifted_pi)/2;
315  double offset = (current_minimum+f0_shifted_pi)/2;
316 
317  double A_times_sin = offset - f0_shifted_pi2;
318 
319  double phi0 = atan2( A_times_sin, A_times_cos);
320 
321 
322  double parameter_shift = phi0 > 0 ? M_PI_half-phi0/2 : -phi0/2-M_PI_half;
323 
324 
325  param_update_mtx[ idx ] = parameter_shift;
326 
327  //revert the changed parameters
328  Matrix_real& solution_guess_mtx_idx = parameters_mtx_vec[idx];
329  solution_guess_mtx_idx[ param_idx_agents[idx] ] = solution_guess_tmp_mtx[ param_idx_agents[idx] ];
330 
331  }
332  }
333  else if (five_point_line_search_double_period) {
334  for (int idx=0; idx<batch_size; idx++) {
335  Matrix_real& solution_guess_mtx_idx = parameters_mtx_vec[idx];
336  solution_guess_mtx_idx[param_idx_agents[idx]] += M_PI_eight;
337  }
338 
339  Matrix_real f0_shifted_pi8_agents = optimization_problem_batched(parameters_mtx_vec);
340 
341  for (int idx=0; idx<batch_size; idx++) {
342  Matrix_real& solution_guess_mtx_idx = parameters_mtx_vec[idx];
343  solution_guess_mtx_idx[param_idx_agents[idx]] += M_PI_eight;
344  }
345 
346  Matrix_real f0_shifted_pi4_agents = optimization_problem_batched(parameters_mtx_vec);
347 
348  for (int idx=0; idx<batch_size; idx++) {
349  Matrix_real& solution_guess_mtx_idx = parameters_mtx_vec[idx];
350  solution_guess_mtx_idx[param_idx_agents[idx]] += M_PI_quarter;
351  }
352 
353  Matrix_real f0_shifted_pi2_agents = optimization_problem_batched(parameters_mtx_vec);
354 
355  for (int idx=0; idx<batch_size; idx++) {
356  Matrix_real& solution_guess_mtx_idx = parameters_mtx_vec[idx];
357  solution_guess_mtx_idx[param_idx_agents[idx]] += M_PI_quarter;
358  }
359 
360  Matrix_real f0_shifted_3pi4_agents = optimization_problem_batched(parameters_mtx_vec);
361  for (int idx=0; idx<batch_size; idx++) {
362  double f0_shifted_pi8 = f0_shifted_pi8_agents[idx];
363  double f0_shifted_pi4 = f0_shifted_pi4_agents[idx];
364  double f0_shifted_pi2 = f0_shifted_pi2_agents[idx];
365  double f0_shifted_3pi4 = f0_shifted_3pi4_agents[idx];
366 
367  double f1 = current_minimum -f0_shifted_pi2;
368  double f2 = -f0_shifted_pi4 + f0_shifted_3pi4;
369 
370  double B = 0.5*sqrt(f1*f1+f2*f2);
371 
372  double delta = atan2(f1, f2) - 2*solution_guess_tmp_mtx[param_idx_agents[idx]];
373 
374  double C = 0.25*(current_minimum + f0_shifted_pi2 + f0_shifted_pi4 + f0_shifted_3pi4);
375 
376  double f3 = 0.5*(current_minimum + f0_shifted_pi2 - 2*C);
377  double f4 = f0_shifted_pi8 - C - B*cos(2*solution_guess_tmp_mtx[param_idx_agents[idx]] + M_PI_quarter +delta);
378 
379  double A = sqrt(f3*f3 + f4*f4);
380 
381  double phi = atan2(f3, f4) - 4*solution_guess_tmp_mtx[param_idx_agents[idx]];
382 
383  double params[5];
384  params[0] = A;
385  params[1] = phi + 4*solution_guess_tmp_mtx[param_idx_agents[idx]];
386  params[2] = B;
387  params[3] = delta + 2*solution_guess_tmp_mtx[param_idx_agents[idx]];
388  params[4] = C;
389 
390  Matrix_real parameter_shift(1, 1);
391  if (abs(B) > abs(A)) {
392  parameter_shift[0] = M_PI_half - delta/2 -solution_guess_tmp_mtx[param_idx_agents[idx]]/2 ;
393  }
394  else {
395  parameter_shift[0] = M_PI_quarter - phi/4 -solution_guess_tmp_mtx[param_idx_agents[idx]]/4;
396  }
397  parameter_shift[0] = std::fmod(parameter_shift[0], M_PI_double);
398 
399  BFGS_Powell cBFGS_Powell(HS_partial_optimization_problem_cos_combined,(void*)&params);
400  cBFGS_Powell.Start_Optimization(parameter_shift, 10);
401 
402  param_update_mtx[ idx ] = parameter_shift[0];
403 
404  //revert the changed parameters
405  Matrix_real& solution_guess_mtx_idx = parameters_mtx_vec[idx];
406  solution_guess_mtx_idx[ param_idx_agents[idx] ] = solution_guess_tmp_mtx[ param_idx_agents[idx] ];
407  }
408 
409 
410  }
411  else {
412  std::string err("solve_layer_optimization_problem_COSINE: Not implemented method.");
413  throw err;
414  }
415 
416 
418  // the line search is converted onto a onediemnsional search between x0+a*param_update_mtx and x0+b*param_update_mtx
419  double interval_coeff = 2.0/(sqrt(5.0) + 1); // = 1/tau in Fig 1 of https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=1606817
420 
421 
422  // lowest point on the search interval
423  double point_a = 0.0;
424  double point_b = 1.0;
425  double epsilon = 1e-2;
426 
427  double interval_length = point_b - point_a;
428 
429  double x1 = point_a + interval_length*interval_coeff*interval_coeff;
430  double x2; // = point_a + interval_length*interval_coeff;
431 
432  Matrix_real parameters_x1 = solution_guess_tmp_mtx.copy();
433  Matrix_real parameters_x2;
434  for( int idx=0; idx<batch_size; idx++ ) {
435  parameters_x1[ param_idx_agents[idx] ] += param_update_mtx[ idx ]*x1;
436  }
437 
438 
439  double val_x1 = optimization_problem( parameters_x1 );
440  double val_x2;
441 
442 
443 
444  int iter_max = 50;
445  int iter = 0;
446 
447  double current_best_point = point_a;
448  double current_best_value = current_minimum;
449 
450 
451  while( true ) {
452 
453  interval_length = point_b - point_a;
454 
455  if ( interval_length < epsilon) {
456  break;
457  }
458 
459  if ( (x1-point_a) < (point_b-x1) ) {
460  // x1 is closer to "a" than to "b" --> x2 should be closer to "b"
461  x2 = point_a + interval_length*interval_coeff;
462 
463  parameters_x2 = solution_guess_tmp_mtx.copy();
464 
465  for( int idx=0; idx<batch_size; idx++ ) {
466  parameters_x2[ param_idx_agents[idx] ] += param_update_mtx[ idx ]*x2;
467  }
468 
469  val_x2 = optimization_problem( parameters_x2 );
470  }
471  else {
472  // x1 should be always closer to "a"
473  x2 = x1;
474  val_x2 = val_x1;
475 
476  x1 = point_a + interval_length*interval_coeff*interval_coeff;
477 
478  parameters_x1 = solution_guess_tmp_mtx.copy();
479 
480  for( int idx=0; idx<batch_size; idx++ ) {
481  parameters_x1[ param_idx_agents[idx] ] += param_update_mtx[ idx ]*x1;
482  }
483 
484  val_x1 = optimization_problem( parameters_x1 );
485 
486  }
487 
488 
489  //std::cout << point_a << " " << x1 << " " << x2 << " " << point_b << std::endl;
490  //std::cout << val_x1 << " " << val_x2 << " " << current_minimum << " " << std::endl;
491 
492  if ( val_x1 < val_x2 ) {
493  point_b = x2;
494  if ( current_best_value > val_x1 ) {
495  current_best_point = x1;
496  current_best_value = val_x1;
497  }
498  }
499  else {
500  point_a = x1;
501  if ( current_best_value > val_x2 ) {
502  current_best_point = x2;
503  current_best_value = val_x2;
504  }
505 
506  x1 = x2;
507  val_x1 = val_x2;
508  }
509 
510 
511  iter = iter + 1;
512 
513  if ( iter > iter_max) {
514  std::stringstream sstream;
515  sstream << "line search not converged: interval length: " << interval_length << " " << interval_coeff << std::endl;
516  print(sstream,1);
517  break;
518  }
519  }
520 
521  // std::cout << "number of costfunction evaluations : " << iter+1 << " " << interval_coeff << std::endl;
522 
523  current_minimum = current_best_value;
524 
525  // update parameters
526  for (int param_idx=0; param_idx<batch_size; param_idx++) {
527  solution_guess_tmp_mtx[ param_idx_agents[param_idx] ] += param_update_mtx[ param_idx ]*current_best_point;
528  }
529 
530 
532 /*
533  // parameters for line search
534  int line_points = 128;
535 
536  std::vector<Matrix_real> parameters_line_search_mtx_vec(line_points);
537  parameters_line_search_mtx_vec.reserve(line_points);
538 
539  // perform line search over the deriction determined previously
540  for( int line_idx=0; line_idx<line_points; line_idx++ ) {
541 
542  Matrix_real parameters_line_idx = solution_guess_tmp_mtx.copy();
543 
544  for( int idx=0; idx<batch_size; idx++ ) {
545  parameters_line_idx[ param_idx_agents[idx] ] += param_update_mtx[ idx ]*(double)line_idx/line_points;
546  }
547 
548  parameters_line_search_mtx_vec[ line_idx] = parameters_line_idx;
549 
550  }
551 
552 
553  Matrix_real line_values = optimization_problem_batched( parameters_line_search_mtx_vec );
554 
555 
556  // find the smallest value
557  double f0_min = line_values[0];
558  int idx_min = 0;
559  for (int idx=1; idx<line_points; idx++) {
560  if ( line_values[idx] < f0_min ) {
561  idx_min = idx;
562  f0_min = line_values[idx];
563  }
564  }
565 
566  current_minimum = f0_min;
567 
568  // update parameters
569  for (int param_idx=0; param_idx<batch_size; param_idx++) {
570  solution_guess_tmp_mtx[ param_idx_agents[param_idx] ] += param_update_mtx[ param_idx ]*(double)idx_min/line_points;
571  }
572 */
573 #ifdef __MPI__
574  MPI_Bcast( solution_guess_tmp_mtx.get_data(), num_of_parameters, MPI_DOUBLE, 0, MPI_COMM_WORLD);
575 #endif
576 
577 
578  // update the current cost function
579  //current_minimum = optimization_problem( solution_guess_tmp_mtx );
580 
581  if ( output_periodicity>0 && iter_idx % output_periodicity == 0 ) {
582  std::stringstream sstream;
583  sstream << "COSINE: processed iterations " << (double)iter_idx/max_inner_iterations_loc*100 << "%, current minimum:" << current_minimum;
584  sstream << " " << " circuit simulation time: " << circuit_simulation_time << std::endl;
585  print(sstream, 1);
586  if ( export_circuit_2_binary_loc > 0 ) {
587  std::string filename("initial_circuit_iteration.binary");
588  if (project_name != "") {
589  filename=project_name+ "_" +filename;
590  }
591  export_gate_list_to_binary(solution_guess_tmp_mtx, this, filename, verbose);
592  }
593 
594  memcpy( optimized_parameters_mtx.get_data(), solution_guess_tmp_mtx.get_data(), num_of_parameters*sizeof(double) );
595 
596  if ( output_periodicity>0 && iter_idx % output_periodicity == 0 ) {
598  }
599 
600 
601  }
602 
603  if (current_minimum < optimization_tolerance_loc ) {
604  break;
605  }
606 
607 
608  // test local minimum convergence
609  f0_mean = f0_mean + (current_minimum - f0_vec[ f0_idx ])/f0_vec.size();
610  f0_vec[ f0_idx ] = current_minimum;
611  f0_idx = (f0_idx + 1) % f0_vec.size();
612 
613  double var_f0 = 0.0;
614  for (int idx=0; idx<f0_vec.size(); idx++) {
615  var_f0 = var_f0 + (f0_vec[idx]-f0_mean)*(f0_vec[idx]-f0_mean);
616  }
617  var_f0 = std::sqrt(var_f0)/f0_vec.size();
618 
619 
620 
621  if ( std::abs( (f0_mean - current_minimum)/f0_mean) < 1e-7 && std::abs(var_f0/f0_mean) < 1e-7 && check_for_convergence > 0 ) {
622  std::stringstream sstream;
623  sstream << "COSINE: converged to minimum at iterations " << (double)iter_idx/max_inner_iterations_loc*100 << "%, current minimum:" << current_minimum;
624  sstream << " circuit simulation time: " << circuit_simulation_time << std::endl;
625  print(sstream, 1);
626  if ( export_circuit_2_binary_loc > 0 ) {
627  std::string filename("initial_circuit_iteration.binary");
628  if (project_name != "") {
629  filename=project_name+ "_" +filename;
630  }
631  export_gate_list_to_binary(solution_guess_tmp_mtx, this, filename, verbose);
632  }
633 
634 
635  break;
636  }
637 
638  }
639 
640  memcpy( optimized_parameters_mtx.get_data(), solution_guess_tmp_mtx.get_data(), num_of_parameters*sizeof(double) );
641 
642  // CPU time
643  CPU_time += (tbb::tick_count::now() - t0_CPU).seconds();
644 
645  sstream.str("");
646  sstream << "obtained minimum: " << current_minimum << std::endl;
647 
648 
649  tbb::tick_count optimization_end = tbb::tick_count::now();
650  optimization_time = optimization_time + (optimization_end-optimization_start).seconds();
651  sstream << "COSINE time: " << CPU_time << " seconds, obtained minimum: " << current_minimum << std::endl;
652 
653  print(sstream, 1);
654 
655 }
656 
657 
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.
Definition: logging.cpp:55
Matrix_real copy() const
Call to create a copy of the matrix.
void HS_partial_optimization_problem_cos_combined(Matrix_real parameters, void *void_params, double *f0, Matrix_real &grad)
???????????????
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.
Definition: Gates_block.h:49
A class implementing the BFGS optimizer based on conjugate gradient direction method of M...
Definition: BFGS_Powell.h:26
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 Start_Optimization(Matrix_real &x, long maximal_iterations_in=5001)
Call this method to start the optimization.
#define M_PI
Definition: qgd_math.h:42
double CPU_time
time spent on optimization
int verbose
Set the verbosity level of the output messages.
Definition: logging.h:50
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...
volatile double current_minimum
The current minimum of the optimization problem.
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.
Definition: COSINE.cpp:43
void export_gate_list_to_binary(Matrix_real &parameters, Gates_block *gates_block, const std::string &filename, int verbosity)
Use to export a quantum circuit into binary format.
int qbit_num
number of qubits spanning the matrix of the operation
Definition: Gate.h:94
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 > &parameters_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.
Definition: matrix_real.h:41
std::mt19937 gen
Standard mersenne_twister_engine seeded with rd()