src/vmlmb.c
/* Apply the L-BFGS Strang's two-loop recursion to compute a search direction.
   Returned value indicates whether the operation was successful otherwise the
   direction is just the gradient (steepest ascent). */
Apply the L-BFGS Strang's two-loop recursion to compute a search direction.
Returned value indicates whether the operation was successful otherwise the
direction is just the gradient (steepest ascent).
Apply the L - BFGS Strang ' s two - loop recursion to compute a search direction . Returned value indicates whether the operation was successful otherwise the direction is just the gradient ( steepest ascent ) .
static opk_status_t
apply(opk_vmlmb_t* opt, const opk_vector_t* g)
{
  double sty, yty;
  opk_index_t j, k;
  opk_status_t result;
  COPY(opt->d, g);
  result = OPK_NOT_POSITIVE_DEFINITE;
  if (opt->method != OPK_VMLMB) {
    for (j = 1; j <= opt->mp; ++j) {
      k = SLOT(j);
      if (RHO(k) > 0) {
        ALPHA(k) = RHO(k)*DOT(opt->d, S(k));
        UPDATE(opt->d, -ALPHA(k), Y(k));
        result = OPK_SUCCESS;
      }
    }
    if (result == OPK_SUCCESS) {
      if (opt->gamma != 1) {
        SCALE(opt->d, opt->gamma);
      }
      for (j = opt->mp; j >= 1; --j) {
        k = SLOT(j);
        if (RHO(k) > 0) {
          double beta = RHO(k)*DOT(opt->d, Y(k));
          UPDATE(opt->d, ALPHA(k) - beta, S(k));
        }
      }
    }
  } else {
    opt->gamma = 0;
    for (j = 1; j <= opt->mp; ++j) {
      k = SLOT(j);
      sty = WDOT(Y(k), S(k));
      if (sty <= 0) {
        RHO(k) = 0;
      } else {
        RHO(k) = 1/sty;
        ALPHA(k) = RHO(k)*WDOT(opt->d, S(k));
        UPDATE(opt->d, -ALPHA(k), Y(k));
        result = OPK_SUCCESS;
        if (opt->gamma == 0) {
          yty = WDOT(Y(k), Y(k));
          opt->gamma = sty/yty;
        }
      }
    }
    if (result == OPK_SUCCESS) {
      if (opt->gamma != 1) {
        SCALE(opt->d, opt->gamma);
      }
      for (j = opt->mp; j >= 1; --j) {
        k = SLOT(j);
        if (RHO(k) > 0) {
          double beta = RHO(k)*WDOT(opt->d, Y(k));
          UPDATE(opt->d, ALPHA(k) - beta, S(k));
        }
      }
      opk_vproduct(opt->d, opt->w, opt->d);
    }
  }
  return result;
}
static opk_status_t apply ( opk_vmlmb_t * opt , const opk_vector_t * g ) { double sty , yty ; opk_index_t j , k ; opk_status_t result ; COPY ( opt -> d , g ) ; result = OPK_NOT_POSITIVE_DEFINITE ; if ( opt -> method != OPK_VMLMB ) { for ( j = 1 ; j <= opt -> mp ; ++ j ) { k = SLOT ( j ) ; if ( RHO ( k ) > 0 ) { ALPHA ( k ) = RHO ( k ) * DOT ( opt -> d , S ( k ) ) ; UPDATE ( opt -> d , - ALPHA ( k ) , Y ( k ) ) ; result = OPK_SUCCESS ; } } if ( result == OPK_SUCCESS ) { if ( opt -> gamma != 1 ) { SCALE ( opt -> d , opt -> gamma ) ; } for ( j = opt -> mp ; j >= 1 ; -- j ) { k = SLOT ( j ) ; if ( RHO ( k ) > 0 ) { double beta = RHO ( k ) * DOT ( opt -> d , Y ( k ) ) ; UPDATE ( opt -> d , ALPHA ( k ) - beta , S ( k ) ) ; } } } } else { opt -> gamma = 0 ; for ( j = 1 ; j <= opt -> mp ; ++ j ) { k = SLOT ( j ) ; sty = WDOT ( Y ( k ) , S ( k ) ) ; if ( sty <= 0 ) { RHO ( k ) = 0 ; } else { RHO ( k ) = 1 / sty ; ALPHA ( k ) = RHO ( k ) * WDOT ( opt -> d , S ( k ) ) ; UPDATE ( opt -> d , - ALPHA ( k ) , Y ( k ) ) ; result = OPK_SUCCESS ; if ( opt -> gamma == 0 ) { yty = WDOT ( Y ( k ) , Y ( k ) ) ; opt -> gamma = sty / yty ; } } } if ( result == OPK_SUCCESS ) { if ( opt -> gamma != 1 ) { SCALE ( opt -> d , opt -> gamma ) ; } for ( j = opt -> mp ; j >= 1 ; -- j ) { k = SLOT ( j ) ; if ( RHO ( k ) > 0 ) { double beta = RHO ( k ) * WDOT ( opt -> d , Y ( k ) ) ; UPDATE ( opt -> d , ALPHA ( k ) - beta , S ( k ) ) ; } } opk_vproduct ( opt -> d , opt -> w , opt -> d ) ; } } return result ; }
Apply the L-BFGS Strang's two-loop recursion to compute a search direction.
Apply the L - BFGS Strang ' s two - loop recursion to compute a search direction .
/* Apply the original L-BFGS Strang's two-loop recursion. */ /* Apply initial inverse Hessian approximation. */ /* Apply L-BFGS Strang's two-loop recursion restricted to the subspace of
       free variables. */ /* Enforce search direction to belong to the subset of the free
         variables. */