/*
 * Copyright (C) 1996-2011 Daniel Waggoner and Tao Zha
 *
 * This free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * It is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * If you did not received a copy of the GNU General Public License
 * with this software, see <http://www.gnu.org/licenses/>.
 */

#ifndef __MARKOV_SWITCHING__
#define __MARKOV_SWITCHING__

#ifdef __cplusplus
extern "C"
{
#endif

#define __SWITCHING_VER_200__

#include "dw_matrix.h"
#include <stdio.h>


//=== Declaring structures so pointers can be defined ===
struct TMarkovStateVariable_tag;
struct TStateModel_tag;
struct TMetropolis_theta_tag;


/*******************************************************************************/
/********************************** QRoutines **********************************/
/*******************************************************************************/
typedef struct
{
  // required routines
  int (*Probability_s0)(TVector p, struct TMarkovStateVariable_tag*);
  int (*ComputeTransitionMatrix)(int t, struct TMarkovStateVariable_tag*, struct TStateModel_tag*);
  PRECISION (*pLogPrior)(struct TMarkovStateVariable_tag*);

  // simulation routines
  PRECISION (*DrawProposalTransitionMatrixParameters)(int*, struct TMarkovStateVariable_tag*, struct TStateModel_tag*);
  int (*DrawTransitionMatrixParameters)(int*, struct TMarkovStateVariable_tag*, struct TStateModel_tag*);
  int (*pDrawTransitionMatrixParametersFromPrior)(struct TMarkovStateVariable_tag*);

  // memory management
  void (*FreeInfo)(void*);
  void* (*DuplicateInfo)(void*);

  // io routines
  int (*WriteSpecification)(FILE*, struct TMarkovStateVariable_tag*, char*);

  // miscellaneous routines
  int (*DefaultTransitionMatrixParameters)(struct TMarkovStateVariable_tag*, struct TStateModel_tag*);
  int (*Update_q_from_BaseTransitionMatrix)(int, struct TMarkovStateVariable_tag*, struct TStateModel_tag*);

} QRoutines;

//=== Constructors ===
QRoutines* CreateQRoutines_empty(void);
QRoutines* DuplicateQRoutines(QRoutines *routines);

/*******************************************************************************/
/*******************************************************************************/
/*******************************************************************************/


/*******************************************************************************/
/******************************** ThetaRoutines ********************************/
/*******************************************************************************/
typedef struct
{
  //=== Computes ln(P(y[t] | Y[t-1], Z[t], theta, q, s[t] = s)) ===
  PRECISION (*pLogConditionalLikelihood)(int s, int t, struct TStateModel_tag *model);

  //=== Computes Log of the prior on the model specific parameters ===
  PRECISION (*pLogPrior)(struct TStateModel_tag *);

  //=== Computes E[y[t] | Y[t-1], Z[t], theta, q, s[t] = s] ===
  TVector (*pExpectationSingleStep)(TVector y, int s, int t, struct TStateModel_tag *model);

  //=== Computes E[epsilon[t] | Y[T], Z[T], theta, q, s[t] = s] ===
  TVector (*pExpectedError)(TVector epsilon, int s, int t, struct TStateModel_tag *model);

  //=== Computes E[y[t] | Y[t-1], Z[t], theta, q, s[t] = s], works even for t > T, ===
  //=== data[tau] = Y[T+tau+1], assumes exogeneous variable z[t] is deterministic  ===
  TVector (*pEyt)(TVector y, int T, TVector *data, int s, int t, struct TStateModel_tag *model);

  //=== Computes E[y[t] | Y[t-1], Z[t], theta, q, s[t] = s, shock(i)], shock(i) is the unit  ===
  //=== value of the model specific ith shock, works even for t > T, data[tau] = Y[T+tau+1], ===
  //=== assumes exogeneous variable z[t] is deterministic                                    ===
  TVector (*pEyt_i)(TVector y, int T, TVector *data, int i, int s, int t, struct TStateModel_tag *model);

  //=== Makes random draw of y[t] given Y[t-1], Z[t], theta, q, s[t] = s, works for t > T, ===
  //=== data[tau] = Y[T+tau+1], assumes exogeneous variable z[t] is deterministic          ===
  TVector (*pyt_draw)(TVector y, int T, TVector *data, int s, int t, struct TStateModel_tag *model);

  //=== Destructs parameters ===
  void (*pDestructor)(void *);

  //=== Draws parameters conditional states and transition probability ===
  void (*pDrawParameters)(struct TStateModel_tag *);
  void (*pDrawParametersFromPrior)(struct TStateModel_tag *);

  //=== Converts between free parameters and model specific parameters ===
  int (*pNumberFreeParametersTheta)(struct TStateModel_tag*);
  void (*pConvertFreeParametersToTheta)(struct TStateModel_tag*, PRECISION*);
  void (*pConvertThetaToFreeParameters)(struct TStateModel_tag*, PRECISION*);

  //=== Notification routines ===
  void (*pStatesChanged)(struct TStateModel_tag*);
  void (*pThetaChanged)(struct TStateModel_tag*);
  void (*pTransitionMatrixParametersChanged)(struct TStateModel_tag*);
  int (*pValidTheta)(struct TStateModel_tag*);

  //=== Allows for initialization of data structures before forward recursion ===
  int (*pInitializeForwardRecursion)(struct TStateModel_tag*);

  //=== Permutes the elements of theta ===
  /* int (*pPermuteTheta)(int*, struct TStateModel_tag*); */
  /* int (*pGetNormalization)(int*, struct TStateModel_tag*); */
  /* int (*pNormalizeRegimes)(struct TStateModel_tag*);                         // sets array normalized_regimes and returns 1 if normalization is necessary */
  /* PRECISION (*pLogConstant_RegimeNormalization)(struct TStateModel_tag*);    //  */

  //=== Identifies model type ===
  char* (*pModelType)(void);

  //=== Checks if draw of regimes is degenerate
  int (*pIsDegenerate)(int*, struct TStateModel_tag*);

  //=== Normalizing regimes
  int (*pComputeNormalizingPermutation)(int*, struct TStateModel_tag*);
  int (*pNormalizeRegimes)(int*, struct TStateModel_tag*, PRECISION*);
  int (*pComputeRegimeNormalizationLogConstant)(struct TStateModel_tag*);

} ThetaRoutines;

//=== Constructors ===
ThetaRoutines* CreateThetaRoutines_empty(void);

/*******************************************************************************/
/*******************************************************************************/
/*******************************************************************************/


/*******************************************************************************/
/**************************** TMarkovStateVariable *****************************/
/*******************************************************************************/
typedef struct TMarkovStateVariable_tag
{
  //=== Flags ===================================================================
  // The transition matrix Q is valid for t0 <= t <= t1.
  int t0, t1;                   
                               
  //=== Lag encoding ============================================================
  // Number of lags encoded.  Must be non-negative.
  int nlags_encoded;

  // Number of base states.  Note that nbasestates^(nlags_encoded+1) = nstates.        
  int nbasestates; 

  // nstates x (nlags_encoded + 1).  lag_index[k][j] is the value of the jth 
  // lag when the overall state is k.        
  int** lag_index;

  // Base transition matrix.  This is filled via a call to 
  // sv_ComputeTransitionMatrix)(t,*,*).  If n_state_variables is 1, then 
  // baseQ = state_variable[0]->Q (as pointers!)     
  TMatrix baseQ;                

  //=== Sizes ===================================================================
  // Equal to nbasestates^(nlags_encoded + 1).
  int nstates; 
 
  // Number of free parameters in transition matrix (either Q or baseQ).          
  int nfree;                    

  //=== Transition matrix =======================================================
  // Q(i,j) is the probability that s(t+1) = i given s(t)=j.  This is filled via 
  // a call to sv_ComputeTransitionMatrix)(t,*,*).  If nlags_encoded is 0, then 
  // Q = baseQ (as pointers!)
  TMatrix Q;                    

  //=== Free parameters =========================================================
  // Free parameters.  This memory is tightly managed and NOT owned by the 
  // structure!
  PRECISION *q;                 

  //=== Parent Markov state variable ============================================
  // Either parent state variable or null pointer.
  struct TMarkovStateVariable_tag *parent;           

  //=== Multiple state variables ================================================
  // number of independent state_variables
  int n_state_variables;    
    
  // Independent state variables. Must have been created via a call to 
  // dw_CreateArray_pointer(n_state_variables,(void (*)(void*))FreeMarkovStateVariable);                           
  struct TMarkovStateVariable_tag **state_variable;

  // nbasestates x n_state_variables. index[k][j] is the value of the jth state 
  // variable when the basestate state is k.  
  int** index; 

  // QA[j] = state_variable[j]->Q (as pointers!).  Currently, this is only used
  // in computing Kronecker products of transistion matrices.                                    
  TMatrix *QA;                                       

  //=== Routines ================================================================
  // See QRoutines for list of available functions.
  QRoutines *routines;   
                            
  // Information for manipulating free transition matrix parameters. 
  void *info;                                        

} TMarkovStateVariable;

//=== Constructors and destructors ===
void FreeMarkovStateVariable(TMarkovStateVariable *sv);
TMarkovStateVariable* CreateMarkovStateVariable_Single(int nstates, int nfree, int nlags, QRoutines *routines, void *info);
TMarkovStateVariable* CreateMarkovStateVariable_Multiple(int nlags, TMarkovStateVariable **state_variables);
TMarkovStateVariable* CreateMarkovStateVariable_base(int nlags_encoded, TMarkovStateVariable *sv);
TMarkovStateVariable* CreateMarkovStateVariable_lags(int nlags_encoded, TMarkovStateVariable *sv);
#define DuplicateMarkovStateVariable(sv) CreateMarkovStateVariable_base((sv)->nlags_encoded,sv)

//=== Base routines ===
void sv_SetupFreeParameters(PRECISION *q, TMarkovStateVariable *sv);
void sv_InvalidateTransitionMatrix(TMarkovStateVariable *sv);
int sv_ComputeTransitionMatrix(int t, TMarkovStateVariable *sv, struct TStateModel_tag *model);
PRECISION sv_LogPrior(TMarkovStateVariable *sv);
int sv_Probability_s0(TVector p, TMarkovStateVariable *sv);

PRECISION sv_DrawProposalTransitionMatrixParameters(int *S, TMarkovStateVariable *sv, struct TStateModel_tag *model);
int sv_DrawTransitionMatrixParameters(int *S, TMarkovStateVariable *sv, struct TStateModel_tag *model);
int sv_DrawTransitionMatrixParametersFromPrior(TMarkovStateVariable *sv);
int sv_DefaultTransitionMatrixParameters(TMarkovStateVariable *sv, struct TStateModel_tag *model);

int sv_ValidRoutines(TMarkovStateVariable *sv);
int sv_ValidMetropolisHastings(TMarkovStateVariable *sv);
int sv_ValidDirectDraw(TMarkovStateVariable *sv);

//=== Lag routines ===
void ConvertBaseTransitionMatrix(TMatrix Q, TMatrix baseQ, int nlags_encoded);
int** CreateLagIndex(int nbasestates, int nlags, int nstates);
TVector* sv_BaseProbabilities(TVector *base_prob, TVector *prob, TMarkovStateVariable *sv);
TVector* sv_FullBaseProbabilities(TVector *prob, TMarkovStateVariable *sv);

//=== Normalization routines ===
int sv_NormalizeRegimes(int *p, int t, TMarkovStateVariable *sv, struct TStateModel_tag *model);
/*******************************************************************************/
/*******************************************************************************/
/*******************************************************************************/

/*******************************************************************************/
/********************************* TStateModel *********************************/
/*******************************************************************************/
typedef struct TStateModel_tag
{
  //===  Markov state variable ===
  TMarkovStateVariable *sv;
  PRECISION *q;                  // free transition matrix parameters
  int* S;                        // integer array of length nobs+1
  
  // Metropolis-Hasting information for q
  int use_metropolis_hasting;
  int metropolis_jumps_q;
  int metropolis_draws_q;

  // Regime normalization
  int kill_unnormalized;
  PRECISION regime_normalization_logconstant;
  int *normalized_regimes;       // integer array of lenth sv->nstates.  If s_t is the internal representation
                                 // of the regime and s_hat_t is the external representation of the regime, then 
                                 // s_t = normalized_regimes[s_hat_t].

  //=== Data bounds ===
  int fobs;                      // first observation for the purpose of computing LogLikelihood_StatesIntegratedOut()
  int nobs;                      // number of observations

  //=== Simulation information ===
  PRECISION max_log_posterior;
  TVector max_posterior_theta;
  TVector max_posterior_q;

  //=== Notification flags ===
  int ForwardRecursionFailed;

  //=== Common work space ===
  int SP_Computed;  // SP[t](i) is valid for 0 <= t <= nobs and 0 <= i < nstates
  int t0;           // C[t], V[t], Z[t], and L(t) are valid for t <= t0
  TVector *C;       // C[t](i) = ln(P(y[t] | Y[t-1], Z[t], s[t]=i, theta, q)) for 0 < t <= nobs, 0 <= i < nstates, and Z[t][i] > 0.0
  TVector *V;       // V[t](i) = P(s[t] = i | Y[t], Z[t], theta, q)  0 <= t <= nobs and 0 <= i < nstates
  TVector *Z;       // Z[t](i) = P(s[t] = i | Y[t-1], Z[t-1], theta, q)  0 < t <= nobs and 0 <= i < nstates
  TVector L;        // L(t) = ln(P(Y[t] | Z[t], theta, q)) 0 <= t <= nobs
  //TMatrix *W;       // W[t](i,j) = P(s[t-1]=i | Y[t], Z[t], theta, q, s[t]=j) 0 < t < nobs, 0 <= i,j < nstates
  TVector *SP;      // SP[t](i) = P(s[t] = i | Y[T], Z[T], theta, q) 0 <= t <= nobs, 0 <= i < nstates

  //=== Model specific parameters and routines to handle them ===
  void *theta;
  ThetaRoutines *routines;

  // Metropolis information for theta
  struct TMetropolis_theta_tag *metropolis_theta;

  //=== Control variables ===
  int NormalizeStates;

  //=== Degenerate draws of states
  int reject_degenerate_draws;  // if positive, reject degenerate draws of states. value determines how many attempts to make before exiting
  int degenerate_draws_cutoff;  // number of draws needed for each state in order not to be degenerate
  int n_degenerate_draws;       // counter for number of degenerate draws of states
  int total_degenerate_draws;   // counter for total number of degenerate draws

} TStateModel;

//=== Constructors/Destructors ===
void FreeStateModel(TStateModel *model);
TStateModel* CreateStateModel(int nobs, TMarkovStateVariable *sv, ThetaRoutines *routines, void *theta);

//=== Notification routines ===
void StatesChanged(TStateModel *model);
void TransitionMatrixParametersChanged(TStateModel *model);
void ThetaChanged(TStateModel *model);
#define ValidTheta(model) (((model)->routines->pValidTheta) ? (model)->routines->pValidTheta(model) : 1)

//=== Transition matrix routines ===
int ComputeTransitionMatrix(int t, TStateModel *model);
int Probability_s0(TVector p, TStateModel *model);
TVector* BaseProbabilities(TVector *base_prob, TVector *prob, TStateModel *model);

//=== Simulation routines ===
int ForwardRecursion(int t, TStateModel *model);
#define InitializeForwardRecursion(model) (((model)->routines->pInitializeForwardRecursion) ?  (model)->routines->pInitializeForwardRecursion(model) : 1) 
int ComputeSmoothedProbabilities(TStateModel *model);
int DrawStates(TStateModel *model);
#define IsDegenerate(regime_counts,model) (((model)->routines->pIsDegenerate) ?  (model)->routines->pIsDegenerate(regime_counts,model) : 0) 
int DrawStatesFromTransitionMatrices(TStateModel *model);
int DrawTransitionMatrixParameters(TStateModel *model);
void ResetMetropolisHastingsCounts_q(TStateModel *model);
int DrawTransitionMatrixParameters_MetropolisHastings(TStateModel *model);
int DrawTransitionMatrixParametersFromPrior(TStateModel *model);
int DefaultTransitionMatrixParameters(TStateModel *model);
void DrawTheta(TStateModel *model);
void DrawThetaFromPrior(TStateModel *model);
void DrawAll(TStateModel *model);

//=== Regime normalization ===
#define ComputeNormalizingPermutation(permutation,model) (((model)->routines->pComputeNormalizingPermutation) ? (model)->routines->pComputeNormalizingPermutation(permutation,model) : 0)
#define ComputeRegimeNormalizationLogConstant(model) (((model)->routines->pComputeRegimeNormalizationConstant) ? (model)->routines->pComputeRegimeNormalizationConstant(model) : 0)
int AreRegimesNormalized(int *permutation, TStateModel *model);
int NormalizeRegimes(int *permutation, TStateModel *model, PRECISION *buffer);

//=== Impulse responses and forecasts ===
TMatrix ImpluseResponse(TMatrix IR, int i, int T, int horizon, TStateModel *model);
TMatrix ForecastMean(TMatrix F, int T, int horizon, TStateModel *model);
TMatrix ForecastRandom(TMatrix F, int T, int horizon, TStateModel *model);
#define Eyt(y,T,data,s,t,model) ((model)->routines->pEyt ? (model)->routines->pEyt(y,T,data,s,t,model) : (TVector)NULL)
#define Eyt_i(y,T,data,i,s,t,model) ((model)->routines->pEyt_i ? (model)->routines->pEyt_i(y,T,data,i,s,t,model) : (TVector)NULL)
#define yt_draw(y,T,data,s,t,model) ((model)->routines->pyt_draw ? (model)->routines->pyt_draw(y,T,data,s,t,model) :(TVector)NULL)


//=== Probability routines ===
// ln(P(y[t] | Y[t-1], Z[t], s[t], theta, q))
#define LogConditionalLikelihood(s,t,model)  ((model)->routines->pLogConditionalLikelihood(s,t,model))

// ln(P(y[t] | Y[t-1], Z[t], theta, q))
PRECISION LogConditionalLikelihood_StatesIntegratedOut(int t, TStateModel *model);

// E[y[t] | Y[t-1], Z[t], s[t], theta, q]
#define ExpectationSingleStep(y,s,t,model) ((model)->routines->pExpectationSingleStep(y,s,t,model))

// E[y[t] | Y[t-1], Z[t], theta, q]
TVector ExpectationSingleStep_StatesIntegratedOut(TVector y, int t, TStateModel *model);

// E[epsilon[t] | Y[T], Z[t], theta, q]
TVector ExpectedError(TVector epsilon, int t, TStateModel *model);

// ln(P(q))
#define LogPrior_q(model) sv_LogPrior((model)->sv)

// ln(P(theta))
#define LogPrior_theta(model)  ((model)->routines->pLogPrior(model))

// ln(P(theta, q))
#define LogPrior(model)  (LogPrior_theta(model) + LogPrior_q(model))

// ln(P(S[T] | theta, q))
PRECISION LogPrior_S(TStateModel *model);

// ln(P(Y[T] | Z[T], S[T], theta, q)) - Assumes that the data is for fobs <= t <= nobs
PRECISION LogLikelihood(TStateModel *model);

// ln(P(Y[T] | Z[T], S[T], theta, q) * P(S[T] | theta, q) * P(theta, q))
#define LogPosterior(model)  (LogLikelihood(model) + LogPrior_S(model) + LogPrior(model))

// ln(P(Y[T] | Z[T], theta, q)) - Assumes that the data is for fobs <= t <= nobs
PRECISION LogLikelihood_StatesIntegratedOut(TStateModel *model);

// ln(P(Y[T] | Z[T], theta, q) * P(theta, q))
PRECISION LogPosterior_StatesIntegratedOut(TStateModel *model);

// P(s[t] = s | Y[t], Z[t], theta, q)
PRECISION ProbabilityStateConditionalCurrent(int s, int t, TStateModel *model);

// P(s[t] = s | Y[t-1], Z[t-1], theta, q)
PRECISION ProbabilityStateConditionalPrevious(int s, int t, TStateModel *model);

// Sum(P(s[t] = k | Y[t], Z[t], theta, q), where lag_index[k][0] = s)
PRECISION ProbabilityBaseStateConditionalCurrent(int s, int t, TStateModel *model);

// ln(P(S[T] = S | Y[T], Z[T], theta, q))
PRECISION LogProbabilityStates(int *S, TStateModel *model);

// p[t] = P(s[t] = s | Y[T], Z[T], theta, q)
TVector ProbabilitiesState(TVector p, int s, TStateModel *model);

// p[t][s] = P(s[t] = s | Y[tau], Z[tau], theta, q)
TVector* RealTimeSmoothedProbabilities(TVector *p, int tau, TStateModel *model);

//=== Free parameters routines ===
#define NumberFreeParametersQ(model)  ((model)->sv->nfree)
void ConvertQToFreeParameters(TStateModel *model, PRECISION *f);
void ConvertFreeParametersToQ(TStateModel *model, PRECISION *f);

#define NumberFreeParametersTheta(model)  ((model)->routines->pNumberFreeParametersTheta(model))
#define ConvertThetaToFreeParameters(model,f)  ((model)->routines->pConvertThetaToFreeParameters(model,f))
void ConvertFreeParametersToTheta(TStateModel *model, PRECISION *f);

//=== Miscellaneous Routines ===
#define ModelType(model) ((model)->routines->pModelType ? (model)->routines->pModelType() : (char*)NULL)

/*******************************************************************************/
/*******************************************************************************/
/*******************************************************************************/

//=== Utility routines ===
TVector Ergodic(TVector v, TMatrix P);
int DrawDiscrete(TVector p);
TVector* IntegrateStatesSingleV(TVector *Y, TVector P, TVector *X, int a, int b, int c);
TMatrix* IntegrateStatesSingleM(TMatrix *Y, TVector P, TMatrix *X, int a, int b, int c);
TVector** IntegrateStatesV(TVector **Y, TVector* P, TVector **X, int a, int b, int c);
TVector IntegrateStatesSingle(TVector Q, TVector P, int a, int b, int c);
TVector* IntegrateStates(TVector *Q, TVector* P, int a, int b, int c);
/*******************************************************************************/
/*******************************************************************************/
/*******************************************************************************/


//=== Obsolete names ===
#define ProbabilityStateGivenCurrentData(s,t,model) ProbabilityStateConditionalCurrent(s,t,model)
#define ProbabilityStateGivenPreviousData(s,t,model) ProbabilityStateConditionalPrevious(s,t,model)
#define ProbabilityStateGivenAllData(P,s,model) ProbabilitiesState(P,s,model)
//PRECISION ProbabilityStatesGivenData(TStateModel *model);
#define LogLikelihoodGivenParameters(model)  LogLikelihood_StatesIntegratedOut(model)
#define LogConditionalProbabilityStates(S, model)  LogProbabilityStates(S, model)
#define LogConditionalPrior_S(model)  LogPrior_S(model)
//PRECISION LogMarginalPosterior(TStateModel *model);
//void DrawAllParameters(TMarkovStateVariable *sv);
//void DrawAllParametersAndNormalizeStates(TMarkovStateVariable *sv);
//PRECISION ComputeMarginalLogLikelihood(TMarkovStateVariable *sv);
/*******************************************************************************/
/*******************************************************************************/
/*******************************************************************************/

#ifdef __cplusplus
}
#endif
  
#endif

/***************************** TMarkovStateVariable *****************************
  The TMarkovStateVariable type can represent either a single Markov state
  variable or a collection of independent Markov state variables.

  The transition matrix Q is generated for a single Markov state variable via
  the routines DrawTransitionMatrixFromPrior_SV() or DrawTransitionMatrix_SV().
  Calls to these functions by multiple independent Markov state variables result
  in recursive call to these functions.

  The vector of states S is generated only by a TStateModel structure containing 
  the TMarkovStateVariable structure.  The state is only generated at the top 
  level and can be propagated downward with a call to PropagateStates_SV().

  The following set of fields are set for both types.
  ===============================================================================
    int UseErgodic
      Uses the ergodic distribution if non-zero and uses the uniform distribution
      otherwise.

    int nstates
      Number of states.  Always positive.

    int nobs
      Number of observations.  Always positive.

    int* S
      S[t] is the state at time t, for 0 <= t <= nobs.  S is created via a call
      to dw_CreateArray_int().  It is guaranteed that 0 <= S[t] < nstates.

    TMatrix Q
      Markov transition matrix.

    struct TMarkovStateVariable_tag *parent
      Parent of the Markov state variable.  If the Markov state variable has no
      parent, then parent is a null pointer.

    int n_state_variables
      Number of state variables.  Will be equal to zero for single Markov state
      variables and larger than one in the case of multiple independent Markov
      state variables.  A value of one can be used to encode additional lagged
      values of the states.

    struct TMarkovStateVariable_tag **state_variable
      An array of markov state variables of length n_state_variables.  When 
      creating a mulitple Markov state variable via a call to the routine
      CreateMarkovStateVariable_Multiple(), the last argument which is a pointer
      to a pointer to a TMarkovStateVariable must have been created with

        dw_CreateArray_pointer(n_state_variables,(void (*)(void*))FreeMarkovStateVariable);

      Furthermore, the structure receives ownership of this argument and is
      responsible for its freeing.

    int** Index
      This is a nstates x n_state_variables rectangular array of integers.  State
      s corresponds to state_variable[i] being equal to Index[s][i].

    int** SA
      An array of integer pointers of length n_state_variables.  The pointers SA[i]
      and state_variable[i]->S point to the same address.

    TMatrix* QA
      An array of matrices of length n_state_variables.  The matrix QA[i] is
      is the matrix state_variable[i]->Q.

  ===============================================================================
  The TMarkovStateVariable routines must follow the following specification.

  TMatrix (*ComputeTransitionMatrix)(TMatrix Q, int t, TMarkovStateVariable *sv)
    Upon success, sv->Q will contain the transistion matrix valid at time t.  The
    fields sv->t0 and sv->t1 will be updated so that sv->t0 <= t <= sv->t1 and
    the transition matrix will be valid for all t between sv->t0 and sv->t1,
    inclusive.  The matrix sv->Q will be return.  Upon failure, a null pointer
    will be returned.

  ===============================================================================
  The following fields are set only for single Markov state variables and are
  set to null for multiple independent Markov state variables.

    TVector B
      The vector B is the vector of quasi-free parameters.

    TVector *b
      Array of vectors of length DimA(FreeDim).  The element b[k] is of length
      FreeDim[k].  Non-standard memory management is used so that

               &(b[k][i])=&B[FreeDim[0] + ... + FreeDim[k-1] + i])

      The elements of b[k] are non-negative and their sum equals one up to
      DimV(b[k])*MACHINE_EPSILON.

    TMatrix Prior
       Prior Dirichlet parameters for Q.

    TVector *Prior_b
      The Dirichlet prior parametrs for b.  Array of vectors of length
      DimA(FreeDim).  The element Prior_b[k] is of length FreeDim[k].
      Non-standard memory management is used so that

            &(Prior_b[k][i])=&B[FreeDim[0] + ... + FreeDim[k-1] + i])

    TVector Prior_B
      The Dirichlet prior parameters for B.  This vector is created and
      initialized by CreateMarkovStateVariable().  The element B[k]-1 is the sum
      of Prior[i][j]-1 over all (i,j) such that NonZeroIndex[i][j] == k.

    int* FreeDim
      FreeDim[k] is the length of the kth free Dirichlet vector.  The length of B
      must be equal to FreeDim[0] + ... + FreeDim[dw_DimA(FreeDim)-1].

    int** NonZeroIndex
      Defines the relationship between Q and B.
                  --
                 | MQ[i][j]*B[NonZeroIndex[i][j]]  if NonZeroIndex[i][j] >=  0
       Q[i][j] = |
                 | 0.0                             if NonZeroIndex[i][j] == -1
                  --
    TMatrix MQ
      Coefficients for the elements of Q in terms of the free parameters B.


  int   nlags_encoded;          // Number of lags encoded in the restrictions
  int   nbasestates;            // Number of base states nbasestates^(nlags_encoded) = nstates
  int** lag_index;              // nstates x (nlags_encoded + 1) lag_index[i][j] is the value of the jth lag when the overall state is k


==================================================================================
Old stuff

    TVector* ba
      For single Markov state variables, ba[i] = b[i].  For multiple state
      variables ba[i] = state_variable[k]->ba[j] where

        i = j + dw_DimA(state_variable[0]->ba) + ... + dw_DimA(state_variable[k-1]->ba)

    TVector* Prior_ba
      For single Markov state variables, Prior_ba[i] = Prior_b[i].  For multiple
      state variables Prior_ba[i] = state_variable[k]->Prior_ba[j] where

        i = j + dw_DimA(state_variable[0]->Prior_ba) + ... + dw_DimA(state_variable[k-1]->Prior_ba)


  ===============================================================================


  ===============================================================================
  Normalization:
   In general, a permutation of the states, together with the corresponding
   permutation of the rows and columns of the transition matrix and the model
   dependent parameters theta, does not change the value of the likelihood
   function and so presents a normalization problem.  However, some permutations
   of the states are not permissible in that they may violate the restrictions
   placed on the transition matrix or restrictions on the model dependent
   parameters.  Furthermore, even if a permutation did not cause a violation of
   any restrictions, a non-symmetric prior on the model dependent parameters
   could cause the value of the likelihood to change.

********************************************************************************/


/*******************************************************************************/
/************************** QRoutines Specifications ***************************/
/********************************************************************************
int ComputeTransitionMatrix(int t, TMarkovStateVariable *sv, TStateModel *model)
  Assumes:
    t     : 0 <= t <= model->nobs
    sv    : pointer to valid TMarkovStateVariable structure
    model : pointer to valid TStateModel structure
  Returns:
    One upon success and zero on failure.
  Results:
    Upon success, all time t transition matrices are computed.  Sets sv->t0 and
    sv->t1.

PRECISION LogPrior_q(TMarkovStateVariable *sv)
  Assumes:
    sv : pointer to valid TMarkovStateVariable structure
  Returns:
    The natural logarithm of the properly scaled prior evaluated at sv->q.

int Probability_s0(TVector p, TMarkovStateVariable *sv)
  Assumes:
    p  : vector of length sv->nstates
    sv : pointer to valid TMarkovStateVariable structure
  Returns:
    One upon success and zero upon failure.
  Results:
    The value of p[i] is the probability that s0 is equal to i.

---------------------------------------------------------------------------------

PRECISION DrawProposalTransitionMatrixParameters(int *S, TMarkovStateVariable *sv, TStateModel *model)
  Assumes:
    S     : integer array of length model->nobs + 1 satisfying 0 <= S[t] < sv->nstates.
    sv    : pointer to valid TMarkovStateVariable structure
    model : pointer to valid TStateModel structure
  Returns:
    The natural logrithm of
      p(q_old | Y[T],Z[T],S[T],theta,q_new)/p(q_new | Y[T],Z[T],S[T],theta,q_old)
    where p( | ) is the proposal density, q_old is the value of sv->q upon entry
    and q_new is the value of sv->q upon exit.
  Results:
    Draws sv->q from the propoal density p(q_new | Y[T], Z[T], S[T], theta, q_old).

DrawTransitionMatrixParameters(int *S, TMarkovStateVariable *sv, TStateModel *model)
  Assumes:
    S     : integer array of length model->nobs + 1 satisfying 0 <= S[t] < sv->nstates.
    sv    : pointer to valid TMarkovStateVariable structure
    model : pointer to valid TStateModel structure
  Returns:
    One upon success and zero otherwise.
  Results:
    Draws sv->q from the conditional posterior density p(q | Y[T], Z[T], S[T], theta).

---------------------------------------------------------------------------------

FreeInfo(void *info)
  Assumes:
    info : pointer to valid structure of appropriate type or null.
  Results:
    Properly frees info structure if it is not null.

DuplicateInfo(void *info)
  Assumes:
    info : pointer to valid structure of appropriate type or null.
  Returns:
    Pointer valid sturcture of appropriate type upon success and null otherwise.
  Results:
    If info is not null, creates new pointer to a structure of the appropriate
    type and duplicates info.

int (*WriteSpecification)(FILE*, struct TMarkovStateVariable_tag*, char*);

---------------------------------------------------------------------------------

DefaultTransitionMatrixParameters(TMarkovStateVariable *sv, TStateModel *model)
  Assumes:
    sv    : pointer to valid TMarkovStateVariable structure
    model : pointer to valid TStateModel structure
  Returns:
    One upon success and zero upon failure.
  Results:
    Sets sv->q to some default value.

Update_q_from_BaseTransitionMatrix(int t, TMarkovStateVariable *sv, TStateModel *model)
  Assumes:
    t     : 0 <= t <= model->nobs
    sv    : pointer to valid TMarkovStateVariable structure
    model : pointer to valid TStateModel structure
  Returns:
    One upon success and zero on failure.
  Results:
    Converts sv->baseQ, which is assumed to be valid for time t,  to sv->q.  Sets
    sv->t0 and sv->t1.
*******************************************************************************/
/*******************************************************************************/
/*******************************************************************************/
