static ssize_t dev_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)
{
	int ret;
	unsigned char str[] = {'0', '1' };

	if (count == 0) {
		return 0;
	}

	ret = copy_to_user(buffer, str + get_bl(), sizeof(unsigned char) ) ? -EFAULT : 0;
	if (ret) {
		return ret;
	}

	return sizeof(unsigned char);
}
Exemplo n.º 2
0
/*----------------------------------------------------------------------------*/
void NOMAD::Directions::compute ( std::list<NOMAD::Direction> & dirs		,
                                 NOMAD::poll_type              poll			,
                                 const NOMAD::OrthogonalMesh  & mesh		)
{
    
    dirs.clear();
    
    // categorical variables: do nothing:
    if ( _is_categorical )
        return;
    
    // binary variables: we use special directions:
    if ( _is_binary )
    {
        compute_binary_directions ( dirs );
        return;
    }
    
    NOMAD::Double                               pow_gps , cst;
    const NOMAD::Direction                    * bl;
    NOMAD::Direction                          * pd;
    int                                         i , j , k , hat_i;
    std::list<NOMAD::Direction>::iterator it2 , end2;
    
    const NOMAD::Point mesh_indices=mesh.get_mesh_indices();
    int mesh_index=int(mesh_indices[0].value()); // single mesh_index used only for isotropic mesh
    
    
    /*-----------------------------------*/
    /*  loop on the types of directions  */
    /*-----------------------------------*/
    const std::set<NOMAD::direction_type> & dir_types =
    (poll == NOMAD::PRIMARY) ? _direction_types : _sec_poll_dir_types;
    
    std::set<NOMAD::direction_type>::const_iterator it , end = dir_types.end() ;
    for ( it = dir_types.begin() ; it != end ; ++it )
    {
        
        if ( *it == NOMAD::UNDEFINED_DIRECTION ||
            *it == NOMAD::NO_DIRECTION        ||
            *it == NOMAD::MODEL_SEARCH_DIR       )
            continue;
        
        /*--------------------------------------------------*/
        /*  Ortho-MADS                                      */
        /* ---> dirs are on a unit n-sphere by construction */
        /*--------------------------------------------------*/
        if ( NOMAD::dir_is_orthomads (*it) )
        {
            bool success_dir;
            
            
            NOMAD::Direction dir ( _nc , 0.0 , *it );
            NOMAD::Double    alpha_t_l;
            
            success_dir=compute_dir_on_unit_sphere ( dir );
            
            if ( success_dir )
            {
#ifdef DEBUG
                if ( dynamic_cast<const NOMAD::XMesh*> ( &mesh ) )
                {
                    _out << std::endl
                    << NOMAD::open_block ( "compute Ortho-MADS directions with XMesh" )
                    << "type              = " << *it << std::endl;
                    NOMAD::Point mesh_indices=mesh.get_mesh_indices();
                    _out<< "Mesh indices  = ( ";
                    mesh_indices.NOMAD::Point::display( _out, " " , -1 , -1 );
                    _out << " )" << std::endl;
                    _out<< "Unit sphere Direction  = ( ";
                    dir.NOMAD::Point::display ( _out , " " , -1 , -1 );
                    _out << " )" << std::endl << NOMAD::close_block();
                }
                else if ( dynamic_cast<const NOMAD::SMesh*> ( &mesh ) )
                {
                    _out << std::endl
                    << NOMAD::open_block ( "compute Ortho-MADS directions with SMesh" )
                    << "type              = " << *it
                    << " on isotropic mesh " << std::endl
                    << "mesh index   (lk) = " << mesh_index   << std::endl
                    << "alpha     (tk,lk) = " << alpha_t_l    << std::endl
                    << "Unit sphere Direction  = ( ";
                    dir.NOMAD::Point::display ( _out , " " , -1 , -1 );
                    _out << " )" << std::endl << NOMAD::close_block();
                    
                }
                
#endif
                // Ortho-MADS 2n and n+1:
                // ----------------------
                if ( *it == NOMAD::ORTHO_2N || *it == NOMAD::ORTHO_NP1_QUAD || *it == NOMAD::ORTHO_NP1_NEG )
                {
                    
                    // creation of the 2n directions:
                    // For ORTHO_NP1 the reduction from 2N to N+1 is done in MADS::POLL
                    NOMAD::Direction ** H = new NOMAD::Direction * [2*_nc];
                    
                    // Ordering D_k alternates Hk and -Hk instead of [H_k -H_k]
                    for ( i = 0 ; i < _nc ; ++i )
                    {
                        dirs.push_back ( NOMAD::Direction ( _nc , 0.0 , *it ) );
                        H[i    ] = &(*(--dirs.end()));
                        dirs.push_back ( NOMAD::Direction ( _nc , 0.0 , *it ) );
                        H[i+_nc] = &(*(--dirs.end()));
                    }
                    
                    // Householder transformations on the 2n directions on a unit n-sphere:
                    householder ( dir , true , H );
                    
                    
                    delete [] H;
                    
                    
                }
                
                // Ortho-MADS 1 or Ortho-MADS 2:
                // -----------------------------
                else
                {
                    dirs.push_back ( dir );
                    if ( *it == NOMAD::ORTHO_2 )
                        dirs.push_back ( -dir );
                }
            }
        }
        
        /*--------------------------------*/
        /*  LT-MADS                       */
        /* ---> dirs NOT on unit n-sphere */
        /*--------------------------------*/
        else if ( NOMAD::dir_is_ltmads (*it) )
        {
            
            if ( !_lt_initialized)
                lt_mads_init();
            
            bl = get_bl ( mesh , *it , hat_i );
            
            // LT-MADS 1 or LT-MADS 2: -b(l) and/or b(l):
            // ------------------------------------------
            if ( *it == NOMAD::LT_1 || *it == NOMAD::LT_2 )
            {
                dirs.push_back ( - *bl );
                if ( *it == NOMAD::LT_2 )
                    dirs.push_back ( *bl );
            }
            
            // LT-MADS 2n or LT-MADS n+1:
            // --------------------------
            else {
                
                // row permutation vector:
                int * row_permutation_vector  = new int [_nc];
                row_permutation_vector[hat_i] = hat_i;
                
                NOMAD::Random_Pickup rp ( _nc );
                
                for ( i = 0 ; i < _nc ; ++i )
                    if ( i != hat_i )
                    {
                        j = rp.pickup();
                        if ( j == hat_i )
                            j = rp.pickup();
                        row_permutation_vector[i] = j;
                    }
                
                rp.reset();
                
                for ( j = 0 ; j < _nc ; ++j )
                {
                    i = rp.pickup();
                    if ( i != hat_i )
                    {
                        
                        dirs.push_back ( NOMAD::Direction ( _nc , 0.0 , *it ) );
                        pd = &(*(--dirs.end()));
                        
                        create_lt_direction ( mesh , *it , i , hat_i , pd );
                        permute_coords ( *pd , row_permutation_vector );
                    }
                    else
                        dirs.push_back ( *bl );
                    
                    // completion to maximal basis:
                    if ( *it == NOMAD::LT_2N )
                        dirs.push_back ( NOMAD::Direction ( - *(--dirs.end()) , NOMAD::LT_2N ) );
                    
                }
                
                delete [] row_permutation_vector;
                
                // completion to minimal basis:
                if ( *it == NOMAD::LT_NP1 )
                {
                    dirs.push_back ( NOMAD::Direction ( _nc , 0.0 , NOMAD::LT_NP1 ) );
                    pd = &(*(--dirs.end()));
                    
                    end2 = --dirs.end();
                    for ( it2 = dirs.begin() ; it2 != end2 ; ++it2 )
                    {
                        for ( i = 0 ; i < _nc ; ++i )
                            (*pd)[i] -= (*it2)[i];
                    }
                }
            }
            
            
        }
        
        /*--------------------------------*/
        /*  GPS                           */
        /* ---> dirs NOT on unit n-sphere */
        /*--------------------------------*/
        else
        {
            
            // GPS for binary variables: should'nt be here:
            if ( *it == NOMAD::GPS_BINARY )
            {
#ifdef DEBUG
                _out << std::endl << "Warning (" << "Directions.cpp" << ", " << __LINE__
                << "): tried to generate binary directions at the wrong place)"
                << std::endl << std::endl;
#endif
                dirs.clear();
                return;
            }
            
            // this value represents the non-zero values in GPS directions
            // (it is tau^{|ell_k|/2}, and it is such that delta_k * pow_gps = Delta_k):
            if ( !pow_gps.is_defined() )
                pow_gps = pow ( mesh.get_update_basis() , abs(mesh_index) / 2.0 );
            
            // GPS 2n, static:
            // ---------------
            
            if ( *it == NOMAD::GPS_2N_STATIC )
            {
                for ( i = 0 ; i < _nc ; ++i )
                {
                    dirs.push_back ( NOMAD::Direction ( _nc , 0.0 , NOMAD::GPS_2N_STATIC ) );
                    pd = &(*(--dirs.end()));
                    (*pd)[i] = pow_gps;
                    
                    dirs.push_back ( NOMAD::Direction ( _nc , 0.0 , NOMAD::GPS_2N_STATIC ) );
                    pd = &(*(--dirs.end()));
                    (*pd)[i] = -pow_gps;
                }
            }
            
            // GPS 2n, random:
            // ---------------
            else if ( *it == NOMAD::GPS_2N_RAND )
            {
                
                int v , cnt;
                
                std::list  <int>::const_iterator end3;
                std::list  <int>::iterator       it3;
                std::list  <int> rem_cols;
                std::vector<int> rem_col_by_row ( _nc );
                
                // creation of the 2n directions:
                std::vector<NOMAD::Direction *> pdirs ( 2 * _nc );
                
                for ( i = 0 ; i < _nc ; ++i )
                {
                    
                    dirs.push_back ( NOMAD::Direction ( _nc , 0.0 , NOMAD::GPS_2N_RAND ) );
                    pdirs[i] = &(*(--dirs.end()));
                    (*pdirs[i])[i] = pow_gps;
                    
                    dirs.push_back ( NOMAD::Direction ( _nc , 0.0 , NOMAD::GPS_2N_RAND ) );
                    pdirs[i+_nc] = &(*(--dirs.end()));
                    (*pdirs[i+_nc])[i] = -pow_gps;
                    
                    rem_cols.push_back(i);
                    rem_col_by_row[i] = i;
                }
                
                // random perturbations:
                for ( i = 1 ; i < _nc ; ++i )
                {
                    if ( rem_col_by_row[i] > 0 )
                    {
                        v = NOMAD::RNG::rand()%3 - 1; // v in { -1 , 0 , 1 }
                        if ( v )
                        {
                            
                            // we decide a (i,j) couple:
                            k    = NOMAD::RNG::rand()%(rem_col_by_row[i]);
                            cnt  = 0;
                            end3 = rem_cols.end();
                            it3  = rem_cols.begin();
                            while ( cnt != k )
                            {
                                ++it3;
                                ++cnt;
                            }
                            j = *it3;
                            
                            // the perturbation:
                            (*pdirs[i])[j] = (*pdirs[j+_nc])[i] = -v * pow_gps;
                            (*pdirs[j])[i] = (*pdirs[i+_nc])[j] =  v * pow_gps;
                            
                            // updates:
                            rem_cols.erase(it3);
                            it3 = rem_cols.begin();
                            while ( *it3 != i )
                                ++it3;
                            rem_cols.erase(it3);
                            for ( k = i+1 ; k < _nc ; ++k )
                                rem_col_by_row[k] -= j<k ? 2 : 1;
                        }
                    }
                }
            }
            
            // GPS n+1, static:
            // ----------------
            else if ( *it == NOMAD::GPS_NP1_STATIC )
            {
                
                // (n+1)^st direction:
                dirs.push_back ( NOMAD::Direction ( _nc , -pow_gps , NOMAD::GPS_NP1_STATIC ) );
                
                // first n directions:
                for ( i = 0 ; i < _nc ; ++i )
                {
                    dirs.push_back ( NOMAD::Direction ( _nc , 0.0 , NOMAD::GPS_NP1_STATIC ) );
                    pd = &(*(--dirs.end()));
                    (*pd)[i] = pow_gps;
                }
            }
            
            // GPS n+1, random:
            // ----------------
            else if ( *it == NOMAD::GPS_NP1_RAND )
            {
                
                // (n+1)^st direction:
                dirs.push_back ( NOMAD::Direction ( _nc , 0.0 , NOMAD::GPS_NP1_RAND ) );
                NOMAD::Direction * pd1 = &(*(--dirs.end()));
                
                NOMAD::Double d;
                
                // first n directions:
                for ( i = 0 ; i < _nc ; ++i )
                {
                    dirs.push_back ( NOMAD::Direction ( _nc , 0.0 , NOMAD::GPS_NP1_RAND ) );
                    pd = &(*(--dirs.end()));
                    
                    d = NOMAD::RNG::rand()%2 ? -pow_gps : pow_gps;
                    (*pd )[i] =  d;
                    (*pd1)[i] = -d;
                }
            }
            
            // GPS n+1, static, uniform angles:
            // --------------------------------
            else if ( *it == NOMAD::GPS_NP1_STATIC_UNIFORM )
            {
                
                cst = pow_gps * sqrt(static_cast<double>(_nc)*(_nc+1))/_nc;
                
                // n first directions:
                for ( j = _nc-1 ; j >= 0 ; --j )
                {
                    dirs.push_back ( NOMAD::Direction ( _nc , 0.0 , NOMAD::GPS_NP1_STATIC_UNIFORM ) );
                    pd = &(*(--dirs.end()));
                    
                    k = _nc-j-1;
                    
                    for ( i = 0 ; i < k ; ++i )
                        (*pd)[i] = -cst / sqrt(static_cast<double>(_nc-i)*(_nc-i+1));
                    
                    (*pd)[k] = (cst * (j+1)) / sqrt(static_cast<double>(j+1)*(j+2));
                    
                }
                
                // (n+1)^st direction:
                dirs.push_back ( NOMAD::Direction ( _nc , 0.0 , NOMAD::GPS_NP1_STATIC_UNIFORM ) );
                pd = &(*(--dirs.end()));
                for ( i = 0 ; i < _nc ; ++i )
                    (*pd)[i] = -cst / sqrt(static_cast<double>(_nc-i)*(_nc-i+1));
                
            }
            
            // GPS n+1, random, uniform angles:
            // --------------------------------
            // (we apply the procedure defined in
            // "Pattern Search Methods for user-provided points:
            // application to molecular geometry problems",
            // by Alberto, Nogueira, Rocha and Vicente,
            // SIOPT 14-4, 1216-1236, 2004, doi:10.1137/S1052623400377955)
            else if ( *it == NOMAD::GPS_NP1_RAND_UNIFORM )
            {
                
                cst = pow_gps * sqrt(static_cast<double>(_nc)*(_nc+1))/_nc;
                
                // n first directions:
                for ( j = _nc-1 ; j >= 0 ; --j )
                {
                    dirs.push_back ( NOMAD::Direction ( _nc , 0.0 , NOMAD::GPS_NP1_STATIC_UNIFORM ) );
                    pd = &(*(--dirs.end()));
                    
                    k = _nc-j-1;
                    
                    for ( i = 0 ; i < k ; ++i )
                        (*pd)[i] = -cst / sqrt(static_cast<double>(_nc-i)*(_nc-i+1));
                    
                    (*pd)[k] = (cst * (j+1)) / sqrt(static_cast<double>(j+1)*(j+2));
                    
                }
                
                // (n+1)^st direction:
                dirs.push_back ( NOMAD::Direction ( _nc , 0.0 , NOMAD::GPS_NP1_STATIC_UNIFORM ) );
                pd = &(*(--dirs.end()));
                for ( i = 0 ; i < _nc ; ++i )
                    (*pd)[i] = -cst / sqrt(static_cast<double>(_nc-i)*(_nc-i+1));
                
                // random perturbations:
                NOMAD::Random_Pickup                  rp   ( _nc );
                std::vector<bool>                     done ( _nc );
                bool                                  chg_sgn;
                std::list<NOMAD::Direction>::iterator it;
                NOMAD::Double                         tmp;
                
                end2 = dirs.end();
                for ( i = 0 ; i < _nc ; ++i )
                    done[i] = false;
                
                for ( i = 0 ; i < _nc ; ++i )
                {
                    k = rp.pickup();
                    if ( i != k && !done[i] )
                    {
                        chg_sgn = ( NOMAD::RNG::rand()%2 != 0 );
                        
                        for ( it = dirs.begin() ; it != end2 ; ++it )
                        {
                            tmp      = (*it)[i];
                            (*it)[i] = ( chg_sgn ? -1.0 : 1.0 ) * (*it)[k];
                            (*it)[k] = tmp;
                        }
                        
                        done[i] = done[k] = true;
                    }
                    else
                        if ( NOMAD::RNG::rand()%2 )
                            for ( it = dirs.begin() ; it != end2 ; ++it )
                                (*it)[i] = -(*it)[i];
                }
            }
        }
    } // end of loop on the types of directions
    
    // The direction are unscaled on a unit n-sphere when necessary (that is directions that are not orthomads)
    for ( it2 = dirs.begin() ; it2 != dirs.end() ; ++it2 )
        if ( ! NOMAD::dir_is_orthomads ( it2->get_type() ) )
        {
            NOMAD::Double norm_dir=it2->norm();
            for (int i=0 ; i < _nc ; ++i )
                (*it2)[i] /= norm_dir;
        }
    
}