( floor ( sqrt(180.0*n) ) );
if ( pmax > 100 )
pmax = 100;
if ( pmax < 30 )
pmax = 30;
if ( pmax < pmin )
pmax = pmin;
return true;
}
// TGP precise mode: pmin=n+1 and pmax=100
// -----------------
if ( _tgp_mode == NOMAD::TGP_PRECISE ) {
pmin = n+1;
pmax = 100;
return true;
}
// TGP user mode: pmin=n+1 and pmax is user decided with constructor 2/2
// --------------
if ( _tgp_mode == NOMAD::TGP_USER ) {
pmin = n+1;
pmax = _usr_pmax;
if ( pmax < pmin ) {
std::ostringstream oss;
oss << "user pmax value must be > " << n;
_error_str = oss.str();
return false;
}
return true;
}
return true;
}
/*----------------------------------------------*/
/* get the TGP BTE parameters (private) */
/*----------------------------------------------*/
bool NOMAD::TGP_Model::get_BTE ( int BTE[3] )
{
// fast TGP mode:
// --------------
// . if p=pmin, then B=2000
// . if p=pmax, then B=1000
// . if pmin ( 10.0 * floor ( (a * _p + b) / 10.0 ) );
BTE[1] = 3*BTE[0];
BTE[2] = 10;
}
// precise TGP mode:
// -----------------
else if ( _tgp_mode == NOMAD::TGP_PRECISE ) {
BTE[0] = 2000;
BTE[1] = 7000;
BTE[2] = 2;
}
// user mode:
// ----------
else {
BTE[0] = _usr_BTE[0];
BTE[1] = _usr_BTE[1];
BTE[2] = _usr_BTE[2];
// check the user BTE parameters:
if ( BTE[0] <= 0 ||
BTE[1] <= 0 ||
BTE[2] <= 0 ||
BTE[1] <= BTE[0] ) {
_error_str = "error with user BTE";
return false;
}
}
return true;
}
/*--------------------------------------------------------------*/
/* compute the ranges, check the fixed variables, set the */
/* different indexes, and return the number of free variables */
/* (private) */
/*--------------------------------------------------------------*/
int NOMAD::TGP_Model::check_fixed_variables
( const std::list & X ,
bool remove_fv )
{
int i;
if ( !_av_index ) {
_av_index = new int [_n0];
for ( i = 0 ; i < _n0 ; ++i )
_av_index[i] = -1;
}
_lb = NOMAD::Point ( _n0 );
_ub = NOMAD::Point ( _n0 );
_fv = NOMAD::Point ( _n0 );
// compute ranges:
std::list::const_iterator it , end = X.end();
for ( it = X.begin() ; it != end ; ++it ) {
for ( i = 0 ; i < _n0 ; ++i ) {
if ( !_lb[i].is_defined() || (**it)[i] < _lb[i] )
_lb[i] = (**it)[i];
if ( !_ub[i].is_defined() || (**it)[i] > _ub[i] )
_ub[i] = (**it)[i];
}
}
// compute n (number of free variables), the fixed variables, and the indexes:
int n = 0;
std::vector fv_index_tmp;
for ( i = 0 ; i < _n0 ; ++i ) {
if ( remove_fv && _lb[i] == _ub[i] ) {
_fv [i] = _lb[i];
_av_index[i] = -1;
}
else {
fv_index_tmp.push_back ( i );
_av_index[i] = n++;
}
}
// complete the fixed var index construction:
if ( _fv_index )
delete [] _fv_index;
_fv_index = NULL;
if ( n > 0 ) {
_fv_index = new int[n];
for ( i = 0 ; i < n ; ++i )
_fv_index[i] = fv_index_tmp[i];
}
return n;
}
/*--------------------------------------------------------*/
/* filter and sort an interpolation set X (private) */
/* . the points are sorted relatively to the distance */
/* from the center */
/* . if the center is not defined (equal to NULL), */
/* an alternate center is constructed */
/*--------------------------------------------------------*/
int NOMAD::TGP_Model::filter_and_sort_X
( const std::vector & X ,
const NOMAD::Point * center ,
std::list & filtered_X ) const
{
NOMAD::Point alt_center;
const NOMAD::Eval_Point * cur = NULL;
int p0 = X.size() , i;
// alternate center if center==NULL:
if ( !center ) {
int j;
NOMAD::Point lb(_n0) , ub(_n0);
for ( i = 0 ; i < p0 ; ++i ) {
cur = X[i];
if ( test_interpolation_point ( cur ) ) {
for ( j = 0 ; j < _n0 ; ++j ) {
if ( !lb[j].is_defined() || (*cur)[j] < lb[j] )
lb[j] = (*cur)[j];
if ( !ub[j].is_defined() || (*cur)[j] > ub[j] )
ub[j] = (*cur)[j];
}
}
}
alt_center = NOMAD::Point(_n0);
for ( j = 0 ; j < _n0 ; ++j )
alt_center[j] = ( lb[j] + ub[j] ) / 2.0;
}
// X_tmp is used to sort the points:
std::multiset tmp_X;
for ( i = 0 ; i < p0 ; ++i ) {
cur = X[i];
// test if the interpolation point is valid for interpolation:
if ( test_interpolation_point ( cur ) ) {
NOMAD::Model_Sorted_Point sorted_pt
( &NOMAD::Cache::get_modifiable_point (*cur) ,
(center) ? *center : alt_center );
tmp_X.insert ( sorted_pt );
}
}
// copy the set X_tmp to filtered_X:
std::multiset::const_iterator it , end = tmp_X.end();
for ( it = tmp_X.begin() ; it != end ; ++it )
filtered_X.push_back ( static_cast ( it->get_point() ) );
return filtered_X.size();
}
/*-----------------------------------------------------*/
/* tests to check if an interpolation point is valid */
/* (private) */
/*-----------------------------------------------------*/
bool NOMAD::TGP_Model::test_interpolation_point ( const NOMAD::Eval_Point * x ) const
{
if ( !x || x->size() != _n0 || !x->is_eval_ok() )
return false;
int m = _bbot.size();
const NOMAD::Point & bbo = x->get_bb_outputs();
if ( bbo.size() != m )
return false;
for ( int j = 0 ; j < m ; ++j )
if ( ( _bbot[j] == NOMAD::OBJ || NOMAD::bbot_is_constraint(_bbot[j]) ) &&
( !bbo[j].is_defined() || bbo[j].abs() > NOMAD::MODEL_MAX_OUTPUT ) )
return false;
// point is valid:
return true;
}
/*--------------------------------------------*/
/* compute the models (one for each output) */
/*--------------------------------------------*/
bool NOMAD::TGP_Model::compute
( std::vector & XX_pts , // IN/OUT
bool compute_Ds2x , // IN
bool compute_improv , // IN
bool pred_outside_bnds ) // IN
{
_model_computed = false;
if ( !_error_str.empty() )
return false;
int i , j , index_obj = -1 , n_XX0 = XX_pts.size() , m = _bbot.size();
// check bbot: there must be exactly one objective:
for ( i = 0 ; i < m ; ++i ) {
if ( _bbot[i] == NOMAD::OBJ ) {
if ( index_obj < 0 )
index_obj = i;
else {
_error_str = "more than one objective";
return false;
}
}
}
if ( index_obj < 0 ) {
_error_str = "no objective";
return false;
}
// check n_XX0:
if ( n_XX0 == 0 ) {
_error_str = "no user-provided prediction point";
return false;
}
// reset XX_pts outputs:
for ( i = 0 ; i < n_XX0 ; ++i ) {
for ( j = 0 ; j < m ; ++j )
XX_pts[i]->set_bb_output ( j , NOMAD::Double() );
XX_pts[i]->set_eval_status ( NOMAD::EVAL_FAIL );
}
// create the XX matrix (prediction points):
std::vector XX_filtered_pts;
NOMAD::Eval_Point * cur2;
// the list of points has to be filtered:
NOMAD::Double tmp;
bool chk;
for ( i = 0 ; i < n_XX0 ; ++i ) {
if ( XX_pts[i]->size() == _n0 ) {
cur2 = XX_pts[i];
chk = true;
for ( j = 0 ; j < _n0 ; ++j ) {
tmp = (*cur2)[j];
if ( !pred_outside_bnds && ( tmp < _lb[j] || tmp > _ub[j] ) ) {
chk = false;
break;
}
}
if ( chk )
XX_filtered_pts.push_back ( cur2 );
}
}
if ( _XX ) {
for ( i = 0 ; i < _n_XX ; ++i )
delete [] _XX[i];
delete [] _XX;
}
_n_XX = XX_filtered_pts.size();
if ( _n_XX == 0 ) {
_error_str = "no prediction point after filtering";
return false;
}
_XX = new double * [_n_XX];
for ( i = 0 ; i < _n_XX ; ++i ) {
_XX[i] = new double[_n];
for ( j = 0 ; j < _n ; ++j )
_XX[i][j] = (*XX_filtered_pts[i])[_fv_index[j]].value();
}
// Xsplit: X+XX: size = nsplit x n:
int nsplit = _p + _n_XX;
double ** Xsplit = new double * [nsplit];
for ( i = 0 ; i < _p ; ++i ) {
Xsplit[i] = new double [_n];
for ( j = 0 ; j < _n ; ++j )
Xsplit[i][j] = _X[i][j];
}
for ( i = _p ; i < nsplit ; ++i ) {
Xsplit[i] = new double [_n];
for ( j = 0 ; j < _n ; ++j )
Xsplit[i][j] = _XX[i-_p][j];
}
// get the rectangle:
if ( _tgp_rect )
delete_matrix ( _tgp_rect );
_tgp_rect = get_data_rect ( Xsplit , nsplit , _n );
// TGP parameters:
Params tgp_params ( _n );
double * dparams = NOMAD::TGP_Model::get_TGP_dparams ( _n );
tgp_params.read_double ( dparams );
delete [] dparams;
int BTE[3];
if ( !get_BTE ( BTE ) ) {
for ( i = 0 ; i < nsplit ; ++i )
delete [] Xsplit[i];
delete [] Xsplit;
return false;
}
// display BTE:
#ifdef TGP_DEBUG
_out << std::endl
<< "BTE={" << BTE[0] << ", " << BTE[1] << ", " << BTE[2] << "}"
<< std::endl;
#endif
// compute the individual TGP models (one for each output):
double * ZZ = new double [_n_XX];
// Ds2x, expected reduction in predictive variance:
if ( _Ds2x == NULL ) {
_Ds2x = new double * [m];
for ( i = 0 ; i < m ; ++i )
_Ds2x[i] = NULL;
}
else {
for ( i = 0 ; i < m ; ++i )
if ( _Ds2x[i] ) {
delete [] _Ds2x[i];
_Ds2x[i] = NULL;
}
}
// improv, expected improvement of the objective (ranks):
if ( _improv ) {
delete [] _improv;
_improv = NULL;
}
if ( compute_improv )
_improv = new int [_n_XX];
for ( i = 0 ; i < m ; ++i ) {
if ( _tgp_models[i] ) {
_Ds2x[i] = ( compute_Ds2x ) ? new double [_n_XX] : NULL;
_tgp_models[i]->compute ( _X ,
_XX ,
Xsplit ,
_n ,
_n_XX ,
nsplit ,
&tgp_params ,
_tgp_rect ,
BTE ,
_tgp_linburn ,
_tgp_verb ,
ZZ ,
_Ds2x[i] ,
(i==index_obj) ? _improv : NULL );
// set XX_pts outputs #i:
for ( j = 0 ; j < _n_XX ; ++j ) {
XX_filtered_pts[j]->set_bb_output ( i , ZZ[j] );
XX_filtered_pts[j]->set_eval_status ( NOMAD::EVAL_OK );
}
// check if TGP has been interrupted:
if ( NOMAD::TGP_Output_Model::get_force_quit() ) {
_error_str = "TGP has been interrupted with ctrl-c";
break;
}
}
}
// clear memory:
for ( i = 0 ; i < nsplit ; ++i )
delete [] Xsplit[i];
delete [] Xsplit;
delete [] ZZ;
_model_computed = _error_str.empty();
return _model_computed;
}
/*--------------------------------------------*/
/* prediction at one point */
/* (x can be of size _n or _n0) */
/*--------------------------------------------*/
bool NOMAD::TGP_Model::predict ( NOMAD::Eval_Point & x , bool pred_outside_bnds )
{
if ( !_error_str.empty() )
return false;
if ( !_model_computed ) {
_error_str = "NOMAD::TGP_Model::compute() has not been called";
return false;
}
int i , i0 , ix , m = x.get_m() , nx = x.size();
// reset point outputs:
x.set_eval_status ( NOMAD::EVAL_FAIL );
for ( i = 0 ; i < m ; ++i )
x.set_bb_output ( i , NOMAD::Double() );
// check dimensions:
if ( m != static_cast(_bbot.size()) ||
( nx != _n0 && nx != _n ) ) {
_error_str = "predict error: bad x dimensions";
return false;
}
double ZZ , * XX = new double[_n];
// set the coordinates and check the bounds:
for ( i = 0 ; i < _n ; ++i ) {
ix = ( nx == _n0 ) ? _fv_index[i] : i;
if ( !pred_outside_bnds ) {
i0 = _fv_index[i];
if ( x[ix] < _lb[i0] || x[ix] > _ub[i0] ) {
delete [] XX;
return false; // this is not an error
}
}
XX[i] = x[ix].value();
}
// predictions (one for each output):
for ( i = 0 ; i < m ; ++i )
if ( _tgp_models[i] ) {
if ( !_tgp_models[i]->predict ( XX ,
_n ,
ZZ ,
_tgp_rect ) ) {
std::ostringstream oss;
oss << "predict error: problem with model #" << i;
_error_str = oss.str();
break;
}
x.set_bb_output ( i , ZZ );
}
delete [] XX;
if ( !_error_str.empty() ) {
x.set_eval_status ( NOMAD::EVAL_FAIL );
return false;
}
x.set_eval_status ( NOMAD::EVAL_OK );
return true;
}
/*-----------------------------------------------------------------*/
/* this function checks if the p x n matrix X is of full rank by */
/* applying the Cholesky decomposition to the sym. def. pos. */
/* nxn matrix X'X */
/* (static, private) */
/*-----------------------------------------------------------------*/
bool NOMAD::TGP_Model::check_full_rank ( double ** X , int p , int n ) {
int i , j , k , ki , kii , kij , kj , kji , nn12 = n*(n+1)/2;
// create XTX (X'X):
double * XTX = new double [nn12];
for ( i = 0 ; i < n ; ++i ) {
ki = i*(i+1)/2;
for ( j = 0 ; j <= i ; ++j ) {
kij = ki + j;
XTX[kij] = 0.0;
for ( k = 0 ; k < p ; ++k )
XTX[kij] += X[k][i] * X[k][j];
}
}
// create chol:
double * chol = new double [nn12] , tmp1 , tmp2 , eps = 1e-10;
// Choleski decomposition:
for ( i = 0 ; i < n ; ++i ) {
ki = i*(i+1)/2;
kii = ki+i;
tmp1 = XTX[kii];
for ( k = 0 ; k < i ; ++k )
tmp1 -= pow(chol[ki+k],2.0);
if ( fabs ( tmp1 ) <= eps ) {
delete [] XTX;
delete [] chol;
return false;
}
if ( i == n-1 )
break;
tmp1 = sqrt(tmp1);
chol[kii] = tmp1;
for ( j = i+1 ; j < n ; ++j ) {
kj = j*(j+1)/2;
kji = kj+i;
tmp2 = XTX[kji];
for ( k = 0 ; k < i ; ++k )
tmp2 -= chol[ki+k]*chol[kj+k];
chol[kji] = tmp2/tmp1;
}
}
delete [] XTX;
delete [] chol;
return true;
}
/*----------------------------------------------------------------*/
/* compute model h and f values given one blackbox output */
/*----------------------------------------------------------------*/
void NOMAD::TGP_Model::eval_hf ( const NOMAD::Point & bbo ,
const NOMAD::Double & h_min ,
NOMAD::hnorm_type h_norm ,
NOMAD::Double & h ,
NOMAD::Double & f ) const
{
f.clear();
h = 0.0;
int m = bbo.size();
if ( m != static_cast(_bbot.size()) )
throw NOMAD::Exception ( "TGP_Model.cpp" , __LINE__ ,
"TGP_Model::eval_hf() called with an invalid bbo argument" );
NOMAD::Double bboi;
for ( int i = 0 ; i < m ; ++i ) {
bboi = bbo[i];
if ( bboi.is_defined() ) {
if ( _bbot[i] == NOMAD::EB || _bbot[i] == NOMAD::PEB_E ) {
if ( bboi > h_min ) {
h.clear();
return;
}
}
else if ( ( _bbot[i] == NOMAD::FILTER ||
_bbot[i] == NOMAD::PB ||
_bbot[i] == NOMAD::PEB_P ) ) {
if ( bboi > h_min ) {
switch ( h_norm ) {
case NOMAD::L1:
h += bboi;
break;
case NOMAD::L2:
h += bboi * bboi;
break;
case NOMAD::LINF:
if ( bboi > h )
h = bboi;
break;
}
}
}
else if ( _bbot[i] == NOMAD::OBJ )
f = bboi;
}
}
if ( h_norm == NOMAD::L2 )
h = h.sqrt();
}
/*---------------------------------------*/
/* compute the TGP dparam array */
/* (static, private) */
/*---------------------------------------*/
double * NOMAD::TGP_Model::get_TGP_dparams ( int n ) {
double * dparams = new double [n*(n+3)+41];
int i , j , k;
// tree (p <- c(as.numeric(params$tree))):
dparams[0] = 0.5;
dparams[1] = 2.0;
dparams[2] = n+2;
if ( dparams[2] < 10 )
dparams[2] = 10;
dparams[3] = 1.0;
dparams[4] = n;
// params$meanfn == "linear" :
dparams[5] = 0.0;
// params$bprior == "bflat" :
dparams[6] = 2.0;
// p <- c(p, as.numeric(params$beta)) : n+1 zeros
k = 6;
for ( i = 0 ; i <= n ; ++i )
dparams[++k] = 0.0;
// p <- c(p, as.numeric(params$Wi)) : I_{n+1}
for ( i = 0 ; i <= n ; ++i )
for ( j = 0 ; j <= n ; ++j )
dparams[++k] = (i!=j) ? 0.0 : 1.0;
// p <- c(p, as.numeric(params$s2tau2)):
dparams[++k] = 1.0;
dparams[++k] = 1.0;
// p <- c(p, as.numeric(params$s2.p)):
dparams[++k] = 5.0;
dparams[++k] = 10.0;
// p <- c(p, as.numeric(params$s2.lam)):
dparams[++k] = 0.2;
dparams[++k] = 10.0;
// p <- c(p, as.numeric(params$tau2.p)):
dparams[++k] = 5.0;
dparams[++k] = 10.0;
// p <- c(p, as.numeric(params$tau2.lam)):
dparams[++k] = 0.2;
dparams[++k] = 0.1;
// params$corr == "expsep" :
dparams[++k] = 1.0;
// p <- c(p, as.numeric(params$gd)):
dparams[++k] = 0.1;
dparams[++k] = 0.5;
// p <- c(p, as.numeric(params$nug.p)):
dparams[++k] = 1.0;
dparams[++k] = 1.0;
dparams[++k] = 1.0;
dparams[++k] = 1.0;
// if (params$nug.lam[1] == "fixed"), p <- c(p, rep(-1, 4)) :
dparams[++k] = -1.0;
dparams[++k] = -1.0;
dparams[++k] = -1.0;
dparams[++k] = -1.0;
// p <- c(p, as.numeric(params$gamma)):
dparams[++k] = 0.0;
dparams[++k] = 0.2;
dparams[++k] = 0.7;
// p <- c(p, as.numeric(params$d.p)):
dparams[++k] = 1.0;
dparams[++k] = 20.0;
dparams[++k] = 10.0;
dparams[++k] = 10.0;
// if (params$d.lam[1] == "fixed"), p <- c(p, rep(-1, 4)):
dparams[++k] = -1.0;
dparams[++k] = -1.0;
dparams[++k] = -1.0;
dparams[++k] = -1.0;
return dparams;
}
/*--------------------------------------------*/
/* display the interpolation set X */
/*--------------------------------------------*/
void NOMAD::TGP_Model::display_X ( const NOMAD::Display & out ,
int display_limit ) const
{
if ( _p == 0 || !_X ) {
out << "no interpolation points" << std::endl;
return;
}
int i , j;
int m = _bbot.size();
int i0 = ( display_limit > 0 ) ? _p - display_limit : 0;
NOMAD::Point x(_n) , bbo(m);
out << NOMAD::open_block ( "interpolation points (X)");
if ( i0 > 0 )
out << "..." << std::endl;
else if ( i0 < 0 )
i0 = 0;
for ( i = i0 ; i < _p ; ++i ) {
for ( j = 0 ; j < _n ; ++j )
x[j] = _X[i][j];
bbo = NOMAD::Point(m);
if ( _tgp_models )
for ( j = 0 ; j < m ; ++j )
if ( _tgp_models[j] )
bbo[j] = (_tgp_models[j]->get_Z())[i];
out << "#";
out.display_int_w ( i , _p );
out << " x=(";
x.display ( out , " " , 15 , -1 );
out << " ) f(x)=[";
bbo.display ( out , " " , 15 , -1 );
out << " ]" << std::endl;
}
std::ostringstream oss;
oss << "(size=" << _p << ")";
out << NOMAD::close_block ( oss.str() ) << std::endl;
}
/*---------------------------------------------------------*/
/* get the XX points with the largest expected reduction */
/* in predictive variance, for each output */
/* (no duplicates) */
/*---------------------------------------------------------*/
void NOMAD::TGP_Model::get_Ds2x_points ( std::set & pts_indexes ) const
{
pts_indexes.clear();
if ( !_Ds2x || _n_XX == 0 )
return;
int i , j , k , m = _bbot.size();
for ( i = 0 ; i < m ; ++i )
if ( _Ds2x[i] ) {
NOMAD::Double max;
k = -1;
for ( j = 0 ; j < _n_XX ; ++j )
if ( !max.is_defined() || _Ds2x[i][j] > max ) {
max = _Ds2x[i][j];
k = j;
}
if ( k >= 0 )
pts_indexes.insert ( k );
}
}
/*----------------------------------------------------------------------------*/
/* get the XX points with the largest expected improvement of the objective */
/*----------------------------------------------------------------------------*/
void NOMAD::TGP_Model::get_improv_points ( std::list & pts_indexes ) const
{
pts_indexes.clear();
if ( !_improv || _n_XX == 0 )
return;
int j;
NOMAD::Point * XX_pt;
std::multiset pts;
std::multiset::const_iterator it , end;
// 1. sort:
for ( j = 0 ; j < _n_XX ; ++j ) {
XX_pt = new NOMAD::Point ( 1 );
(*XX_pt)[0] = j;
pts.insert ( NOMAD::Model_Sorted_Point ( XX_pt , _improv[j] ) );
}
// 2. construct pts_indexes (exclude points with improv >= n_XX):
end = pts.end();
for ( it = pts.begin() ; it != end ; ++it ) {
if ( it->get_dist() < _n_XX )
pts_indexes.push_back ( static_cast ( (*it->get_point())[0].value() ) );
delete it->get_point();
}
}
/*--------------------------------------------------------------*/
/* display the expected improvement of the objective (improv) */
/* (better ranks are displayed first) */
/*--------------------------------------------------------------*/
void NOMAD::TGP_Model::display_improv ( const NOMAD::Display & out ,
int display_limit ) const
{
if ( !_improv || _n_XX == 0 ) {
out << "improv has not been computed" << std::endl;
return;
}
int j , k;
NOMAD::Point * XX_pt;
std::multiset pts;
std::multiset::const_iterator it , end;
// 1. sort:
for ( j = 0 ; j < _n_XX ; ++j ) {
// construct a NOMAD::Point from matrix _XX:
XX_pt = new NOMAD::Point ( _fv );
for ( k = 0 ; k < _n0 ; ++k )
if ( _av_index[k] >= 0 )
(*XX_pt)[k] = _XX[j][_av_index[k]];
// insert this point in the sorted list:
pts.insert ( NOMAD::Model_Sorted_Point ( XX_pt , _improv[j] ) );
}
// 2. display:
end = pts.end();
for ( j = 0 , it = pts.begin() ; it != end ; ++it , ++j ) {
if ( display_limit <= 0 || j < display_limit ) {
out << "x=( ";
it->get_point()->display ( out , " " , 6 , -1 );
out << " ) improv=" << it->get_dist() << std::endl;
}
else if ( j == display_limit )
out << "..." << std::endl;
delete it->get_point();
}
}
/*----------------------------------------------------------------*/
/* display the expected reduction in predictive variance (Ds2x) */
/* (larger values are displayed first) */
/*----------------------------------------------------------------*/
void NOMAD::TGP_Model::display_Ds2x ( const NOMAD::Display & out ,
int display_limit ) const
{
if ( !_Ds2x || _n_XX == 0 ) {
out << "matrix Ds2x has not been computed" << std::endl;
return;
}
int i , j , k , m = _bbot.size();
NOMAD::Point * XX_pt;
std::multiset pts;
std::multiset::const_iterator it , end;
for ( i = 0 ; i < m ; ++i ) {
if ( m > 1 ) {
std::ostringstream oss;
oss << "output #" << i;
out << NOMAD::open_block ( oss.str() );
}
if ( _Ds2x[i] ) {
// 1. sort:
for ( j = 0 ; j < _n_XX ; ++j ) {
// construct a NOMAD::Point from matrix _XX:
XX_pt = new NOMAD::Point ( _fv );
for ( k = 0 ; k < _n0 ; ++k )
if ( _av_index[k] >= 0 )
(*XX_pt)[k] = _XX[j][_av_index[k]];
// insert this point in the sorted list:
pts.insert ( NOMAD::Model_Sorted_Point ( XX_pt , -_Ds2x[i][j] ) );
}
// 2. display:
end = pts.end();
for ( j = 0 , it = pts.begin() ; it != end ; ++it , ++j ) {
if ( display_limit <= 0 || j < display_limit ) {
out << "x=( ";
it->get_point()->display ( out , " " , 6 , -1 );
out << " ) Ds2x=" << it->get_dist()*-1.0 << std::endl;
}
else if ( j == display_limit )
out << "..." << std::endl;
delete it->get_point();
}
pts.clear();
}
else
out << "NULL" << std::endl;
if ( m > 1 )
out.close_block();
}
}
/*-------------------------------------------------------*/
/* display the error stats for the interpolation set X */
/*-------------------------------------------------------*/
void NOMAD::TGP_Model::display_X_errors ( const NOMAD::Display & out )
{
if ( _p == 0 || !_X ) {
out << "no interpolation points" << std::endl;
return;
}
int i , j , m = _bbot.size();
NOMAD::Point min_err(m) , max_err(m) , avg_err(m,0.0) , sd_err(m,0.0);
NOMAD::Eval_Point x ( _n , m );
double ** err = new double * [_p];
for ( i = 0 ; i < _p ; ++i ) {
err[i] = new double[m];
for ( j = 0 ; j < _n ; ++j )
x[j] = _X[i][j];
if ( predict ( x , true ) ) {
for ( j = 0 ; j < m ; ++j )
if ( _tgp_models[j] ) {
// relative error (in %) for point #i and output #j:
err[i][j] = ( x.get_bb_outputs()[j].rel_err((_tgp_models[j]->get_Z())[i])
* 100.0).value();
// out << "f=" << (_tgp_models[j]->get_Z())[i] << " "
// << "m=" << x.get_bb_outputs()[j] << " err=" << err[i][j]
// << std::endl;
if ( !min_err[j].is_defined() || err[i][j] < min_err[j].value() )
min_err[j] = err[i][j];
if ( !max_err[j].is_defined() || err[i][j] > max_err[j].value() )
max_err[j] = err[i][j];
avg_err[j] += err[i][j];
}
}
else {
for ( j = 0 ; j <= i ; ++j )
delete [] err[j];
delete [] err;
out << "cannot predict interpolation errors ("
<< _error_str << ")" << std::endl;
return;
}
}
for ( j = 0 ; j < m ; ++j )
if ( _tgp_models[j] ) {
// compute the median error:
NOMAD::Double med_err;
{
if ( _p == 1 )
med_err = err[0][j];
else if ( _p == 2 )
med_err = ( err[0][j] + err[1][j] ) / 2.0;
else {
std::multiset sorted_errors;
for ( i = 0 ; i < _p ; ++i )
sorted_errors.insert ( err[i][j] );
std::multiset::const_iterator it , end = sorted_errors.end();
--end;
for ( it = sorted_errors.begin() , i = 0 ; it != end ; ++it , ++i ) {
if ( i == (_p+1)/2-1 ) {
med_err = *it;
if ( _p%2==0 ) {
++it;
med_err = ( med_err + *it ) / 2.0;
}
break;
}
}
}
}
// compute the mean and the standard deviation:
avg_err[j] /= _p;
for ( i = 0 ; i < _p ; ++i )
sd_err[j] += ( avg_err[j] - err[i][j] ).pow2();
sd_err[j] = (sd_err[j] / _p).sqrt();
// display:
if ( m > 1 ) {
std::ostringstream oss;
oss << "output #" << j;
if ( _tgp_models[j]->is_fixed() )
oss << " (fixed)";
else if ( _tgp_models[j]->is_binary() )
oss << " (binary)";
out << NOMAD::open_block ( oss.str() );
}
out << "min : ";
min_err[j].display ( out , "%6.2f" );
out << std::endl << "max : ";
max_err[j].display ( out , "%6.2f" );
out << std::endl << "median: ";
med_err.display ( out , "%6.2f" );
out << std::endl << "mean : ";
avg_err[j].display ( out , "%6.2f" );
out << std::endl << "sd : ";
sd_err[j].display ( out , "%6.2f" );
out << std::endl;
if ( m > 1 )
out.close_block();
}
for ( i = 0 ; i < _p ; ++i )
delete [] err[i];
delete [] err;
}
/*--------------------------------------------*/
/* display */
/*--------------------------------------------*/
void NOMAD::TGP_Model::display ( const NOMAD::Display & out ) const
{
if ( !_error_str.empty() ) {
out << "error with model" << std::endl;
return;
}
int i , j;
// fixed variables:
out << "fixed_var = [ " << _fv << "]" << std::endl;
out << "av_index = ";
if ( _av_index ) {
out << "[ ";
for ( i = 0 ; i < _n0 ; ++i )
out << _av_index[i] << " ";
out << "]" << std::endl;
}
else
out << "NULL" << std::endl;
out << "fv_index = ";
if ( _fv_index ) {
out << "[ ";
for ( i = 0 ; i < _n ; ++i )
out << _fv_index[i] << " ";
out << "]" << std::endl;
}
else
out << "NULL" << std::endl;
// bounds:
out << "lb = [ " << _lb << "]" << std::endl
<< "ub = [ " << _ub << "]" << std::endl
<< std::endl;
// display X:
if ( !_X )
out << "X = NULL" << std::endl;
else {
out << "X = [";
for ( i = 0 ; i < _p ; ++i ) {
out << "\t";
for ( j = 0 ; j < _n ; ++j )
out << std::setw(15) << _X[i][j] << " ";
out << ( (i==_p-1) ? "]" : ";" ) << std::endl;
}
out << "size(X)=" << _p << "x" << _n << std::endl << std::endl;
}
// display XX:
if ( !_XX )
out << "XX = NULL" << std::endl;
else {
out << "XX = [";
for ( i = 0 ; i < _n_XX ; ++i ) {
out << "\t";
for ( j = 0 ; j < _n ; ++j )
out << std::setw(15) << _XX[i][j] << " ";
out << ( (i==_n_XX-1) ? "]" : ";" ) << std::endl;
}
out << "size(XX)=" << _n_XX << "x" << _n << std::endl << std::endl;
}
// display models:
out << std::endl;
if ( _tgp_models ) {
int m = _bbot.size();
for ( i = 0 ; i < m ; ++i ) {
if ( _tgp_models[i] ) {
std::ostringstream oss;
oss << "model #" << i;
out.open_block ( oss.str() );
_tgp_models[i]->display ( out );
out.close_block();
}
else
out << "model #" << i << ": NULL" << std::endl;
out << std::endl;
}
}
else
out << "no models" << std::endl << std::endl;
}
/*----------------------------------------------------------------*/
/* access to the width of the interpolation set */
/*----------------------------------------------------------------*/
#ifdef MODEL_STATS
NOMAD::Double NOMAD::TGP_Model::get_Yw ( void ) const
{
NOMAD::Double Yw , tmp;
for ( int i = 0 ; i < _n0 ; ++i ) {
tmp = _ub[i]-_lb[i];
if ( !Yw.is_defined() || tmp > Yw )
Yw = tmp;
}
return Yw;
}
#endif
#endif