/*--------------------------------------------------------------------------
 * pcnaive.h - definitions/declarations for PcNaiveDgp class
 *
 *       (C) Jurgen Doornik 1994
 *
 *--------------------------------------------------------------------------*/

#ifndef PCNAIVE_INCLUDED
#define PCNAIVE_INCLUDED

#import <ranmc>

enum
{   U_DGP, Z_DGP, Y_DGP
};

class PcNaiveDgp
{
    decl m_cY;                                  // dimension of Y
    decl m_cZ;                                  // dimension of Z
    decl m_mZ;                                     // generated Z
    decl m_mY;                                     // generated Y
    decl m_mU;                                     // generated U
	decl m_mZC;//custom Z, set using SetZCustom() before generate
	decl m_bSimultaneous, m_bArmaErrors;

    decl m_mB0t;                // B0' error AR parameters [n][n]
    decl m_mB1t;                // B1' error MA parameters [n][n]
    decl m_iEdist;                          // error distribution
    decl m_mEdistM, m_mEdistS;//error dist pars[1][n],[1 or n][n]

    decl m_mC0t;                       // C0' coefs on Z_1 [q][q]
    decl m_mC1t;                  // c1' coefs on constant [1][q]
    decl m_mC2t;                     // c2' coefs on trend [1][q]

    decl m_iZdist;                              // Z distribution
    decl m_mZdistM, m_mZdistS;// Z dist params [1][q],[1 or q][q]
    decl m_fFixedZ;                           // TRUE for fixed Z
	decl m_bCustomZ; // TRUE: call add custom Z when generating Z

    decl m_mA0;                // A0 structural coefs on Y [n][n]
    decl m_mA1;              // A1 structural coefs on Y_1 [n][n]
    decl m_mA2;                // A2 structural coefs on Z [n][q]
    decl m_mA3;         // a3 structural coefs on constant [n][1]
    decl m_mA5;              // A5 structural coefs on Y_2 [n][n]
    decl m_mDinv;          // inv(D) inverse of coefs on Y [n][n]
    decl m_mA1tRf;            // A1'inv(D) rf coefs on Y_1 [n][n]
    decl m_mA2tRf;              // A2'inv(D) rf coefs on Z [q][n]
    decl m_mA3tRf;       // a3'inv(D) rf coefs on constant [1][n]
    decl m_mA5tRf;            // A5'inv(D) rf coefs on Y_2 [n][n]
	decl m_cYlag;						         // maximum Y lag
	decl m_mAlpha, m_mBeta;//Alpha, Beta, when formulating as ECM 
	decl m_bUsedEcm;

	decl m_bInitY;			// TRUE: initial value of Y specified
	decl m_mInitY;			 // holds initial values of Y, [2][n]
	decl m_mInitZ;			 // holds initial values of Z, [1][q]

    PcNaiveDgp(const cY, const cZ);                // constructor

    Asymp();                        // prints asymptotic analysis
	AsympEx(const asModelY, const asModelZ, const cT);//and plims
    DiscardZ();                     // next rep will create new Z
	Generate(const cT);          // generates the data, returns Y
	GenerateTo(const cT);	  // as Generate(), but returning Y~U
	GenerateBreakTo(const cT,	   // generates data with a break
		const iTbreak, const iTreset,
		const mA0, const mA1, const mA2, const mA3, const mA4);
    GetU();                                          // returns U
    GetY();                                          // returns Y
    GetZ();                                          // returns Z
    Print();                                     // print the DGP
    SetDistribution(const iEqn,  // install an error distribution
        const iDist, mM, mS);
    SetFixedZ(const fSetting);
	SetInit(const iDgp, const mInit);// to specify initial values
    SetUParameter(const B0,      // install U equation parameters
       const B1);
    SetYParameter(const mA0,     // install Y equation parameters
        const mA1, const mA2, const mA3, ...);
	SetYParameterEcm(const mAlpha,  // install Y eqn in VECM form
		const mBeta, const mZpar, const vConst, ...);
    SetZParameter(const mC0,     // install Z equation parameters
        const mC1, const mC2);
	SetZCustom(mCZ);			// install the custom Z component

	generateZ(const cT);     
	generateU(const cT);     
	generateY(const iT1, const iT2, const mU, const mInitY,
		const mA1tRf, const mA2tRf, const mA3tRf,
		const mA5tRf, const mDinv);
    generateHeteroObs(const cT);    //generates by obs, returns Y
	companion(const bdoY_2);// computes companion form, returns a lot
};

#endif /* PCNAIVE_INCLUDED */
