/*1:*/
#line 38 "./decision_rule.hweb"

#ifndef DECISION_RULE_H
#define DECISION_RULE_H

#include <matio.h> 

#include "kord_exception.h"
#include "korder.h"
#include "normal_conjugate.h"
#include "mersenne_twister.h"

/*2:*/
#line 75 "./decision_rule.hweb"

class ShockRealization{
public:
virtual~ShockRealization(){}
virtual void get(int n,Vector&out)= 0;
virtual int numShocks()const= 0;
};

/*:2*/
#line 49 "./decision_rule.hweb"
;
/*3:*/
#line 96 "./decision_rule.hweb"

class DecisionRule{
public:
enum emethod{horner,trad};
virtual~DecisionRule(){}
virtual TwoDMatrix*simulate(emethod em,int np,const Vector&ystart,
ShockRealization&sr)const= 0;
virtual void eval(emethod em,Vector&out,const ConstVector&v)const= 0;
virtual void evaluate(emethod em,Vector&out,const ConstVector&ys,
const ConstVector&u)const= 0;
virtual void writeMat(mat_t*fd,const char*prefix)const= 0;
virtual DecisionRule*centralizedClone(const Vector&fixpoint)const= 0;
virtual const Vector&getSteady()const= 0;
virtual int nexog()const= 0;
virtual const PartitionY&getYPart()const= 0;
};

/*:3*/
#line 50 "./decision_rule.hweb"
;
/*4:*/
#line 136 "./decision_rule.hweb"

template<int t> 
class DecisionRuleImpl:public ctraits<t> ::Tpol,public DecisionRule{
protected:
typedef typename ctraits<t> ::Tpol _Tparent;
const Vector ysteady;
const PartitionY ypart;
const int nu;
public:
DecisionRuleImpl(const _Tparent&pol,const PartitionY&yp,int nuu,
const Vector&ys)
:ctraits<t> ::Tpol(pol),ysteady(ys),ypart(yp),nu(nuu){}
DecisionRuleImpl(_Tparent&pol,const PartitionY&yp,int nuu,
const Vector&ys)
:ctraits<t> ::Tpol(0,yp.ny(),pol),ysteady(ys),ypart(yp),
nu(nuu){}
DecisionRuleImpl(const _Tg&g,const PartitionY&yp,int nuu,
const Vector&ys,double sigma)
:ctraits<t> ::Tpol(yp.ny(),yp.nys()+nuu),ysteady(ys),ypart(yp),nu(nuu)
{fillTensors(g,sigma);}
DecisionRuleImpl(const DecisionRuleImpl<t> &dr,const ConstVector&fixpoint)
:ctraits<t> ::Tpol(dr.ypart.ny(),dr.ypart.nys()+dr.nu),
ysteady(fixpoint),ypart(dr.ypart),nu(dr.nu)
{centralize(dr);}
const Vector&getSteady()const
{return ysteady;}
/*8:*/
#line 294 "./decision_rule.hweb"

TwoDMatrix*simulate(emethod em,int np,const Vector&ystart,
ShockRealization&sr)const
{
KORD_RAISE_IF(ysteady.length()!=ystart.length(),
"Start and steady lengths differ in DecisionRuleImpl::simulate");
TwoDMatrix*res= new TwoDMatrix(ypart.ny(),np);

/*9:*/
#line 313 "./decision_rule.hweb"

Vector dyu(ypart.nys()+nu);
ConstVector ystart_pred(ystart,ypart.nstat,ypart.nys());
ConstVector ysteady_pred(ysteady,ypart.nstat,ypart.nys());
Vector dy(dyu,0,ypart.nys());
Vector u(dyu,ypart.nys(),nu);


/*:9*/
#line 302 "./decision_rule.hweb"
;
/*10:*/
#line 324 "./decision_rule.hweb"

dy= ystart_pred;
dy.add(-1.0,ysteady_pred);
sr.get(0,u);
Vector out(*res,0);
eval(em,out,dyu);

/*:10*/
#line 303 "./decision_rule.hweb"
;
/*11:*/
#line 334 "./decision_rule.hweb"

int i= 1;
while(i<np){
ConstVector ym(*res,i-1);
ConstVector dym(ym,ypart.nstat,ypart.nys());
dy= dym;
sr.get(i,u);
Vector out(*res,i);
eval(em,out,dyu);
if(!out.isFinite()){
if(i+1<np){
TwoDMatrix rest(*res,i+1,np-i-1);
rest.zeros();
}
break;
}
i++;
}

/*:11*/
#line 304 "./decision_rule.hweb"
;
/*12:*/
#line 356 "./decision_rule.hweb"

for(int j= 0;j<i;j++){
Vector col(*res,j);
col.add(1.0,ysteady);
}


/*:12*/
#line 305 "./decision_rule.hweb"
;
return res;
}

/*:8*/
#line 162 "./decision_rule.hweb"
;
/*13:*/
#line 368 "./decision_rule.hweb"

void evaluate(emethod em,Vector&out,const ConstVector&ys,
const ConstVector&u)const
{
KORD_RAISE_IF(ys.length()!=ypart.nys()||u.length()!=nu,
"Wrong dimensions of input vectors in DecisionRuleImpl::evaluate");
KORD_RAISE_IF(out.length()!=ypart.ny(),
"Wrong dimension of output vector in DecisionRuleImpl::evaluate");
ConstVector ysteady_pred(ysteady,ypart.nstat,ypart.nys());
Vector ys_u(ypart.nys()+nu);
Vector ys_u1(ys_u,0,ypart.nys());
ys_u1= ys;
ys_u1.add(-1.0,ysteady_pred);
Vector ys_u2(ys_u,ypart.nys(),nu);
ys_u2= u;
eval(em,out,ys_u);
out.add(1.0,ysteady);
}

/*:13*/
#line 163 "./decision_rule.hweb"
;
/*14:*/
#line 390 "./decision_rule.hweb"

DecisionRule*centralizedClone(const Vector&fixpoint)const
{
return new DecisionRuleImpl<t> (*this,fixpoint);
}

/*:14*/
#line 164 "./decision_rule.hweb"
;
/*16:*/
#line 409 "./decision_rule.hweb"

void writeMat(mat_t*fd,const char*prefix)const
{
ctraits<t> ::Tpol::writeMat(fd,prefix);
TwoDMatrix dum(ysteady.length(),1);
dum.getData()= ysteady;
char tmp[100];
sprintf(tmp,"%s_ss",prefix);
ConstTwoDMatrix(dum).writeMat(fd,tmp);
}

/*:16*/
#line 165 "./decision_rule.hweb"
;
int nexog()const
{return nu;}
const PartitionY&getYPart()const
{return ypart;}
protected:
/*5:*/
#line 212 "./decision_rule.hweb"

void fillTensors(const _Tg&g,double sigma)
{
IntSequence tns(2);
tns[0]= ypart.nys();tns[1]= nu;
int dfact= 1;
for(int d= 0;d<=g.getMaxDim();d++,dfact*= d){
_Ttensym*g_yud= new _Ttensym(ypart.ny(),ypart.nys()+nu,d);
g_yud->zeros();
/*6:*/
#line 236 "./decision_rule.hweb"

for(int i= 0;i<=d;i++){
int j= d-i;
int kfact= 1;
_Ttensor tmp(ypart.ny(),
TensorDimens(Symmetry(i,j),tns));
tmp.zeros();
for(int k= 0;k+d<=g.getMaxDim();k++,kfact*= k){
Symmetry sym(i,j,0,k);
if(g.check(sym)){
double mult= pow(sigma,k)/dfact/kfact;
tmp.add(mult,*(g.get(sym)));
}
}
g_yud->addSubTensor(tmp);
}

/*:6*/
#line 221 "./decision_rule.hweb"
;
this->insert(g_yud);
}
}

/*:5*/
#line 171 "./decision_rule.hweb"
;
/*7:*/
#line 262 "./decision_rule.hweb"

void centralize(const DecisionRuleImpl&dr)
{
Vector dstate(ypart.nys()+nu);
dstate.zeros();
Vector dstate_star(dstate,0,ypart.nys());
ConstVector newsteady_star(ysteady,ypart.nstat,ypart.nys());
ConstVector oldsteady_star(dr.ysteady,ypart.nstat,ypart.nys());
dstate_star.add(1.0,newsteady_star);
dstate_star.add(-1.0,oldsteady_star);

_Tpol pol(dr);
int dfac= 1;
for(int d= 1;d<=dr.getMaxDim();d++,dfac*= d){
pol.derivative(d-1);
_Ttensym*der= pol.evalPartially(d,dstate);
der->mult(1.0/dfac);
this->insert(der);
}
}

/*:7*/
#line 172 "./decision_rule.hweb"
;
/*15:*/
#line 399 "./decision_rule.hweb"

void eval(emethod em,Vector&out,const ConstVector&v)const
{
if(em==DecisionRule::horner)
_Tparent::evalHorner(out,v);
else
_Tparent::evalTrad(out,v);
}

/*:15*/
#line 173 "./decision_rule.hweb"
;
};

/*:4*/
#line 51 "./decision_rule.hweb"
;
/*17:*/
#line 425 "./decision_rule.hweb"

class UnfoldDecisionRule;
class FoldDecisionRule:public DecisionRuleImpl<KOrder::fold> {
friend class UnfoldDecisionRule;
public:
FoldDecisionRule(const ctraits<KOrder::fold> ::Tpol&pol,const PartitionY&yp,int nuu,
const Vector&ys)
:DecisionRuleImpl<KOrder::fold> (pol,yp,nuu,ys){}
FoldDecisionRule(ctraits<KOrder::fold> ::Tpol&pol,const PartitionY&yp,int nuu,
const Vector&ys)
:DecisionRuleImpl<KOrder::fold> (pol,yp,nuu,ys){}
FoldDecisionRule(const ctraits<KOrder::fold> ::Tg&g,const PartitionY&yp,int nuu,
const Vector&ys,double sigma)
:DecisionRuleImpl<KOrder::fold> (g,yp,nuu,ys,sigma){}
FoldDecisionRule(const DecisionRuleImpl<KOrder::fold> &dr,const ConstVector&fixpoint)
:DecisionRuleImpl<KOrder::fold> (dr,fixpoint){}
FoldDecisionRule(const UnfoldDecisionRule&udr);
};

/*:17*/
#line 52 "./decision_rule.hweb"
;
/*18:*/
#line 448 "./decision_rule.hweb"

class UnfoldDecisionRule:public DecisionRuleImpl<KOrder::unfold> {
friend class FoldDecisionRule;
public:
UnfoldDecisionRule(const ctraits<KOrder::unfold> ::Tpol&pol,const PartitionY&yp,int nuu,
const Vector&ys)
:DecisionRuleImpl<KOrder::unfold> (pol,yp,nuu,ys){}
UnfoldDecisionRule(ctraits<KOrder::unfold> ::Tpol&pol,const PartitionY&yp,int nuu,
const Vector&ys)
:DecisionRuleImpl<KOrder::unfold> (pol,yp,nuu,ys){}
UnfoldDecisionRule(const ctraits<KOrder::unfold> ::Tg&g,const PartitionY&yp,int nuu,
const Vector&ys,double sigma)
:DecisionRuleImpl<KOrder::unfold> (g,yp,nuu,ys,sigma){}
UnfoldDecisionRule(const DecisionRuleImpl<KOrder::unfold> &dr,const ConstVector&fixpoint)
:DecisionRuleImpl<KOrder::unfold> (dr,fixpoint){}
UnfoldDecisionRule(const FoldDecisionRule&udr);
};


/*:18*/
#line 53 "./decision_rule.hweb"
;
/*19:*/
#line 480 "./decision_rule.hweb"

template<int t> 
class DRFixPoint:public ctraits<t> ::Tpol{
typedef typename ctraits<t> ::Tpol _Tparent;
static int max_iter;
static int max_newton_iter;
static int newton_pause;
static double tol;
const Vector ysteady;
const PartitionY ypart;
_Tparent*bigf;
_Tparent*bigfder;
public:
typedef typename DecisionRule::emethod emethod;
/*20:*/
#line 519 "./decision_rule.hweb"

DRFixPoint(const _Tg&g,const PartitionY&yp,
const Vector&ys,double sigma)
:ctraits<t> ::Tpol(yp.ny(),yp.nys()),
ysteady(ys),ypart(yp),bigf(NULL),bigfder(NULL)
{
fillTensors(g,sigma);
_Tparent yspol(ypart.nstat,ypart.nys(),*this);
bigf= new _Tparent((const _Tparent&)yspol);
_Ttensym*frst= bigf->get(Symmetry(1));
for(int i= 0;i<ypart.nys();i++)
frst->get(i,i)= frst->get(i,i)-1;
bigfder= new _Tparent(*bigf,0);
}

/*:20*/
#line 494 "./decision_rule.hweb"
;
/*21:*/
#line 535 "./decision_rule.hweb"

virtual~DRFixPoint()
{
if(bigf)
delete bigf;
if(bigfder)
delete bigfder;
}

/*:21*/
#line 495 "./decision_rule.hweb"
;
/*25:*/
#line 658 "./decision_rule.hweb"

bool calcFixPoint(emethod em,Vector&out)
{
KORD_RAISE_IF(out.length()!=ypart.ny(),
"Wrong length of out in DRFixPoint::calcFixPoint");

Vector delta(ypart.nys());
Vector ystar(ypart.nys());
ystar.zeros();

iter= 0;
newton_iter_last= 0;
newton_iter_total= 0;
bool converged= false;
do{
if((iter/newton_pause)*newton_pause==iter)
converged= solveNewton(ystar);
if(!converged){
bigf->evalHorner(delta,ystar);
KORD_RAISE_IF_X(!delta.isFinite(),
"NaN or Inf asserted in DRFixPoint::calcFixPoint",
KORD_FP_NOT_FINITE);
ystar.add(1.0,delta);
converged= delta.getNorm()<tol;
}
iter++;
}while(iter<max_iter&&!converged);

if(converged){
_Tparent::evalHorner(out,ystar);
out.add(1.0,ysteady);
}

return converged;
}


/*:25*/
#line 496 "./decision_rule.hweb"
;
int getNumIter()const
{return iter;}
int getNewtonLastIter()const
{return newton_iter_last;}
int getNewtonTotalIter()const
{return newton_iter_total;}
protected:
/*22:*/
#line 550 "./decision_rule.hweb"

void fillTensors(const _Tg&g,double sigma)
{
int dfact= 1;
for(int d= 0;d<=g.getMaxDim();d++,dfact*= d){
_Ttensym*g_yd= new _Ttensym(ypart.ny(),ypart.nys(),d);
g_yd->zeros();
int kfact= 1;
for(int k= 0;d+k<=g.getMaxDim();k++,kfact*= k){
if(g.check(Symmetry(d,0,0,k))){
const _Ttensor*ten= g.get(Symmetry(d,0,0,k));
double mult= pow(sigma,k)/dfact/kfact;
g_yd->add(mult,*ten);
}
}
this->insert(g_yd);
}
}

/*:22*/
#line 504 "./decision_rule.hweb"
;
/*23:*/
#line 583 "./decision_rule.hweb"

bool solveNewton(Vector&y)
{
const double urelax_threshold= 1.e-5;
Vector sol((const Vector&)y);
Vector delta(y.length());
newton_iter_last= 0;
bool delta_finite= true;
double flastnorm= 0.0;
double fnorm= 0.0;
bool converged= false;
double urelax= 1.0;

do{
_Ttensym*jacob= bigfder->evalPartially(1,sol);
bigf->evalHorner(delta,sol);
if(newton_iter_last==0)
flastnorm= delta.getNorm();
delta_finite= delta.isFinite();
if(delta_finite){
ConstTwoDMatrix(*jacob).multInvLeft(delta);
/*24:*/
#line 628 "./decision_rule.hweb"

bool urelax_found= false;
urelax= 1.0;
while(!urelax_found&&urelax> urelax_threshold){
Vector soltmp((const Vector&)sol);
soltmp.add(-urelax,delta);
Vector f(sol.length());
bigf->evalHorner(f,soltmp);
fnorm= f.getNorm();
if(fnorm<=flastnorm)
urelax_found= true;
else
urelax*= std::min(0.5,flastnorm/fnorm);
}


/*:24*/
#line 604 "./decision_rule.hweb"
;
sol.add(-urelax,delta);
delta_finite= delta.isFinite();
}
delete jacob;
newton_iter_last++;
converged= delta_finite&&fnorm<tol;
flastnorm= fnorm;
}while(!converged&&newton_iter_last<max_newton_iter
&&urelax> urelax_threshold);

newton_iter_total+= newton_iter_last;
if(!converged)
newton_iter_last= 0;
y= (const Vector&)sol;
return converged;
}

/*:23*/
#line 505 "./decision_rule.hweb"
;
private:
int iter;
int newton_iter_last;
int newton_iter_total;
};


/*:19*/
#line 54 "./decision_rule.hweb"
;
/*26:*/
#line 699 "./decision_rule.hweb"

class ExplicitShockRealization;
class SimResults{
protected:
int num_y;
int num_per;
int num_burn;
vector<TwoDMatrix*> data;
vector<ExplicitShockRealization*> shocks;
public:
SimResults(int ny,int nper,int nburn= 0)
:num_y(ny),num_per(nper),num_burn(nburn){}
virtual~SimResults();
void simulate(int num_sim,const DecisionRule&dr,const Vector&start,
const TwoDMatrix&vcov,Journal&journal);
void simulate(int num_sim,const DecisionRule&dr,const Vector&start,
const TwoDMatrix&vcov);
int getNumPer()const
{return num_per;}
int getNumBurn()const
{return num_burn;}
int getNumSets()const
{return(int)data.size();}
const TwoDMatrix&getData(int i)const
{return*(data[i]);}
const ExplicitShockRealization&getShocks(int i)const
{return*(shocks[i]);}
bool addDataSet(TwoDMatrix*d,ExplicitShockRealization*sr);
void writeMat(const char*base,const char*lname)const;
void writeMat(mat_t*fd,const char*lname)const;
};

/*:26*/
#line 55 "./decision_rule.hweb"
;
/*27:*/
#line 734 "./decision_rule.hweb"

class SimResultsStats:public SimResults{
protected:
Vector mean;
TwoDMatrix vcov;
public:
SimResultsStats(int ny,int nper,int nburn= 0)
:SimResults(ny,nper,nburn),mean(ny),vcov(ny,ny){}
void simulate(int num_sim,const DecisionRule&dr,const Vector&start,
const TwoDMatrix&vcov,Journal&journal);
void writeMat(mat_t*fd,const char*lname)const;
protected:
void calcMean();
void calcVcov();
};

/*:27*/
#line 56 "./decision_rule.hweb"
;
/*28:*/
#line 754 "./decision_rule.hweb"

class SimResultsDynamicStats:public SimResults{
protected:
TwoDMatrix mean;
TwoDMatrix variance;
public:
SimResultsDynamicStats(int ny,int nper,int nburn= 0)
:SimResults(ny,nper,nburn),mean(ny,nper),variance(ny,nper){}
void simulate(int num_sim,const DecisionRule&dr,const Vector&start,
const TwoDMatrix&vcov,Journal&journal);
void writeMat(mat_t*fd,const char*lname)const;
protected:
void calcMean();
void calcVariance();
};


/*:28*/
#line 57 "./decision_rule.hweb"
;
/*29:*/
#line 778 "./decision_rule.hweb"

class SimulationIRFWorker;
class SimResultsIRF:public SimResults{
friend class SimulationIRFWorker;
protected:
const SimResults&control;
int ishock;
double imp;
TwoDMatrix means;
TwoDMatrix variances;
public:
SimResultsIRF(const SimResults&cntl,int ny,int nper,int i,double impulse)
:SimResults(ny,nper,0),control(cntl),
ishock(i),imp(impulse),
means(ny,nper),variances(ny,nper){}
void simulate(const DecisionRule&dr,Journal&journal);
void simulate(const DecisionRule&dr);
void writeMat(mat_t*fd,const char*lname)const;
protected:
void calcMeans();
void calcVariances();
};

/*:29*/
#line 58 "./decision_rule.hweb"
;
/*30:*/
#line 807 "./decision_rule.hweb"

class RTSimulationWorker;
class RTSimResultsStats{
friend class RTSimulationWorker;
protected:
Vector mean;
TwoDMatrix vcov;
int num_per;
int num_burn;
NormalConj nc;
int incomplete_simulations;
int thrown_periods;
public:
RTSimResultsStats(int ny,int nper,int nburn= 0)
:mean(ny),vcov(ny,ny),
num_per(nper),num_burn(nburn),nc(ny),
incomplete_simulations(0),thrown_periods(0){}
void simulate(int num_sim,const DecisionRule&dr,const Vector&start,
const TwoDMatrix&vcov,Journal&journal);
void simulate(int num_sim,const DecisionRule&dr,const Vector&start,
const TwoDMatrix&vcov);
void writeMat(mat_t*fd,const char*lname);
};

/*:30*/
#line 59 "./decision_rule.hweb"
;
/*31:*/
#line 845 "./decision_rule.hweb"

class DynamicModel;
class IRFResults{
vector<SimResultsIRF*> irf_res;
const DynamicModel&model;
vector<int> irf_list_ind;
public:
IRFResults(const DynamicModel&mod,const DecisionRule&dr,
const SimResults&control,const vector<int> &ili,
Journal&journal);
~IRFResults();
void writeMat(mat_t*fd,const char*prefix)const;
};

/*:31*/
#line 60 "./decision_rule.hweb"
;
/*32:*/
#line 862 "./decision_rule.hweb"

class SimulationWorker:public THREAD{
protected:
SimResults&res;
const DecisionRule&dr;
DecisionRule::emethod em;
int np;
const Vector&st;
ShockRealization&sr;
public:
SimulationWorker(SimResults&sim_res,
const DecisionRule&dec_rule,
DecisionRule::emethod emet,int num_per,
const Vector&start,ShockRealization&shock_r)
:res(sim_res),dr(dec_rule),em(emet),np(num_per),st(start),sr(shock_r){}
void operator()();
};

/*:32*/
#line 61 "./decision_rule.hweb"
;
/*33:*/
#line 885 "./decision_rule.hweb"

class SimulationIRFWorker:public THREAD{
SimResultsIRF&res;
const DecisionRule&dr;
DecisionRule::emethod em;
int np;
int idata;
int ishock;
double imp;
public:
SimulationIRFWorker(SimResultsIRF&sim_res,
const DecisionRule&dec_rule,
DecisionRule::emethod emet,int num_per,
int id,int ishck,double impulse)
:res(sim_res),dr(dec_rule),em(emet),np(num_per),
idata(id),ishock(ishck),imp(impulse){}
void operator()();
};

/*:33*/
#line 62 "./decision_rule.hweb"
;
/*34:*/
#line 910 "./decision_rule.hweb"

class RTSimulationWorker:public THREAD{
protected:
RTSimResultsStats&res;
const DecisionRule&dr;
DecisionRule::emethod em;
int np;
const Vector&ystart;
ShockRealization&sr;
public:
RTSimulationWorker(RTSimResultsStats&sim_res,
const DecisionRule&dec_rule,
DecisionRule::emethod emet,int num_per,
const Vector&start,ShockRealization&shock_r)
:res(sim_res),dr(dec_rule),em(emet),np(num_per),ystart(start),sr(shock_r){}
void operator()();
};

/*:34*/
#line 63 "./decision_rule.hweb"
;
/*35:*/
#line 932 "./decision_rule.hweb"

class RandomShockRealization:virtual public ShockRealization{
protected:
MersenneTwister mtwister;
TwoDMatrix factor;
public:
RandomShockRealization(const TwoDMatrix&v,unsigned int iseed)
:mtwister(iseed),factor(v.nrows(),v.nrows())
{schurFactor(v);}
RandomShockRealization(const RandomShockRealization&sr)
:mtwister(sr.mtwister),factor(sr.factor){}
virtual~RandomShockRealization(){}
void get(int n,Vector&out);
int numShocks()const
{return factor.nrows();}
protected:
void choleskyFactor(const TwoDMatrix&v);
void schurFactor(const TwoDMatrix&v);
};

/*:35*/
#line 64 "./decision_rule.hweb"
;
/*36:*/
#line 955 "./decision_rule.hweb"

class ExplicitShockRealization:virtual public ShockRealization{
TwoDMatrix shocks;
public:
ExplicitShockRealization(const TwoDMatrix&sh)
:shocks(sh){}
ExplicitShockRealization(const ConstTwoDMatrix&sh)
:shocks(sh){}
ExplicitShockRealization(const ExplicitShockRealization&sr)
:shocks(sr.shocks){}
ExplicitShockRealization(ShockRealization&sr,int num_per);
void get(int n,Vector&out);
int numShocks()const
{return shocks.nrows();}
const TwoDMatrix&getShocks()
{return shocks;}
void addToShock(int ishock,int iper,double val);
void print()const
{shocks.print();}
};

/*:36*/
#line 65 "./decision_rule.hweb"
;
/*37:*/
#line 985 "./decision_rule.hweb"

class GenShockRealization:public RandomShockRealization,public ExplicitShockRealization{
public:
GenShockRealization(const TwoDMatrix&v,const TwoDMatrix&sh,int seed)
:RandomShockRealization(v,seed),ExplicitShockRealization(sh)
{
KORD_RAISE_IF(sh.nrows()!=v.nrows()||v.nrows()!=v.ncols(),
"Wrong dimension of input matrix in GenShockRealization constructor");
}
void get(int n,Vector&out);
int numShocks()const
{return RandomShockRealization::numShocks();}
};

/*:37*/
#line 66 "./decision_rule.hweb"
;

#endif

/*:1*/
