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); }
/*----------------------------------------------------------------------------*/ 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; } }