/*--------------------------------------------------------------------------
 * pcfimldgp.h - definitions/declarations for PcFimlDgp class
 *
 *       (C) Jurgen Doornik 1998
 *
 *--------------------------------------------------------------------------*/

#ifndef PCFIMLDGP_INCLUDED
#define PCFIMLDGP_INCLUDED

#import <database>
#import <ranmc>

enum
{   Y_VAR, X_VAR, U_VAR, Z_VAR
};

enum
{   U_DGP, Z_DGP, Y_DGP
};

class PcFimlDgp : Database
{
    decl m_iT1, m_iT2;         	// generation sample
    decl m_cY;              	// number of dependent variables
    decl m_cZ;              	// number of regressors at lag 0
    decl m_mPit;             	// URF/RRF coefficient matrix   [k][m_cY]
    decl m_mC0t;             	// coefficient matrix on Z_1    [q][q]
    decl m_iEdist;         		// error distribution
    decl m_mEdistM, m_mEdistS;	// error dist pars[1][n],[1 or n][n]
    decl m_iZdist;          	// Z distribution
    decl m_mZdistM, m_mZdistS;	// Z dist params [1][q],[1 or q][q]
    decl m_bFixedZ;             // TRUE for fixed Z
    decl m_bHaveZ;              // FALSE if Z needs to be generated
	decl m_bUseObsLoop;			// TRUE: loop over observations to generate
	decl m_mxDgpLag;			// used to allow for initial values

	decl m_cYU;					// = 2 * m_cY
	decl m_cYUZ;				// = 2 * m_cY + m_cZ
	decl m_cYUZV;				// = 2 * m_cY + 2 * m_cZ
	decl m_mxSelLag;			// highest lag in selection
	decl m_mDepY;				// database indices of dependent vars, Y eqn
	decl m_mRegY;				// database indices of regressors, Y eqn
	decl m_mLagY;				// corresponding lag lengths, Y eqn
	decl m_mDepZ;				// database indices of depvars/regs, Z eqn
	decl m_mLagZ;				// corresponding lag lengths, Z eqn

	decl m_mInitY;			 	// holds initial values of Y, [m][n]
	decl m_mInitZ;			 	// holds initial values of Z, [1][q]
	
    PcFimlDgp(const cY, const cZ);  // constructor

	Asymp();                        // prints asymptotic analysis
	AsympEx(const asModelY, const asModelX, const cT);// same for PcNaive compatibility
	Create(const iFreq,
		const iYear1, const iPeriod1, const cTdiscard, const mxDgpLag, const mxT);
	DiscardZ();						// call to regenerate Z in next GenerateTo()
	GenerateTo(const cT);           // generates the data, returns Y~U
    GetU();                         // returns U
	GetV();                         // returns V
    GetY();                         // returns Y
    GetZ();                         // returns Z
    Print();                        // print the DGP
	SetDistribution(const iEqn, const iDist, mPar1, mPar2);
	SetFixedZ(const fSetting);		// set Z fixed or non-fixed
	SetInit(const iDgp, const mInit);// to specify initial values
    SetU(const m);                  // sets U
	SetV(const m);                  // sets V
    SetY(const m);                  // sets Y
    SetZ(const m);                  // sets Z
	SetYParameter(const mPit);
	SetZParameter(const mC0);
	UseObsLoop(const bUseObsLoop);	// switches looping over obs on or off 

	virtual Prepare();				// called once prior to generation
									// the next 8 are called from GenerateTo()
	virtual GenerateV(const cT);
	virtual GenerateZ(const cT, const mC0t, const mV);
	virtual GenerateU(const cT);
	virtual GenerateY(const cT, const mPit, const mU);
	virtual GenerateV_t(const iT);
	virtual GenerateZ_t(const iT, const mC0t);
	virtual GenerateU_t(const iT);
	virtual GenerateY_t(const iT, const mPit);
};

#endif /* PCFIMLDGP_INCLUDED */
