Library Constant Elasticity of Substitution
Notes prepared for GAMS General Equilibrium Workshop
Thomas F. Rutherford
|
k | be the reference the index of second-level nest |
denote the fraction of good i inputs assigned to the kth nest | |
denote the benchmark value share of total cost which enters through the kth nest | |
denote the top-level elasticity of substitution | |
denote the elasticity of substitution in the kth aggregate | |
denote the price index associated with aggregate k, normalized
to equal unity in the benchmark, i.e.:
|
Demand indices for second-level aggregates are needed to express demand functions in a compact form. Let denote the demand index for aggregate k, normalized to unity in the benchmark; i.e.
Compensated demand functions are obtained by differentiating . In this derivative, one term arise for each nest in which the commodity enters, so:
Simple differentiation shows that benchmark cross-elasticities of substitution have the form:
Given the benchmark value shares and the benchmark cross-price elasticities of substitution, , we can solve for values of , , and . We compute these parameters using a constrained nonlinear programming algorithm, CONOPT, which is available through GAMS, the same programming environment in which the equilibrium model is specified. Perroni and Rutherford (EER, 1994) prove that calibration of the NNCES form is possible for arbitrary dimensions whenever the given Slutsky matrix is negative semi-definite. The two-level (NxN) function is flexible for three inputs; and although we have not proven that it is flexible for 4 inputs, the only difficulties we have encountered have resulted from indefinite calibration data points.
Two GAMS programs are listed below. The first illustrates two analytic calibrations of the three-factor cost function. The second illustrates the use of numerical methods to calibrate a four-factor cost function.
* ======================================================================== * Model-specific data defined here: SET I Production input aggregates / A,B,C /; ALIAS (I,J); PARAMETER THETA(I) Benchmark value shares /A 0.2, B 0.5, C 0.3/ AUES(I,J) Benchmark cross-elasticities (off-diagonals) / A.B 2 A.C -0.05 B.C 0.5 /; * ======================================================================== * Use an analytic calibration of the three-factor CES cost * function: ABORT$(CARD(I) NE 3) "Error: not a three-factor model!"; * Fill in off-diagonals: AUES(I,J)$AUES(J,I) = AUES(J,I); * Verify that the cross elasticities are symmetric: ABORT$SUM((I,J), ABS(AUES(I,J)-AUES(J,I))) " AUES values non-symmetric?"; * Check that all value shares are positive: ABORT$(SMIN(I, THETA(I)) LE 0) " Zero value shares are not valid:",THETA; * Fill in the elasticity matrices: AUES(I,I) = 0; AUES(I,I) = -SUM(J, AUES(I,J)*THETA(J))/THETA(I); DISPLAY AUES; SET N Potential nesting /N1*N3/ K(N) Nesting aggregates used in the model I1(I) Good fully assigned to first nest I2(I) Good fully assigned to second nest I3(I) Good split between nests; SCALAR ASSIGNED /0/; PARAMETER ESUB(*,*) Alternative calibrated elasticities SHR(*,I,N) Alternative calibrated shares SIGMA(N) Second level elasticities S(I,N) Nesting assignments (in model) GAMMA Top level elasticity (in model); * First the Leontief structure: ESUB("LTF","GAMMA") = SMAX((I,J), AUES(I,J)); ESUB("LTF",N) = 0; LOOP((I,J)$((AUES(I,J) EQ ESUB("LTF","GAMMA"))*(NOT ASSIGNED)), I1(I) = YES; I2(J) = YES; ASSIGNED = 1; ); I3(I) = YES$((NOT I1(I))*(NOT I2(I))); DISPLAY I1,I2,I3; LOOP((I1,I2,I3), SHR("LTF",I1,"N1") = 1; SHR("LTF",I2,"N2") = 1; SHR("LTF",I3,"N1") = THETA(I1)*(1-AUES(I1,I3)/AUES(I1,I2)) / ( 1 - THETA(I3) * (1-AUES(I1,I3)/AUES(I1,I2)) ); SHR("LTF",I3,"N2") = THETA(I2)*(1-AUES(I2,I3)/AUES(I1,I2)) / ( 1 - THETA(I3) * (1-AUES(I2,I3)/AUES(I1,I2)) ); SHR("LTF",I3,"N3") = 1 - SHR("LTF",I3,"N1") - SHR("LTF",I3,"N2"); ); ABORT$(SMIN((I,N), SHR("LTF",I,N)) LT 0) "Benchmark AUES is indefinite."; * Now, the CES function: ESUB("CES","GAMMA") = SMAX((I,J), AUES(I,J)); ESUB("CES","N1") = 0; LOOP((I1,I2,I3), SHR("CES",I1,"N1") = 1; SHR("CES",I2,"N2") = 1; ESUB("CES","N2") = (AUES(I1,I2)*AUES(I1,I3)-AUES(I2,I3)*AUES(I1,I1)) / (AUES(I1,I3)-AUES(I1,I1)); SHR("CES",I3,"N1") = (AUES(I1,I2)-AUES(I1,I3)) / (AUES(I1,I2)-AUES(I1,I1)); SHR("CES",I3,"N2") = 1 - SHR("CES",I3,"N1"); ); ABORT$(SMIN(N, ESUB("CES",N)) LT 0) "Benchmark AUES is indefinite?"; ABORT$(SMIN((I,N), SHR("CES",I,N)) LT 0) "Benchmark AUES is indefinite?"; PARAMETER PRICE(I) PRICE INDICES USING TO VERIFY CALIBRATION AUESCHK(*,I,J) CHECK OF BENCHMARK AUES VALUES; PRICE(I) = 1; $ontext $MODEL:CHKCALIB $SECTORS: Y ! PRODUCTION FUNCTION D(I) $COMMODITIES: PY ! PRODUCTION FUNCTION OUTPUT P(I) ! FACTORS OF PRODUCTION PFX ! AGGREGATE PRICE LEVEL $CONSUMERS: RA $PROD:Y s:GAMMA K.TL:SIGMA(K) O:PY Q:1 I:P(I)#(K) Q:(THETA(I)*S(I,K)) K.TL: $PROD:D(I) O:P(I) Q:THETA(I) I:PFX Q:(THETA(I)*PRICE(I)) $DEMAND:RA D:PFX E:PFX Q:2 E:PY Q:-1 $OFFTEXT $SYSINCLUDE mpsgeset CHKCALIB SCALAR DELTA /1.E-5/; SET FUNCTION /LTF, CES/; ALIAS (I,II); LOOP(FUNCTION, K(N) = YES$SUM(I, SHR(FUNCTION,I,N)); GAMMA = ESUB(FUNCTION,"GAMMA"); SIGMA(K) = ESUB(FUNCTION,K); S(I,K) = SHR(FUNCTION,I,K); LOOP(II, PRICE(J) = 1; PRICE(II) = 1 + DELTA; $INCLUDE CHKCALIB.GEN SOLVE CHKCALIB USING MCP; AUESCHK(FUNCTION,J,II) = (D.L(J)-1) / (DELTA*THETA(II)); )); AUESCHK(FUNCTION,I,J) = AUESCHK(FUNCTION,I,J) - AUES(I,J); DISPLAY AUESCHK; * Evaluate the demand functions: $LIBINCLUDE qadplot SET PR Alternative price levels /PR0*PR10/; PARAMETER DEMAND(FUNCTION,I,PR) Demand functions DPLOT(PR,FUNCTION) Plotting output array; LOOP(II, LOOP(FUNCTION, K(N) = YES$SUM(I, SHR(FUNCTION,I,N)); GAMMA = ESUB(FUNCTION,"GAMMA"); SIGMA(K) = ESUB(FUNCTION,K); S(I,K) = SHR(FUNCTION,I,K); LOOP(PR, PRICE(J) = 1; PRICE(II) = 0.2 * ORD(PR); $INCLUDE CHKCALIB.GEN SOLVE CHKCALIB USING MCP; DEMAND(FUNCTION,II,PR) = D.L(II); DPLOT(PR,FUNCTION) = D.L(II); ); ); $LIBINCLUDE qadplot DPLOT PR FUNCTION ); DISPLAY DEMAND;
Figure 1: Demand Function Comparison -- Good A
Figure 2: Demand Function Comparison -- Good B
Figure 3: Demand Function Comparison -- Good C
SET I Production input aggregates / K, L, E, M/; ALIAS (I,J); * ======================================================================== * Model-specific data defined here: PARAMETER THETA(I) Benchmark value shares /K 0.2, L 0.4, E 0.05, M 0.35/ AUES(I,J) Benchmark cross-elasticities (off-diagonals) / K.L 1 K.E -0.1 K.M 0 L.E 0.3 L.M 0 E.M 0.1 /; * ======================================================================== SCALAR EPSILON Minimum value share tolerance /0.001/; * Fill in off-diagonals: AUES(I,J)$AUES(J,I) = AUES(J,I); * Verify that the cross elasticities are symmetric: ABORT$SUM((I,J), ABS(AUES(I,J)-AUES(J,I))) " AUES values non-symmetric?"; * Check that all value shares are positive: ABORT$(SMIN(I, THETA(I)) LE 0) " Zero value shares are not valid:",THETA; * Fill in the elasticity matrices: AUES(I,I) = 0; AUES(I,I) = -SUM(J, AUES(I,J)*THETA(J))/THETA(I); DISPLAY AUES; * ======================================================================== * Define variables and equations for NNCES calibration: SET N Nests within the two-level NNCES function /N1*N4/, K(N) Nests which are in use; VARIABLES S(I,N) Fraction of good I which enters through nest N, SHARE(N) Value share of nest N, SIGMA(N) Elasticity of substitution within nest N, GAMMA Elasticity of substitution at the top level, OBJ Objective function; POSITIVE VARIABLES S, SHARE, SIGMA, GAMMA; EQUATIONS SDEF(I) Nest shares must sum to one, TDEF(N) Nest share in total cost, ELAST(I,J) Consistency with given AUES values, OBJDEF Maximize concentration; ELAST(I,J)$(ORD(I) GT ORD(J)).. AUES(I,J) =E= GAMMA + SUM(K, (SIGMA(K)-GAMMA)*S(I,K)*S(J,K)/SHARE(K)); TDEF(K).. SHARE(K) =E= SUM(I, THETA(I) * S(I,K)); SDEF(I).. SUM(N, S(I,N)) =E= 1; * Maximize concentration at the same time keeping the elasticities * to be reasonable: OBJDEF.. OBJ =E= SUM((I,K),S(I,K)*S(I,K)) - SQR(GAMMA) - SUM(K, SQR(SIGMA(K))); MODEL CESCALIB /ELAST, TDEF, SDEF, OBJDEF/; * Apply some bounds to avoid divide by zero: SHARE.LO(N) = EPSILON; SCALAR SOLVED Flag for having solved the calibration problem /0/ MINSHR Minimum share in candidate calibration; SET TRIES Counter on the number of attempted calibrations /T1*T10/; * We use the random number generator to select starting points, * so it is helpful to initialize the seed so that the results * will be reproducible: OPTION SEED=0; LOOP(TRIES$(NOT SOLVED), * Initialize the set of active nests and the bounds: K(N) = YES; S.LO(I,N) = 0; S.UP(I,N) = 1; SHARE.LO(N) = EPSILON; SHARE.UP(N) = 1; SIGMA.LO(N) = 0; SIGMA.UP(N) = +INF; * Install a starting point: SHARE.L(K) = MAX(UNIFORM(0,1), EPSILON); S.L(I,K) = UNIFORM(0,1); GAMMA.L = UNIFORM(0,1); SIGMA.L(K) = UNIFORM(0,1); * Drop any basis information so that we start from scratch: SDEF.M(I) = 0; TDEF.M(K) = 0; ELAST.M(I,J) = 0; SOLVE CESCALIB USING NLP MAXIMIZING OBJ; SOLVED = 1$(CESCALIB.MODELSTAT LE 2); * We have a solution -- now see if it is not on a bound: IF (SOLVED, MINSHR = SMIN(K, SHARE.L(K)) - EPSILON; IF (MINSHR EQ 0, * Drop nests which have shares equal to EPSILON in the current * solution: K(N)$(SHARE.L(N) EQ EPSILON) = NO; S.FX(I,N)$(NOT K(N)) = 0; SHARE.FX(N)$(NOT K(N)) = 0; SIGMA.FX(N)$(NOT K(N)) = 0; DISPLAY "Recalibrating with the following nests:",K; SOLVE CESCALIB USING NLP MAXIMIZING OBJ; IF (CESCALIB.MODELSTAT GT 2, SOLVED = 0;); MINSHR = SMIN(K, SHARE.L(K)) - EPSILON; IF (MINSHR EQ 0, SOLVED = 0;); ); ); ); IF (SOLVED, DISPLAY "Function calibrated:",GAMMA.L,SIGMA.L,SHARE.L,S.L; ELSE DISPLAY "Function calibration fails!"; ); $ONTEXT *========================================================================== Solution from MINOS5 obtained on the second try, following an ITERATION INTERRUPT on the first: ---- 151 Function calibrated: ---- 151 VARIABLE GAMMA.L = 0.300 Elasticity of substitution at the top level ---- 151 VARIABLE SIGMA.L Elasticity of substitution within nest N N3 7.804 ---- 151 VARIABLE SHARE.L Value share of nest N N1 0.604, N2 0.266, N3 0.030, N4 0.100 ---- 151 VARIABLE S.L Fraction of good I which enters through nest N N1 N2 N3 N4 K 0.797 0.069 0.133 L 0.960 0.040 E 1.000 M 0.630 0.304 0.067 *========================================================================== The following solution is obtained by CONOPT on the second try, following a LOCALLY INFEASIBLE termination on the first problem. Notice that it is identical to the MINOS5 solution except that the nesting assigments have been permuted: ---- 149 Function calibrated: ---- 149 VARIABLE GAMMA.L = 0.300 Elasticity of substitution at the top level ---- 149 VARIABLE SIGMA.L Elasticity of substitution within nest N N4 7.804 ---- 149 VARIABLE SHARE.L Value share of nest N N1 0.100, N2 0.604, N3 0.266, N4 0.030 ---- 149 VARIABLE S.L Fraction of good I which enters through nest N N1 N2 N3 N4 K 0.133 0.797 0.069 L 0.960 0.040 E 1.000 M 0.067 0.630 0.304 *========================================================================== $OFFTEXT $TITLE Numerical Verification of the the AUES Calibration Results PARAMETER PRICE(I) PRICE INDICES USING TO VERIFY CALIBRATION AUESCHK(I,J) CHECK OF BENCHMARK AUES VALUES; PRICE(I) = 1; $ontext $MODEL:CHKCALIB $SECTORS: Y ! PRODUCTION FUNCTION D(I) $COMMODITIES: PY ! PRODUCTION FUNCTION OUTPUT P(I) ! FACTORS OF PRODUCTION PFX ! AGGREGATE PRICE LEVEL $CONSUMERS: RA $PROD:Y s:GAMMA.L K.TL:SIGMA.L(K) O:PY Q:1 I:P(I)#(K) Q:(THETA(I)*S.L(I,K)) K.TL: $PROD:D(I) O:P(I) Q:THETA(I) I:PFX Q:(THETA(I)*PRICE(I)) $DEMAND:RA D:PFX E:PFX Q:2 E:PY Q:-1 $OFFTEXT $SYSINCLUDE mpsgeset CHKCALIB CHKCALIB.ITERLIM = 0; $INCLUDE CHKCALIB.GEN SOLVE CHKCALIB USING MCP; CHKCALIB.ITERLIM = 2000; SCALAR DELTA /1.E-5/; ALIAS (I,II); LOOP(II, PRICE(J) = 1; PRICE(II) = 1 + DELTA; $INCLUDE CHKCALIB.GEN SOLVE CHKCALIB USING MCP; AUESCHK(J,II) = (D.L(J)-1) / (DELTA*THETA(II)); ); DISPLAY AUES, AUESCHK;
This material was published in the MUG newsletter, 8/95.
Following Ballard, Fullerton, Shoven and Whalley (BFSW), we
consider a representative agent whose utility is based upon current
consumption, future consumption and current leisure. Changes in
"future consumption" in this static framework are
associated with changes in the level of savings. There are three
prices which jointly determine the price index for future
consumption. These are:
PI | the composite price index for investment goods |
PK | the composite rental price for capital services |
PC | the composite price of current consumption. |
All of these prices equal unity in the benchmark equilibrium.
Capital income in each future year finances future consumption, which is expected to cost the same as in the current period, PC (static expectations). The consumer demand for savings therefore depends not only on PI, but also on PK and PC, namely:
The price index for savings is unity in the benchmark period. In a counter-factual equilibrium, however, we would expect generally that . When these price indices are not equal, there is a "virtual tax payment" associated with savings demand.
Following BFSW, we adopt a nested constant-elasticity-of-substitution function to represent preferences. In this function, at the top level demand for savings (future consumption) trades off with a second CES aggregate of leisure and current consumption. These preferences can be summarized with the following expenditure function:
Demand functions can be written as follows:
Demands are written here in terms of their benchmark values (S0, C0 and ) and current and benchmark income (I and I0).
There are four components in income. The first is the value of labor endowment (E), defined inclusive of leisure. The second is the value of capital endowment (K). The third is all other income (M). The fourth is the value of "virtual tax revenue" associated with differences between the shadow price of savings and the cost of investment.
The following parameter values are specified exogenously:
Shephard's lemma applied at benchmark prices provides the following identities which are helpful in deriving expressions for and :
The expression for
does not involve
, so we may first solve for
and use this value in determining
: