casadi_bfgs.hpp
1 // NOLINT(legal/copyright)
2 // SYMBOL "bfgs"
3 // BFGS update
4 template<typename T1>
5 void casadi_bfgs(const casadi_int* sp_h, T1* h, const T1* dx,
6  const T1* glag, const T1* glag_old, T1* w) {
7  // Local variables
8  casadi_int nx;
9  T1 *yk, *qk, dxBkdx, omega, theta, phi;
10  // Dimension
11  nx = sp_h[0];
12  // Work vectors
13  yk = w; w += nx;
14  qk = w; w += nx;
15  // yk = glag - glag_old
16  casadi_copy(glag, nx, yk);
17  casadi_axpy(nx, -1., glag_old, yk);
18  // qk = H*dx
19  casadi_clear(qk, nx);
20  casadi_mv(h, sp_h, dx, qk, 0);
21  // Calculating theta
22  dxBkdx = casadi_dot(nx, dx, qk);
23  // C-REPLACE "if_else" "casadi_if_else"
24  omega = if_else(casadi_dot(nx, yk, dx) < 0.2 * casadi_dot(nx, dx, qk),
25  0.8 * dxBkdx / (dxBkdx - casadi_dot(nx, dx, yk)), 1);
26  // yk = omega * yk + (1 - omega) * qk;
27  casadi_scal(nx, omega, yk);
28  casadi_axpy(nx, 1 - omega, qk, yk);
29  theta = 1. / casadi_dot(nx, dx, yk);
30  phi = 1. / casadi_dot(nx, qk, dx);
31  // Update H
32  casadi_rank1(h, sp_h, theta, yk, yk);
33  casadi_rank1(h, sp_h, -phi, qk, qk);
34 }
35 
36 // SYMBOL "bfgs_reset"
37 // Removes off-diagonal entries
38 template<typename T1>
39 void casadi_bfgs_reset(const casadi_int* sp_h, T1* h) {
40  casadi_int ncol, c, k;
41  const casadi_int *colind, *row;
42  ncol = sp_h[1];
43  colind = sp_h+2; row = sp_h+ncol+3;
44  for (c=0; c<ncol; ++c) {
45  for (k=colind[c]; k<colind[c+1]; ++k) {
46  if (c!=row[k]) h[k] = 0;
47  }
48  }
49 }