Quantum Gate Decomposer  v1.3
Powerful decomposition of almost any unitary into U3 and CNOT gates
Functor_Cost_Function_Gradient.cpp
Go to the documentation of this file.
4 
5 
17 void N_Qubit_Decomposition::optimization_problem_grad( const gsl_vector* parameters, void* void_instance, gsl_vector* grad ) {
18 
19  // The function value at x0
20  double f0;
21 
22  // calculate the approximate gradient
23  optimization_problem_combined( parameters, void_instance, &f0, grad);
24 
25 }
26 
27 
35 void N_Qubit_Decomposition::optimization_problem_combined( const gsl_vector* parameters, void* void_instance, double* f0, gsl_vector* grad ) {
36 
37  N_Qubit_Decomposition* instance = reinterpret_cast<N_Qubit_Decomposition*>(void_instance);
38 
39  int parameter_num_loc = instance->get_parameter_num();
40 
41  // storage for the function values calculated at the displaced points x
42  gsl_vector* f = gsl_vector_alloc(grad->size);
43 
44  // the difference in one direction in the parameter for the gradient calculation
45  double dparam = 1e-8;
46 
47  // calculate the function values at displaced x and the central x0 points through TBB parallel for
48  tbb::parallel_for(0, parameter_num_loc+1, 1, functor_grad<N_Qubit_Decomposition>( parameters, instance, f, f0, dparam ));
49 
50 /*
51  // sequential version
52  functor_sub_optimization_grad<N_Qubit_Decomposition> tmp = functor_grad<N_Qubit_Decomposition>( parameters, instance, f, f0, dparam );
53  for (int idx=0; idx<parameter_num_loc+1; idx++) {
54  tmp(idx);
55  }
56 */
57 
58  for (int idx=0; idx<parameter_num_loc; idx++) {
59  // calculate and set the gradient
60  gsl_vector_set(grad, idx, (f->data[idx]-(*f0))/dparam);
61  }
62 
63 
64  gsl_vector_free(f);
65 }
66 
67 
68 
69 
76 void Sub_Matrix_Decomposition::optimization_problem_grad( const gsl_vector* parameters, void* void_instance, gsl_vector* grad ) {
77 
78  // The function value at x0
79  double f0;
80 
81  // calculate the approximate gradient
82  optimization_problem_combined( parameters, void_instance, &f0, grad);
83 
84 }
85 
86 
87 
95 void Sub_Matrix_Decomposition::optimization_problem_combined( const gsl_vector* parameters, void* void_instance, double* f0, gsl_vector* grad ) {
96 
97  Sub_Matrix_Decomposition* instance = reinterpret_cast<Sub_Matrix_Decomposition*>(void_instance);
98 
99  int parameter_num_loc = instance->get_parameter_num();
100 
101  // storage for the function values calculated at the displaced points x
102  gsl_vector* f = gsl_vector_alloc(grad->size);
103 
104  // the difference in one direction in the parameter for the gradient calculation
105  double dparam = 1e-8;
106 
107  // calculate the function values at displaced x and the central x0 points through TBB parallel for
108  tbb::parallel_for(0, parameter_num_loc+1, 1, functor_grad<Sub_Matrix_Decomposition>( parameters, instance, f, f0, dparam ));
109 
110 /*
111  // sequential version
112  functor_sub_optimization_grad<Sub_Matrix_Decomposition> tmp = functor_grad<Sub_Matrix_Decomposition>( parameters, instance, f, f0, dparam );
113  #pragma omp parallel for
114  for (int idx=0; idx<parameter_num_loc+1; idx++) {
115  tmp(idx);
116  }
117 */
118 
119 
120  for (int idx=0; idx<parameter_num_loc; idx++) {
121  // calculate and set the gradient
122  gsl_vector_set(grad, idx, (f->data[idx]-(*f0))/dparam);
123  }
124 
125 
126  gsl_vector_free(f);
127 
128 }
129 
130 
131 
132 
141 template<typename decomp_class>
142 functor_grad<decomp_class>::functor_grad( const gsl_vector* parameters_in, decomp_class* instance_in, gsl_vector* f_in, double* f0_in, double dparam_in ) {
143 
144  parameters = parameters_in;
145  instance = instance_in;
146  f = f_in;
147  f0 = f0_in;
148 
149  // the difference in one direction in the parameter for the gradient calculation
150  dparam = dparam_in;
151 
152 }
153 
154 
159 template<typename decomp_class>
161 
162  if (i == (int)parameters->size) {
163  // calculate function value at x0
164  *f0 = instance->optimization_problem(parameters, reinterpret_cast<void*>(instance));
165  }
166  else {
167 
168  gsl_vector* parameters_d = gsl_vector_calloc(parameters->size);
169  memcpy( parameters_d->data, parameters->data, parameters->size*sizeof(double) );
170  parameters_d->data[i] = parameters_d->data[i] + dparam;
171 
172  // calculate the cost function at the displaced point
173  f->data[i] = instance->optimization_problem(parameters_d, reinterpret_cast<void*>(instance));
174 
175  // release vectors
176  gsl_vector_free(parameters_d);
177  parameters_d = NULL;
178 
179  }
180 
181 
182 }
183 
184 
185 
186 
187 
int get_parameter_num()
Call to get the number of free parameters.
static void optimization_problem_combined(const gsl_vector *parameters, void *void_instance, double *f0, gsl_vector *grad)
Call to calculate both the cost function and the its gradient components.
static void optimization_problem_grad(const gsl_vector *parameters, void *void_instance, gsl_vector *grad)
Calculate the approximate derivative (f-f0)/(x-x0) of the cost function with respect to the free para...
void operator()(int i) const
Operator to calculate a gradient component of a cost function labeled by index i.
Header file for the paralleized calculation of the gradient components of the cost functions (support...
static void optimization_problem_combined(const gsl_vector *parameters, void *void_instance, double *f0, gsl_vector *grad)
Call to calculate both the cost function and the its gradient components.
functor_grad(const gsl_vector *parameters_in, decomp_class *instance_in, gsl_vector *f_in, double *f0_in, double dparam_in)
Constructor of the class.
Function operator class to calculate the gradient components of the cost function in parallel.
Header file for a class responsible for the disentanglement of one qubit from the others.
static void optimization_problem_grad(const gsl_vector *parameters, void *void_instance, gsl_vector *grad)
Calculate the approximate derivative (f-f0)/(x-x0) of the cost function with respect to the free para...
A class responsible for the disentanglement of one qubit from the others.
Header file for a class to determine the decomposition of a unitary into a sequence of CNOT and U3 op...
A class to determine the decomposition of a unitary into a sequence of CNOT and U3 operations.