コード例 #1
0
ファイル: struve.cpp プロジェクト: c304728539/itpp-fastica
double struve(double v, double x)
{
  double y, ya, f, g, h, t;
  double onef2err, threef0err;

  f = floor(v);
  if ((v < 0) && (v - f == 0.5)) {
    y = jv(-v, x);
    f = 1.0 - f;
    g =  2.0 * floor(f / 2.0);
    if (g != f)
      y = -y;
    return(y);
  }
  t = 0.25 * x * x;
  f = fabs(x);
  g = 1.5 * fabs(v);
  if ((f > 30.0) && (f > g)) {
    onef2err = 1.0e38;
    y = 0.0;
  }
  else {
    y = onef2(1.0, 1.5, 1.5 + v, -t, &onef2err);
  }

  if ((f < 18.0) || (x < 0.0)) {
    threef0err = 1.0e38;
    ya = 0.0;
  }
  else {
    ya = threef0(1.0, 0.5, 0.5 - v, -1.0 / t, &threef0err);
  }

  f = sqrt(PI);
  h = pow(0.5 * x, v - 1.0);

  if (onef2err <= threef0err) {
    g = gam(v + 1.5);
    y = y * h * t / (0.5 * f * g);
    return(y);
  }
  else {
    g = gam(v + 0.5);
    ya = ya * h / (f * g);
    ya = ya + yv(v, x);
    return(ya);
  }
}
コード例 #2
0
ファイル: Matrix1.cpp プロジェクト: mejwaller/numanal
vector<float> tridag(const vector<float> &a,const vector<float> &b, const vector<float> &c, const vector<float> &r)
{
    vector<float> u(b.size(),0.0);
    vector<float> gam(b.size());
    float bet;

    if(FCMP(b[0],0.0))
    {
        cout << "Error - matrix[0][0] == 0.0 - try rewriting eqns. as a set of order n-1 with u2 trivually elimianted..." << endl;
        return u;
    }

    u[0] = r[0]/(bet=b[0]);
    for(unsigned long int j = 1; j<b.size(); j++)
    {
        gam[j] = c[j-1]/bet;
        bet = b[j]-a[j]*gam[j];
        if(FCMP(bet,0.0))
        {
            cout << "Error -  cannot solve tridag system.\n" << endl;
            return u;
        }
        u[j] = (r[j]-a[j]*u[j-1])/bet;
    }
    for(unsigned long int i = b.size()-2; i>=0;i--)
    {
        u[i]-=gam[i+1]*u[i+1];
        if(i==0)
        {
            break;
        }
    }
    return u;
}
コード例 #3
0
ファイル: pictures.c プロジェクト: mortid0/gefestus
double get_freq(double temper)
{
    double rm = 0.5*mass[0];
    double cr = 2.0 * sqrt(2.0*K*temper/(rm*PI));
    double sigma = PI*diam[0]*diam[0];
    double fr = conc[0]*sigma*pow(cr, 2.0*viscos - 1)*(2.0/sqrt(PI))*gam(2.5 - viscos)*pow(2.0*K*temper/rm,1.0-viscos);
    return fr;
}
コード例 #4
0
ファイル: occvode.cpp プロジェクト: bhache/pkg-neuron
int Cvode::solvex_thread_part1(double* b, NrnThread* nt){
//printf("Cvode::solvex_thread %d t=%g t_=%g\n", nt->id, nt->t, t_);
//printf("Cvode::solvex_thread %d %g\n", nt->id, gam());
//printf("\tenter b\n");
//for (int i=0; i < neq_; ++i) { printf("\t\t%d %g\n", i, b[i]);}
	int i;
	CvodeThreadData& z = ctd_[nt->id];
	nt->cj = 1./gam();
	nt->_dt = gam();
	if (z.nvsize_ == 0) { return 0; }
	lhs(nt); // special version for cvode.
	scatter_ydot(b, nt->id);
	nrn_mul_capacity(nt, z.cmlcap_->ml);
	for (i=0; i < z.no_cap_count_; ++i) {
		NODERHS(z.no_cap_node_[i]) = 0.;
	}
	// solve it
	nrn_multisplit_triang(nt);
	return 0;
}
コード例 #5
0
ファイル: topology.cpp プロジェクト: ybouret/iics
//==============================================================================
//! simultaneous tridiagonal system
//==============================================================================
static inline
void vertex_tridiag(const array<Real>   &a,
                    const array<Real>   &b,
                    const array<Real>   &c,
                    const array<Vertex> &r,
                    array<Vertex>       &u,
                    const size_t         n)
{
    const Vertex org(0,0);
    
    assert(n<=a.size());
    assert(n<=b.size());
    assert(n<=c.size());
    assert(n<=r.size());
    assert(n<=u.size());
    assert(Fabs(b[1])>0);
    Vertex         bet;
    vector<Vertex> gam(n,org);
    u[1]=r[1]/(bet.x=bet.y=b[1]);
    for(size_t j=2;j<=n;j++)
    {
        Vertex    &gam_j = gam[j];
        const Real c_jm  = c[j-1];
        gam_j.x = c_jm/bet.x;
        gam_j.y = c_jm/bet.y;
        
        const Real b_j = b[j];
        const Real a_j = a[j];
        
        bet.x = b_j - a_j * gam_j.x;
        bet.y = b_j - a_j * gam_j.y;
        
        if ( Fabs(bet.x) <= 0 || Fabs(bet.y) <= 0 )
            throw exception("Error 2 in tridag");
        
        const Vertex &r_j = r[j];
        Vertex       &u_j = u[j];
        const Vertex &u_jm = u[j-1];
        
        u_j.x = (r_j.x - a_j * u_jm.x) / bet.x;
        u_j.y = (r_j.y - a_j * u_jm.y) / bet.y;
    }
    for(size_t j=(n-1);j>=1;j--)
    {
        Vertex       &u_j    = u[j];
        const Vertex &u_jp   = u[j+1];
        const Vertex &gam_jp = gam[j+1];
        u_j.x -= gam_jp.x * u_jp.x;
        u_j.y -= gam_jp.y * u_jp.y;
    }
    
}
コード例 #6
0
ファイル: occvode.cpp プロジェクト: bhache/pkg-neuron
int Cvode::solvex_thread(double* b, double* y, NrnThread* nt){
//printf("Cvode::solvex_thread %d t=%g t_=%g\n", nt->id, nt->t, t_);
//printf("Cvode::solvex_thread %d %g\n", nt->id, gam());
//printf("\tenter b\n");
//for (int i=0; i < neq_; ++i) { printf("\t\t%d %g\n", i, b[i]);}
	int i;
	CvodeThreadData& z = CTD(nt->id);
	nt->cj = 1./gam();
	nt->_dt = gam();
	if (z.nvsize_ == 0) { return 0; }
	lhs(nt); // special version for cvode.
	scatter_ydot(b, nt->id);
	nrn_mul_capacity(nt, z.cmlcap_->ml);
	for (i=0; i < z.no_cap_count_; ++i) {
		NODERHS(z.no_cap_node_[i]) = 0.;
	}
	// solve it
#if PARANEURON
	if (nrn_multisplit_solve_) {
		(*nrn_multisplit_solve_)();
	}else
#endif
	{
		triang(nt);
		bksub(nt);
	}
//for (i=0; i < v_node_count; ++i) {
//	printf("%d rhs %d %g t=%g\n", nrnmpi_myid, i, VEC_RHS(i), t);
//}
	if (ncv_->stiff() == 2) {
		solvemem(nt);
	}else{
		// bug here should multiply by gam
	}
	gather_ydot(b, nt->id);
//printf("\texit b\n");
//for (i=0; i < neq_; ++i) { printf("\t\t%d %g\n", i, b[i]);}
	return 0;
}
コード例 #7
0
ファイル: tridag.cpp プロジェクト: hildingur/filtering
void NR::tridag(Vec_I_DP &a, Vec_I_DP &b, Vec_I_DP &c, Vec_I_DP &r, Vec_O_DP &u)
{
    int j;
    DP bet;

    int n=a.size();
    Vec_DP gam(n);
    if (b[0] == 0.0) nrerror("Error 1 in tridag");
    u[0]=r[0]/(bet=b[0]);
    for (j=1; j<n; j++) {
        gam[j]=c[j-1]/bet;
        bet=b[j]-a[j]*gam[j];
        if (bet == 0.0) nrerror("Error 2 in tridag");
        u[j]=(r[j]-a[j]*u[j-1])/bet;
    }
    for (j=(n-2); j>=0; j--)
        u[j] -= gam[j+1]*u[j+1];
}
コード例 #8
0
void StreamPower::Tridag(std::vector<double>& a, std::vector<double>& b, std::vector<double>& c, std::vector<double>& r, std::vector<double>& u, int n)
{
	int j;
	double bet;
	std::vector<double> gam(n);

	u[0] = r[0] / (bet = b[0]);
	for (j = 1; j < n; j++)
	{
		gam[j] = c[j - 1] / bet;
		bet = b[j] - a[j] * gam[j];
		u[j] = (r[j] - a[j] * u[j - 1]) / bet;
	}
	for (j = (n - 2); j > 0; j--)
	{
		u[j] -= gam[j + 1] * u[j + 1];
	}

}
コード例 #9
0
ファイル: hyperg.cpp プロジェクト: c304728539/itpp-fastica
static double hy1f1a(double a, double b, double x, double *err)
{
  double h1, h2, t, u, temp, acanc, asum, err1, err2;

  if (x == 0) {
    acanc = 1.0;
    asum = MAXNUM;
    goto adone;
  }
  temp = log(fabs(x));
  t = x + temp * (a - b);
  u = -temp * a;

  if (b > 0) {
    temp = lgam(b);
    t += temp;
    u += temp;
  }

  h1 = hyp2f0(a, a - b + 1, -1.0 / x, 1, &err1);

  temp = exp(u) / gam(b - a);
  h1 *= temp;
  err1 *= temp;

  h2 = hyp2f0(b - a, 1.0 - a, 1.0 / x, 2, &err2);

  if (a < 0)
    temp = exp(t) / gam(a);
  else
    temp = exp(t - lgam(a));

  h2 *= temp;
  err2 *= temp;

  if (x < 0.0)
    asum = h1;
  else
    asum = h2;

  acanc = fabs(err1) + fabs(err2);


  if (b < 0) {
    temp = gam(b);
    asum *= temp;
    acanc *= fabs(temp);
  }


  if (asum != 0.0)
    acanc /= fabs(asum);

  acanc *= 30.0; /* fudge factor, since error of asymptotic formula
    * often seems this much larger than advertised */

adone:


  *err = acanc;
  return(asum);
}
コード例 #10
0
ファイル: test1.cpp プロジェクト: sjneph/hmm
int main()
{
  // Observed sequence 
  typedef float T;
  std::vector<T> observed, initial, tmp;
  std::vector< std::vector<T> > transition, emission, results;
  std::string obs = "010000000010000100001000000000";
  make_vector(observed, obs);
  std::copy(observed.begin(), observed.end(), std::ostream_iterator<T>(std::cout, " "));
  std::cout << std::endl << "Length = " << observed.size() << std::endl;

  // Initial state probabilities
  initial.push_back(0.5), initial.push_back(0.5);

  // Transitional probabilities
  tmp.clear();
  tmp.push_back(0.9), tmp.push_back(0.1);
  transition.push_back(tmp);

  tmp.clear();
  tmp.push_back(0.5), tmp.push_back(0.5);
  transition.push_back(tmp);

  // Emission probabilities
  tmp.clear();
  tmp.push_back(0.2), tmp.push_back(0.3), tmp.push_back(0.5);
  emission.push_back(tmp);

  tmp.clear();
  tmp.push_back(0.5), tmp.push_back(0.2), tmp.push_back(0.3);
  emission.push_back(tmp);

  dolog(initial, transition, emission);

  // Test full forward
  std::cout << "Full Forward" << std::endl;
  std::size_t index = observed.size();
  results.resize(initial.size());
  for ( std::size_t i = 0; i < results.size(); ++i )
    results[i].resize(index);

  ci::hmm::forward_full(observed, initial, transition, emission, index, results);
  for ( std::size_t i = 0; i < results.size(); ++i ) {
    for ( std::size_t j = 0; j < results[i].size(); ++j )
      std::cout << results[i][j] << "\t";
    std::cout << std::endl;
  } // for

  // Test indexed forward
  std::cout << "Indexed Forward" << std::endl;
  std::vector<T> ok(initial.size(), 0);
  ci::hmm::forward_index(observed, initial, transition, emission, 1, ok);
  std::copy(ok.begin(), ok.end(), std::ostream_iterator<T>(std::cout, "\t"));
  std::cout << std::endl;

  // Test next forward
  ok.clear();
  ok.resize(initial.size(), 0);
  for ( std::size_t i = 1; i <= observed.size(); ++i ) {
    std::cout << "Next Forward (" << i << ")" << std::endl;
    ci::hmm::forward_next(observed, initial, transition, emission, i, ok);
    std::copy(ok.begin(), ok.end(), std::ostream_iterator<T>(std::cout, "\t"));
    std::cout << std::endl;
  }

  // Test backward
  std::cout << "Full Backward" << std::endl;
  results.clear();
  results.resize(initial.size());
  for ( std::size_t i = 0; i < results.size(); ++i )
    results[i].resize(observed.size(), 0);
  index = 1;

  ci::hmm::backward_full(observed, initial, transition, emission, index, results);
  for ( std::size_t i = 0; i < results.size(); ++i ) {
    for ( std::size_t j = 0; j < results[i].size(); ++j )
      std::cout << results[i][j] << "\t";
    std::cout << std::endl;
  } // for

  // Test indexed backward
  std::cout << "Indexed Backward" << std::endl;
  ok.clear();
  ok.resize(initial.size());
  ci::hmm::backward_index(observed, initial, transition, emission, index, ok);
  std::copy(ok.begin(), ok.end(), std::ostream_iterator<T>(std::cout, "\t"));
  std::cout << std::endl;

  // Test next backward
  ok.clear();
  ok.resize(initial.size(), 0);
  for ( std::size_t i = observed.size(); i > 0; --i ) {
    std::cout << "Next Backward (" << i << ")" << std::endl;
    ci::hmm::backward_next(observed, initial, transition, emission, i, ok);
    std::copy(ok.begin(), ok.end(), std::ostream_iterator<T>(std::cout, "\t"));
    std::cout << std::endl;
  }

  typedef std::vector<T> FOO;
  FOO const* foo;
  ci::hmm::details::BackCache< FOO, FOO, std::vector<FOO>, std::vector<FOO>, T > backcheaterA(observed, initial, transition, emission);
  for ( std::size_t i = 0; i < observed.size(); ++i ) {
    std::cout << "Cheat Backward->Forward (" << i << ")" << std::endl;
    foo = backcheaterA.Next();
    std::copy(foo->begin(), foo->end(), std::ostream_iterator<T>(std::cout, "\t"));
    std::cout << std::endl;
  }

  // Test extended next backward
  std::vector< std::vector<T> > dummy(initial.size());
  for ( std::size_t i = 0; i < dummy.size(); ++i )
    dummy[i] = std::vector<T>(initial.size(), 0);

  for ( std::size_t i = observed.size(); i > 0; --i ) {
    std::cout << "(Ext) Next Backward (" << i << ")" << std::endl;
    ci::hmm::backward_enext(observed, initial, transition, emission, i, dummy);
    for ( std::size_t j = 0; j < dummy.size(); ++j ) {
      for ( std::size_t k = 0; k < dummy[j].size(); ++k )
        std::cout << dummy[k][j] << "\t";
     std::cout << std::endl;
    } // for
    std::cout << std::endl;
  } // for


  // Problem 1
  float ans1 = ci::hmm::evalp(observed, initial, transition, emission);
  std::cout << "Answer to problem 1: " << ans1 << std::endl;

  // Problem 2
  // Test viterbi
  std::cout << "Viterbi answer to problem 2" << std::endl;
  std::ostream_iterator<T> os(std::cout, "\t");
  ci::hmm::viterbi(observed, initial, transition, emission, os);
  std::cout << std::endl;

  // Test gamma
  std::cout << "Testing Gamma" << std::endl;
  results.clear();
  results.resize(initial.size());
  for ( std::size_t i = 0; i < results.size(); ++i )
    results[i].resize(observed.size(), 0);
  ci::hmm::gamma_m_full(observed, initial, transition, emission, results);
  for ( std::size_t i = 0; i < results.size(); ++i ) {
    for ( std::size_t j = 0; j < results[i].size(); ++j )
      std::cout << results[i][j] << "\t";
    std::cout << std::endl;
  } // for

  std::cout << "New Gamma" << std::endl;
  std::vector<T> alpha(initial.size(), 0), beta(alpha.size(), 0), gam(alpha.size(), 0);
  ci::hmm::details::BackCache< FOO, FOO, std::vector<FOO>, std::vector<FOO>, T > backcheaterB(observed, initial, transition, emission);
  for ( std::size_t i = 1; i <= observed.size(); ++i ) {
    std::vector<T> const* foo = backcheaterB.Next();
    ci::hmm::gamma(observed, initial, transition, emission, i, *foo, alpha, gam);
    delete foo;
    std::copy(gam.begin(), gam.end(), std::ostream_iterator<T>(std::cout, "\t"));
    std::cout << std::endl;
  } // for

  // Test xi
  std::cout << "Testing xi" << std::endl;

  std::vector< std::vector< std::vector<T> > > v(initial.size());
  for ( std::size_t i = 0; i < v.size(); ++i ) {
    v[i].resize(initial.size());
    for ( std::size_t j = 0; j < v[i].size(); ++j )
      v[i][j].resize(observed.size(), 0); // should be observed.size()-1, but need to compare to old outputs
  }
  ci::hmm::xi_full(observed, initial, transition, emission, v);
  for ( std::size_t i = 0; i < v.size(); ++i ) {
    for ( std::size_t j = 0; j < v[i].size(); ++j ) {
      for ( std::size_t k = 0; k < v[i][j].size(); ++k )
        std::cout << v[i][j][k] << "\t";
      std::cout << std::endl;
    }
    std::cout << std::endl;
  } // for

  std::cout << "YO NEW-XI" << std::endl;
  std::vector< std::vector<T> > v2(initial.size());
  for ( std::size_t i = 0; i < v2.size(); ++i ) {
    v2[i].resize(initial.size());
  }

  ci::hmm::details::BackCache< std::vector<T>, std::vector<T>, std::vector< std::vector<T> >, std::vector< std::vector<T> >, T > backcheater(observed, initial, transition, emission);
  alpha.resize(alpha.size(), 0), beta.resize(beta.size(), 0);
  foo = backcheater.Next(); // must move up one spot in backward->forward direction
  for ( std::size_t s = 1; s < observed.size(); ++s ) {
    std::vector<T> const* foo = backcheater.Next();
    ci::hmm::xi(observed, initial, transition, emission, s, *foo, alpha, v2);
    delete foo;
    for ( std::size_t i = 0; i < v2.size(); ++i ) {
      for ( std::size_t j = 0; j < v2[i].size(); ++j )
        std::cout << v2[i][j] << "\t";
      std::cout << std::endl;
    } // for
  } // for
  std::cout << std::endl;

  // Problem 3
  // Test training
  std::cout << "Problem 3" << std::endl;
  std::cout << "Start Initial" << std::endl;
  for ( std::size_t i = 0; i < initial.size(); ++i )
    std::cout << initial[i] << std::endl;

  std::vector<T> keepobserved(observed), keepinitial(initial);
  std::vector< std::vector<T> > keeptransition(transition), keepemission(emission);

  std::size_t numiter = 2;
  for ( std::size_t i = 0; i < numiter; ++i ) {
    ci::hmm::train_full(observed, initial, transition, emission);
//    dolog(initial, transition, emission);

    std::cout << "Iteration: " << (i+1) << std::endl;

    std::cout << "New Initial" << std::endl;
    for ( std::size_t i = 0; i < initial.size(); ++i )
      std::cout << initial[i] << std::endl;

    std::cout << "New Transition" << std::endl;
    for ( std::size_t i = 0; i < transition.size(); ++i ) {
      for ( std::size_t j = 0; j < transition[i].size(); ++j )
        std::cout << transition[i][j] << "\t";
      std::cout << std::endl;
    } // for

    std::cout << "New Emission" << std::endl;
    for ( std::size_t i = 0; i < emission.size(); ++i ) {
      for ( std::size_t j = 0; j < emission[i].size(); ++j ) {
        if ( emission[i][j] == ci::inf<T>() )
          emission[i][j] = 0;
        std::cout << emission[i][j] << "\t";
      } // for
      std::cout << std::endl;
    } // for
  } // for


  std::cout << "Finale: *********************" << std::endl;

  observed = keepobserved;
  initial = keepinitial;
  transition = keeptransition;
  emission = keepemission;

  std::cout << "New Training" << std::endl;
  for ( std::size_t i = 0; i < numiter; ++i ) {
    ci::hmm::train(observed, initial, transition, emission);

    std::cout << "Iteration " << (i+1) << std::endl;

    std::cout << "New Initial" << std::endl;
    std::cout << initial.size() << std::endl;
    std::cout.flush();
    for ( std::size_t i = 0; i < initial.size(); ++i )
      std::cout << initial[i] << std::endl;
    std::cout.flush();

    std::cout << "New Transition" << std::endl;
    for ( std::size_t i = 0; i < transition.size(); ++i ) {
      for ( std::size_t j = 0; j < transition[i].size(); ++j )
        std::cout << transition[i][j] << "\t";
      std::cout << std::endl;
    } // for

    std::cout << "New Emission" << std::endl;
    for ( std::size_t i = 0; i < emission.size(); ++i ) {
      for ( std::size_t j = 0; j < emission[i].size(); ++j ) {
        if ( emission[i][j] == ci::inf<T>() )
          emission[i][j] = 0;
        std::cout << emission[i][j] << "\t";
      } // for
      std::cout << std::endl;
    } // for
  } // for

  return(0);
}
コード例 #11
0
nlopt_result mlsl_minimize(int n, nlopt_func f, void *f_data,
			   const double *lb, const double *ub, /* bounds */
			   double *x, /* in: initial guess, out: minimizer */
			   double *minf,
			   nlopt_stopping *stop,
			   nlopt_opt local_opt,
			   int Nsamples, /* #samples/iteration (0=default) */
			   int lds) /* random or low-discrepancy seq. (lds) */
{
     nlopt_result ret = NLOPT_SUCCESS;
     mlsl_data d;
     int i;
     pt *p;

     if (!Nsamples)
	  d.N = 4; /* FIXME: what is good number of samples per iteration? */
     else
	  d.N = Nsamples;
     if (d.N < 1) return NLOPT_INVALID_ARGS;

     d.n = n;
     d.lb = lb; d.ub = ub;
     d.stop = stop;
     d.f = f; d.f_data = f_data;
     rb_tree_init(&d.pts, pt_compare);
     rb_tree_init(&d.lms, lm_compare);
     d.s = lds ? nlopt_sobol_create((unsigned) n) : NULL;

     nlopt_set_min_objective(local_opt, fcount, &d);
     nlopt_set_lower_bounds(local_opt, lb);
     nlopt_set_upper_bounds(local_opt, ub);
     nlopt_set_stopval(local_opt, stop->minf_max);

     d.gamma = MLSL_GAMMA;

     d.R_prefactor = sqrt(2./K2PI) * pow(gam(n) * MLSL_SIGMA, 1.0/n);
     for (i = 0; i < n; ++i)
	  d.R_prefactor *= pow(ub[i] - lb[i], 1.0/n);

     /* MLSL also suggests setting some minimum distance from points
	to previous local minimiza and to the boundaries; I don't know
	how to choose this as a fixed number, so I set it proportional
	to R; see also the comments at top.  dlm and dbound are the
	proportionality constants. */
     d.dlm = 1.0; /* min distance/R to local minima (FIXME: good value?) */
     d.dbound = 1e-6; /* min distance/R to ub/lb boundaries (good value?) */
     

     p = alloc_pt(n);
     if (!p) { ret = NLOPT_OUT_OF_MEMORY; goto done; }

     /* FIXME: how many sobol points to skip, if any? */
     nlopt_sobol_skip(d.s, (unsigned) (10*n+d.N), p->x);

     memcpy(p->x, x, n * sizeof(double));
     p->f = f(n, x, NULL, f_data);
     stop->nevals++;
     if (!rb_tree_insert(&d.pts, (rb_key) p)) { 
	  free(p); ret = NLOPT_OUT_OF_MEMORY; 
     }
     if (nlopt_stop_forced(stop)) ret = NLOPT_FORCED_STOP;
     else if (nlopt_stop_evals(stop)) ret = NLOPT_MAXEVAL_REACHED;
     else if (nlopt_stop_time(stop)) ret = NLOPT_MAXTIME_REACHED;
     else if (p->f < stop->minf_max) ret = NLOPT_MINF_MAX_REACHED;

     while (ret == NLOPT_SUCCESS) {
	  rb_node *node;
	  double R;

	  get_minf(&d, minf, x);

	  /* sampling phase: add random/quasi-random points */
	  for (i = 0; i < d.N && ret == NLOPT_SUCCESS; ++i) {
	       p = alloc_pt(n);
	       if (!p) { ret = NLOPT_OUT_OF_MEMORY; goto done; }
	       if (d.s) nlopt_sobol_next(d.s, p->x, lb, ub);
	       else { /* use random points instead of LDS */
		    int j;
		    for (j = 0; j < n; ++j) p->x[j] = nlopt_urand(lb[j],ub[j]);
	       }
	       p->f = f(n, p->x, NULL, f_data);
	       stop->nevals++;
	       if (!rb_tree_insert(&d.pts, (rb_key) p)) { 
		    free(p); ret = NLOPT_OUT_OF_MEMORY;
	       }
	       if (nlopt_stop_forced(stop)) ret = NLOPT_FORCED_STOP;
	       else if (nlopt_stop_evals(stop)) ret = NLOPT_MAXEVAL_REACHED;
	       else if (nlopt_stop_time(stop)) ret = NLOPT_MAXTIME_REACHED;
	       else if (p->f < stop->minf_max) ret = NLOPT_MINF_MAX_REACHED;
	       else {
		    find_closest_pt(n, &d.pts, p);
		    find_closest_lm(n, &d.lms, p);
		    pts_update_newpt(n, &d.pts, p);
	       }
	  }

	  /* distance threshhold parameter R in MLSL */
	  R = d.R_prefactor 
	       * pow(log((double) d.pts.N) / d.pts.N, 1.0 / n);

	  /* local search phase: do local opt. for promising points */
	  node = rb_tree_min(&d.pts);
	  for (i = (int) (ceil(d.gamma * d.pts.N) + 0.5); 
	       node && i > 0 && ret == NLOPT_SUCCESS; --i) {
	       p = (pt *) node->k;
	       if (is_potential_minimizer(&d, p, 
					  R, d.dlm*R, d.dbound*R)) {
		    nlopt_result lret;
		    double *lm;
		    double t = nlopt_seconds();

		    if (nlopt_stop_forced(stop)) {
			 ret = NLOPT_FORCED_STOP; break;
		    }
		    if (nlopt_stop_evals(stop)) {
                         ret = NLOPT_MAXEVAL_REACHED; break;
		    }
		    if (stop->maxtime > 0 &&
			t - stop->start >= stop->maxtime) {
			 ret = NLOPT_MAXTIME_REACHED; break;
		    }
		    lm = (double *) malloc(sizeof(double) * (n+1));
		    if (!lm) { ret = NLOPT_OUT_OF_MEMORY; goto done; }
		    memcpy(lm+1, p->x, sizeof(double) * n);
		    lret = nlopt_optimize_limited(local_opt, lm+1, lm,
						  stop->maxeval - stop->nevals,
						  stop->maxtime -
						  (t - stop->start));
		    p->minimized = 1;
		    if (lret < 0) { free(lm); ret = lret; goto done; }
		    if (!rb_tree_insert(&d.lms, lm)) { 
			 free(lm); ret = NLOPT_OUT_OF_MEMORY;
		    }
		    else if (nlopt_stop_forced(stop)) ret = NLOPT_FORCED_STOP;
		    else if (*lm < stop->minf_max) 
			 ret = NLOPT_MINF_MAX_REACHED;
		    else if (nlopt_stop_evals(stop))
			 ret = NLOPT_MAXEVAL_REACHED;
		    else if (nlopt_stop_time(stop))
			 ret = NLOPT_MAXTIME_REACHED;
		    else
			 pts_update_newlm(n, &d.pts, lm);
	       }

	       /* TODO: additional stopping criteria based
		  e.g. on improvement in function values, etc? */
	       
	       node = rb_tree_succ(node);
	  }
     }

     get_minf(&d, minf, x);

 done:
     nlopt_sobol_destroy(d.s);
     rb_tree_destroy_with_keys(&d.lms);
     rb_tree_destroy_with_keys(&d.pts);
     return ret;
}