Recursive versus Intertemporal: A Worked Example


Thomas F. Rutherford
University of Colorado


Dear Tom,

I want to use your base model (GTAPinGAMS) for modelling
a recursive dynamics. Teoretically, I understand the concept of a
dynamic model. Writting into MPSGE model I get difficulties particularly
the treatment of invesment. Could you give a hint !

Thank you very much for your hint.

Regards,


This is the closest thing I have to offer. It is a set of model runs and notes which I hope will eventually become a paper. This model is a simplified version of the GTAPinGAMS formulation. I believe that you can find the correspondences necessary to use these ideas with GTAPinGAMS.

There are a number of alternative approaches to dynamic modeling. There are fundamental differences between models which employ "consistent expections" and recursive models in which agents are lack a coherent representation of expections. The latter class of models are characterized by "overshoot and collapse" behavior.

There are also different varieties of dynamic models -- those in which capital flows equalize rates of return across countries and those in which constraints on period-by-period borrowing lead to differences in real rates of return.

This page presents three models: (i) A forward-looking model with complete capital markets, (ii) A forward-looking model with incomplete capital markets (constraints on period-by-period capital flows) and (iii) A recursive model in which agents do not form consistent expectations of future prices. All of the models are calibrated to a common baseline equilibrium growth path. There are two regions in the model (OECD and ROW), and the experiment involves carbon emission reductions in the OECD to achieve a given target.

In a single period of the recursive model a key input parameter is ks_n(r), "new vintage capital" for region r. This represents the value of the region's gross investment in the previous period. The allocation of new capital across regions is done so as to equalize the return to new vintage capital inputs. The level of savings is determined by a fixed marginal propensity to save in all regions.

Define from the previous period solution thetak(r) as the share of new vintage capital which is installed in region r.

When a region demands new investment, this is a good which is produced by fixed shares of construction inputs in all regions of the world. The relative fraction of a given region output in the global investment activity is determined by thetak(r) from the previous solution.

Here is where thetar(r) enters the model:

$prod:inv
        o:pinv          q:(sum(r, invest(r)))
        i:pa(cgd,r)     q:(thetak(r)*sum(rr,invest(rr)))
The following represent the GAMS/MPSGE programs used to represent the three different models. Thereafter follows a program which generates a graphical comparison of results from the three models.

MODELD.GMS:


$title  A Dynamic Model of Carbon Emissions and Trade 

*	-----------------------------------------------------------------------
*	This version forward-looking w/ or w/o balance of payments constraints.
*	-----------------------------------------------------------------------

*	Read run options and benchmark data from an external file:

$include bmkdata

scalar	esub_t		Intertemporal elasticity	/0.5/;

set	bop(r,t)	Periods subject to balance of payments constraints;

parameter	labor(r,t)	Labor supply growth path
		srvshr(t)	Survival share
		ktx		Extant capital in terminal period;

labor(r,t) = qref(t);
srvshr(t) = (1-depr)**(ord(t)-1);
ktx(r) = sum(tlast, thetax*capital(r)*srvshr(tlast))*(1-depr);

alias (t,tt)

parameter	u0(r)	Baseline PV of expenditure
		vx	Value of benchmark exports
		vm	Value of benchmark imports;

u0(r) = sum(t, pref(t)*labor(r,t)*c0(r));
vx(g,r) = sum(rr$(not sameas(r,rr)), m0(g,r,rr));
vm(g,r) = sum(rr$(not sameas(r,rr)), m0(g,rr,r));

$ontext

$model:dynamic

$sectors:
	u(r)		! Intertemporal utility
	c(r,t)		! Consumption
	y(g,r,t)	! Production index
	x(g,r,t)$vx(g,r)
	m(g,r,t)$vm(g,r)	! Import demand
	a(g,r,t)	! Armington demand
	ed(r,t)		! Energy demand
	es(r,t)		! Energy supply
	inv(r,t)
	k(r,t)
	yx(g,r,t)$k0(g,r)	! Extant production

$commodities:
	pu(r)
	pc(r,t)			! Consumption good price
	pm(g,r,t)$vm(g,r)	! Import aggregate price
	pa(g,r,t)	! Armington aggregate price
	pe(r,t)		! Energy demand price
	pew(t)		! World energy price
	pl(r,t)		! Wage rate
	pk(r,t)		! Capital price
	rk(r,t)		! Capital price
	py(g,r,t)	! Non-energy output price
	px(g,r,t)$vx(g,r)
	pr(r,t)		! Price of energy resource inputs
	pkt(r)

	rkx(g,r,t)$k0(g,r)	! Return to extant capital

$consumers:
	ra(r)		! Representative agent

$auxiliary:
	kt(r)			! Terminal capital stock
	mu(r,t)$bop(r,t)	! Balance of payments premium
	tau(r,t)$(card(etax) and annexb(r))	! Carbon tax rate (ad-valorem)
	target(t)$(card(etax) and compensate)	! Abatement target

$prod:u(r)  s:esub_t
	o:pu(r)		q:u0(r)
	i:pc(r,t)	q:(labor(r,t)*c0(r)) p:pref(t)  

$prod:c(r,t) s:esub c:1 
	o:pc(r,t)	q:c0(r)
	i:pa(g,r,t)	q:cd0(g,r)	c:
	i:pe(r,t)	q:ce0(r) a:ra(r) n:tau(r,t)$(card(etax) and annexb(r))

$prod:inv(r,t)
	o:pk(r,t+1)		q:invest(r)
	o:pkt(r)$tlast(t)	q:invest(r)
	i:pa(cgd,r,t)		q:invest(r)	

$prod:k(r,t)
	o:pk(r,t+1)		q:(capital(r)*(1-depr))
	o:pkt(r)$tlast(t)	q:(capital(r)*(1-depr))
	o:rk(r,t)		q:earnings(r)
	i:pk(r,t)		q:capital(r)

$prod:x(g,r,t)$vx(g,r)
	o:px(g,r,t)	q:vx(g,r)	a:ra(r)  n:mu(r,t)$bop(r,t) m:-1$bop(r,t)
	i:py(g,r,t)	q:vx(g,r)

$prod:yx(g,r,t)$k0(g,r)  s:0
	o:py(g,r,t)	q:y0(g,r)	
	i:pa(gg,r,t)	q:id0(gg,g,r)	
	i:pe(r,t)	q:e0(g,r)  a:ra(r) n:tau(r,t)$etax(g,r) 
	i:rkx(g,r,t)	q:k0(g,r)  
	i:pl(r,t)	q:l0(g,r)  

$prod:y(g,r,t)$merge s:0 e:esub  kl(e):1
	o:py(g,r,t)	q:y0(g,r)	
	i:pa(gg,r,t)	q:id0(gg,g,r)	
	i:pe(r,t)	q:e0(g,r)  a:ra(r) n:tau(r,t)$etax(g,r) e:
	i:rk(r,t)	q:k0(g,r)  kl:
	i:pl(r,t)	q:l0(g,r)  kl:

$prod:y(g,r,t)$green s:0 kle:1 ke(kle):esub
	o:py(g,r,t)	q:y0(g,r)	
	i:pa(gg,r,t)	q:id0(gg,g,r)	
	i:pe(r,t)	q:e0(g,r)  a:ra(r) n:tau(r,t)$etax(g,r) ke:
	i:rk(r,t)	q:k0(g,r)  ke:
	i:pl(r,t)	q:l0(g,r)  kle:

$prod:a(g,r,t)  s:sigmadm  
	o:pa(g,r,t)	q:s0(g,r)	
	i:pm(g,r,t)	q:vm(g,r) a:ra(r)  n:mu(r,t)$bop(r,t) 
	i:py(g,r,t)	q:m0(g,r,r)

$prod:m(g,r,t)$vm(g,r)  s:(2*sigmadm)  
	o:pm(g,r,t)	q:vm(g,r)
	i:px(g,rr,t)$(not sameas(r,rr))	q:m0(g,rr,r)  

$prod:es(r,t)  s:sigma(r)
	o:pew(t)	q:es0(r)	a:ra(r)  n:mu(r,t)$bop(r,t) m:-1$bop(r,t)
	i:pa(g,r,t)	q:ec0(g,r)	
	i:pr(r,t)	q:er0(r)

$prod:ed(r,t)
	o:pe(r,t)	q:ed0(r)
	i:pew(t)	q:ed0(r)	a:ra(r)  n:mu(r,t)$bop(r,t) 

$constraint:tau(r,t)$(card(etax) and annexb(r))
	carblim(t,r)*target(t) =e= ed(r,t);

$constraint:target(t)$(card(etax) and compensate)
	sum(r,ed(r,t)*ed0(r)) =e= sum(r, carblim(t,r)*ed0(r));

$demand:ra(r) 
	d:pu(r)		q:u0(r)
	e:rkx(g,r,t)	q:(k0(g,r)*thetax*srvshr(t))
	e:pc(rr,t)	q:(theta(rr)*bopdef(r)*qref(t))
	e:pkt(r)	q:-1  r:kt(r)
	e:pkt(r)	q:ktx(r)
	e:pk(r,tfirst)	q:(capital(r)*(1-thetax))
	e:pl(r,t)	q:(labor(r,t)*sum(g,l0(g,r)))
	e:pr(r,t)	q:(labor(r,t)*er0(r))

$constraint:mu(r,t)$bop(r,t)
	sum(g, x(g,r,t)*vx(g,r)*px(g,r,t)) + es(r,t)*es0(r)*pew(t)
	+ sum(rr,pc(rr,t)*(theta(rr)*bopdef(r)*qref(t)))
	=e= sum(g, m(g,r,t)*vm(g,r)*pm(g,r,t)) + ed(r,t)*ed0(r)*pew(t);

$constraint:kt(r)
	sum(tlast(t), inv(r,t)/inv(r,t-1) - c(r,t)/c(r,t-1)) =e= 0;

$offtext
$sysinclude mpsgeset dynamic

kt.l(r) = sum(tlast,qref(tlast)*capital(r)*(1+g0));
k.l(r,T) = qref(t)-thetax*srvshr(t);
c.l(r,t) = qref(t);
y.l(g,r,t) = qref(t)-thetax*srvshr(t)$k0(g,r);
yx.l(g,r,t) = thetax*srvshr(t);
yx.l(g,r,t)$(not k0(g,r)) = 0;
x.l(g,r,t) = qref(t)$vx(g,r);
a.l(g,r,t) = qref(t);
m.l(g,r,t) = qref(t);
m.l(g,r,t)$(not vm(g,r)) = 0;
ed.l(r,t) = qref(t);
es.l(r,t) = qref(t);
inv.l(r,t) = qref(t);
pc.l(r,t) = pref(t);
pa.l(g,r,t) = pref(t);
pm.l(g,r,t) = pref(t);
pm.l(g,r,t)$(not vm(g,r)) = 0;
pe.l(r,t) = pref(t);
pew.l(t) = pref(t);
pl.l(r,t) = pref(t);
pk.l(r,t) = (1+r0) * pref(t);
rkx.l(g,r,t) = pref(t);
rk.l(r,t) = pref(t);
py.l(g,r,t) = pref(t);
px.l(g,r,t) = pref(t)$vx(g,r);
pr.l(r,t) = pref(t);
pkt.l(r) = sum(tlast, pref(tlast));

target.l(t) = 1;

*	Benchmark replication check, including a cross-check of
*	the balance of payments constraint:

bop(r,t) = yes;
option mcp=path;
dynamic.iterlim = 0;
$include dynamic.gen
solve dynamic using mcp;

parameter	def	Balance of payments deficit;
def(t,r) = ( sum(g, x.l(g,r,t)*vx(g,r)*px.l(g,r,t)) + es.l(r,t)*es0(r)*pew.l(t)
	+ sum(rr,pc.l(rr,t)*(theta(rr)*bopdef(r)*qref(t)))
	- (  sum(g, m.l(g,r,t)*vm(g,r)*pm.l(g,r,t)) + ed.l(r,t)*ed0(r)*pew.l(t) )
	 ) / (pref(t)*labor(r,t)*c0(r)*pu.l("oecd")); 
display def;

dynamic.iterlim = 8000;

*	--------------------------------------------------------
*	Set the policy parameters for a 20% reduction target:

elimit(annexb) = 0.8;
carblim(t,r)$(year(t) gt 2000) = 1 - ((1-elimit(r)) * (year(t)-2000)/10);;
carblim(t,r)$(year(t) ge 2010) = elimit(r)*labor(r,t)/labor(r,"2010");
carblim(t,r)$(not annexb(r)) = qref(t);
display carblim;

*	--------------------------------------------------------
*	Compute the uniform tax scenario with capital flows:

exempt(g) = 0;
etax(g,r) = yes$annexb(r);
bop(r,t) = no;
$include dynamic.gen
solve dynamic using mcp;

def(t,r) = ( sum(g, x.l(g,r,t)*vx(g,r)*px.l(g,r,t)) + es.l(r,t)*es0(r)*pew.l(t)
	+ sum(rr,pc.l(rr,t)*(theta(rr)*bopdef(r)*qref(t)))
	- (  sum(g, m.l(g,r,t)*vm(g,r)*pm.l(g,r,t)) + ed.l(r,t)*ed0(r)*pew.l(t) )
	 ) / (pref(t)*labor(r,t)*c0(r)*pu.l("oecd")); 
display def;

def(t,"chk") = sum(r, def(t,r)*labor(r,t)*c0(r));
display def;
$setglobal gp_row t
$setglobal gp_term gif
$libinclude gnuplot def

parameter report;
report(t,"ed","x",r) = ed.l(r,t)*ed0(r);
report(t,"ed","x","total") = sum(r, ed.l(r,t)*ed0(r));
report(t,"c","x",r) = c.l(r,t);
report(t,"tau","x",r) = tau.l(r,t)$(card(etax) and annexb(r));
report(t,"inv","x",r) = inv.l(r,t) * invest(r);
report(t,"rk", "x",r) = rk.l(r,t)/pc.l(r,t);
report(t,"es","x",r)  = es.l(r,t);
report(t,"y",g,r)     = y.l(g,r,t);
report(t,"py",g,r)    = py.l(g,r,t)/pc.l(r,t);
file kcap /capflow.sol/; put kcap;
$libinclude gams2txt report

*	--------------------------------------------------------
*	Now, execute the same scenario with balance of payments
*	constraints:

bop("oecd",t)$(not tlast(t)) = yes;
mu.lo(r,t)$bop(r,t) = -inf;

$include dynamic.gen
solve dynamic using mcp;

def(t,r) = ( sum(g, x.l(g,r,t)*vx(g,r)*px.l(g,r,t)) + es.l(r,t)*es0(r)*pew.l(t)
	+ sum(rr,pc.l(rr,t)*(theta(rr)*bopdef(r)*qref(t)))
	- (  sum(g, m.l(g,r,t)*vm(g,r)*pm.l(g,r,t)) + ed.l(r,t)*ed0(r)*pew.l(t) )
	 ) / (pref(t)*labor(r,t)*c0(r)*pu.l("oecd")); 
display def;

def(t,"chk") = sum(r, def(t,r)*labor(r,t)*c0(r));
display "The following should be identically zero:", def;

parameter report;

report(t,"ed","x",r) = ed.l(r,t)*ed0(r);
report(t,"ed","x","total") = sum(r, ed.l(r,t)*ed0(r));
report(t,"c","x",r) = c.l(r,t);
report(t,"tau","x",r) = tau.l(r,t)$(card(etax) and annexb(r));
report(t,"inv","x",r) = inv.l(r,t) * invest(r);
report(t,"rk", "x",r) = rk.l(r,t)/pc.l(r,t);
report(t,"es","x",r)  = es.l(r,t);
report(t,"y",g,r)     = y.l(g,r,t);
report(t,"py",g,r)    = py.l(g,r,t)/pc.l(r,t);
file ksol /bopcon.sol/; put ksol;
$libinclude gams2txt report



MODELR.GMS:


$title  Recursive-dynamic model of carbon emissions and trade

*	------------------------------------------------------------------
*	This version recursive dynamic.
*	------------------------------------------------------------------

*	Read run options and benchmark data from an external file:

$include bmkdata

scalar	bmkchk		Switch for benchmark check	/0/;

parameter	labor(r)	Labor supply,
		ks_n(r)		New vintage capital
		ks_s(r,r)	Sunk capital (flexible coefficient)
		ks_x(g,r)	Extant capital
		thetai(r)	Regional shares of investment in solution
		thetak(r)	Regional share of new capital in solution;

ks_n(r)   = sum(g, k0(g,r)) * (depr + g0) / (1 + g0);
ks_s(r,r) = sum(g, k0(g,r)) * (1-thetax) - ks_n(r);
ks_x(g,r) = k0(g,r) * thetax;
thetai(r) = invest(r)/sum(rr,invest(rr));
thetak(r) = ks_n(r)/sum(rr, ks_n(rr));
labor(r) = sum(g, l0(g,r));

$ontext

$model:global

$sectors:
	c(r)		! Consumption
	y(g,r)		! Production index
	yx(g,r)$k0(g,r)
	a(g,r)		! Armington demand
	ed(r)		! Energy demand
	es(r)		! Energy supply

	inv		! Global investment
	kn(r)		! New-vintage capital allocation

$commodities:
	pc(r)	! Consumption good price
	pa(g,r)	! Armington aggregate price
	pe(r)	! Energy demand price
	pew	! World energy price
	pl(r)	! Wage rate
	py(g,r)	! Non-energy output price
	pr(r)	! Price of energy resource inputs
	pinv	! Investment cost

	rk(r)			! Return to regional capital
	rkx(g,r)$k0(g,r)	! Return to extant capital
	rkn			! Return to new vintage capital

$consumers:
	ra(r)	! Representative agent

$auxiliary:
	tau(r)$(card(etax) and annexb(r))	! Carbon tax rate (ad-valorem)
	target$compensate			! Scale factor for leakage-compensation

$prod:c(r) s:esub c:1 
	o:pc(r)		q:c0(r)
	i:pa(g,r)	q:cd0(g,r)	c:
	i:pe(r)		q:ce0(r) a:ra(r) n:tau(r)$(card(etax) and annexb(r))

$prod:yx(g,r)$k0(g,r)  s:0
	o:py(g,r)	q:y0(g,r)
	i:pa(gg,r)	q:id0(gg,g,r)
	i:pe(r)		q:e0(g,r)  a:ra(r) n:tau(r)$etax(g,r) 
	i:rkx(g,r)	q:k0(g,r)  
	i:pl(r)		q:l0(g,r)  

$prod:y(g,r)$merge s:0 e:esub  kl(e):1
	o:py(g,r)	q:y0(g,r)
	i:pa(gg,r)	q:id0(gg,g,r)
	i:pe(r)		q:e0(g,r)  a:ra(r) n:tau(r)$etax(g,r) e:
	i:rk(r)		q:k0(g,r)  kl:
	i:pl(r)		q:l0(g,r)  kl:

$prod:y(g,r)$green s:0 kle:1 ke(kle):esub
	o:py(g,r)	q:y0(g,r)
	i:pa(gg,r)	q:id0(gg,g,r)
	i:pe(r)		q:e0(g,r)  a:ra(r) n:tau(r)$etax(g,r) ke:
	i:rk(r)		q:k0(g,r)  ke:
	i:pl(r)		q:l0(g,r)  kle:

$prod:a(g,r)  s:sigmadm  m:(2*sigmadm)  
	o:pa(g,r)	q:s0(g,r)
	i:py(g,rr)	q:m0(g,rr,r)  m:$(not sameas(r,rr))

$prod:es(r)  s:sigma(r)
	o:pew		q:es0(r)
	i:pa(g,r)	q:ec0(g,r)
	i:pr(r)		q:er0(r)

$prod:ed(r)
	o:pe(r)		q:ed0(r)
	i:pew		q:ed0(r)

$constraint:tau(r)$(card(etax) and annexb(r))
	elimit(r)*target =e= ed(r);

$constraint:target$compensate
	sum(r, ed(r)*ed0(r)) =e= sum(r, ed0(r)*elimit(r));

$prod:inv
	o:pinv		q:(sum(r, invest(r)))
	i:pa(cgd,r)	q:(thetak(r)*sum(rr,invest(rr)))

$prod:kn(r)
	o:rk(r)		q:1
	i:rkn		q:1

$demand:ra(r)  s:1
	d:pc(r)		q:c0(r)
	d:pinv		q:invest(r)
	e:pc(rr)	q:(theta(rr)*bopdef(r))
	e:rkn		q:ks_n(r)
	e:rkx(g,r)	q:ks_x(g,r)
	e:rk(rr)	q:ks_s(r,rr)
	e:pl(r)		q:labor(r)
	e:pr(r)		q:er0(r)

$report:
	v:i(r)		d:pinv	demand:ra(r)

$offtext
$sysinclude mpsgeset global

*	Benchmark replication check:

kn.l(r) = ks_n(r);
yx.l(g,r) = thetax$k0(g,r);
y.l(g,r)$k0(g,r) = 1-thetax;

target.l = 1;
target.fx$(not compensate) = 1;

*	Verify benchmark consistnency:

global.iterlim = 0;

if (not bmkchk,

*	Always consider a 20% reduction target after 2010:

	elimit(annexb) = 0.8;
	elimit(r)$(not annexb(r)) = 1;

	carblim(t,r)$(year(t) gt 2000) = 1 - ((1-elimit(r)) * (year(t)-2000)/10);
	carblim(t,r)$(year(t) ge 2010) = elimit(r)*qref(t)/qref("2010");
	carblim(t,r)$(not annexb(r)) = qref(t);
	display carblim;

*	Compute the uniform tax scenario:

	exempt(g) = 0;
	etax(g,r) = yes$(annexb(r) and (not exempt(g)));

	global.iterlim = 8000;
else
	tau.fx(r) = 0;

);

parameter	report	solution report;

loop(t$(ord(t) le 21),
	
*	Apply the emission limit:

	elimit(r) = carblim(t,r);
	display thetai, thetak, elimit;

$include global.gen
	solve global using mcp;

	report(t,"ed","x",r) = ed.l(r)*ed0(r);
	report(t,"ed","x","total") = sum(r, ed.l(r)*ed0(r));
	report(t,"c","x",r) = c.l(r);
	report(t,"tau","x",r) = tau.l(r)$(card(etax) and annexb(r));
	report(t,"inv","x",r) = inv.l * thetak(r) * sum(rr, invest(rr));
	report(t,"rk", "x",r) = rk.l(r)/pc.l(r);
	report(t,"es","x",r)  = es.l(r);
	report(t,"y",g,r)     = y.l(g,r);
	report(t,"py",g,r)    = py.l(g,r)/pc.l(r);

*	The following equation distributes new capital holdings 
*	uniformly across investors. The current value of thetai(r)
*	represents region r's share of investment in the previous 
*	period, and these shares then allocation new investment across
*	share holdings.

*	The complete mixing assumption may not reflect
*	actual investment behavior, but it is probably the closest
*	approximation of the forwarding-looking model.

	ks_s(r,rr) = (1-depr) * (ks_s(r,rr) + thetai(r) * kn.l(rr));

*	Update region r's share of global investment:

	thetai(r) = i.l(r) / sum(rr, i.l(rr));

*	Update share of capital flowing into region r:

	thetak(r) = kn.l(r) / sum(rr, kn.l(rr));

*	Depreciate extant capital holdings:

	ks_x(g,r) = (1-depr) * ks_x(g,r);

*	New vintage capital holdings:

	ks_n(r) = (r0 + depr) * i.l(r);

*	Update other endowments:

	labor(r)  = (1 + g0) * labor(r);
	er0(r)	  = (1 + g0) * er0(r);
	bopdef(r) = (1 + g0) * bopdef(r);

	c.l(r) = c.l(r) * (1 + g0);
	yx.l(g,r) = yx.l(g,r) * (1 - depr);
	y.l(g,r)$k0(g,r) = c.l(r) - yx.l(g,r);
	y.l(g,r)$(not k0(g,r)) = c.l(r);
	a.l(g,r) = a.l(g,r) * (1 + g0);
	ed.l(r) = ed.l(r) * (1 + g0);
	es.l(r) = es.l(r) * (1 + g0);
	inv.l = inv.l * (1 + g0);
	kn.l(r) = kn.l(r) * (1 + g0);
);
file ksol /recursive.sol/; put ksol;
$libinclude gams2txt report

$exit

$include global.gen
solve global using mcp;

parameter	leakage		Leakage rate (%)
		welfare		Welfare cost 
		carbtax		Carbon tax (ad-valorem %);


leakage("uniform","energy")  = 100 * 
	sum(r$(not annexb(r)), ed0(r) * (ed.l(r) - 1))
      / sum(r$annexb(r),       ed0(r) * (1 - ed.l(r)));

leakage("uniform","carbon")  = 100 * 
	sum(r$(not annexb(r)), carbon(r,"total") * (ed.l(r) - 1))
      / sum(r$annexb(r),       carbon(r,"total") * (1 - ed.l(r)));


welfare(r,"uniform") = round( 100 * (c.l(r)-1), 1);
carbtax(r,"uniform") = 100 * tau.l(r);

COMPARE.GMS:


$title Plot comparisons of results from three models

set	t		Time (years) /2000*2020/,
	tl(t) /2000,2005,2010,2015,2020/;

set r /oecd,row/;

$setglobal gp_xl tl
$setglobal gp_row t

parameter recursive /
$include recursive.sol
/;

parameter capflow /
$include capflow.sol
/;
parameter bopcon /
$include bopcon.sol
/;

*	Generate gif images:

$setglobal gp_term gif

parameter	invest	Investment
		rk	Return to capital (pct change)
		es	Energy supply
		tau	Carbon tax rates
		C	Consumption (pct change)
		emit	Emissions;
parameter qref;
scalar 	g0	Benchmark growth rate	/ 0.02 /;

qref(t) = (1 + g0)**(ord(t)-1);

set rplot(*);  
rplot(r) = yes; 
rplot("oecd_d") = yes;
rplot("row_d") = yes;
rplot("oecd_b") = yes;
rplot("row_b") = yes;

c(t,r) =  recursive(t,"c","x",r);
c(t,"oecd_d") =  capflow(t,"c","x","oecd");
c(t,"row_d") =  capflow(t,"c","x","row");
c(t,"oecd_b") =  bopcon(t,"c","x","oecd");
c(t,"row_b") =  bopcon(t,"c","x","row");

c(t,rplot) = 100 * (c(t,rplot)/qref(t) - 1);
$libinclude gnuplot c

rk(t,r) = 100 * (recursive(t,"rk","x",r) - 1);
rk(t,"oecd_d") = 100 * (capflow(t,"rk","x","oecd") - 1);
rk(t,"row_d") = 100 * (capflow(t,"rk","x","row") - 1);
rk(t,"oecd_b") = 100 * (bopcon(t,"rk","x","oecd") - 1);
rk(t,"row_b") = 100 * (bopcon(t,"rk","x","row") - 1);
$libinclude gnuplot rk


invest(t,r) = recursive(t,"inv","x",r);
invest(t,"oecd_d") = capflow(t,"inv","x","oecd");
invest(t,"row_d") = capflow(t,"inv","x","row");
invest(t,"oecd_b") = bopcon(t,"inv","x","oecd");
invest(t,"row_b") = bopcon(t,"inv","x","row");
$libinclude gnuplot invest


emit(t,r) = recursive(t,"ed","x",r);
emit(t,"total") = recursive(t,"ed","x","total");
emit(t,"oecd_d") = capflow(t,"ed","x","oecd");
emit(t,"row_d") = capflow(t,"ed","x","row");
emit(t,"total_d") = capflow(t,"ed","x","total");

emit(t,"oecd_b") = bopcon(t,"ed","x","oecd");
emit(t,"row_b") = bopcon(t,"ed","x","row");
emit(t,"total_b") = bopcon(t,"ed","x","total");
$libinclude gnuplot emit

tau(t,r) = recursive(t,"tau","x",r);
tau(t,"oecd_d") = capflow(t,"tau","x","oecd");
tau(t,"row_d") = capflow(t,"tau","x","row");
tau(t,"oecd_b") = bopcon(t,"tau","x","oecd");
tau(t,"row_b") = bopcon(t,"tau","x","row");
$libinclude gnuplot tau


es(t,r) = recursive(t,"es","x",r);
es(t,"oecd_d") = capflow(t,"es","x","oecd");
es(t,"row_d") = capflow(t,"es","x","row");
es(t,"oecd_b") = bopcon(t,"es","x","oecd");
es(t,"row_b") = bopcon(t,"es","x","row");
$libinclude gnuplot es

BMKDATA.GMS:


*==>bmkdata.gms		Read the benchmark dataset

scalar	eta		Elasticity of energy supply	/1/
	sigmadm		Armington elasticity		/2/
	esub		Energy demand elasticity	/0.5/
	merge		Use Merge demand structure      /0/
	green		Use Green demand structure	/1/,
	compensate	Evaluate leakage-compensated equilibria /1/,

	r0	Benchmark interest rate / 0.05 /
	g0	Benchmark growth rate	/ 0.02 /
	depr	Depreciation rate	/ 0.07 /
	thetax	Extant production share / 0.75 /;


set	t		Time (maximum model horizon -- years) /2000*2040/,
	tlast(t)	Last period,
	tfirst(t)	First period;

*	Read the raw data:

$INCLUDE aggr.dat

alias (r,rr), (g,gg);

parameter
	chk		Check of global energy markets
	ed0(r)		Regional energy demand;

ed0(r) = ce0(r) + sum(g, e0(g,r));

chk("value") = sum(r, es0(r) - ed0(r));
chk("percent") = 100 * sum(r, es0(r) - ed0(r)) / sum(r,es0(r));
display chk;

*	Scale energy supply to equal energy demand globally:

es0(r) = es0(r) * sum(rr, ed0(rr)) / sum(rr, es0(rr));


*	Computed parameters -- the benchmark data will typically not 
*	provide an exact benchmark equilibrium.  For this reason, it is
*	necessary to compute a benchmark dataset which is as close as
*	possible to the input data:

parameter
	s0(g,r)		Supply of Armington aggregate
	y0(g,r)		Sectoral output;

*	Retrieve the calibration results:

y0(g,r) = sum(gg, id0(gg,g,r)) + e0(g,r) + k0(g,r) + l0(g,r);
s0(g,r) = sum(gg, id0(g,gg,r)) + cd0(g,r) + ec0(g,r);

*	Assign other calibrated parameters:

parameter
	achk(g,r)	Check of regional consumption markets (%)
	er0(r)		Energy resoure
	c0(r)		Regional consumption value
	bopdef(r)	Balance of payments deficit
	theta(r)	Regional shares of aggregate demand
	sigma(r)	Elasticity of substitution in energy supply
	thetar(r)	Value share of resources in energy supply;


er0(r) = es0(r) - sum(g, ec0(g,r));
thetar(r) = er0(r)/es0(r);
display thetar;
sigma(r) = eta * thetar(r)/(1-thetar(r));
c0(r) = sum(g, cd0(g,r)) + ce0(r);
achk(g,r) = 100 * (s0(g,r) - cd0(g,r) - sum(gg, id0(g,gg,r)) - ec0(g,r))/s0(g,r);

chk("value") = sum(r, es0(r) - ed0(r));
chk("percent") = 100 * sum(r, es0(r) - ed0(r)) / sum(r,es0(r));

display chk, achk;

*	Balance of payments deficits:

bopdef(r) = sum((g,rr), m0(g,rr,r)-m0(g,r,rr)) + ed0(r) - es0(r);
theta(r) = c0(r) / sum(rr, c0(rr));

*	Policy instruments:

set		etax(*,r)	Energy tax
		exempt(g)	Goods exempt from tax;
parameter	elimit(r)	Emission limit;

elimit(r) = 1;
exempt(g) = no;
etax(g,r) = no;
etax("c",r) = no;

set	cgd(g)	Identify the investment god /cgd/;

parameter	year(t); year(t) = 1999 + ord(t);

tfirst(t) = yes$(ord(t) eq 1);
tlast(t) = yes$(ord(t) eq card(t));

parameter	capital		Regional capital stocks
		invest		Regional investment
		earnings	Calibrated capital earnings
		capchk		Ratio of calibrated earnings to benchmark
		pref(t)		Reference price path
		qref(t)		Reference quantity path
		carblim(t,r)	Carbon emissions limit;

carblim(t,r) = 1;
invest(r) = cd0("cgd",r);
capital(r) = invest(r) / (g0+depr);
earnings(r) = capital(r) * (r0 + depr);
capchk(r) = earnings(r) /sum(g, k0(g,r));
display capchk;

*	Adjust labor and capital value shares accordingly:

l0(g,r) = l0(g,r) + k0(g,r);
k0(g,r) = k0(g,r) * earnings(r) / sum(gg, k0(gg,r));
l0(g,r) = l0(g,r) - k0(g,r);
display k0,l0;

*	Define the reference price and quantity indices:

pref(t) = 1/(1 + r0)**(ord(t)-1);
qref(t) = (1 + g0)**(ord(t)-1);

*	Remove investment demand from the final consumption vector:

cd0("cgd",r) = 0;
c0(r) = ce0(r) + sum(g, cd0(g,r));


AGGR.DAT:


set g  Goods /
EIS                Energy-intensive goods
CGD                Investment goods
y                  Other goods and services
/;
set r  Regions /
ROW                ROW countries
oecd               OECD countries
/;
set annexb(r) /oecd/;
parameter cd0 Consumer demand/
*=>gams2prm cd0x cd0
* Called from D:\WORKSHOP\MUENSTER\LEAKAGE\AGGR.GMS, line 1200
* 07/16/99 14:17:47
EIS.ROW   1.91814994213555E+01
EIS.oecd   4.74590942264071E+01
CGD.ROW   1.48674307621276E+02
CGD.oecd   4.43324370800807E+02
y.ROW   4.04776943271069E+02
y.oecd   1.53935837961554E+03
/;
parameter ce0 Energy final demand/
*=>gams2prm ce0x ce0
* Called from D:\WORKSHOP\MUENSTER\LEAKAGE\AGGR.GMS, line 1473
* 07/16/99 14:17:47
ROW   1.18398760000000E+01
oecd   3.04577240000000E+01
/;
parameter id0 Intermediate demand/
*=>gams2prm id0x id0
* Called from D:\WORKSHOP\MUENSTER\LEAKAGE\AGGR.GMS, line 1709
* 07/16/99 14:17:47
EIS.EIS.ROW   3.43054962550903E+01
EIS.EIS.oecd   9.75734486898846E+01
EIS.CGD.ROW   6.88782817891295E-01
EIS.CGD.oecd   1.27850869775425E+00
EIS.y.ROW   6.59857233004141E+01
EIS.y.oecd   1.76781102363022E+02
y.EIS.ROW   3.37476782363236E+01
y.EIS.oecd   9.13546756920966E+01
y.CGD.ROW   1.49713503490839E+02
y.CGD.oecd   4.44533373010817E+02
y.y.ROW   4.62204069955892E+02
y.y.oecd   1.48892503637097E+03
/;
parameter e0 Energy use/
*=>gams2prm e0x e0
* Called from D:\WORKSHOP\MUENSTER\LEAKAGE\AGGR.GMS, line 1945
* 07/16/99 14:17:47
EIS.ROW   8.51325811275889E+00
EIS.oecd   1.32712079878864E+01
CGD.ROW   1.14283298791226E-01
CGD.oecd   9.60013217381704E-02
y.ROW   2.90618034520120E+01
y.oecd   3.62988167067247E+01
/;
parameter k0 Capital demand/
*=>gams2prm k0x k0
* Called from D:\WORKSHOP\MUENSTER\LEAKAGE\AGGR.GMS, line 2181
* 07/16/99 14:17:47
EIS.ROW   2.49176757610161E+01
EIS.oecd   5.67113476276185E+01
y.ROW   2.69741622890410E+02
y.oecd   7.00289763787685E+02
/;
parameter l0 Labor demand/
*=>gams2prm l0x l0
* Called from D:\WORKSHOP\MUENSTER\LEAKAGE\AGGR.GMS, line 2417
* 07/16/99 14:17:47
EIS.ROW   1.45349213638299E+01
EIS.oecd   7.82230317148800E+01
y.ROW   2.40741558413746E+02
y.oecd   1.19508578795731E+03
/;
parameter m0 Trade flows/
*=>gams2prm m0x m0
* Called from D:\WORKSHOP\MUENSTER\LEAKAGE\AGGR.GMS, line 2653
* 07/16/99 14:17:47
EIS.ROW.ROW   1.08519655718741E+02
EIS.ROW.oecd   7.49937401027759E+00
EIS.oecd.ROW   1.61452783642903E+01
EIS.oecd.oecd   3.20988433348076E+02
CGD.ROW.ROW   1.50516569607522E+02
CGD.oecd.oecd   4.45907883030309E+02
y.ROW.ROW   9.79624899634489E+02
y.ROW.oecd   8.81098783779849E+01
y.oecd.ROW   9.52691466514548E+01
y.oecd.oecd   3.50211136053426E+03
/;
parameter es0 Energy supply/
*=>gams2prm es0x es0
* Called from D:\WORKSHOP\MUENSTER\LEAKAGE\AGGR.GMS, line 2889
* 07/16/99 14:17:47
ROW   6.15950912126926E+01
oecd   6.80578796672188E+01
/;
parameter ec0 Energy costs/
*=>gams2prm ec0x ec0
* Called from D:\WORKSHOP\MUENSTER\LEAKAGE\AGGR.GMS, line 3125
* 07/16/99 14:17:47
EIS.ROW   4.50343228828040E+00
EIS.oecd   5.39565338128560E+00
CGD.ROW   1.84226198624608E+00
CGD.oecd   2.58351222950270E+00
y.ROW   2.44518513318198E+01
y.oecd   2.60497742228211E+01
/;