Sequential Quantum Gate Decomposer  v1.9.3
Powerful decomposition of general unitarias into one- and two-qubit gates gates
BFGS.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 #include "BFGS_Powell.h"
27 
28 #include <fstream>
29 
30 
31 #ifdef __DFE__
32 #include "common_DFE.h"
33 #endif
34 
35 
36 
43 
44 
45 #ifdef __DFE__
46  if ( qbit_num >= 2 && get_accelerator_num() > 0 ) {
47  upload_Umtx_to_DFE();
48  }
49 #endif
50 
51  if (gates.size() == 0 ) {
52  return;
53  }
54 
55 
56  if (solution_guess.size() == 0 ) {
57  solution_guess = Matrix_real(num_of_parameters,1);
58  }
59 
60 
61  if (optimized_parameters_mtx.size() == 0) {
62  optimized_parameters_mtx = Matrix_real(1, num_of_parameters);
63  memcpy(optimized_parameters_mtx.get_data(), solution_guess.get_data(), num_of_parameters*sizeof(double) );
64  }
65 
66  // maximal number of iteration loops
67  int iteration_loops_max;
68  long long value;
69  if ( config.count("max_iteration_loops_bfgs") > 0 ) {
70  config["max_iteration_loops_bfgs"].get_property( value );
71  iteration_loops_max = (int) value;
72  }
73  else if ( config.count("max_iteration_loops") > 0 ) {
74  config["max_iteration_loops"].get_property( value );
75  iteration_loops_max = (int) value;
76  }
77  else {
78  try {
79  iteration_loops_max = std::max(iteration_loops[qbit_num], 1);
80  }
81  catch (...) {
82  iteration_loops_max = 1;
83  }
84  }
85 
86  // random generator of real numbers
87  std::uniform_real_distribution<> distrib_real(0.0, 2*M_PI);
88 
89  // maximal number of inner iterations overriden by config
90  long long max_inner_iterations_loc;
91  if ( config.count("max_inner_iterations_bfgs") > 0 ) {
92  config["max_inner_iterations_bfgs"].get_property( max_inner_iterations_loc );
93  }
94  else if ( config.count("max_inner_iterations") > 0 ) {
95  config["max_inner_iterations"].get_property( max_inner_iterations_loc );
96  }
97  else {
98  max_inner_iterations_loc =max_inner_iterations;
99  }
100 
101 
102  // The number if iterations after which the current results are displed/exported
103  int output_periodicity;
104  if ( config.count("output_periodicity_cosine") > 0 ) {
105  long long value = 1;
106  config["output_periodicity_cosine"].get_property( value );
107  output_periodicity = (int) value;
108  }
109  if ( config.count("output_periodicity") > 0 ) {
110  long long value = 1;
111  config["output_periodicity"].get_property( value );
112  output_periodicity = (int) value;
113  }
114  else {
115  output_periodicity = 0;
116  }
117 
118 
119 
120  // do the optimization loops
121  for (long long idx=0; idx<iteration_loops_max; idx++) {
122 
123 
124  BFGS_Powell cBFGS_Powell(optimization_problem_combined, this);
125  double f = cBFGS_Powell.Start_Optimization(solution_guess, max_inner_iterations_loc);
126 
127  if (current_minimum > f) {
128  current_minimum = f;
129  memcpy( optimized_parameters_mtx.get_data(), solution_guess.get_data(), num_of_parameters*sizeof(double) );
130  for ( int jdx=0; jdx<num_of_parameters; jdx++) {
131  solution_guess[jdx] = solution_guess[jdx] + distrib_real(gen)/100;
132  }
133  }
134  /*else {
135  for ( int jdx=0; jdx<num_of_parameters; jdx++) {
136  solution_guess[jdx] = solution_guess[jdx] + distrib_real(gen);
137  }
138  }*/
139 
140  if ( output_periodicity>0 && idx % output_periodicity == 0 ) {
142  }
143 
144 #ifdef __MPI__
145  MPI_Bcast( (void*)solution_guess.get_data(), num_of_parameters, MPI_DOUBLE, 0, MPI_COMM_WORLD);
146 #endif
147 
148 
149 
150  }
151 
152 }
153 
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...
double current_minimum
The current minimum of the optimization problem.
int get_accelerator_num()
Get the number of accelerators to be reserved on DFEs on users demand.
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:46
A class implementing the BFGS optimizer based on conjugate gradient direction method of M...
Definition: BFGS_Powell.h:26
double Start_Optimization(Matrix_real &x, long maximal_iterations_in=5001)
Call this method to start the optimization.
std::map< int, int > iteration_loops
A map of <int n: int num> indicating the number of iteration in each step of the decomposition.
void solve_layer_optimization_problem_BFGS(int num_of_parameters, Matrix_real &solution_guess)
Call to solve layer by layer the optimization problem via BBFG algorithm.
Definition: BFGS.cpp:42
int size() const
Call to get the number of the allocated elements.
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.
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...
int qbit_num
number of qubits spanning the matrix of the operation
Definition: Gate.h:81
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.
Class to store data of complex arrays and its properties.
Definition: matrix_real.h:39
std::mt19937 gen
Standard mersenne_twister_engine seeded with rd()