Exemplo n.º 1
0
 int line_search_backtracking_owlqn(
    int n,
    T *x,
    T *f,
    T *g,
    T *s,
    T *stp,
    const T* xp,
    const T* gp,
    T *wp,
    callback_data_t<T> *cd,
    const lbfgs_parameter_t *param
    )
{
    int i, count = 0;
    T width = 0.5, norm = 0.;
    T finit = *f, dgtest;

    /* Check the input parameters for errors. */
    if (*stp <= 0.) {
        return LBFGSERR_INVALIDPARAMETERS;
    }

    /* Choose the orthant for the new point. */
    for (i = 0;i < n;++i) {
        wp[i] = (xp[i] == 0.) ? -gp[i] : xp[i];
    }

    for (;;) {
        /* Update the current point. */
        veccpy(x, xp, n);
        vecadd(x, s, *stp, n);

        /* The current point is projected onto the orthant. */
        owlqn_project(x, wp, param->orthantwise_start, param->orthantwise_end);

        /* Evaluate the function and gradient values. */
        *f = cd->proc_evaluate(cd->instance, x, g, cd->n, *stp);

        /* Compute the L1 norm of the variables and add it to the object value. */
        norm = owlqn_x1norm(x, param->orthantwise_start, param->orthantwise_end);
        *f += norm * param->orthantwise_c;

        ++count;

        dgtest = 0.;
        for (i = 0;i < n;++i) {
            dgtest += (x[i] - xp[i]) * gp[i];
        }

        if (*f <= finit + param->ftol * dgtest) {
            /* The sufficient decrease condition. */
            return count;
        }

        if (*stp < param->min_step) {
            /* The step is the minimum value. */
            return LBFGSERR_MINIMUMSTEP;
        }
        if (*stp > param->max_step) {
            /* The step is the maximum value. */
            return LBFGSERR_MAXIMUMSTEP;
        }
        if (param->max_linesearch <= count) {
            /* Maximum number of iteration. */
            return LBFGSERR_MAXIMUMLINESEARCH;
        }

        (*stp) *= width;
    }
}
Exemplo n.º 2
0
static int line_search_backtracking_owlqn(
  int n,
  double* x,
  double* f,
  double* g,
  double* s,
  double* step,
  const double* xp,
  const double* gp,
  double* wp,
  callback_data_t* cd,
  const lbfgs_parameter_t* param
) {
  int i, count = 0;
  double width = 0.5, norm = 0.0;
  double finit = *f, dgtest;

  /* Check the input parameters for errors. */
  if (*step <= 0.0) {
    return LBFGSERR_INVALIDPARAMETERS;
  }

  /* Choose the orthant for the new point. */
  for (i = 0; i < n; i++) {
    wp[i] = (xp[i] == 0.0) ? -gp[i] : xp[i];
  }

  for (;;) {
    veccpy(x, xp, n);
    vecadd(x, s, *step, n);

    /* The current point is projected onto the orthant. */
    owlqn_project(x, wp, param->orthantwise_start, param->orthantwise_end);

    *f = cd->evaluate(cd->instance, cd->n, x, g, *step);
    count++;

    /* Compute the L1 norm of the variables and add it to the object value. */
    norm = owlqn_x1norm(x, param->orthantwise_start, param->orthantwise_end);
    *f += norm * param->orthantwise_c;

    dgtest = 0.0;
    for (i = 0; i < n; i++) {
      dgtest += (x[i] - xp[i]) * gp[i];
    }

    if (*f <= finit + param->ftol * dgtest) {
      /* The sufficient decrease condition. */
      return count;
    }

    if (*step < param->min_step) {
      /* The step is the minimum value. */
      return LBFGSERR_MINIMUMSTEP;
    }
    if (*step > param->max_step) {
      /* The step is the maximum value. */
      return LBFGSERR_MAXIMUMSTEP;
    }
    if (count >= param->max_linesearch) {
      /* Maximum number of iteration. */
      return LBFGSERR_MAXIMUMLINESEARCH;
    }

    (*step) *= width;
  }
}