Пример #1
0
void printbeta(char *input, int length)
{
    int i;

    for(i=0; i < length; i++)
    {
        //printf("%c", findbeta(input[i]) );
        printf("%c", findbeta(toupper(input[i])) );
    }

    //printf("\ni=%d\n", i);
}
Пример #2
0
void printbeta(char *input, char *output, int length)
{
    int i;

    for(i=0; i < length; i++)
    {
        output[i]=findbeta(toupper(input[i]));
        printf("%c", output[i]);
    }
    output[i]='\0';

    //printf("\ni=%d\n", i);
}
Пример #3
0
/// Solve the trust-region subproblem using
/// the method of More and Sorensen
///
/// Using the implementation as in Algorithm 7.3.6
/// of Trust Region Methods
///
/// main output  d, the soln to the TR subproblem
/// @param J :: The Jacobian.
/// @param f :: The residuals.
/// @param hf :: The Hessian (sort of).
/// @param Delta :: The raduis of the trust region.
/// @param d :: The output vector of corrections to the parameters giving the
///       solution to the TR subproblem.
/// @param nd :: The 2-norm of d.
/// @param options :: The options.
/// @param inform :: The inform struct.
/// @param w :: The work struct.
void more_sorensen(const DoubleFortranMatrix &J, const DoubleFortranVector &f,
                   const DoubleFortranMatrix &hf, double Delta,
                   DoubleFortranVector &d, double &nd,
                   const nlls_options &options, nlls_inform &inform,
                   more_sorensen_work &w) {

  // The code finds
  //  d = arg min_p   v^T p + 0.5 * p^T A p
  //       s.t. ||p|| \leq Delta
  //
  // set A and v for the model being considered here...

  // Set A = J^T J
  matmult_inner(J, w.A);
  // add any second order information...
  // so A = J^T J + HF
  w.A += hf;
  // now form v = J^T f
  mult_Jt(J, f, w.v);

  // if scaling needed, do it
  if (options.scale != 0) {
    apply_scaling(J, w.A, w.v, w.apply_scaling_ws, options, inform);
  }

  auto n = J.len2();
  auto scale_back = [n, &d, &options, &w]() {
    if (options.scale != 0) {
      for (int i = 1; i <= n; ++i) {
        d(i) = d(i) / w.apply_scaling_ws.diag(i);
      }
    }
  };

  auto local_ms_shift = options.more_sorensen_shift;
  // d = -A\v
  DoubleFortranVector negv = w.v;
  negv *= -1.0;
  solve_spd(w.A, negv, w.LtL, d, inform);
  double sigma = 0.0;
  if (inform.status == NLLS_ERROR::OK) {
    // A is symmetric positive definite....
    sigma = zero;
  } else {
    // reset the error calls -- handled in the code....
    inform.status = NLLS_ERROR::OK;
    inform.external_return = 0;
    inform.external_name = "";
    min_eig_symm(w.A, sigma, w.y1);
    if (inform.status != NLLS_ERROR::OK) {
      scale_back();
      return;
    }
    sigma = -(sigma - local_ms_shift);
    // find a shift that makes (A + sigma I) positive definite
    get_pd_shift(sigma, d, options, inform, w);
    if (inform.status != NLLS_ERROR::OK) {
      scale_back();
      return;
    }
  }

  nd = norm2(d);
  if (boost::math::isnan(nd) || boost::math::isinf(nd)) {
    inform.status = NLLS_ERROR::NAN_OR_INF;
    throw std::runtime_error("Step is NaN or infinite.");
  }

  // now, we're not in the trust region initally, so iterate....
  auto sigma_shift = zero;
  int no_restarts = 0;
  // set 'small' in the context of the algorithm
  double epsilon =
      std::max(options.more_sorensen_tol * Delta, options.more_sorensen_tiny);
  int it = 1;
  for (; it <= options.more_sorensen_maxits; ++it) {

    if (nd <= Delta + epsilon) {
      // we're within the tr radius
      if (fabs(sigma) < options.more_sorensen_tiny ||
          fabs(nd - Delta) < epsilon) {
        // we're good....exit
        break;
      }
      if (w.y1.len() == n) {
        double alpha = 0.0;
        findbeta(d, w.y1, Delta, alpha, inform);
        if (inform.status == NLLS_ERROR::OK) {
          DoubleFortranVector tmp = w.y1;
          tmp *= alpha;
          d += tmp;
        }
      }
      // also good....exit
      break;
    }

    // w.q = R'\d
    // DTRSM( "Left", "Lower", "No Transpose", "Non-unit", n, 1, one, w.LtL, n,
    // w.q, n );
    for (int j = 1; j <= w.LtL.len1(); ++j) {
      for (int k = j + 1; k <= w.LtL.len1(); ++k) {
        w.LtL(j, k) = 0.0;
      }
    }
    w.LtL.solve(d, w.q);

    auto nq = norm2(w.q);
    sigma_shift = (pow((nd / nq), 2)) * ((nd - Delta) / Delta);
    if (fabs(sigma_shift) < options.more_sorensen_tiny * fabs(sigma)) {
      if (no_restarts < 1) {
        // find a shift that makes (A + sigma I) positive definite
        get_pd_shift(sigma, d, options, inform, w);
        if (inform.status != NLLS_ERROR::OK) {
          break;
        }
        no_restarts = no_restarts + 1;
      } else {
        // we're not going to make progress...jump out
        inform.status = NLLS_ERROR::MS_NO_PROGRESS;
        break;
      }
    } else {
      sigma = sigma + sigma_shift;
    }

    shift_matrix(w.A, sigma, w.AplusSigma);
    DoubleFortranVector negv = w.v;
    negv *= -1.0;
    solve_spd(w.AplusSigma, negv, w.LtL, d, inform);
    if (inform.status != NLLS_ERROR::OK) {
      break;
    }

    nd = norm2(d);
  }

  if (it == options.more_sorensen_maxits) {
    // maxits reached, not converged
    inform.status = NLLS_ERROR::MS_MAXITS;
  }
  scale_back();
}