double ML_multi_DownhillSimplex::amotry(mat_ratep_type& p, 
                                        v_ratep_type& y,
                                        v_ratep_type& psum,
                                        ptr_eval_func funk,
                                        const int ihi,
                                        const double fac
                                       )
{
    size_t j;
    int n_adjusted;
    double fac1, fac2, ytry;
    size_t ndim = p[0].size();
    v_ratep_type ptry(ndim);
    fac1 = (1.0 - fac) / ndim;
    fac2 = fac1 - fac;
    for (j = 0; j < ndim; ++j)
        ptry[j] = psum[j]*fac1 - p[ihi][j]*fac2;
    if (CONFIG_BOUNDS_ADJUST) {
        bounds_adjust(ptry, n_adjusted);
    }
    if (DEBUG_BOUNDS_TRACE) bounds_trace(ptry, "amotry");
    ytry = (this->*funk)(ptry);
    if (ytry < y[ihi]) {
        y[ihi] = ytry;
        for (j = 0; j < ndim; ++j) {
            psum[j] += ptry[j] - p[ihi][j];
            p[ihi][j] = ptry[j];
        }
        if (CONFIG_BOUNDS_ADJUST) {
            bounds_adjust(ptry, n_adjusted);
        }
        if (DEBUG_BOUNDS_TRACE) bounds_trace(p[ihi], "amotry");
    }
    if (DEBUG_AMOTRY) {
        std::cout << "amotry(): ytry=" << ytry << std::endl;
        if (DEBUG_PRINT_DATA_STRUCTURES)
            print_data_structures(p, y);
    }
    return(ytry);
}
// Extrapolate by a factor of fac through the face of the simplex
// opposite the high point to a new point.  If the new point is 
// better, swap it with the high point.
double
NonGradient::amotry( std::vector<double>& simplex, 
                 std::vector<double>& height,
                 double psum[], int ihi, double fac, PatchData &pd, MsqError &err)
{
  int numRow = getDimension();
  int numCol = numRow + 1;
  std::vector<double> ptry(numRow); // does this make sense?
  double fac1=(1.0-fac)/static_cast<double>(numRow);
  double fac2=fac1-fac;
  for (int row=0;row<numRow;row++)
  {
    ptry[row]=psum[row]*fac1-simplex[row+ihi*numRow]*fac2;
  }
  if( mNonGradDebug >= 3 ) 
  {      
    std::cout << "Try ";
  }      
  MSQ_PRINT(3)("Try");
  double ytry = evaluate(&ptry[0], pd, err); // value at trial point
  if( mNonGradDebug >= 3 ) 
  {      
    std::cout << ytry << std::endl;
  }      
  MSQ_PRINT(3)("yTry");
  if (ytry < height[ihi]) // better than highest (worst)
  {
    height[ihi]=ytry;     // swap ihi and ytry
    for (int row=0;row<numRow;row++)
    {
      psum[row] += (ptry[row]-simplex[row+ihi*numRow]);
      simplex[row+ihi*numRow]=ptry[row];
    }
  }
  return ytry;
}