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

#include "dw_state_space_command_line_output.h"
#include "dw_state_space_historical_decomposition.h"
#include "dw_state_space_forecast.h"
#include "dw_state_space_counterfactual.h"
#include "dw_state_space_variance_decomposition.h"
#include "dw_state_space_impulse_response.h"
#include "dw_MSStateSpace.h"
#include "dw_metropolis_simulation.h"
#include "dw_parse_cmd.h"
#include "dw_ascii.h"
#include "dw_array.h"
#include "dw_rand.h"
#include "dw_std.h"
#include "dw_histogram.h"
#include "dw_math.h"
#include "dw_error.h"
#include "dw_mdd_switch.h"

#include <math.h>
#include <string.h>

// Get tag from command line
char* GetTag(int nargs, char **args)
{
  char *tag;
  tag=dw_ParseString(nargs,args,'t',(char*)NULL);
  tag=dw_ParseString_String(nargs,args,"ft",tag);
  tag=dw_ParseString_String(nargs,args,"outtag",tag);
  return tag;
}

/*
   Returns 1 if model is a T_MSStateSpace model and 0 otherwise
*/
int IsStateSpaceModel(TStateModel *model)
{
  char *model_id=ModelType(model);
  if (!model_id || strcmp(model_id,"T_MSStateSpace"))
    {
      printf("Expecting T_MSStateSpace model - Model type = %s\n",model_id ? model_id : "null");
      return 0;
    }
  else
    return 1;
}

/*
   Returns 1 if -parmfile flag is not present.
   Returns 2 if parameters successfully read.
   Returns 0 otherwise. 

   offset should generally be 2 because first two elements are the log posterior and log likelihood.
*/
int ReadParameters(int nargs, char **args, TStateModel *model, int offset, int verbose)
{
  FILE *f_in;
  char *filename;
  TVector parameters;
  if (filename=dw_ParseString_String(nargs,args,"parmfile",(char*)NULL))
    if (f_in=fopen(filename,"rt"))
      {
	if (!dw_ReadVector(f_in,parameters=CreateVector(offset + NumberFreeParametersTheta(model) + NumberFreeParametersQ(model))))
	  {
	    printf("Unable to read parameters file - %s.\n",filename);
	    return 0;
	  }
	else
	  {
	    ConvertFreeParametersToTheta(model,pElementV(parameters)+offset);
	    ConvertFreeParametersToQ(model,pElementV(parameters)+offset+NumberFreeParametersTheta(model));
	    if (verbose)
	      {
		printf("Parameter file: %s\n",filename);
		if (offset > 1)
		  printf("Log Likelihood: %le  -  %le\n",ElementV(parameters,1),LogLikelihood_StatesIntegratedOut(model));
		if (offset > 0)
		  printf("Log Posterior: %le  -  %le\n",ElementV(parameters,0),LogPosterior_StatesIntegratedOut(model));
	      }
	  }
	FreeVector(parameters);
	fclose(f_in);
      }
    else
      {
	printf("Unable to open parameters file - %s.\n",filename);
	return 0;
      }
  return 1;
}

/*
  Attempts to read delimited file containing a matrix.  
*/
TMatrix dw_ReadDelimitedFile_matrix(FILE *f, char* filename, char delimiter, int flag, double invalid_identifier)
{
  int nrows, ncols, i, j;
  double **M=dw_ReadDelimitedFile_double(f,filename,delimiter,flag,invalid_identifier);
  TMatrix D;
  if (!M) return (TMatrix)NULL;
  nrows=dw_DimA(M);
  ncols=dw_DimA(M[0]);
  for (i=nrows-1; i > 0; i--) 
    if (ncols != dw_DimA(M[0]))
      {
	dw_FreeArray(M);
	return (TMatrix)NULL;
      }
  D=CreateMatrix(nrows,ncols);
  for (i=nrows-1; i >= 0; i--)
    for (j=ncols-1; j >= 0; j--)
      ElementM(D,i,j)=M[i][j];
  dw_FreeArray(M);
  return D;
}

/*
   Attempts to read percentiles from command line.  Searches for command line argument of the form

     -percentiles n p[0] p[1] ... p[n-1]
   
   If -percentiles is not present, and -error_bands is present, returns default percentiles which
   are (0.16  0.50  0.84).
*/
TVector ReadPercentiles(int nargs, char** args)
{
  int i, j, n;
  TVector percentiles=(TVector)NULL;
  if ((i=dw_FindArgument_String(nargs,args,"percentiles")) != -1)
    {
      if ((i+1 < nargs) && dw_IsInteger(args[i+1]) && ((n=atoi(args[i+1])) > 0) && (i+1+n < nargs))
	{
	  percentiles=CreateVector(n);
	  for (j=0; j < n; j++)
	    if (!dw_IsFloat(args[i+2+j])|| ((ElementV(percentiles,j)=atof(args[i+2+j])) <= 0.0) || (ElementV(percentiles,j) >= 1.0)) 
	      {
		FreeVector(percentiles);
		dw_UserError("Error parsing percentiles\n");
		return (TVector)NULL;
	      }
	}
      else
	dw_UserError("Error parsing percentiles\n");
    }
  else
    if (dw_FindArgument_String(nargs,args,"error_bands") != -1)
      {
	percentiles=CreateVector(3);
	ElementV(percentiles,0)=0.16; ElementV(percentiles,1)=0.5; ElementV(percentiles,2)=0.84;
      }
  return percentiles;
}


/*
   Command line parameters

    General parameters
     -t : filename tag
     -ft : filename tag - supersedes -t
     -outtag : filename tag - supersedes -t and -ft

    Adaptive jump ratio parameters
     -cs <real>: target acceptance rate for single variable calibrations (default = 0.20)
     -ca <real> : target acceptance rate for overall calibrations (default = 0.25)
     -ps <integer> : the initial period for the single variable calibrations (default = 20)
     -pa <integer> : the initial period for the overall calibrations (default = 20)
     -mps <integer> : the maximum period for the single variable calibrations (default = 8*ps)
     -mpa <integer> : the maximum period for the overall calibrations (default = 16*mps)
     -diagonal : Forces calibration using two-pass diagonal, even if calibration has alread been performed.
                 This is the default option.
     -variance <filename> : Forces calibration using two-pass variance, even if calibration has already
                            been performed.  Reads draws from filename.
     -hessian : Forces calibration using two-pass hessian, even if calibration has already been performed.
     -special : Forces calibration using two-pass with custom directions (calls SetupDirections()), even if 
                calibration has already been performed.
     -af <filename> : file for storing the calibrated metropolis parameters. (default = metropolis_theta_<tag>.out)
     -hf <filename> : file containing the hessian matrix. (default = outdataout_<tag>.prn)
     -database : write to the database instead of a file.

    Simulation parameters
     -seed : seed value for the random number generator (default = 0 - uses clock and pid)
     -ndraws : number of draws to save (default = 1000)
     -burnin : number of burn-in draws (default = 0.1 * ndraws)
     -thin : thinning factor.  Total number of draws made is thin*ndraws + burnin (default = 1)
     -of <filename> : output filename (default = simulation_<tag>.out)
     -parmfile <parameter filename> : parameter filename
     -random <filename> : Reads previous simulation output and randomly selects a starting value. 
     -database : Saves draws to database - not currently implemented 
   
   Attempts to setup metropolis parameters from command line for simulating theta. Note if none of -diagonal,
   -hessian, or -special are specified, the default behavior is to first look for calibration file and it is
   not present to use the two-pass diagonal method.
*/
void dw_state_space_simulate_command_line(int n_args, char **args, TStateModel *model)
{
  FILE *f_out, *f_start;
  char *tag, *default_filename, *filename, *fmt;
  int j, row, ndraws, burn_in, thin, default_period=20, n_theta=NumberFreeParametersTheta(model),
    n_q=NumberFreeParametersQ(model);
  TMatrix draws;
  TVector parameters;
  PRECISION logposterior, loglikelihood;

  // Initialize generator
  dw_initialize_generator(dw_ParseInteger_String(n_args,args,"seed",0));

  // Get tag from command line
  tag=dw_ParseString(n_args,args,'t',(char*)NULL);
  tag=dw_ParseString_String(n_args,args,"ft",tag);
  tag=dw_ParseString_String(n_args,args,"outtag",tag);

  // Create parameters vector
  parameters=CreateVector(2+n_theta+n_q);
  
  // Write initial value
  fmt="simulation_startmax_%s.out";
  sprintf(filename=(char*)dw_malloc(strlen(fmt) + strlen(tag) - 1),fmt,tag);
  if (!(f_start=fopen(filename,"wt")))
    {
      printf("Unable to open %s\n",filename);
      dw_free(filename);
    }
  else
    {
      dw_free(filename);
      ElementV(parameters,0)=LogPosterior_StatesIntegratedOut(model);
      ElementV(parameters,1)=LogLikelihood_StatesIntegratedOut(model);
      if (n_theta) ConvertThetaToFreeParameters(model,pElementV(parameters)+2);
      if (n_q) ConvertQToFreeParameters(model,pElementV(parameters)+2+n_theta);
      dw_PrintVector(f_start,parameters," %.14le");

      // Push starting value into model and write new initial value
      switch (ReadParameters(n_args,args,model,2,0))
	{
	case 0:      
	  break;
	case 2:
	  if (f_start)
	    {
	      ElementV(parameters,0)=LogPosterior_StatesIntegratedOut(model);
	      ElementV(parameters,1)=LogLikelihood_StatesIntegratedOut(model);
	      if (n_theta) ConvertThetaToFreeParameters(model,pElementV(parameters)+2);
	      if (n_q) ConvertQToFreeParameters(model,pElementV(parameters)+2+n_theta);
	      dw_PrintVector(f_start,parameters," %.14le");
	    }
	case 1:
	  // Random starting values
	  if (filename=dw_ParseString_String(n_args,args,"random",(char*)NULL))
	    if (draws=dw_ReadPosteriorDraws((FILE*)NULL,filename,(char*)NULL,n_theta+n_q))
	      {
		row=(int)floor(dw_uniform_rnd()*RowM(draws));
		if (row >= RowM(draws)) row=RowM(draws);
		RowVector(parameters,draws,row);
		if (n_theta) ConvertFreeParametersToTheta(model,pElementV(parameters)+2);
		if (n_q) ConvertFreeParametersToQ(model,pElementV(parameters)+2+n_theta);
		printf("Using row %d as random starting value from %s\n",row,filename);
		printf("initial log posterior = %le  -  %le\n",logposterior=LogPosterior_StatesIntegratedOut(model),ElementV(parameters,0));
		printf("initial log likelihood = %le  -  %le\n",loglikelihood=LogLikelihood_StatesIntegratedOut(model),ElementV(parameters,1));
		ElementV(parameters,0)=logposterior;
		ElementV(parameters,1)=loglikelihood;
		if (f_start) dw_PrintVector(f_start,parameters," %.14le");
		FreeMatrix(draws);
	      }
	    else
	      {
		printf("Unable to open %s\n",filename);
		break;
	      }

	  // Set maximum posterior
	  model->max_log_posterior=LogPosterior_StatesIntegratedOut(model);
	  if (model->max_posterior_theta) ConvertThetaToFreeParameters(model,pElementV(model->max_posterior_theta));
	  if (model->max_posterior_q) ConvertQToFreeParameters(model,pElementV(model->max_posterior_q));

	  if (SetUpMetropolisSimulation(n_args,args,tag,model,default_period))
	    {
	      // simulation parameters
	      ndraws=dw_ParseInteger_String(n_args,args,"ndraws",1000);
	      burn_in=dw_ParseInteger_String(n_args,args,"burnin",ndraws/10);
	      thin=dw_ParseInteger_String(n_args,args,"thin",1);

	      // Starting Simulation
	      if (dw_FindArgument_String(n_args,args,"database") == -1)
		{
		        
		  // output filename
      		  fmt="simulation_%s.out";
      		  sprintf(default_filename=(char*)dw_malloc(strlen(fmt) + strlen(tag) - 1),fmt,tag);
      		  filename=dw_ParseString_String(n_args,args,"fo",default_filename);
		        
		  // Jake's Modifications to take an input and output file
		  char *tmp_name = NULL;
		  int i=0;
		  for (i=0;i< n_args;i++) {
		    if (strstr(args[i],"-o") != NULL || strstr(args[i],"/o") != NULL || strstr(args[i],"--output") != NULL) {
		      // Change the output file for the estimation to the passed argument
		      if ((tmp_name=strstr(args[i],"=")) != NULL)	{
			tmp_name+=1;
		      } else {
			tmp_name = args[i+1];
		      }
		      filename = tmp_name;
		    }
		  }
      		  
      		  if (f_out=fopen(filename,"wt"))
      		    {
      		      Simulate(burn_in,ndraws,thin,1000,model,f_out);
      		      if (f_start)
      			{
      			  if (n_theta) ConvertFreeParametersToTheta(model,pElementV(model->max_posterior_theta));
      			  if (n_q) ConvertFreeParametersToQ(model,pElementV(model->max_posterior_q));
      			  fprintf(f_start,"%.14le %.14le",model->max_log_posterior,LogLikelihood_StatesIntegratedOut(model));
      			  if (model->max_posterior_theta)
      			    for (j=0; j < n_theta; j++) fprintf(f_start," %.14le",ElementV(model->max_posterior_theta,j));
      			  if (model->max_posterior_q)
      			    dw_PrintVector(f_start,model->max_posterior_q," %.14le");
      			  else
      			    fprintf(f_start,"\n");
      			}
      		      fclose(f_out);
      		    }
      		  else
      		    printf("Unable to open %s\n",filename);

      		  dw_free(default_filename);
      		}
	      else
		{
		  f_out=(FILE*)NULL;
		  // initialize sdsm
		  //sdsm_init(1001,100,100,1,0,1,1);
		  printf("-database not yet supported\n");
		  break;
		}
	    }
	  else
	    printf("Error setting up Metropolis adaptive simulation\n");
	}
    }

  if (f_start) fclose(f_start);
  FreeVector(parameters);
}


/*
   Command line parameters

     -t <tag> : input and output tag

     -ft <tag> : takes precedence over -t

     -outtag <tag> : takes presedence over -t and -ft

     -parmfile <parameter filename> : parameter filename

     -horizon : The horizon over which to compute the forecasts. (default = 12)

     -data : Number of actual data points to include. (default = 0)

     -mean : Produces mean forecast.  (default = off)

     -error_bands : Output error bands.  (default = off - only median is computed)

     -percentiles n p_1 p_2 ... p_n : Percentiles to compute. The first parameter
        after percentiles must be the number of percentiles and the following 
        values are the actual percentiles. (default = 3  0.16  0.50  0.84 if 
        error_bands flag is set and default = 1 0.50 otherwise)

     -parameter_uncertainty : Apply parameter uncertainty when computing error bands.

     -thin : Thinning factor.  Only 1/thin of the draws in posterior draws file 
        are used. (default = 1)

     -shocks_per_parameter : Number of shocks and regime paths to draw for each
        parameter draw.  (default = 1 if parameter_uncertainty is set and 
        default = 10,000 otherwise)

     -regimes : Produces forecasts as if each regime were permanent.

     -regime s : Produces forecasts as if regime s were permanent.

     -special :  Products conditional forecast - hard coded shocks, make changes to Forecast_ConditionalShocks_Special

*/
void dw_state_space_forecast_command_line(int nargs, char **args, TStateModel *model)
{
  FILE *f_out;
  char *out_filename, *fmt, *tag;
  TMatrix posterior_draws=(TMatrix)NULL, Fs;
  TVector *F, percentiles=(TVector)NULL;
  int s, i, j, n, t, horizon, thin, draws, plotdata,
    nparameters=NumberFreeParametersTheta(model) + NumberFreeParametersQ(model);
  T_MSStateSpace *statespace;

  if (!IsStateSpaceModel(model)) return;

  statespace=(T_MSStateSpace*)(model->theta);

  tag=GetTag(nargs,args);

  ReadParameters(nargs,args,model,2,0);

  // Get horizon from command line
  horizon=dw_ParseInteger_String(nargs,args,"horizon",12);

  // Get number of data points to plot
  plotdata=dw_ParseInteger_String(nargs,args,"data",0);

  // Mean forecast
  if (dw_FindArgument_String(nargs,args,"mean") != -1)
    {
      fmt="forecasts_mean_%s.prn";
      sprintf(out_filename=(char*)dw_malloc(strlen(fmt) + strlen(tag) - 1),fmt,tag);
      f_out=fopen(out_filename,"wt");
      dw_free(out_filename);
      printf("Constructing mean forecast\n");
      if (F=dw_state_space_mean_unconditional_forecast((TVector*)NULL,horizon,statespace->nobs,model))
      	{
      	  for (t=statespace->nobs-plotdata+1; t <= statespace->nobs; t++)
      	    {
      	      fprintf(f_out,"%d ",t);
      	      dw_PrintVector(f_out,statespace->y[t],"%le ");
      	    }
      	  for (i=0; i < horizon; i++)
      	    {
      	      fprintf(f_out,"%d ",t++);
      	      dw_PrintVector(f_out,F[i],"%le ");
      	    }
      	  dw_FreeArray(F);
      	}
      fclose(f_out);
      return;
    }

  // Special forecast
  if (dw_FindArgument_String(nargs,args,"special") != -1)
    {
      fmt="forecasts_special_%s.prn";
      sprintf(out_filename=(char*)dw_malloc(strlen(fmt) + strlen(tag) - 1),fmt,tag);
      f_out=fopen(out_filename,"wt");
      dw_free(out_filename);
      printf("Constructing special forecast\n");
      if (Fs=Forecast_ConditionalShocks_Special(horizon,model))
	{
      	  for (t=statespace->nobs-plotdata+1; t <= statespace->nobs; t++)
      	    {
      	      fprintf(f_out,"%d ",t);
      	      dw_PrintVector(f_out,statespace->y[t],"%le ");
      	    }
      	  for (i=0; i < horizon; i++)
      	    {
      	      fprintf(f_out,"%d ",t++);
      	      for (j=0; j < ColM(Fs); j++) fprintf(f_out,"%le ",ElementM(Fs,i,j));
      	      fprintf(f_out,"\n");
      	    }
      	  FreeMatrix(Fs);
      	}
      fclose(f_out);
      return;
    }

  if (dw_FindArgument_String(nargs,args,"parameter_uncertainty") != -1)
    {
      // Read posterior draws
      printf("Reading posterior draws\n");
      posterior_draws=dw_ReadPosteriorDraws((FILE*)NULL,(char*)NULL,tag,nparameters);
      if (!posterior_draws)
      	{
      	  printf("dw_state_space_forecast_command_line(): Unable to read posterior draws\n");
      	  printf("  tag: %s\n",tag ? tag : "null");
      	  dw_exit(0);
      	}

      // Get thinning factor from command line
      thin=dw_ParseInteger_String(nargs,args,"thin",1);

      // Get shocks_per_parameter from command line
      draws=dw_ParseInteger_String(nargs,args,"shocks_per_parameter",1);
    }
  else
    {
      // Using posterior estimate
      posterior_draws=(TMatrix)NULL;

      // thinning factor not used
      thin=1;

      // Get shocks_per_parameter from command line
      draws=dw_ParseInteger_String(nargs,args,"shocks_per_parameter",10000);
    }

  // Setup percentiles
  if ((i=dw_FindArgument_String(nargs,args,"percentiles")) == -1)
    if (dw_FindArgument_String(nargs,args,"error_bands") == -1)
      {
	percentiles=CreateVector(1);
      	ElementV(percentiles,0)=0.5;
      }
    else
      {
	percentiles=CreateVector(3);
      	ElementV(percentiles,0)=0.16; ElementV(percentiles,1)=0.5; ElementV(percentiles,2)=0.84;
      }
  else
    if ((i+1 < nargs) && dw_IsInteger(args[i+1]) && ((n=atoi(args[i+1])) > 0) && (i+1+n < nargs))
      {
	percentiles=CreateVector(n);
      	for (j=0; j < n; j++)
      	  if (!dw_IsFloat(args[i+2+j])|| ((ElementV(percentiles,j)=atof(args[i+2+j])) <= 0.0)
      	      || (ElementV(percentiles,j) >= 1.0)) break;
      	if (j < n)
      	  {
      	    FreeVector(percentiles);
      	    printf("dw_state_space_forecast_command_line(): Error parsing percentiles\n");
      	    dw_exit(0);
      	  }
      }
    else
      {
	printf("dw_state_space_forecast_command_line(): Error parsing percentiles\n");
      	dw_exit(0);
      }

  if (dw_FindArgument_String(nargs,args,"regimes") != -1)
    for (s=0; s < statespace->nbasestates; s++)
      {
	fmt="forecasts_percentiles_regime_%d_%s.prn";
      	sprintf(out_filename=(char*)dw_malloc(strlen(fmt) + strlen(tag) - 3),fmt,s,tag);
      	f_out=fopen(out_filename,"wt");
      	dw_free(out_filename);
      	printf("Constructing percentiles for forecasts - regime %d\n",s);
      	dw_state_space_forecast_percentile_regime(f_out,percentiles,draws,posterior_draws,thin,s,model->nobs,horizon,model,plotdata);
      	fclose(f_out);
      }
  else
    if (((s=dw_ParseInteger_String(nargs,args,"regime",-1)) >= 0) && (s < statespace->nbasestates))
      {
      	fmt="forecasts_percentiles_regime_%d_%s.prn";
      	sprintf(out_filename=(char*)dw_malloc(strlen(fmt) + strlen(tag) - 3),fmt,s,tag);
      	f_out=fopen(out_filename,"wt");
      	dw_free(out_filename);
      	printf("Constructing percentiles for forecasts - regime %d\n",s);
      	dw_state_space_forecast_percentile_regime(f_out,percentiles,draws,posterior_draws,thin,s,model->nobs,horizon,model,plotdata);
      	fclose(f_out);
      }
    else
      {
      	fmt="forecasts_percentiles_%s.prn";
      	sprintf(out_filename=(char*)dw_malloc(strlen(fmt) + strlen(tag) - 1),fmt,tag);
      	f_out=fopen(out_filename,"wt");
      	dw_free(out_filename);
      	printf("Constructing percentiles for forecasts - %d draws of shocks per posterior value\n",draws);
      	dw_state_space_forecast_percentile(f_out,percentiles,draws,posterior_draws,thin,model->nobs,horizon,model,plotdata);
      	fclose(f_out);
      }

  FreeMatrix(posterior_draws);
  FreeVector(percentiles);
}

/*
   Command line parameters

     -t <tag> : input and output tag

     -ft <tag> : takes precedence over -t

     -outtag <tag> : takes presedence over -t and -ft

     -parmfile <parameter filename> : parameter filename

     -horizon : The horizon over which to compute the forecast historical decompostion. (default = 12)

     -startdate : The period in which to begin the historical decomposition (default = 2);

     -observables : Produces historical decomposition of observables (default = off)

     -states : Produces historical decomposition of states. (default = off)
*/
void dw_state_space_historical_decomposition_command_line(int nargs, char **args, TStateModel *model)
{
  FILE *f_out;
  char *out_filename, *fmt, *tag;
  TMatrix historical_decomposition;
  int  i, j, k, t, horizon, start_date;
  T_MSStateSpace *statespace;

  if (!IsStateSpaceModel(model)) return;

  statespace=(T_MSStateSpace*)(model->theta);

  tag=GetTag(nargs,args);

  ReadParameters(nargs,args,model,2,0);

  // Get horizon from command line
  horizon=dw_ParseInteger_String(nargs,args,"horizon",12);

  // Get start date
  start_date=dw_ParseInteger_String(nargs,args,"startdate",2);

  if (dw_FindArgument_String(nargs,args,"observables") != -1)
    {
      fmt="historical_%s.out";
      sprintf(out_filename=(char*)dw_malloc(strlen(fmt) + strlen(tag) - 1),fmt,tag);
      f_out=fopen(out_filename,"wt");
      dw_free(out_filename);
      printf("Constructing historical decompositions - observables\n");
      historical_decomposition=dw_state_space_historical_decomposition((TMatrix)NULL,start_date,horizon,model);
      for (t=0; t < RowM(historical_decomposition); t++)
	{
	  fprintf(f_out,"%d, ",start_date+t);
	  for (k=0, i=0; i < statespace->ny; i++)
	    {
	      for (j=0; j < statespace->nepsilon+statespace->nu+2; j++, k++)
		fprintf(f_out,"%.14le, ",ElementM(historical_decomposition,t,k));
	      fprintf(f_out,", , ");
	    }
	  fprintf(f_out,"\n");
	}
      fclose(f_out);

      /***** Debugging output *****/
      CheckHistoricalDecomposition(historical_decomposition,1,model);
      Check_SmoothedInfo(model,0.1);
      Check_FilteredInfo(model,0.1);
      /****************************/

      FreeMatrix(historical_decomposition);
    }

  if (dw_FindArgument_String(nargs,args,"states") != -1)
    {
      fmt="historicalstates_%s.out";
      sprintf(out_filename=(char*)dw_malloc(strlen(fmt) + strlen(tag) - 1),fmt,tag);
      f_out=fopen(out_filename,"wt");
      dw_free(out_filename);
      printf("Constructing historical decompositions - states\n");
      historical_decomposition=dw_state_space_historical_decomposition_states((TMatrix)NULL,start_date,horizon,model);
      for (t=0; t < RowM(historical_decomposition); t++)
	{
	  fprintf(f_out,"%d, ",start_date+t);
          for (k=0, i=0; i < statespace->nz; i++)
	    {
	      for (j=0; j < statespace->nepsilon+2; j++, k++)
		fprintf(f_out,"%.14le, ",ElementM(historical_decomposition,t,k));
	      fprintf(f_out,", , ");
	    }
	  fprintf(f_out,"\n");
	}
      fclose(f_out);
      FreeMatrix(historical_decomposition);
    }
}

/*
   Command line parameters

     -t <tag> : input and output tag

     -ft <tag> : takes precedence over -t

     -outtag <tag> : takes presedence over -t and -ft

     -parmfile <parameter filename> : parameter filename

     -horizon : The horizon over which to compute the impulse responses. (default = 12)

     -parameter_uncertainty : Use posterior draws to compute error bands for the impulse responses

     -percentiles n p_1 p_2 ... p_n : Percentiles to compute. The first parameter
        after percentiles must be the number of percentiles and the following 
        values are the actual percentiles. (default = 3  0.16  0.50  0.84)

     -thin : Thinning factor.  Only 1/thin of the draws in posterior draws file are used. (default = 1)

     -states : Print impluse responses of state variables to shocks (default = off)

     -observables : Print impulse responses of observable variables to shocks (default = off)

     -ergodic : Print impuluse responses using ergodic distribution as initial condition for shocks.

     -regimes : Print impulse responses as if each regime were permanent.

     -regime s : Print impulse responses as if regime s were permanent.

*/
void dw_state_space_impulse_response_command_line(int nargs, char **args, TStateModel *model)
{
  FILE *f_out;
  char *out_filename, *fmt, *tag;
  TMatrix posterior_draws;
  TVector percentiles=(TVector)NULL, init_prob=(TVector)NULL;
  int s, i, j, n, nparameters=NumberFreeParametersTheta(model) + NumberFreeParametersQ(model), h, thin, states, observables,
    parameter_uncertainty;
  T_MSStateSpace *statespace;

  if (!IsStateSpaceModel(model)) return;

  statespace=(T_MSStateSpace*)(model->theta);

  tag=GetTag(nargs,args);

  ReadParameters(nargs,args,model,2,0);

  // Read posterior draws
  if (parameter_uncertainty=(dw_FindArgument_String(nargs,args,"parameter_uncertainty") == -1) ? 0 : 1)
    {
      printf("Reading posterior draws\n");
      posterior_draws=dw_ReadPosteriorDraws((FILE*)NULL,(char*)NULL,tag,nparameters);
      if (!posterior_draws)
	{
	  printf("dw_state_space_impulse_response_command_line(): Unable to read posterior draws\n");
	  printf("  tag: %s\n",tag ? tag : "null");
	  dw_exit(0);
	}
    }
  else
    {
      posterior_draws=(TMatrix)NULL;
    }

  // Setup percentiles, horizon, thinning factor
  if ((i=dw_FindArgument_String(nargs,args,"percentiles")) == -1)
    if (parameter_uncertainty)
      {
	percentiles=CreateVector(3);
	ElementV(percentiles,0)=0.16; ElementV(percentiles,1)=0.5; ElementV(percentiles,2)=0.84;
      }
    else
      {
	percentiles=CreateVector(1);
	ElementV(percentiles,0)=0.5;
      }
  else
    if ((i+1 < nargs) && dw_IsInteger(args[i+1]) && ((n=atoi(args[i+1])) > 0) && (i+1+n < nargs))
      {
	percentiles=CreateVector(n);
	for (j=0; j < n; j++)
	  if (!dw_IsFloat(args[i+2+j])|| ((ElementV(percentiles,j)=atof(args[i+2+j])) <= 0.0)
	      || (ElementV(percentiles,j) >= 1.0)) break;
	if (j < n)
	  {
	    FreeVector(percentiles);
	    printf("dw_state_space_impulse_response_command_line(): Error parsing percentiles\n");
	    dw_exit(0);
	  }
      }
    else
      {
	printf("dw_state_space_impulse_response_command_line(): Error parsing percentiles\n");
	dw_exit(0);
      }
  h=dw_ParseInteger_String(nargs,args,"horizon",8);
  thin=dw_ParseInteger_String(nargs,args,"thin",1);

  // print impulse response of states
  states=(dw_FindArgument_String(nargs,args,"states") == -1) ? 0 : 1;

  // print impulse response of observables
  observables=(dw_FindArgument_String(nargs,args,"observables") == -1) ? 0 : 1;

  // ergodic impulse responses
  if (dw_FindArgument_String(nargs,args,"ergodic") != -1)
    {
      if (states)
	{
	  // Open output file for impulse responses of states
	  fmt="ir_states_percentiles_ergodic_%s.prn";
	  sprintf(out_filename=(char*)dw_malloc(strlen(fmt) + strlen(tag) - 1),fmt,tag);
	  f_out=fopen(out_filename,"wt");
	  dw_free(out_filename);

	  // Compute percentiles for impulse responses of states
	  printf("Constructing percentiles for impulse responses of states - ergodic\n");
	  dw_state_space_impulse_response_states_percentile_ergodic(f_out,percentiles,posterior_draws,thin,init_prob,h,model);
	  fclose(f_out);
	}

      if (observables)
	{
	  // Open output file for impulse responses of observables
	  fmt="ir_observables_percentiles_ergodic_%s.prn";
	  sprintf(out_filename=(char*)dw_malloc(strlen(fmt) + strlen(tag) - 1),fmt,tag);
	  f_out=fopen(out_filename,"wt");
	  dw_free(out_filename);

	  // Compute percentiles for impulse responses of observables
	  printf("Constructing percentiles for impulse responses of observables - ergodic\n");
	  dw_state_space_impulse_response_observables_percentile_ergodic(f_out,percentiles,posterior_draws,thin,init_prob,h,model);
	  fclose(f_out);
	}
    }

  if (dw_FindArgument_String(nargs,args,"regimes") != -1)
    for (s=0; s < statespace->nbasestates; s++)
      {
	if (states)
	  {
	    // Open output file for impulse responses of states
	    fmt="ir_states_percentiles_regime_%d_%s.prn";
	    sprintf(out_filename=(char*)dw_malloc(strlen(fmt) + strlen(tag) + 10),fmt,s,tag);
	    f_out=fopen(out_filename,"wt");
	    dw_free(out_filename);

	    // Compute percentiles for impulse responses of states
	    printf("Constructing percentiles for impulse responses of states - regime %d\n",s);
	    dw_state_space_impulse_response_states_percentile_regime(f_out,s,percentiles,posterior_draws,thin,h,model);
	    fclose(f_out);
	  }

	if (observables)
	  {
	    // Open output file for impulse responses of observables
	    fmt="ir_observables_percentiles_regime_%d_%s.prn";
	    sprintf(out_filename=(char*)dw_malloc(strlen(fmt) + strlen(tag) + 10),fmt,s,tag);
	    f_out=fopen(out_filename,"wt");
	    dw_free(out_filename);

	    // Compute percentiles for impulse responses of observables
	    printf("Constructing percentiles for impulse responses of observables - regime %d\n",s);
	    dw_state_space_impulse_response_observables_percentile_regime(f_out,s,percentiles,posterior_draws,thin,h,model);
	    fclose(f_out);
	  }
      }
  else
    if (((s=dw_ParseInteger_String(nargs,args,"regime",-1)) >= 0) && (s < statespace->nbasestates))
      {
	if (states)
	  {
	    // Open output file for impulse responses of states
	    fmt="ir_states_percentiles_regime_%d_%s.prn";
	    sprintf(out_filename=(char*)dw_malloc(strlen(fmt) + strlen(tag) + 10),fmt,s,tag);
	    f_out=fopen(out_filename,"wt");
	    dw_free(out_filename);

	    // Compute percentiles for impulse responses of states
	    printf("Constructing percentiles for impulse responses of states - regime %d\n",s);
	    dw_state_space_impulse_response_states_percentile_regime(f_out,s,percentiles,posterior_draws,thin,h,model);
	    fclose(f_out);
	  }

	if (observables)
	  {
	    // Open output file for impulse responses of observables
	    fmt="ir_observables_percentiles_regime_%d_%s.prn";
	    sprintf(out_filename=(char*)dw_malloc(strlen(fmt) + strlen(tag) + 10),fmt,s,tag);
	    f_out=fopen(out_filename,"wt");
	    dw_free(out_filename);

	    // Compute percentiles for impulse responses of observables
	    printf("Constructing percentiles for impulse responses of observables - regime %d\n",s);
	    dw_state_space_impulse_response_observables_percentile_regime(f_out,s,percentiles,posterior_draws,thin,h,model);
	    fclose(f_out);
	  }
      }

  FreeMatrix(posterior_draws);
  FreeVector(percentiles);
}

/*
   Command line parameters

   -t <tag> : input and output tag

   -ft <tag> : takes precedence over -t

   -outtag <tag> : takes presedence over -t and -ft

   -parmfile <parameter filename>
      default = simulation_<tag>.out if parameter_uncertainty is set

   -states
      Print variance decomposition of state variables. (default = off)

   -observables
      Print variance decomposition of observable variables. (default = on unless
      -states is set)

   -horizon <integer>
      If this argument exists, then the forecast horizon is given by the passed 
      integer.  The default value is 12.

   -filtered
      Uses filtered probabilities at the end of the sample as initial conditions 
      for regime probabilities.  The default behavior is to us the erogdic 
      distribution for the initial conditions.  This flag only applies if neither 
      -regimes nor -regime is specified. 

   -parameter_uncertainty 
      Use posterior draws to compute error bands for the variance decomposition.

   -shocks_per_parameter <integer> 
      Number of regime paths to draw for each parameter draw.  The default value 
      is 10 if parameter_uncertainty is set and 10,000 otherwise.

   -error_bands 
      Output percentile error bands.  (default = off - mean is computed)

   -percentiles n p_1 p_2 ... p_n
      Percentiles to compute. The first parameter after percentiles must be the 
      number of percentiles and the following values are the actual percentiles. 
      (default = 3  0.16  0.50  0.84 - only meaningful if -error_bands is set)
     
   -thin 
      Thinning factor.  Only 1/thin of the draws in posterior draws file are 
      used. The default value is 1.

   -regimes 
      Produces forecasts as if each regime were permanent. (default = off)

   -regime <integer>
      Produces forecasts as if the given regime were permanent.  Regime numbers 
      are zero based.  (default = off)
*/
static void PrintVarianceDecomposition(int horizon, int observables, TVector percentiles, int draws, FILE *posterior_file, int thin, int regime, int ergodic, char *tag, TStateModel *model)
{
  T_MSStateSpace *statespace=(T_MSStateSpace*)(model->theta);
  FILE *f_out;
  char filename[1024];
  int i, flag=observables ? IR_OBSERVABLES : IR_STATES, nvars=observables ? statespace->ny : statespace->nz, nshocks=observables ? statespace->nepsilon+statespace->nu : statespace->nepsilon;
  TMatrixHistogram *histogram;
  TMatrix tvd;

  // reset posterior file
  if (posterior_file) rewind(posterior_file);

  // open output file
  strcpy(filename,"vd_");
  strcat(filename,observables ? "observables_" : "states_");
  strcat(filename,percentiles ? "percentiles_" : "mean_");
  if (regime >= 0)
    sprintf(filename+strlen(filename),"regime%d_",regime);
  else
    strcat(filename,ergodic ? "ergodic_" : "filtered_");
  if (strlen(filename) + strlen(tag) < 1020)
    {
      strcat(filename,tag);
      strcat(filename,".out");
    }
  else
    {
      printf("PrintVarianceDecomposition(): filename too long, increase buffer size.");
      return;
    }

  if (f_out=fopen(filename,"wt"))
    {
      // percentiles or mean
      if (percentiles)
	{
	  if (histogram=(regime >= 0) ? state_space_variance_decomposition_percentiles_regime(posterior_file,thin,regime,horizon,model,flag)
	      : state_space_variance_decomposition_percentiles(draws,posterior_file,thin,ergodic,horizon,model,flag))
	    {
	      tvd=CreateMatrix(horizon,nvars*nshocks);
	      for (i=0; i < DimV(percentiles); i++)
		{
		  MatrixPercentile(tvd,ElementV(percentiles,i),histogram);
		  dw_PrintMatrix(f_out,tvd,"%lg ");
		  fprintf(f_out,"\n");
		}
	      FreeMatrix(tvd);
	      FreeMatrixHistogram(histogram);
	    }
	}
      else
	{
	  if (tvd=(regime >= 0) ? state_space_variance_decomposition_mean_regime(posterior_file,thin,regime,horizon,model,flag)
	      : state_space_variance_decomposition_mean(draws,posterior_file,thin,ergodic,horizon,model,flag))
	    {
	      NormalizeVarianceDecomposition(tvd,observables ? statespace->ny : statespace->nz);
	      dw_PrintMatrix(f_out,tvd,"%lg ");
	      FreeMatrix(tvd);
	    }
	}

      fclose(f_out);
    }
}
void dw_state_space_variance_decomposition_command_line(int nargs, char **args, TStateModel *model)
{
  T_MSStateSpace *statespace=(T_MSStateSpace*)(model->theta);
  FILE *f_posterior;
  char *filename, *fmt, *tag;
  TVector percentiles=(TVector)NULL;
  int s, horizon, thin, states, observables, ergodic, draws;

  if (!IsStateSpaceModel(model)) return;

  tag=GetTag(nargs,args);

  // Parameter uncertainty
  if (dw_FindArgument_String(nargs,args,"parameter_uncertainty") != -1)
    {
      if (filename=dw_ParseString_String(nargs,args,"parmfile",(char*)NULL))
	{
	  if (!(f_posterior=fopen(filename,"rt")))
	    {
	      printf("dw_state_space_variance_decomposition_command line(): Unable to open posterior draws file: %s\n",filename);
	      return;
	    }
	}
      else
	{
	  fmt="simulation_%s.out";
	  sprintf(filename=(char*)dw_malloc(strlen(fmt) + strlen(tag) - 1),fmt,tag);
	  if (!(f_posterior=fopen(filename,"rt")))
	    {
	      printf("dw_state_space_variance_decomposition_command line(): Unable to open posterior draws file: %s\n",filename);
	      dw_free(filename);
	      return;
	    }
	  dw_free(filename);
	}
      thin=dw_ParseInteger_String(nargs,args,"thin",1);
      draws=dw_ParseInteger_String(nargs,args,"shocks_per_parameter",10);
    }
  else
    {
      f_posterior=(FILE*)NULL;
      thin=1;
      draws=dw_ParseInteger_String(nargs,args,"shocks_per_parameter",10000);
      if (!ReadParameters(nargs,args,model,2,0))
	{
	  printf("dw_state_space_variance_decomposition_command line(): Unable to open posterior draws file: %s\n",dw_ParseString_String(nargs,args,"parmfile",(char*)NULL));
	  return;
	}
    }

  // Error bands and percentiles
  percentiles=ReadPercentiles(nargs,args);

  // horizon
  horizon=dw_ParseInteger_String(nargs,args,"horizon",12);

  // print variance decomposition of states
  states=(dw_FindArgument_String(nargs,args,"states") == -1) ? 0 : 1;

  // print variance decomposition of observables
  observables=(dw_FindArgument_String(nargs,args,"observables") == -1) ? 1-states : 1;

  // ergodic variance decomposition
  ergodic=(dw_FindArgument_String(nargs,args,"filtered") != -1) ? 0 : 1; 

  if (dw_FindArgument_String(nargs,args,"regimes") != -1)
    for (s=0; s < statespace->nbasestates; s++)
      {
	if (states) PrintVarianceDecomposition(horizon,0,percentiles,draws,f_posterior,thin,s,-1,tag,model);
	if (observables) PrintVarianceDecomposition(horizon,1,percentiles,draws,f_posterior,thin,s,-1,tag,model);
      }
  else
    if (((s=dw_ParseInteger_String(nargs,args,"regime",-1)) >= 0) && (s < statespace->nbasestates))
      {
	if (states) PrintVarianceDecomposition(horizon,0,percentiles,draws,f_posterior,thin,s,-1,tag,model);
	if (observables) PrintVarianceDecomposition(horizon,1,percentiles,draws,f_posterior,thin,s,-1,tag,model);
      }
    else
      {
	if (states) PrintVarianceDecomposition(horizon,0,percentiles,draws,f_posterior,thin,-1,ergodic,tag,model);
	if (observables) PrintVarianceDecomposition(horizon,1,percentiles,draws,f_posterior,thin,-1,ergodic,tag,model);
      }

  if (f_posterior) fclose(f_posterior);
  FreeVector(percentiles);
}


/*
   Command line parameters

     -t <tag> : input and output tag

     -ft <tag> : takes precedence over -t

     -outtag <tag> : takes presedence over -t and -ft

     -parmfile <parameter filename> : parameter filename
*/
void dw_state_space_smoothed_shocks_command_line(int nargs, char **args, TStateModel *model)
{
  FILE *f_out;
  char *out_filename, *fmt, *tag;
  TVector *smoothed_shocks;
  int  t;
  T_MSStateSpace *statespace;

  if (!IsStateSpaceModel(model)) return;

  statespace=(T_MSStateSpace*)(model->theta);

  tag=GetTag(nargs,args);

  ReadParameters(nargs,args,model,2,0);

  printf("Constructing smoothed shocks\n");
  fmt="smoothedshocks_%s.out";
  sprintf(out_filename=(char*)dw_malloc(strlen(fmt) + strlen(tag) - 1),fmt,tag);
  f_out=fopen(out_filename,"wt");
  dw_free(out_filename);
  smoothed_shocks=SmoothedShocks(model);
  for (t=2; t <= statespace->nobs; t++)
    {
      fprintf(f_out,"%d",t);
      dw_PrintVector(f_out,smoothed_shocks[t],", %lf");
    }
  fclose(f_out);
  dw_FreeArray(smoothed_shocks);
}

/*
   Command line parameters

     -t <tag> : input and output tag

     -ft <tag> : takes precedence over -t

     -outtag <tag> : takes presedence over -t and -ft

     -parmfile <parameter filename> : parameter filename
*/
void dw_state_space_smoothed_states_command_line(int nargs, char **args, TStateModel *model)
{
  FILE *f_out;
  char *out_filename, *fmt, *tag;
  int t;
  T_MSStateSpace *statespace;
  TVector *smoothed_states;

  if (!IsStateSpaceModel(model)) return;

  statespace=(T_MSStateSpace*)(model->theta);

  tag=GetTag(nargs,args);

  ReadParameters(nargs,args,model,2,0);

  fmt="smoothedstates_%s.out";
  sprintf(out_filename=(char*)dw_malloc(strlen(fmt) + strlen(tag) - 1),fmt,tag);
  f_out=fopen(out_filename,"wt");
  dw_free(out_filename);
  printf("Constructing smoothed states\n");
  smoothed_states=SmoothedStates(model);
  //Smooth_MSStateSpace(model);
  for (t=1; t <= statespace->nobs; t++)
    {
      fprintf(f_out,"%d",t);
      dw_PrintVector(f_out,smoothed_states[t],", %lf");
    }
  fclose(f_out);
  dw_FreeArray(smoothed_states);
}

/*
   Command line parameters

     -t <tag> : input and output tag

     -ft <tag> : takes precedence over -t

     -outtag <tag> : takes presedence over -t and -ft

     -parmfile <parameter filename> : parameter filename

     -smoothed : produces smoothed probabilities

     -filtered : produces filtered probabilities
 
     -base : produces base probabilities
*/
void dw_state_space_probabilities_command_line(int nargs, char **args, TStateModel *model)
{
  char *out_filename, *fmt, *tag;
  FILE *f_out;
  int t;
  T_MSStateSpace *statespace;
  TVector *base;

  if (!IsStateSpaceModel(model)) return;

  statespace=(T_MSStateSpace*)(model->theta);

  tag=GetTag(nargs,args);

  ReadParameters(nargs,args,model,2,0);

  if (dw_FindArgument_String(nargs,args,"smoothed") != -1)
    if (dw_FindArgument_String(nargs,args,"base") != -1)
      {
	printf("Constructing smoothed base probabilities\n");
	fmt="smoothbaseprob_%s.out";
	sprintf(out_filename=(char*)dw_malloc(strlen(fmt) + strlen(tag) - 1),fmt,tag);
	if (f_out=fopen(out_filename,"wt"))
	  {
	    if (ComputeSmoothedProbabilities(model))
	      {
		base=sv_FullBaseProbabilities(model->SP,model->sv);
		for (t=0; t <= statespace->nobs; t++)
		  {
		    fprintf(f_out,"%d",t);
		    dw_PrintVector(f_out,base[t],", %lf");
		  }
		dw_FreeArray(base);
	      }
	    fclose(f_out);
	  }
	dw_free(out_filename);
      }
    else
      {
	printf("Constructing smoothed probabilities\n");
	fmt="smoothprob_%s.out";
	sprintf(out_filename=(char*)dw_malloc(strlen(fmt) + strlen(tag) - 1),fmt,tag);
	if (f_out=fopen(out_filename,"wt"))
	  {
	    if (ComputeSmoothedProbabilities(model))
	      {
		for (t=0; t <= statespace->nobs; t++)
		  {
		    fprintf(f_out,"%d",t);
		    dw_PrintVector(f_out,model->SP[t],", %lf");
		  }
	      }
	    fclose(f_out);
	  }
	dw_free(out_filename);
      }

  if (dw_FindArgument_String(nargs,args,"filtered") != -1)
    {
      printf("Constructing filtered probabilities\n");
      fmt="filterprob_%s.out";
      sprintf(out_filename=(char*)dw_malloc(strlen(fmt) + strlen(tag) - 1),fmt,tag);
      if (f_out=fopen(out_filename,"wt"))
	{
	  if (ForwardRecursion(model->nobs,model))
	    {
	      for (t=0; t <= statespace->nobs; t++)
		{
		  fprintf(f_out,"%d",t);
		  dw_PrintVector(f_out,model->V[t],", %lf");
		}
	    }
	  fclose(f_out);
	}
      dw_free(out_filename);
    }
}

/*
   Command line parameters

     -t <tag> : input and output tag

     -ft <tag> : takes precedence over -t

     -outtag <tag> : takes presedence over -t and -ft

     -parmfile <parameter filename> 

     -shocks <epsilon shocks filename> : default smoothedshocks_<tag>.out

     -prob <marginal regime probabilities filename> : default smoothbaseprob_<tag>.out
 
     -states <states filename> : default smoothedstates_<tag>.out 

     -t0 <integer> : first period to produce counterfactual data (default = 1)
*/
void dw_state_space_counterfactual_command_line(int nargs, char **args, TStateModel *model)
{
  char *filename, *fmt, *tag, *shocks_filename, *prob_filename, *states_filename;
  FILE *f_out;
  int t0;
  T_MSStateSpace *statespace;
  TMatrix data, shocks, prob, states;

  printf("Constructing counterfactual experiment\n");

  if (!IsStateSpaceModel(model)) return;

  statespace=(T_MSStateSpace*)(model->theta);

  tag=GetTag(nargs,args);

  ReadParameters(nargs,args,model,2,0);  

  t0=dw_ParseInteger_String(nargs,args,"t0",1);

  // shocks
  fmt="smoothedshocks_%s.out";
  sprintf(filename=(char*)dw_malloc(strlen(fmt) + strlen(tag) - 1),fmt,tag);
  shocks_filename=dw_ParseString_String(nargs,args,"shocks",filename);
  shocks=dw_ReadDelimitedFile_matrix((FILE*)NULL,shocks_filename,',',REMOVE_EMPTY_FIELDS | STRIP_WHITESPACE,-1.0e-300);

  if (shocks)
    {
      printf("shocks file: %s\n",shocks_filename);
      dw_free(filename);
      // base probabilities
      fmt="smoothbaseprob_%s.out";
      sprintf(filename=(char*)dw_malloc(strlen(fmt) + strlen(tag) - 1),fmt,tag);
      prob_filename=dw_ParseString_String(nargs,args,"prob",filename);
      prob=dw_ReadDelimitedFile_matrix((FILE*)NULL,prob_filename,',',REMOVE_EMPTY_FIELDS | STRIP_WHITESPACE,-1.0e-300);

      if (prob)
	{
	  printf("probabilities file: %s\n",prob_filename);
	  dw_free(filename);
	  // states
	  fmt="smoothedstates_%s.out";
	  sprintf(filename=(char*)dw_malloc(strlen(fmt) + strlen(tag) - 1),fmt,tag);
	  states_filename=dw_ParseString_String(nargs,args,"states",filename);
	  states=dw_ReadDelimitedFile_matrix((FILE*)NULL,states_filename,',',REMOVE_EMPTY_FIELDS | STRIP_WHITESPACE,-1.0e-300);
  
	  if (states)
	    {
	      printf("states file: %s\n",states_filename);
	      dw_free(filename);
	      fmt="counterfactual_%s.out";
	      sprintf(filename=(char*)dw_malloc(strlen(fmt) + strlen(tag) - 1),fmt,tag);
	      if (f_out=fopen(filename,"wt"))
		{
		  if (data=dw_state_space_counterfactual((TMatrix)NULL,t0,states,shocks,prob,model))
		    {
		      dw_PrintMatrix(f_out,data,"%lg, ");
		      FreeMatrix(data);
		    }
		  else
		    printf("Error producing counterfactual\n");
		  fclose(f_out);
		}
	      else
		printf("Unable to create output file: %s\n",filename);
	      dw_free(filename);
	      FreeMatrix(states);
	    }
	  else
	    {
	      printf("Unable to open smoothed states file: %s\n",states_filename);
	      dw_free(filename);
	    }
	  FreeMatrix(prob);
	}
      else
	{
	  printf("Unable to open smoothed probabilities file: %s\n",prob_filename);
	  dw_free(filename);
	}
      FreeMatrix(shocks);
    }
  else
    {
      printf("Unable to open smoothed shocks file: %s\n",shocks_filename);
      dw_free(filename);
    }
}

/*
   Command line parameter - see each function for specific parameters

     -forecast       : produce forecast
     -ir             : produce impulse responses
     -historical     : produce historical decomposition
     -smoothedshocks : produce smoothed shocks
     -smoothedstates : produce smoothed states
     -probabilties   : produce smoothed or filtered probabilities
     -counterfactual : produce counterfactual experiment
*/
void dw_command_line_statespace_output(int nargs, char** args, TStateModel *model)
{
  // forecasts
  if (dw_FindArgument_String(nargs,args,"forecast") != -1)
    dw_state_space_forecast_command_line(nargs,args,model);

  // impulse responses - requires posterior draws
  if (dw_FindArgument_String(nargs,args,"ir") != -1)
    dw_state_space_impulse_response_command_line(nargs,args,model);

  // historical decomposition
  if (dw_FindArgument_String(nargs,args,"historical") != -1)
    dw_state_space_historical_decomposition_command_line(nargs,args,model);

  // smoothed shocks
  if (dw_FindArgument_String(nargs,args,"smoothedshocks") != -1)
    dw_state_space_smoothed_shocks_command_line(nargs,args,model);

  // smoothed states
  if (dw_FindArgument_String(nargs,args,"smoothedstates") != -1)
    dw_state_space_smoothed_states_command_line(nargs,args,model);

  // probabilities
  if (dw_FindArgument_String(nargs,args,"probabilities") != -1)
    dw_state_space_probabilities_command_line(nargs,args,model);

  // counterfactual
  if (dw_FindArgument_String(nargs,args,"counterfactual") != -1)
    dw_state_space_counterfactual_command_line(nargs,args,model);

  // simulation
  if (dw_FindArgument_String(nargs,args,"simulation") != -1)
    dw_state_space_simulate_command_line(nargs,args,model);

  // mdd
  if (dw_FindArgument_String(nargs,args,"mdd") != -1)
    dw_marginal_data_density_command_line(nargs,args,model,0);

  // variance decomposition
  if (dw_FindArgument_String(nargs,args,"variance_decomposition") != -1)
    dw_state_space_variance_decomposition_command_line(nargs,args,model);
}
