#ifndef __BAYESM_H__
#define __BAYESM_H__
#include <RcppArmadillo.h>
#include <Rcpp.h>
#include <stdio.h>
#include <time.h>
using namespace arma;
using namespace Rcpp;
//CUSTOM STRUCTS--------------------------------------------------------------------------------------------------
//Used in rhierLinearMixture, rhierLinearModel, rhierMnlDP, rhierMnlRwMixture, rhierNegbinRw, and rsurGibbs
struct moments{
vec y;
mat X;
mat Xlong;
mat XpX;
vec Xpy;
mat hess;
};
//Used in rhierLinearMixture, rhierLinearModel, rhierMnlRWMixture, and utilityFunctions.cpp
struct unireg{
vec beta;
double sigmasq;
};
//Used in rhierMnlDP, rhierMnlRwMixture, and utilityFunctions.cpp
struct mnlMetropOnceOut{
vec betadraw;
int stay;
double oldll;
};
//Used in rDPGibbs, rhierMnlDP, rivDP, and utilityFunctions.cpp
struct lambda{
vec mubar;
double Amu;
double nu;
mat V;
};
//Used in rDPGibbs, rhierMnlDP, rivDP, and utilityFunctions.cpp
struct priorAlpha{
double power;
double alphamin;
double alphamax;
int n;
};
//Used in rDPGibbs, rhierMnlDP, rivDP, and utilityFunctions.cpp
struct murooti{
vec mu;
mat rooti;
};
//Used in rDPGibbs, rhierMnlDP, rivDP, and utilityFunctions.cpp
struct thetaStarIndex{
ivec indic;
std::vector<murooti> thetaStar_vector;
};
//Used in rhierMnlDP, rivDP
struct DPOut{
ivec indic;
std::vector<murooti> thetaStar_vector;
std::vector<murooti> thetaNp1_vector;
double alpha;
int Istar;
lambda lambda_struct;
};
//EXPOSED FUNCTIONS-----------------------------------------------------------------------------------------------
List rwishart(int const& nu, mat const& V);
List rmultireg(mat const& Y, mat const& X, mat const& Bbar, mat const& A, int nu, mat const& V);
vec rdirichlet(vec const& alpha);
double llmnl(vec const& beta, vec const& y, mat const& X);
mat lndIChisq(double nu, double ssq, mat const& X);
double lndMvst(vec const& x, int nu, vec const& mu, mat const& rooti, bool NORMC);
double lndMvn(vec const& x, vec const& mu, mat const& rooti);
double lndIWishart(double nu, mat const& V, mat const& IW);
vec rmvst(int nu, vec const& mu, mat const& root);
vec breg(vec const& y, mat const& X, vec const& betabar, mat const& A);
vec cgetC(double e, int k);
List rmixGibbs( mat const& y, mat const& Bbar, mat const& A, int nu, mat const& V, vec const& a, vec const& p, vec const& z);
//rmixGibbs contains the following support functions, which are called ONLY THROUGH rmixGibbs: drawCompsFromLabels, drawLabelsFromComps, and drawPFromLabels
List rmixGibbs_mod( mat const& y, int nvar_c, mat const& mustarbarc, mat const& Amu, int nu, mat const& V, mat const& Gammabar, mat const& A_Gamma, int nu_Sigma, mat const& V_Sigma, vec const& a, vec const& p, vec const& z, List prev_rootic);
//rmixGibbs contains the following support functions, which are called ONLY THROUGH rmixGibbs: drawCompsFromLabels, drawLabelsFromComps, and drawPFromLabels
//SUPPORT FUNCTIONS (contained in utilityFunctions.cpp)-----------------------------------------------------------
//Used in rmvpGibbs and rmnpGibbs
vec condmom(vec const& x, vec const& mu, mat const& sigmai, int p, int j);
double rtrun1(double mu, double sigma,double trunpt, int above);
//Used in rhierLinearModel, rhierLinearMixture and rhierMnlRWMixture
mat drawDelta(mat const& x,mat const& y,vec const& z,List const& comps,vec const& deltabar,mat const& Ad);
unireg runiregG(vec const& y, mat const& X, mat const& XpX, vec const& Xpy, double sigmasq, mat const& A, vec const& Abetabar, int nu, double ssq);
//Used in rnegbinRW and rhierNegbinRw
double llnegbin(vec const& y, vec const& lambda, double alpha, bool constant);
double lpostbeta(double alpha, vec const& beta, mat const& X, vec const& y, vec const& betabar, mat const& rootA);
double lpostalpha(double alpha, vec const& beta, mat const& X, vec const& y, double a, double b);
//Used in rbprobitGibbs and rordprobitGibbs
vec breg1(mat const& root, mat const& X, vec const& y, vec const& Abetabar);
vec rtrunVec(vec const& mu,vec const& sigma, vec const& a, vec const& b);
//Used in rhierMnlDP and rhierMnlRwMixture
mnlMetropOnceOut mnlMetropOnce(vec const& y, mat const& X, vec const& oldbeta, double oldll,double s, mat const& incroot, vec const& betabar, mat const& rootpi,int const& pr);
//Used in rDPGibbs, rhierMnlDP, rivDP
int rmultinomF(vec const& p);
mat yden(std::vector<murooti> const& thetaStar, mat const& y);
ivec numcomp(ivec const& indic, int k);
murooti thetaD(mat const& y, lambda const& lambda_struct);
thetaStarIndex thetaStarDraw(ivec indic, std::vector<murooti> thetaStar_vector, mat const& y, mat ydenmat, vec const& q0v, double alpha, lambda const& lambda_struct, int maxuniq);
vec q0(mat const& y, lambda const& lambda_struct);
vec seq_rcpp(double from, double to, int len); //kept _rcpp due to conflict with base seq function
double alphaD(priorAlpha const& priorAlpha_struct, int Istar, int gridsize);
murooti GD(lambda const& lambda_struct);
lambda lambdaD(lambda const& lambda_struct, std::vector<murooti> const& thetaStar_vector, vec const& alim, vec const& nulim, vec const& vlim, int gridsize);
//FUNCTION TIMING (contained in functionTiming.cpp)---------------------------------------------------------------
void startMcmcTimer();
void infoMcmcTimer(int rep, int R);
void endMcmcTimer();
#endif