//
// 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
