rank pass toy

This commit is contained in:
kalenhaha
2014-04-07 23:25:35 +08:00
parent 1bbbb0cf7f
commit 1136c71e64
32 changed files with 2237 additions and 2146 deletions

View File

@@ -14,198 +14,203 @@
namespace xgboost{
namespace utils{
/*!
/*!
* \brief an iterator that iterates over a configure file and gets the configures
*/
class ConfigIterator{
public:
/*!
* \brief constructor
/*!
* \brief constructor
* \param fname name of configure file
*/
ConfigIterator( const char *fname ){
fi = FopenCheck( fname, "r");
ch_buf = fgetc( fi );
ConfigIterator(const char *fname){
fi = FopenCheck(fname, "r");
ch_buf = fgetc(fi);
}
/*! \brief destructor */
~ConfigIterator(){
fclose( fi );
fclose(fi);
}
/*!
/*!
* \brief get current name, called after Next returns true
* \return current parameter name
* \return current parameter name
*/
inline const char *name( void )const{
inline const char *name(void)const{
return s_name;
}
/*!
/*!
* \brief get current value, called after Next returns true
* \return current parameter value
* \return current parameter value
*/
inline const char *val( void ) const{
inline const char *val(void) const{
return s_val;
}
/*!
/*!
* \brief move iterator to next position
* \return true if there is value in next position
*/
inline bool Next( void ){
while( !feof( fi ) ){
GetNextToken( s_name );
if( s_name[0] == '=') return false;
if( GetNextToken( s_buf ) || s_buf[0] != '=' ) return false;
if( GetNextToken( s_val ) || s_val[0] == '=' ) return false;
inline bool Next(void){
while (!feof(fi)){
GetNextToken(s_name);
if (s_name[0] == '=') return false;
if (GetNextToken(s_buf) || s_buf[0] != '=') return false;
if (GetNextToken(s_val) || s_val[0] == '=') return false;
return true;
}
return false;
}
private:
FILE *fi;
FILE *fi;
char ch_buf;
char s_name[256],s_val[256],s_buf[246];
inline void SkipLine(){
char s_name[256], s_val[256], s_buf[246];
inline void SkipLine(){
do{
ch_buf = fgetc( fi );
}while( ch_buf != EOF && ch_buf != '\n' && ch_buf != '\r' );
ch_buf = fgetc(fi);
} while (ch_buf != EOF && ch_buf != '\n' && ch_buf != '\r');
}
inline void ParseStr( char tok[] ){
int i = 0;
while( (ch_buf = fgetc(fi)) != EOF ){
switch( ch_buf ){
case '\\': tok[i++] = fgetc( fi ); break;
case '\"': tok[i++] = '\0';
return;
inline void ParseStr(char tok[]){
int i = 0;
while ((ch_buf = fgetc(fi)) != EOF){
switch (ch_buf){
case '\\': tok[i++] = fgetc(fi); break;
case '\"': tok[i++] = '\0';
return;
case '\r':
case '\n': Error("unterminated string"); break;
default: tok[i++] = ch_buf;
}
}
Error("unterminated string");
Error("unterminated string");
}
// return newline
inline bool GetNextToken( char tok[] ){
inline bool GetNextToken(char tok[]){
int i = 0;
bool new_line = false;
while( ch_buf != EOF ){
switch( ch_buf ){
case '#' : SkipLine(); new_line = true; break;
bool new_line = false;
while (ch_buf != EOF){
switch (ch_buf){
case '#': SkipLine(); new_line = true; break;
case '\"':
if( i == 0 ){
ParseStr( tok );ch_buf = fgetc(fi); return new_line;
}else{
Error("token followed directly by string");
if (i == 0){
ParseStr(tok); ch_buf = fgetc(fi); return new_line;
}
else{
Error("token followed directly by string");
}
case '=':
if( i == 0 ) {
ch_buf = fgetc( fi );
tok[0] = '=';
tok[1] = '\0';
}else{
tok[i] = '\0';
if (i == 0) {
ch_buf = fgetc(fi);
tok[0] = '=';
tok[1] = '\0';
}
else{
tok[i] = '\0';
}
return new_line;
case '\r':
case '\r':
case '\n':
if( i == 0 ) new_line = true;
if (i == 0) new_line = true;
case '\t':
case ' ' :
ch_buf = fgetc( fi );
if( i > 0 ){
tok[i] = '\0';
case ' ':
ch_buf = fgetc(fi);
if (i > 0){
tok[i] = '\0';
return new_line;
}
}
break;
default:
default:
tok[i++] = ch_buf;
ch_buf = fgetc( fi );
break;
ch_buf = fgetc(fi);
break;
}
}
return true;
}
};
};
namespace utils{
/*!
* \brief a class that save parameter configurations
* temporally and allows to get them out later
/*!
* \brief a class that save parameter configurations
* temporally and allows to get them out later
* there are two kinds of priority in ConfigSaver
*/
class ConfigSaver{
public:
/*! \brief constructor */
ConfigSaver( void ){ idx = 0; }
ConfigSaver(void){ idx = 0; }
/*! \brief clear all saves */
inline void Clear( void ){
inline void Clear(void){
idx = 0;
names.clear(); values.clear();
names_high.clear(); values_high.clear();
}
/*!
* \brief push back a parameter setting
/*!
* \brief push back a parameter setting
* \param name name of parameter
* \param val value of parameter
* \param priority whether the setting has higher priority: high priority occurs
* \param priority whether the setting has higher priority: high priority occurs
* latter when read from ConfigSaver, and can overwrite existing settings
*/
inline void PushBack( const char *name, const char *val, int priority = 0 ){
if( priority == 0 ){
names.push_back( std::string( name ) );
values.push_back( std::string( val ) );
}else{
names_high.push_back( std::string( name ) );
values_high.push_back( std::string( val ) );
inline void PushBack(const char *name, const char *val, int priority = 0){
if (priority == 0){
names.push_back(std::string(name));
values.push_back(std::string(val));
}
else{
names_high.push_back(std::string(name));
values_high.push_back(std::string(val));
}
}
/*! \brief set pointer to beginning of the ConfigSaver */
inline void BeforeFirst( void ){
inline void BeforeFirst(void){
idx = 0;
}
/*!
/*!
* \brief move iterator to next position
* \return true if there is value in next position
*/
inline bool Next( void ){
if( idx >= names.size() + names_high.size() ){
inline bool Next(void){
if (idx >= names.size() + names_high.size()){
return false;
}
idx ++;
idx++;
return true;
}
/*!
/*!
* \brief get current name, called after Next returns true
* \return current parameter name
*/
inline const char *name( void ) const{
Assert( idx > 0, "can't call name before first");
* \return current parameter name
*/
inline const char *name(void) const{
Assert(idx > 0, "can't call name before first");
size_t i = idx - 1;
if( i >= names.size() ){
return names_high[ i - names.size() ].c_str();
}else{
return names[ i ].c_str();
if (i >= names.size()){
return names_high[i - names.size()].c_str();
}
else{
return names[i].c_str();
}
}
/*!
/*!
* \brief get current value, called after Next returns true
* \return current parameter value
* \return current parameter value
*/
inline const char *val( void ) const{
Assert( idx > 0, "can't call name before first");
inline const char *val(void) const{
Assert(idx > 0, "can't call name before first");
size_t i = idx - 1;
if( i >= values.size() ){
return values_high[ i - values.size() ].c_str();
}else{
return values[ i ].c_str();
if (i >= values.size()){
return values_high[i - values.size()].c_str();
}
else{
return values[i].c_str();
}
}
private:
std::vector<std::string> names;
std::vector<std::string> values;
std::vector<std::string> names_high;
std::vector<std::string> values_high;
std::vector<std::string> values_high;
size_t idx;
};
};

View File

@@ -16,48 +16,48 @@ namespace xgboost{
class FeatMap{
public:
enum Type{
kIndicator = 0,
kIndicator = 0,
kQuantitive = 1,
kInteger = 2,
kFloat = 3
};
public:
/*! \brief load feature map from text format */
inline void LoadText( const char *fname ){
FILE *fi = utils::FopenCheck( fname, "r" );
this->LoadText( fi );
fclose( fi );
inline void LoadText(const char *fname){
FILE *fi = utils::FopenCheck(fname, "r");
this->LoadText(fi);
fclose(fi);
}
/*! \brief load feature map from text format */
inline void LoadText( FILE *fi ){
inline void LoadText(FILE *fi){
int fid;
char fname[256], ftype[256];
while( fscanf( fi, "%d%s%s", &fid, fname, ftype ) == 3 ){
utils::Assert( fid == (int)names_.size(), "invalid fmap format" );
names_.push_back( std::string(fname) );
types_.push_back( GetType( ftype ) );
while (fscanf(fi, "%d%s%s", &fid, fname, ftype) == 3){
utils::Assert(fid == (int)names_.size(), "invalid fmap format");
names_.push_back(std::string(fname));
types_.push_back(GetType(ftype));
}
}
/*! \brief number of known features */
size_t size( void ) const{
size_t size(void) const{
return names_.size();
}
/*! \brief return name of specific feature */
const char* name( size_t idx ) const{
utils::Assert( idx < names_.size(), "utils::FMap::name feature index exceed bound" );
return names_[ idx ].c_str();
const char* name(size_t idx) const{
utils::Assert(idx < names_.size(), "utils::FMap::name feature index exceed bound");
return names_[idx].c_str();
}
/*! \brief return type of specific feature */
const Type& type( size_t idx ) const{
utils::Assert( idx < names_.size(), "utils::FMap::name feature index exceed bound" );
return types_[ idx ];
const Type& type(size_t idx) const{
utils::Assert(idx < names_.size(), "utils::FMap::name feature index exceed bound");
return types_[idx];
}
private:
inline static Type GetType( const char *tname ){
if( !strcmp( "i", tname ) ) return kIndicator;
if( !strcmp( "q", tname ) ) return kQuantitive;
if( !strcmp( "int", tname ) ) return kInteger;
if( !strcmp( "float", tname ) ) return kFloat;
inline static Type GetType(const char *tname){
if (!strcmp("i", tname)) return kIndicator;
if (!strcmp("q", tname)) return kQuantitive;
if (!strcmp("int", tname)) return kInteger;
if (!strcmp("float", tname)) return kFloat;
utils::Error("unknown feature type, use i for indicator and q for quantity");
return kIndicator;
}
@@ -73,50 +73,50 @@ namespace xgboost{
/*! \brief feature constraint, allow or disallow some feature during training */
class FeatConstrain{
public:
FeatConstrain( void ){
FeatConstrain(void){
default_state_ = +1;
}
/*!\brief set parameters */
inline void SetParam( const char *name, const char *val ){
inline void SetParam(const char *name, const char *val){
int a, b;
if( !strcmp( name, "fban") ){
this->ParseRange( val, a, b );
this->SetRange( a, b, -1 );
if (!strcmp(name, "fban")){
this->ParseRange(val, a, b);
this->SetRange(a, b, -1);
}
if( !strcmp( name, "fpass") ){
this->ParseRange( val, a, b );
this->SetRange( a, b, +1 );
if (!strcmp(name, "fpass")){
this->ParseRange(val, a, b);
this->SetRange(a, b, +1);
}
if( !strcmp( name, "fdefault") ){
default_state_ = atoi( val );
if (!strcmp(name, "fdefault")){
default_state_ = atoi(val);
}
}
/*! \brief whether constrain is specified */
inline bool HasConstrain( void ) const {
inline bool HasConstrain(void) const {
return state_.size() != 0 && default_state_ == 1;
}
/*! \brief whether a feature index is banned or not */
inline bool NotBanned( unsigned index ) const{
inline bool NotBanned(unsigned index) const{
int rt = index < state_.size() ? state_[index] : default_state_;
if( rt == 0 ) rt = default_state_;
if (rt == 0) rt = default_state_;
return rt == 1;
}
private:
inline void SetRange( int a, int b, int st ){
if( b > (int)state_.size() ) state_.resize( b, 0 );
for( int i = a; i < b; ++ i ){
inline void SetRange(int a, int b, int st){
if (b >(int)state_.size()) state_.resize(b, 0);
for (int i = a; i < b; ++i){
state_[i] = st;
}
}
}
inline void ParseRange( const char *val, int &a, int &b ){
if( sscanf( val, "%d-%d", &a, &b ) == 2 ) return;
utils::Assert( sscanf( val, "%d", &a ) == 1 );
inline void ParseRange(const char *val, int &a, int &b){
if (sscanf(val, "%d-%d", &a, &b) == 2) return;
utils::Assert(sscanf(val, "%d", &a) == 1);
b = a + 1;
}
/*! \brief default state */
int default_state_;
/*! \brief whether the state here is, +1:pass, -1: ban, 0:default */
std::vector<int> state_;
std::vector<int> state_;
};
}; // namespace utils
}; // namespace xgboost

View File

@@ -2,7 +2,7 @@
* \file xgboost_matrix_csr.h
* \brief this file defines some easy to use STL based class for in memory sparse CSR matrix
* \author Tianqi Chen: tianqi.tchen@gmail.com
*/
*/
#ifndef XGBOOST_MATRIX_CSR_H
#define XGBOOST_MATRIX_CSR_H
#include <vector>
@@ -11,13 +11,13 @@
namespace xgboost{
namespace utils{
/*!
* \brief a class used to help construct CSR format matrix,
/*!
* \brief a class used to help construct CSR format matrix,
* can be used to convert row major CSR to column major CSR
* \tparam IndexType type of index used to store the index position, usually unsigned or size_t
* \tparam whether enabling the usage of aclist, this option must be enabled manually
*/
template<typename IndexType,bool UseAcList = false>
template<typename IndexType, bool UseAcList = false>
struct SparseCSRMBuilder{
private:
/*! \brief dummy variable used in the indicator matrix construction */
@@ -29,100 +29,102 @@ namespace xgboost{
/*! \brief a list of active rows, used when many rows are empty */
std::vector<size_t> &aclist;
public:
SparseCSRMBuilder( std::vector<size_t> &p_rptr,
std::vector<IndexType> &p_findex )
:rptr(p_rptr), findex( p_findex ), aclist( dummy_aclist ){
Assert( !UseAcList, "enabling bug" );
}
/*! \brief use with caution! rptr must be cleaned before use */
SparseCSRMBuilder( std::vector<size_t> &p_rptr,
std::vector<IndexType> &p_findex,
std::vector<size_t> &p_aclist )
:rptr(p_rptr), findex( p_findex ), aclist( p_aclist ){
Assert( UseAcList, "must manually enable the option use aclist" );
SparseCSRMBuilder(std::vector<size_t> &p_rptr,
std::vector<IndexType> &p_findex)
:rptr(p_rptr), findex(p_findex), aclist(dummy_aclist){
Assert(!UseAcList, "enabling bug");
}
/*! \brief use with caution! rptr must be cleaned before use */
SparseCSRMBuilder(std::vector<size_t> &p_rptr,
std::vector<IndexType> &p_findex,
std::vector<size_t> &p_aclist)
:rptr(p_rptr), findex(p_findex), aclist(p_aclist){
Assert(UseAcList, "must manually enable the option use aclist");
}
public:
/*!
/*!
* \brief step 1: initialize the number of rows in the data, not necessary exact
* \nrows number of rows in the matrix, can be smaller than expected
*/
inline void InitBudget( size_t nrows = 0 ){
if( !UseAcList ){
inline void InitBudget(size_t nrows = 0){
if (!UseAcList){
rptr.clear();
rptr.resize( nrows + 1, 0 );
}else{
Assert( nrows + 1 == rptr.size(), "rptr must be initialized already" );
rptr.resize(nrows + 1, 0);
}
else{
Assert(nrows + 1 == rptr.size(), "rptr must be initialized already");
this->Cleanup();
}
}
/*!
/*!
* \brief step 2: add budget to each rows, this function is called when aclist is used
* \param row_id the id of the row
* \param nelem number of element budget add to this row
*/
inline void AddBudget( size_t row_id, size_t nelem = 1 ){
if( rptr.size() < row_id + 2 ){
rptr.resize( row_id + 2, 0 );
inline void AddBudget(size_t row_id, size_t nelem = 1){
if (rptr.size() < row_id + 2){
rptr.resize(row_id + 2, 0);
}
if( UseAcList ){
if( rptr[ row_id + 1 ] == 0 ) aclist.push_back( row_id );
if (UseAcList){
if (rptr[row_id + 1] == 0) aclist.push_back(row_id);
}
rptr[ row_id + 1 ] += nelem;
rptr[row_id + 1] += nelem;
}
/*! \brief step 3: initialize the necessary storage */
inline void InitStorage( void ){
inline void InitStorage(void){
// initialize rptr to be beginning of each segment
size_t start = 0;
if( !UseAcList ){
for( size_t i = 1; i < rptr.size(); i ++ ){
size_t rlen = rptr[ i ];
rptr[ i ] = start;
start += rlen;
}
}else{
// case with active list
std::sort( aclist.begin(), aclist.end() );
for( size_t i = 0; i < aclist.size(); i ++ ){
size_t ridx = aclist[ i ];
size_t rlen = rptr[ ridx + 1 ];
rptr[ ridx + 1 ] = start;
// set previous rptr to right position if previous feature is not active
if( i == 0 || ridx != aclist[i-1] + 1 ) rptr[ ridx ] = start;
if (!UseAcList){
for (size_t i = 1; i < rptr.size(); i++){
size_t rlen = rptr[i];
rptr[i] = start;
start += rlen;
}
}
findex.resize( start );
else{
// case with active list
std::sort(aclist.begin(), aclist.end());
for (size_t i = 0; i < aclist.size(); i++){
size_t ridx = aclist[i];
size_t rlen = rptr[ridx + 1];
rptr[ridx + 1] = start;
// set previous rptr to right position if previous feature is not active
if (i == 0 || ridx != aclist[i - 1] + 1) rptr[ridx] = start;
start += rlen;
}
}
findex.resize(start);
}
/*!
* \brief step 4:
* used in indicator matrix construction, add new
* element to each row, the number of calls shall be exactly same as add_budget
/*!
* \brief step 4:
* used in indicator matrix construction, add new
* element to each row, the number of calls shall be exactly same as add_budget
*/
inline void PushElem( size_t row_id, IndexType col_id ){
size_t &rp = rptr[ row_id + 1 ];
findex[ rp ++ ] = col_id;
inline void PushElem(size_t row_id, IndexType col_id){
size_t &rp = rptr[row_id + 1];
findex[rp++] = col_id;
}
/*!
/*!
* \brief step 5: only needed when aclist is used
* clean up the rptr for next usage
*/
inline void Cleanup( void ){
Assert( UseAcList, "this function can only be called use AcList" );
for( size_t i = 0; i < aclist.size(); i ++ ){
*/
inline void Cleanup(void){
Assert(UseAcList, "this function can only be called use AcList");
for (size_t i = 0; i < aclist.size(); i++){
const size_t ridx = aclist[i];
rptr[ ridx ] = 0; rptr[ ridx + 1 ] = 0;
rptr[ridx] = 0; rptr[ridx + 1] = 0;
}
aclist.clear();
}
};
};
namespace utils{
/*!
/*!
* \brief simple sparse matrix container
* \tparam IndexType type of index used to store the index position, usually unsigned or size_t
*/
*/
template<typename IndexType>
struct SparseCSRMat{
private:
@@ -134,22 +136,22 @@ namespace xgboost{
/*! \brief matrix builder*/
SparseCSRMBuilder<IndexType> builder;
public:
SparseCSRMat( void ):builder( rptr, findex ){
}
SparseCSRMat(void) :builder(rptr, findex){
}
public:
/*! \return number of rows in the matrx */
inline size_t NumRow( void ) const{
inline size_t NumRow(void) const{
return rptr.size() - 1;
}
/*! \return number of elements r-th row */
inline size_t NumElem( size_t r ) const{
return rptr[ r + 1 ] - rptr[ r ];
inline size_t NumElem(size_t r) const{
return rptr[r + 1] - rptr[r];
}
/*! \return r-th row */
inline const IndexType *operator[]( size_t r ) const{
return &findex[ rptr[r] ];
}
};
/*! \return r-th row */
inline const IndexType *operator[](size_t r) const{
return &findex[rptr[r]];
}
};
};
};
#endif

View File

@@ -3,16 +3,16 @@
/*!
* \file xgboost_omp.h
* \brief header to handle OpenMP compatibility issues
*
*
* \author Tianqi Chen: tianqi.tchen@gmail.com
*/
#if defined(_OPENMP)
#include <omp.h>
#else
//#warning "OpenMP is not available, compile to single thread code"
#warning "OpenMP is not available, compile to single thread code"
inline int omp_get_thread_num() { return 0; }
inline int omp_get_num_threads() { return 1; }
inline void omp_set_num_threads( int nthread ) {}
inline void omp_set_num_threads(int nthread) {}
#endif
#endif

View File

@@ -23,107 +23,108 @@ typedef unsigned int uint32_t;
namespace xgboost{
namespace random{
/*! \brief seed the PRNG */
inline void Seed( uint32_t seed ){
srand( seed );
inline void Seed(uint32_t seed){
srand(seed);
}
/*! \brief return a real number uniform in [0,1) */
inline double NextDouble(){
return static_cast<double>( rand() ) / (static_cast<double>( RAND_MAX )+1.0);
return static_cast<double>(rand()) / (static_cast<double>(RAND_MAX)+1.0);
}
/*! \brief return a real numer uniform in (0,1) */
inline double NextDouble2(){
return (static_cast<double>( rand() ) + 1.0 ) / (static_cast<double>(RAND_MAX) + 2.0);
return (static_cast<double>(rand()) + 1.0) / (static_cast<double>(RAND_MAX)+2.0);
}
};
namespace random{
/*! \brief return a random number */
inline uint32_t NextUInt32( void ){
inline uint32_t NextUInt32(void){
return (uint32_t)rand();
}
/*! \brief return a random number in n */
inline uint32_t NextUInt32( uint32_t n ){
return (uint32_t) floor( NextDouble() * n ) ;
}
inline uint32_t NextUInt32(uint32_t n){
return (uint32_t)floor(NextDouble() * n);
}
/*! \brief return x~N(0,1) */
inline double SampleNormal(){
double x,y,s;
double x, y, s;
do{
x = 2 * NextDouble2() - 1.0;
y = 2 * NextDouble2() - 1.0;
s = x*x + y*y;
}while( s >= 1.0 || s == 0.0 );
return x * sqrt( -2.0 * log(s) / s ) ;
} while (s >= 1.0 || s == 0.0);
return x * sqrt(-2.0 * log(s) / s);
}
/*! \brief return iid x,y ~N(0,1) */
inline void SampleNormal2D( double &xx, double &yy ){
double x,y,s;
inline void SampleNormal2D(double &xx, double &yy){
double x, y, s;
do{
x = 2 * NextDouble2() - 1.0;
y = 2 * NextDouble2() - 1.0;
s = x*x + y*y;
}while( s >= 1.0 || s == 0.0 );
double t = sqrt( -2.0 * log(s) / s ) ;
xx = x * t;
} while (s >= 1.0 || s == 0.0);
double t = sqrt(-2.0 * log(s) / s);
xx = x * t;
yy = y * t;
}
/*! \brief return x~N(mu,sigma^2) */
inline double SampleNormal( double mu, double sigma ){
inline double SampleNormal(double mu, double sigma){
return SampleNormal() * sigma + mu;
}
/*! \brief return 1 with probability p, coin flip */
inline int SampleBinary( double p ){
return NextDouble() < p;
inline int SampleBinary(double p){
return NextDouble() < p;
}
/*! \brief return distribution from Gamma( alpha, beta ) */
inline double SampleGamma( double alpha, double beta ) {
if ( alpha < 1.0 ) {
inline double SampleGamma(double alpha, double beta) {
if (alpha < 1.0) {
double u;
do {
u = NextDouble();
} while (u == 0.0);
return SampleGamma(alpha + 1.0, beta) * pow(u, 1.0 / alpha);
} else {
double d,c,x,v,u;
d = alpha - 1.0/3.0;
c = 1.0 / sqrt( 9.0 * d );
}
else {
double d, c, x, v, u;
d = alpha - 1.0 / 3.0;
c = 1.0 / sqrt(9.0 * d);
do {
do {
x = SampleNormal();
v = 1.0 + c*x;
} while ( v <= 0.0 );
} while (v <= 0.0);
v = v * v * v;
u = NextDouble();
} while ( (u >= (1.0 - 0.0331 * (x*x) * (x*x)))
&& (log(u) >= (0.5 * x * x + d * (1.0 - v + log(v)))) );
} while ((u >= (1.0 - 0.0331 * (x*x) * (x*x)))
&& (log(u) >= (0.5 * x * x + d * (1.0 - v + log(v)))));
return d * v / beta;
}
}
template<typename T>
inline void Exchange( T &a, T &b ){
inline void Exchange(T &a, T &b){
T c;
c = a;
a = b;
b = c;
}
template<typename T>
inline void Shuffle( T *data, size_t sz ){
if( sz == 0 ) return;
for( uint32_t i = (uint32_t)sz - 1; i > 0; i-- ){
Exchange( data[i], data[ NextUInt32( i+1 ) ] );
}
inline void Shuffle(T *data, size_t sz){
if (sz == 0) return;
for (uint32_t i = (uint32_t)sz - 1; i > 0; i--){
Exchange(data[i], data[NextUInt32(i + 1)]);
}
}
// random shuffle the data inside, require PRNG
template<typename T>
inline void Shuffle( std::vector<T> &data ){
Shuffle( &data[0], data.size() );
inline void Shuffle(std::vector<T> &data){
Shuffle(&data[0], data.size());
}
};
};

View File

@@ -9,44 +9,44 @@
*/
namespace xgboost{
namespace utils{
/*!
* \brief interface of stream I/O, used to serialize model
/*!
* \brief interface of stream I/O, used to serialize model
*/
class IStream{
public:
/*!
/*!
* \brief read data from stream
* \param ptr pointer to memory buffer
* \param size size of block
* \return usually is the size of data readed
*/
virtual size_t Read( void *ptr, size_t size ) = 0;
/*!
virtual size_t Read(void *ptr, size_t size) = 0;
/*!
* \brief write data to stream
* \param ptr pointer to memory buffer
* \param size size of block
*/
virtual void Write( const void *ptr, size_t size ) = 0;
virtual void Write(const void *ptr, size_t size) = 0;
/*! \brief virtual destructor */
virtual ~IStream( void ){}
virtual ~IStream(void){}
};
/*! \brief implementation of file i/o stream */
class FileStream: public IStream{
class FileStream : public IStream{
private:
FILE *fp;
public:
FileStream( FILE *fp ){
public:
FileStream(FILE *fp){
this->fp = fp;
}
virtual size_t Read( void *ptr, size_t size ){
return fread( ptr, size, 1, fp );
virtual size_t Read(void *ptr, size_t size){
return fread(ptr, size, 1, fp);
}
virtual void Write( const void *ptr, size_t size ){
fwrite( ptr, size, 1, fp );
virtual void Write(const void *ptr, size_t size){
fwrite(ptr, size, 1, fp);
}
inline void Close( void ){
fclose( fp );
inline void Close(void){
fclose(fp);
}
};
};

View File

@@ -36,39 +36,39 @@ extern "C"{
namespace xgboost{
/*! \brief namespace for helper utils of the project */
namespace utils{
inline void Error( const char *msg ){
fprintf( stderr, "Error:%s\n",msg );
exit( -1 );
}
inline void Assert( bool exp ){
if( !exp ) Error( "AssertError" );
}
inline void Assert( bool exp, const char *msg ){
if( !exp ) Error( msg );
inline void Error(const char *msg){
fprintf(stderr, "Error:%s\n", msg);
exit(-1);
}
inline void Warning( const char *msg ){
fprintf( stderr, "warning:%s\n",msg );
inline void Assert(bool exp){
if (!exp) Error("AssertError");
}
inline void Assert(bool exp, const char *msg){
if (!exp) Error(msg);
}
inline void Warning(const char *msg){
fprintf(stderr, "warning:%s\n", msg);
}
/*! \brief replace fopen, report error when the file open fails */
inline FILE *FopenCheck( const char *fname , const char *flag ){
FILE *fp = fopen64( fname , flag );
if( fp == NULL ){
fprintf( stderr, "can not open file \"%s\"\n",fname );
exit( -1 );
inline FILE *FopenCheck(const char *fname, const char *flag){
FILE *fp = fopen64(fname, flag);
if (fp == NULL){
fprintf(stderr, "can not open file \"%s\"\n", fname);
exit(-1);
}
return fp;
}
/*! \brief replace fopen, */
inline FILE *FopenTry( const char *fname , const char *flag ){
FILE *fp = fopen64( fname , flag );
if( fp == NULL ){
fprintf( stderr, "can not open file \"%s\"\n",fname );
exit( -1 );
inline FILE *FopenTry(const char *fname, const char *flag){
FILE *fp = fopen64(fname, flag);
if (fp == NULL){
fprintf(stderr, "can not open file \"%s\"\n", fname);
exit(-1);
}
return fp;
}