$title A Successive Recalibration Algorithm for GE Models with Many Households (DECOMPHH,SEQ=304) $onText This program constitutes explicit documentation of the solution algorithm used to solve a general equilibrium model of the economic effects of Russia's accession to the WTO based on Goskomstat's consumer expenditure survey. That model has 55094 households. For further details, see the working paper: Poverty Effects of Russia's WTO Accession: modeling "real" households and endogenous productivity effects. Thomas Rutherford, University of Colorado David Tarr, The World Bank Oleksandr Shepotylo, University of Maryland September, 2004 Contact: dtarr@worldbank.org This is a small GAMS program which formulates a simple exchange model with multiple households and shows how the model can be solved either in "bottom-up" mode (with an explicit representation of the consumer demands in the model) or through successive computation of a "top-down" model. The default configuration of this model has 1000 households. The program output is the reporting parameter itrlog which should be displayed as follows: ---- 459 PARAMETER itrlog Equilibrium price levels bottomup iter0 iter1 iter2 iter3 iter4 iter5 i1 0.96239 0.95735 0.96309 0.96230 0.96241 0.96239 0.96239 i2 0.99602 0.99546 0.99607 0.99601 0.99602 0.99602 0.99602 i3 1.00449 1.00511 1.00439 1.00451 1.00449 1.00450 1.00449 i4 1.05347 1.05983 1.05275 1.05355 1.05346 1.05347 1.05347 i5 0.98992 0.98869 0.99005 0.98990 0.98992 0.98992 0.98992 i6 1.01483 1.01677 1.01456 1.01487 1.01483 1.01483 1.01483 i7 1.00364 1.00420 1.00353 1.00365 1.00363 1.00364 1.00364 i8 0.93811 0.93088 0.93903 0.93800 0.93813 0.93811 0.93812 i9 1.02511 1.02800 1.02476 1.02515 1.02510 1.02511 1.02511 i10 1.01202 1.01371 1.01176 1.01206 1.01201 1.01202 1.01202 CPU 0.36100 0.03000 0.04000 0.03000 0.03000 0.03000 0.02000 delta 0.25639 0.03186 0.00407 0.00052 0.00007 8.740106E-6 Rows labeled i1 to i10 report equilibrium prices from various models. "bottomup" presents equilibrium prices for the integrated model in which each of the households is explicitly modeled. The columns labeled "iter0", "iter1", etc. report equilibrium prices returned for successive steps in the approximation procedure. Notice that the bottom up model agrees to five decimals the last three iterations of the decomposition procedure. The row labeled "CPU" reports elapsed time (calculated using the GAMS internal function "system.timeexec") required to process each of the models. (Notice that even with as few as 1000 households, the decomposition procedure is much faster than the integrated bottom-up model.) The row labeled "delta" reports the computed deviation at each step in the decomposition procedure. This deviation is the 1-norm of changes in computed equilibrium prices from one iteration to the next. The decomposition algorithm is terminated when delta falls below 1e-5 Keywords: mixed complementarity problem, general equilibrium model, constant returns to scale, consumption, trade policy, world trade organization, income groups, productivity $offText * Define the dimensions of the model here: $if not set nhh $set nhh 1000 Set h 'households' / h1*h%nhh% / i 'commodities' / i1*i10 /; Alias (i,j); * Use randomly generated input data: Parameter c0(i,h) 'reference consumption levels' e0(i,h) 'commodity endowments' timestart 'run time' sigma(h) 'elasticities of substitution in demand'; c0(i,h) = uniform(0,1); e0(i,h) = uniform(0,1); sigma(h) = uniform(0.25, 2); * Avoid the tedium of coding both Cobb-Douglas and CES demand functions: sigma(h)$(abs(sigma(h) - 1) < 0.01) = 0.99; display c0, e0, sigma; * Declare and solve a model with a fully disaggregate set of households: $onText $MODEL:bottomup $COMMODITIES: p(i) $CONSUMERS: hh(h) $DEMAND:hh(h) s:sigma(h) e:p(i) q:e0(i,h) d:p(i) q:c0(i,h) $offText $sysInclude mpsgeset bottomup * When an MPSGE model is formulated with high dimensionality, it is * often necessary to manually increase the allocated workspace. Here * I am allocating 50 megabytes to the workspace array, a value which * is adequate for more than 10,000 households: bottomup.workSpace = 50; * Solve the bottom-up model in a single shot: timestart = system.timeExec; $include BOTTOMUP.GEN solve bottomup using mcp; Parameter itrlog(*,*) 'equilibrium price levels'; itrlog("CPU","bottomup") = system.timeExec - timestart; itrlog(i,"bottomup") = p.l(i)*card(i)/sum(j, p.l(j)); * Next, solve the same model recursively using the * successive recalibration algorithm: * The top-down model is based on a single representative * agent whose preferences are successively adjusted to * locally portray the "community indifference curve" which * describes the underlying household endowments and preferences: Parameter theta(i,h) 'household benchmark budget shares' pc(h) 'household consumption price index' u(h) 'household utility index (relative to c0)' pref(i) 'reference price' cref(i) 'reference demand quantity'; * Compute the benchmark budget shares: theta(i,h) = c0(i,h)/sum(j, c0(j,h)); * Initially calibrate the community indifference curve * based on a price point at the center of the simplex: u(h) = sum(i, e0(i,h))/sum(i, c0(i,h)); cref(i) = sum(h, c0(i,h)*u(h)); pref(i) = 1; * Here is the top-down model. Note that the h set does not appear in this model: $onText $MODEL:topdown $COMMODITIES: p(i) ! Commodity prices $CONSUMERS: ra ! Reprsentative agent: * Preferences are Cobb-Douglas: $DEMAND:ra s:1 e:p(i) q:(sum(h, e0(i,h))) d:p(i) q:cref(i) p:pref(i) $offText $sysInclude mpsgeset topdown * Fix aggregate income to normalize the price system: ra.fx = sum(h, hh.l(h)); Set iter 'iterations in the projection algorithm' / iter0*iter10 /; Parameter delta 'convergence metric' / 1 /; * Loop until we have drive the sum of absolute price changes to a small level: loop(iter$(delta > 1e-5), * Within each iteration we solve the top-down model. Note that * each solution is very cheap because the model is small and the * previous iteration's solution is already in place: timestart = system.timeexec; $ include TOPDOWN.GEN solve topdown using mcp; itrlog("CPU",iter) = system.timeExec - timestart; * Record the current deviation: delta = sum(i, abs(p.l(i) - pref(i))); itrlog("delta",iter) = delta; * Update the iteration log: itrlog(i,iter) = p.l(i)*card(i)/sum(j, p.l(j)); * Recalibrate preferences of the representative agent based on * demands of the individual households: pc(h) = sum(i, theta(i,h)*p.l(i)**(1 - sigma(h)))**(1/(1 - sigma(h))); * Utility index for household h (relative to c0): u(h) = sum(i, e0(i,h)*p.l(i))/(pc(h)*sum(i, c0(i,h))); * Reference consumption level for the representative agent: cref(i) = sum(h, c0(i,h)*u(h)*(pc(h)/p.l(i))**sigma(h)); pref(i) = p.l(i); ); option itrlog:5; display itrlog;