//
// C++ Interface: itpp_ext
//
// Description:
//
//
// Author: smidl <smidl@utia.cas.cz>, (C) 2008
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include <itpp/itbase.h>

#ifndef ITEX_H
#define ITEX_H

using std::cout;
using std::endl;

namespace itpp {
extern vec empty_vec;

Array<int> to_Arr ( const ivec &indices );
ivec linspace ( int from, int to );

vec get_vec ( const vec &v, const ivec &indexlist );

bvec operator& ( const bvec &a, const bvec &b );
bvec operator| ( const bvec &a, const bvec &b );

bvec operator> ( const vec &t1, const vec &t2 );

bvec operator< ( const vec &t1, const vec &t2 );

ivec get_from_bvec ( const ivec &v, const bvec &binlist );

// template<class Num_T>
// void set_subvector(vec &ov, ivec &iv, const Vec<Num_T> &v);

void set_subvector ( vec &ov, const ivec &iv, const vec &v );

template<class Num_T> inline
void set_col_part ( mat &M, int c, const Vec<Num_T> &v ) {
	copy_vector ( v.size(), v._data(), M._data() + c*M.rows() );
}

static const double inf = std::numeric_limits<double>::infinity();

//#if 0
/*!
  \brief Gamma distribution
  \ingroup randgen
*/
class Gamma_RNG {
public:
//! constructor. Set lambda.
	Gamma_RNG ( double a = 1.0, double b = 1.0 );
	//! Set lambda
	void setup ( double a0, double b0 ) {
		alpha = a0;
		beta = b0;
	}
	//! get lambda
	double get_setup() const;
	//! Get one sample.
	double operator() () {
		return sample();
	}
	//! Get a sample vector.
	vec operator() ( int n );
	//! Get a sample matrix.
	mat operator() ( int h, int w );
protected:
private:
	//!
	double sample();
	//!
	double alpha;
	//!
	double beta;
	//!
	Random_Generator RNG;
	Normal_RNG NRNG;
	//! compatibility with R
	inline double exp_rand() {
		return -std::log ( RNG.random_01() );
	}
	inline double unif_rand() {
		return RNG.random_01();
	}
	inline double norm_rand() {
		return NRNG.sample();
	}

};
bool qr ( const mat &A, mat &R );
//#endif
//! reimplementation of matlab num2str
std::string num2str ( double d );

//! reimplementation of matlabs num2str
std::string num2str ( int i );

//! implementation of digamma (psi) function
double psi ( double );

//! implementation of matlab triu function
void triu ( mat &A );

//! implementation of Mixtools function randun
//! This function uses Park-Miller linear congruential pseudo-random generator with A=16807 B=0 M=2^31-1
//!     (it spans all 2^31-1 numbers and has good statistical properties)
double randun();
//! implementation of Mixtools function randun
vec randun ( int n );
//! implementation of Mixtools function randun
mat randun ( int n, int m );

//! function returns unique entries in input vector \c in
ivec unique ( const ivec &in );

//! function returns unique entries of vector \c in that are not present in vector \c base
ivec unique_complement ( const ivec &in, const ivec &base );
}


#endif //ITEX_H
