53 Zmtx[row_offset + idx] = 1.0;
104 double norm_Z = -1.0;
116 double fprev = fabs(f + f + 1.0);
125 double search_direction__grad_overlap = 0.0;
131 if (search_direction__grad_overlap < 0.0) {
134 d__dot__g = search_direction__grad_overlap;
139 double gradient_norm = 0.0;
141 gradient_norm += g[idx] * g[idx];
146 if (gradient_norm <= acc * acc) {
152 if (d__dot__g >= 0.0) {
175 line_search(x, g, search_direction, x0_search, g0_search, maximal_step, d__dot__g, f);
207 double norm_delta = 0.0;
208 double delta_T__dot__gamma = 0.0;
218 delta[idx] = x[idx] - x0[idx];
220 norm_delta += delta[idx] * delta[idx];
221 tmp += g0[idx] * delta[idx];
223 gamma[idx] = g[idx] - g0[idx];
225 delta_T__dot__gamma += gamma[idx] * delta[idx];
229 if (delta_T__dot__gamma < fabs(tmp) * 0.1) {
234 delta_T__dot__gamma = std::max(
num_precision, delta_T__dot__gamma );
250 for (
long col_idx = variable_num-1; col_idx > 0; col_idx--) {
256 long col_idx_tmp = col_idx - 1;
265 long row_offset = col_idx_tmp;
267 for (
long row_idx = 0; row_idx <
variable_num; row_idx++) {
269 tmp = cos_val *
Zmtx[row_offset + 1] - sin_val *
Zmtx[row_offset];
270 Zmtx[row_offset] = cos_val * Zmtx[row_offset] + sin_val * Zmtx[row_offset + 1];
271 Zmtx[row_offset + 1] = tmp;
284 norm_Z = norm_delta / delta_T__dot__gamma;
286 tmp = sqrt(norm_Z * norm_delta / delta_T__dot__gamma);
288 norm_Z = std::min(norm_Z, tmp);
289 norm_Z = std::max(norm_Z, tmp*0.1);
294 tmp = sqrt(delta_T__dot__gamma);
301 Zmtx[row_offset] = delta[idx] / tmp;
304 Zmtx[row_offset] = 0;
315 memset( gamma_T__dot__Z.
get_data(), 0.0, gamma_T__dot__Z.
size()*
sizeof(double) );
318 for (
long row_idx = 0; row_idx <
variable_num; row_idx++) {
320 double& gamma_element = gamma[row_idx];
322 for (
long col_idx = 1; col_idx <
variable_num; col_idx++) {
323 gamma_T__dot__Z[col_idx] += gamma_element *
Zmtx[row_offset + col_idx];
333 for (
long col_idx = 1; col_idx <
variable_num; col_idx++) {
334 gamma_T__dot__Z[col_idx] = gamma_T__dot__Z[col_idx]/delta_T__dot__gamma;
339 memset( norm_Z_tmp_mtx.
get_data(), 0.0, norm_Z_tmp_mtx.
size()*
sizeof(double) );
342 for (
long row_idx = 0; row_idx <
variable_num; row_idx++) {
344 double& delta_element = delta[row_idx];
346 for (
long col_idx = 1; col_idx <
variable_num; col_idx++) {
347 double& Z_element =
Zmtx[row_offset + col_idx];
349 Z_element = Z_element - gamma_T__dot__Z[col_idx] * delta_element;
351 norm_Z_tmp_mtx[col_idx] += Z_element * Z_element;
365 for (
long col_idx = 1; col_idx <
variable_num; col_idx++) {
367 if (norm_Z_tmp_mtx[col_idx] < norm_Z && norm_Z_tmp_mtx[col_idx] >
num_precision) {
369 tmp = sqrt(norm_Z / norm_Z_tmp_mtx[col_idx]);
371 row_offset = col_idx;
372 for (
long row_idx = 0; row_idx <
variable_num; row_idx++) {
374 Zmtx[row_offset] = tmp *
Zmtx[row_offset];
403 for (
long row_idx = 0; row_idx <
variable_num; row_idx++) {
405 double& g_element = g[row_idx];
407 for (
long col_idx = 0; col_idx <
variable_num; col_idx++) {
417 memset(search_direction.
get_data(), 0.0, search_direction.
size()*
sizeof(double) );
419 for (
long row_idx = 0; row_idx <
variable_num; row_idx++) {
421 for (
long col_idx = 0; col_idx <
variable_num; col_idx++) {
422 search_direction[row_idx] = search_direction[row_idx] -
Zmtx[row_offset + col_idx] *
Z_T__dot__g[col_idx];
431 search_direction__grad_overlap = 0.0;
434 search_direction__grad_overlap += search_direction[idx] * g[idx];
A class implementing the BFGS iterations on the.
void get_f_ang_gradient(Matrix_real &x, double &f, Matrix_real &g)
Call this method to obtain the cost function and its gradient at a gives position given by x...
void get_Maximal_Line_Search_Step(Matrix_real &search_direction, double &maximal_step, double &search_direction__grad_overlap)
Call this method to obtain the maximal step size during the line search.
void Initialize_Zmtx()
Initialize the matrix Z to identity.
BFGS_Powell(void(*f_pointer)(Matrix_real, void *, double *, Matrix_real &), void *meta_data_in)
Constructor of the class.
long maximal_iterations
maximal count of iterations during the optimization
~BFGS_Powell()
Destructor of the class.
void Optimize(Matrix_real &x, double &f)
Call this method to start the optimization process.
void line_search(Matrix_real &x, Matrix_real &g, Matrix_real &search_direction, Matrix_real &x0_search, Matrix_real &g0_search, double &maximal_step, double &d__dot__g, double &f)
Call to perform inexact line search terminated with Wolfe 1st and 2nd conditions. ...
void get_search_direction(Matrix_real &g, Matrix_real &search_direction, double &search_direction__grad_overlap)
Method to get the search direction in the next line search.
scalar * get_data() const
Call to get the pointer to the stored data.
enum solver_status status
status of the solver
long function_call_count
number of function calls during the optimization process
int size() const
Call to get the number of the allocated elements.
int variable_num
number of independent variables in the problem
double num_precision
numerical precision used in the calculations
void BFGS_iteration(Matrix_real &x, Matrix_real &g, Matrix_real &x0_search, Matrix_real &g0_search, double &norm_Z)
Method implementing the BFGS update of the matrix Z.
Class to store data of complex arrays and its properties.