/*----------------------------------------------------------------*/
bool NOMAD::Directions::compute_one_direction ( NOMAD::Direction & dir,
											   int mesh_index,
											   int halton_index  )    
{
	dir.clear();
	
	// categorical variables: do nothing:
	if ( _is_categorical )
		return false;
	
	/*-------------------------------*/
	/*        binary variables       */
	/*  (we use a random direction)  */
	/*-------------------------------*/
	if ( _is_binary ) {
		
		dir.reset     ( _nc , 0.0         );
		dir.set_type  ( NOMAD::GPS_BINARY );
		dir[NOMAD::RNG::rand()%_nc] = (NOMAD::RNG::rand()%2) ? -1.0 : 1.0; 
	}
	
	/*----------------*/
	/*  Ortho-MADS  */
	/*----------------*/
	else if ( _is_orthomads ) {
			
			if ( !_primes )
				ortho_mads_init ( _halton_seed );
			
			dir.reset    ( _nc , 0.0      );
			dir.set_type ( NOMAD::ORTHO_1 );
			
			NOMAD::Double alpha_t_l;
			
			if ( !compute_halton_dir ( halton_index , mesh_index , alpha_t_l , dir ) )
				return false;		  
//		}
	}
	
	/*-------------*/
	/*  LT-MADS 1  */
	/*-------------*/
	else {
		if ( !_lt_initialized)
			lt_mads_init();
		int hat_i;
		dir = *get_bl ( mesh_index , NOMAD::LT_1 , hat_i );  
	}
	
	return true;
}
/*-----------------------------------------------------------------------------*/
bool NOMAD::Directions::compute_dir_on_unit_sphere ( NOMAD::Direction	& random_dir ) const
{
    
    int           i;
    NOMAD::Double norm,d;
    
    for ( i = 0 ; i < _nc ; ++i )
        random_dir[i]=NOMAD::RNG::normal_rand(0,1);
    
    norm=random_dir.norm();
    
    if ( norm==0 )
        return false;
    
    
    for ( i = 0 ; i < _nc ; ++i )
        random_dir[i]/=norm;
    
    return true;
    
}
/*----------------------------------------------------------------*/
void NOMAD::Directions::householder ( const NOMAD::Direction  & halton_dir     ,
				      bool                      complete_to_2n ,
				      NOMAD::Direction       ** H                ) const
{
  int i , j;

  NOMAD::Double norm2 = halton_dir.squared_norm() , v , h2i;

  for ( i = 0 ; i < _nc ; ++i ) {
    
    h2i = 2 * halton_dir[i];

    for ( j = 0 ; j < _nc ; ++j ) {

      // H[i]:
      (*H[i])[j] = v = (i==j) ? norm2 - h2i * halton_dir[j] : - h2i * halton_dir[j];

      // -H[i]:
      if ( complete_to_2n )
	(*H[i+_nc])[j] = -v;
    }
  }
}
/*---------------------------------------------------------*/
bool NOMAD::Directions::compute_halton_dir ( int                halton_index ,
					     int                mesh_index   ,
					     NOMAD::Double    & alpha_t_l    ,
					     NOMAD::Direction & halton_dir     ) const
{
  alpha_t_l.clear();

  int           i;
  NOMAD::Double d , norm = 0.0;
  NOMAD::Point  b ( _nc );

  for ( i = 0 ; i < _nc ; ++i ) 
  {
    d = Directions::get_phi ( halton_index , _primes[i] );
    b[i] = 2*d - 1.0;
    norm += b[i].pow2();
  }
  norm = norm.sqrt();

  // desired squared norm for q:

  NOMAD::direction_type hdt = halton_dir.get_type();

  NOMAD::Double target = ( hdt == NOMAD::ORTHO_2N || hdt == NOMAD::ORTHO_NP1_QUAD || hdt == NOMAD::ORTHO_NP1_NEG ) ?
    pow ( NOMAD::Mesh::get_mesh_update_basis() , abs(mesh_index) / 2.0 ) :
    pow ( NOMAD::Mesh::get_mesh_update_basis() , abs(mesh_index)       );
	

  NOMAD::Double x  = target.sqrt();
  NOMAD::Double fx = eval_ortho_norm ( x , norm , b , halton_dir );
  NOMAD::Double y  = 1.0 , fy , delta_x , abs_dx , min , delta_min , diff , eps;
  bool          inc , possible , set_eps = false;
  int           cnt = 0;

  while ( fx != target )
  {
	  
	  // safety test:
	  if ( ++cnt > 1000 )
	  {
#ifdef DEBUG
		  _out << std::endl << "Warning (" << "Directions.cpp" << ", " << __LINE__
		  << "): could not compute Halton direction for (t="
		  << halton_index << ", ell=" << mesh_index
		  << ")" << std::endl << std::endl;
#endif
		  alpha_t_l.clear();
		  halton_dir.clear();
		  return false;
	  }
	  
	  if ( set_eps ) 
	  {
		  eps     = 1e-8;
		  set_eps = false;
	  }
	  else
		  eps = 0.0;
	  
	  inc = ( fx < target );
	  
	  possible = false;
	  min      = 1e+20;
	  for ( i = 0 ; i < _nc ; ++i ) 
	  {
		  if ( b[i] != 0.0 ) 
		  {
			  if ( b[i] > 0.0 )
			  {
				  if ( inc )
					  diff  =  0.5+eps;
				  else
					  diff  = -0.5-eps;
			  }
			  else 
			  {
				  if ( inc )
					  diff  = -0.5-eps;
				  else
					  diff  =  0.5+eps;
			  }
			  
			  delta_x = norm * ( halton_dir[i] + diff) / b[i] - x;
			  
			  y = x + delta_x;
			  
			  if ( y > 0 )
			  {
				  abs_dx = delta_x.abs();
				  if ( abs_dx < min )
				  {
					  min       = abs_dx;
					  delta_min = delta_x;
					  possible  = true;
				  }
			  }
		  }
	  }
	  
	  if ( !possible ) {
#ifdef DEBUG
		  _out << std::endl << "Warning (" << "Directions.cpp" << ", " << __LINE__
		  << "): could not compute Halton direction for (t="
		  << halton_index << ", ell=" << mesh_index << ")"
		  << std::endl << std::endl;
#endif
		  alpha_t_l.clear();
		  halton_dir.clear();
		  return false;
	  }
	  
	  y  = x + delta_min;
	  fy = eval_ortho_norm ( y , norm , b , halton_dir );
	  
	  if ( fx == fy ) {
		  set_eps = true;
		  continue;
	  }
	  
	  if ( fy==target )
		  break;
	  
	  if ( inc && fy > target && fx > 0 ) {
		  eval_ortho_norm ( x , norm , b , halton_dir );
		  break;
	  }
	  
	  if ( !inc && fy < target && fy > 0 )
		  break;
	  
	  x  = y;
	  fx = fy;
  }

  alpha_t_l = y;

  return true;
}
Exemple #5
0
 /// Reset the infeasible successful direction.
 void reset_infeas_success_dir ( void ) const { _infeas_success_dir.clear(); }
/*---------------------------------------------------------*/
void NOMAD::Variable_Group::get_directions ( std::list<NOMAD::Direction> & dirs               ,
											NOMAD::poll_type              poll               ,
											const NOMAD::Point          & poll_center        ,
											int                           mesh_index         ,
											const NOMAD::Direction      & feas_success_dir   ,
											const NOMAD::Direction      & infeas_success_dir   )
{
	
	int nc = static_cast<int>(_var_indexes.size());	
	
	// vectors are of size nc :
	// ------------------------
	if ( nc == poll_center.size() ) {
		
		_directions->compute ( dirs               ,
							  poll               ,
							  poll_center        ,
							  mesh_index         ,
							  -1                 ,
							  feas_success_dir   ,
							  infeas_success_dir   );
		return;
	}
	
	// construct vectors of size nc from vectors of size < nc :
	// --------------------------------------------------------
	std::set<int>::const_iterator it ;
	int                           i = 0;
	
	NOMAD::Point     new_poll_center ( nc );
	NOMAD::Direction new_fsd , new_isd;  
		
	if ( feas_success_dir.is_defined() )
		new_fsd = NOMAD::Direction ( nc , 0.0 , feas_success_dir.get_type() );
	
	if ( infeas_success_dir.is_defined() )
		new_isd = NOMAD::Direction ( nc , 0.0 , infeas_success_dir.get_type() );
		
	for ( it = _var_indexes.begin() ; it != _var_indexes.end() ; ++it )
	{
		
		new_poll_center[i] = poll_center[*it];
		
		if ( feas_success_dir.is_defined() )
			new_fsd[i] = feas_success_dir  [*it];
		
		if ( infeas_success_dir.is_defined() )
			new_isd[i] = infeas_success_dir[*it];
				
		++i;
	}
	
	_directions->compute ( dirs              ,
						  poll              ,
						  new_poll_center   ,
						  mesh_index        ,
						  -1                ,
						  new_fsd           ,
						  new_isd             );
	
}