This worksheet is and will remain a work in progress. Please contact us at wmixon@berry.edu if you have suggestions for improving this material.

Draft date: 4/24/2012

A Static Aggregate Demand/Aggregate Supply Model

This worksheet illustrates a simple Aggregate Demand/Aggregate Supply model. In such a model, two relationships tie the level of real output to the price level. The model is static in that  it addresses the levels of the two variables, rather than their rates of change. Related worksheets illustrate dynamic counterparts to this model.

The illustration begins with the simplest model, one in which the price level is given and in which only the real sector of the economy is taken into account. Sections 2 and 3 introduce the monetary sector of  the economy and allows for investment to be a function of the interest rate. Sections 4 and 5 allow for determination of the aggregate price level, which is taken as fixed in Sections 1 - 3.

1 Simplest Keynesian Model

The model developed here has the following characteristics:

1) Aggregate Expenditures equals the sum of planned consumption (C),  planned investment (I), and planned government spending (G). That is, the economy is closed to foreign trade.

2) At equilibrium Aggregate Expenditures equals actual output.

3) Actual output (which equals income) varies to adjust to the level of Aggregate Expenditures. This assumption is appropriate when changes in the output level can be achieved without any effect on the general price level.

4) The level of planned consumption is a stable (linear in this  illustration) function of actual output.

5) The level of planned investment is a constant, unaffected by the current level of actual output. That is, planned investment  is exogenous to the model.

6) The level of government spending is also exogenous to the model.

7) Taxes do not change as actual income changes (indeed taxes are not explicitly addressed, though taxes presumably affect the consumption function--the relationship between total real output and planned consumption.

This model has three parameters: a, b, I, and G. We indicate that the values are fixed with the appended zeros: a0, b0,I0, and G0 are defined values that can be passed to the evaluation (ev) command as required.

(%i1) kill(all)$ fpprintprec:5$ ratprint:false$
a0: 1000.0$ b0 : 0.8$ I0 : 600.0$ G0 : 900.0$
C : a + b*Y$ AE : C + I + G$
Yeq : (a + I + G)/(1 - b)$ Y_AE:Y$
multiplier : 1/(1 - b)$
print("The C function =", ev(C,a=a0,b=b0))$
print("The AE function is ", ev(C,a=a0,b=b0) + I0 + G0 )$
print("At equilibrium, Y = ", ev(Yeq, a=a0,b=b0,I=I0,G=G0))$
print("The multiplier =", ev(multiplier,a=a0,b=b0,I=I0,G=G0))$

Result 
(%i16) C(Y,a,b):= a + b*Y;
AE(Y,a,b,I,G) := a + b*Y + I + G;
Yeq0: ev(Yeq,a=a0,b=b0,I=I0,G=G0);

Result 

The components of Aggregate Expenditures, shown as functions of Y, appear below. Of these components, only C is affected by Y in our simple illustration. As a result, the AE = C + I + G line is parallel to the C line.

The nature of the model is not appreciably affected by allowing I or G to relate to Y, or by adding taxes explicitly. These restrictions are applied only for simplicity. Likewise, the relationship need not be linear.

(%i19) wxdraw2d(user_preamble = ["set size ratio -1", "set key top left"],
dimensions=[480,480],xlabel = "Actual output",
ylabel = "Desired expenditures", xrange=[0,1.5*Yeq0],
yrange = [0,1.5*Yeq0], xtics = 4000,
key = "C", explicit(C(Y, a0,b0),Y,0,1.5*Yeq0), color = blue,
key = "C+I", explicit(C(Y, a0,b0) + I0,Y,0,1.5*Yeq0),
line_width=2, key = "AE = C+I+G",
explicit(C(Y, a0,b0)+I0+G0,Y,0,1.5*Yeq0) )$

Result

In this model, the equilibrium condition is that AE = Y. That is,equilibrium requires that the amount of real output that consumers, investors, and governments choose to purchase is equal to the the amount produced.

1.1 Equilibrium in the Simple Model 

(%i20) wxdraw2d(user_preamble = ["set size ratio -1", "set key top left"],
dimensions=[480,480],xlabel = "Actual output", xtics = 4000,
ylabel = "Desired expenditures", xrange=[0,1.5*Yeq0],
yrange = [0,1.5*Yeq0], line_type=dots, points_joined=true,
key="", points([[Yeq0,0],[Yeq0,Yeq0],[0,Yeq0] ]), line_type=solid,
key = "AE = C+I+G", explicit(C(Y, a0,b0)+I0+G0,Y,0,1.5*Yeq0),
color = blue,key ="AE = Y", explicit(Y,Y,0,1.5*Yeq0),
color = red, label( [string(Yeq0),Yeq0, Yeq0])   )$

Result
(%i21) Ylow: 0.8*Yeq0$ Yhigh : 1.2*Yeq0$
print("For Y =",Ylow,"desired output is", AE(Ylow,a0,b0,I0,G0))$
print(" Undesired inventory depletion is", % - Ylow)$
print("For Y =",Yhigh,"desired output is", AE(Yhigh,a0,b0,I0,G0))$
print(" Undesired inventory accumulation is", Yhigh - %)$
Result 

1.2 Shifting the AE Function

Suppose that I (or G) increases by 1000. Then AE for each value of Y is 1000 units higher than before. The new equilibrium value of Y is 17500, consistent with the fact that the multiplier equals5.0 (why?).

(%i27) Yeq1 : ev(Yeq, a=a0,b=b0,I = I0 + 1000, G = G0);

Result 

The graph below shows the effect of shifting the AE curve upward by 1000. The new point of intersection is at AE = Y = 17500, thevalue computed above.

(%i28) wxdraw2d(user_preamble = ["set size ratio -1", "set key top left"],
dimensions=[480,480],xlabel = "Actual output", xtics = {Yeq0,Yeq1},
ylabel = "Desired expenditures", xrange=[0,2*Yeq0], ytics={Yeq0,Yeq1},
yrange = [0,2*Yeq0], line_type=dots, points_joined=true,
points([[Yeq0,0],[Yeq0,Yeq0],[0,Yeq0] ]),
points([[Yeq1,0],[Yeq1,Yeq1],[0,Yeq1] ]),
line_type=solid,
key = "AE = C+I0+G0", explicit(AE(Y,a0,b0,I0,G0),Y,0,2*Yeq0),
key ="AE = Y", explicit(Y,Y,0,2*Yeq0),color=blue,
key ="AE = C + I0 + G0 + 1000", line_width=2,
explicit(AE(Y, a0,b0,I0+1000,G0),Y, 0, 2*Yeq0) )$

Result

2 The Capital Market

This section generalizes the model used in the preceding section in two ways. First, it adds a simple tax function.  More importantly, it treats investment as a function of the interest rate. [A simple modification could also treat consumption as afunction of the interest rate. This change would not affect the nature of the model, however, and is avoided for simplicity's sake.]

The consumption function is now a function of the tax rate, but is otherwise unchanged from that used in the preceding section.  Investment is now a function of the interest rate; the function shifts if either c or d changes. Aggregate Expenditures (C + I + G)is now a function of both Y and r.

(%i29) C(Y,a,b, t) := a + b*(1-t)*Y $
I(r) := c - d*r$ C(Y,a,b,t) + I(r) + G$
AE(Y,r,a,b,t,c,d,G) := ''%;

Result

2.1 Deriving the IS Curve

The equilibrium condition in the goods market remains as before: AE = Y. Now, however, the resulting expression involves both Y and r. Solving the equilibrium condition for r results in a functional relationship between r and Y. This is called the IS curve. [This name relates to a condition in the simple model without G and t, that  equilibrium also implies that investment and saving be equal. In the current model equilibrium requires that investment plus government spending = saving plus taxes.]

The third command below converts the result of the solution into an explicit function.

(%i33) solve(AE(Y,r,a,b,t,c,d,G)=Y,r)$
rhs(%[1]); IS(Y,a,b,t,c,d, G):= ''%;

Result

An aside: The multiplier is now smaller than before. Because 15% of income (we assume t = 0.15), is used to pay taxes, the multiplier decreases from 5.0 to 3.125.

(%i36) multiplier: 1/(1-b*(1-t));
ev(multiplier, b=b0,t=0.15);
ev(multiplier, b=b0,t=0.0);

Result
(%i39) [t0, c0, d0] : [0.15, 750, 25]$ IS(Y,a0,b0,0.2,I0,d0, G0);
wxdraw2d(xlabel = "Y", ylabel = "r",
yrange = [0,150], key = "IS0",
explicit(IS(Y,a0,b0,t0,c0,d0, G0),Y,0,10000),
color = blue,key = "IS1",
explicit(IS(Y,a0,b0,t0,c0,d0, G0 - 200),Y,0,10000)
)$

Result

Exercise: Confirm that the 200 reduction in G causes the equilibrium Y value to decrease by 625 (3.125*200) for any
value of r. Do this by solving the IS function for two values of G (G0 and G0 - 200). Solving for Y will produce the two Y values.

3 The Money Market 

The goods market is just one market that generates a functional relationship between Y and r. A second market is the money market. The demand for money can be modeled as a function of the interest rate (which represents an opportunity cost of holding money rather than either bonds, which generate income) and the income level (higher income typically involves more transactions, which are facilitated by having more (real) money balances.

To be more specific, the demand for real money balances (M/P) is modeled as a constant-elasticity function of the income level Y and the interest rate r: Md = P*m*Y*r^E. The amount of money that people wish to hold is proportional to both the price and income levels, and it has a constant-elasticity relationship with the interest rate.

(%i42) declare(E, noninteger)$ assume(m>0,M>0,Md>0, P>0,Y>0)$
Md(Y, r, P, m, E) := P*m*Y*r^E;
solve(Md = Md(Y,r,P,m,E),r)$ rhs(%[1]);
rd(Y,Md, P,m,E):= ''%;

Result
(%i48) m0 : 2.5$ E0 : -2$ P0 : 1.0$ M0: 1000$ M1:1500$ Y0: 6000$ Y1: 7000$
wxdraw2d(yrange=[0, 10],xrange = [0, 2000], xlabel="Ms, Md ($)", ylabel =
"r, percent", key="Money Demand",
explicit(rd(Y0,Md,1.0,m0,E0),Md,0.0001, 2500), color = blue,
key = "Initial Money Supply", implicit(M-M0,M,0,M0+1,r,0,100),
line_width = 2, key = "New Money supply", implicit(M-M1,M,0,M1+1,r,0,100)
)$

Result 

To determine the values of the two equilibrium interest rates in the graph, solve the expression Md = M, where M is a quantity of money. The solve( ) command does not routinely work well with this specification (depending on the value of E). The find_root( )command provides numerical approximation to the equilibrium values.

(%i56) find_root(Md(Y0,r,P0,m0,E0)- M0, r, 0.01, 100);
find_root(Md(Y0,r,P0,m0,E0)- M1, r, 0.01, 100);
Result 

An income level change shifts the demand curve for money, leading to a new equilibrium interest rate. The graph below shows the shift dueto a reduction in Y from Y = 6000 to Y = 7000.

(%i58) wxdraw2d(user_preamble="set key bottom left",
yrange=[0, 5],xrange = [0, 1500], key="Initial Money Demand",
explicit(rd(Y0,Md,1.0,m0,E0),Md,0.0001, 1500), color = blue,
key = "Money Supply", implicit(M-M0,M,0,M0+1,r,0,10),line_width = 2,
key = "New Money Demand", explicit(rd(Y1,Md,1.0,m0,E0),Md,0.0001, 1500) )$

Result

Again, find_root( ) is used to determine that the equilibrium interest rate rises from 3.873 to 4.1833 (approximately) as a
result of an increase from Y = 6000 to Y = 7000, given M = 100.

(%i59) find_root(Md(Y0,r,P0,m0,E0)- M0, r, 0.01, 100);
find_root(Md(Y1,r,P0,m0,E0)- M0, r, 0.01, 100);
Result 

3.1 The LM Curve

We formally develop the relationship between Y and the equilibrium r value by deriving the LM curve. An LM curve shows the equilibrium interest rate, given a quantity of money, as a function of Y. It is, therefore the money market counterpart to the IS curve, which shows equilibrium in the goods market. The position of the LM curve depends on the money supply and the parameters of the money demand function.

To determine the expression for the LM curve, solve the curve Md = M for r. The resulting equation, below, is LM = (M/(m*P*Y) )^(1/E), so the interest rate is a constant-elasticity function of Y (here, the elasticity is 1/2).

(%i61) solve(Md(Y,r,P,m,E)-M, r)$ rhs(%[1]);
LM(Y,M, P,m,E) := ''%;

Result

The position of the LM curve depends on the money supply and the parameters of the money demand function. The graph below shows two LM curves, one for M = 100 and the other for M = 150. Increasing M causes r to fall for each value of Y.

(%i64) wxdraw2d(user_preamble="set key bottom right",
xlabel="Y", ylabel = "r",
yrange = [0, 5], xlabel = "Y", ylabel = "r",
key = "LM0", explicit(LM(Y,M0,P0,m0,E0),Y,0,10000),
color = blue, key = "LM1",
explicit(LM(Y,M1,P0,m0,E0),Y,0,10000) )$

Result

3.2 Equilibrium Y and r Values

Combining the IS and LM curves provides enough information to produce the equilibrium values of Y and r in this fixed-price model of the goods and money markets. The graph below shows the equilibrium values. The absolute slope of the IS curve is quite large given this system's parameters. This is, a large change in r is associated with a relatively small change in Y. This should not be taken as generallythe case.

(%i65) wxdraw2d(xrange = [5000,10000], yrange = [0, 10], xlabel="Y",
ylabel="r", key = "LM", explicit(LM(Y,M0,P0,m0,E0),Y,0,10000),
 key="IS",line_width=2,
explicit(IS(Y,a0,b0,t0,c0,d0,G0),Y,0,10000) )$

Result

Again, find_root( ) produces the equilibrium value of Y, Yeq0.

(%i66) Yeq0: find_root(IS(Y,a0,b0,t0,c0,d0,G0)-
    LM(Y,M0, P0,m0,E0), Y,.0001, 100000 );

Result

Placing the equilibrium value of Y, Yeq0, into the expression for either the IS curve or the LM curve produces the equilibrium interest rate.

(%i67) req0: IS(Yeq0,a0,b0,0.2,I0,d0,G0);
LM(Yeq0,M0, P0,m0,E0);

Result

We can add the equilibrium values to the graph.

(%i69) wxdraw2d(yrange = [0, 10], xlabel="Y", ylabel="r",
points_joined=true, line_type=dots,
points([[Yeq0,0], [Yeq0,req0], [0,req0] ]),
line_type=solid, key = "LM",
explicit(LM(Y,M0,P0,m0,E0),Y,0,10000),key="IS",
line_width=2, explicit(IS(Y,a0,b0,.2,I0,d0,G0),Y,0,10000) )$

Result

4 Aggregate Demand: Variable General Price Level

The model development above began with a variable real output rate, Y and fixed values of the interest rate r and the general price level P. Then r became endogenous, determined by the intersection of the IS and LM curves. The general price level is still fixed. This section relaxes the assumption that P is a constant. The model contains an Aggregate Demand curve, AD, which consists of a set of equilibrium values of Y and P. (We could insert a value of P in the IS/LM analysis above and also determine the implied value of r.)

Maxima solves for the intersection of the IS and LM curves below.

(%i70) ADsoln:solve(IS(Y,a,b,t,c,d,G)=
    LM(Y,M, P,m,E), Y );

Result

The resulting expression above shows that we cannot solve for Y as an explicit function of the general price level, or vice versa. Rather, both Y and P must be determined jointly. Accordingly, we express theAggregate Demand function as an  implicit function of Y and P.

(%i71) ADsoln[1]$ AD(Y,P,m,E,a,b,t,c,d,G,M) := Y - ''%;

Result

When the price level was fixed, we set P = 1 and determined that Y = 7933.3. The cell below shows that the combination P = 1 and Y = 7933.3 is a point on the AD curve.

(%i73) find_root(AD(Y,1,m0,E0,a0,b0,t0, c0, d0,G0,M0),Y,0.001,10000 );

Result

We can generalize the result above to any number of points on the AD curve. The illustration below creates eleven such points. We use the makelist( ) command twice. In the second use find_root( )  command is embedded in the makelist( ) command. We use cons( ) to add names to the two lists and matrix( ) to produce a more easily read table of values.

The table of values below reveals the inverse relationship between real output, Y, and the general price level, P.

(%i74) AD(Y,P,m0,E0,a0,b0,t0, c0, d0,G0,M0);
PList: makelist(.1*i, i, 5, 15)$
YList : makelist(
  find_root( AD(Y,.1*i,m0,E0,a0,b0,t0, c0, d0,G0,M0),Y,0.001,10000),
    i, 5, 15 )$
PList: cons("P", PList)$ YList: cons("Y", YList)$
matrix(PList,YList);

Result

The graph below generalized the results in the table, showing the relationship between Y and P over a range of values. We set the ip_grid to set the fineness of the grid search for drawingimplicit functions (the default is ip_grid = [50,50]).

(%i80) wxdraw2d(xrange=[7500,8000],ip_grid=[400,100],
xlabel="Y", ylabel = "P", key = "Aggregate Demand",
implicit(AD(Y,P,m0,E0,a0,b0,t0, c0, d0,G0,M0), Y,5000,10000, P, 0.001, 5)
)$

Result

5 The Equilibrium Price Level: AD = AS

Once we have developed the AD curve, adding an Aggregate Supply curve, AS, is mechanically simple (though the development of the AS might involve complex reasoning). Three cases are considered: in the long run, the AS curve is vertical (Y is fixed); in the very short run, the AS may be horizontal (P if fixed); and in periods of intermediate length, AS is upward-sloping (P and Y are directly related to each other).

5.1 The Long Run 

The graph below depicts the situation in the long run. Technological data determine the real output level (we use Y = 7800), irrespective of the value of P. Thus, we draw a vertical lineat Y = 7800, using the implicit expression Y - 7800 = 0.

(%i81) wxdraw2d(xrange=[7500,8000],ip_grid=[400,100],
xlabel="Y", ylabel = "P", key = "Aggregate Demand",
implicit(AD(Y,P,m0,E0,a0,b0,t0, c0, d0,G0,M0), Y,5000,10000, P, 0.001, 5),
color = blue, key = "Aggregate Supply, LRAS", implicit(Y-7800,Y,.001,10000,P,.001,5))$

Result

The cell below determines that P = 1.9459 in the illustration above. It also shows P values for two other possible Y values, one of which is the value determined above when P = 1.We bind the name P2 to the price when Y = 7800 for use below.

(%i82) AD(7800,P,m0,E0,a0,b0,t0, c0, d0,G0,M0);
P2: find_root(AD(7800,P,m0,E0,a0,b0,t0, c0, d0,G0,M0),P,.01,15);
find_root(AD(Yeq0,P,m0,E0,a0,b0,t0, c0, d0,G0,M0),P,.01,15);
find_root(AD(8000,P,m0,E0,a0,b0,t0, c0, d0,G0,M0),P,.01,15);

Result

5.2 The Short Run(s)

In the short run, real output can vary. In the simplest Keynesian model, which might apply when a significant level of unemployment persists, the price level is constant over some relevant output range. We can illustrate this model by setting a price level. Suppose that the price level is 1.5 over the relevantrange of output. The graph below shows the resulting equilibrium.

(%i86) wxdraw2d(xrange=[7500,8000],ip_grid=[400,100],
xlabel="Y", ylabel = "P", key = "Aggregate Demand",
implicit(AD(Y,P,m0,E0,a0,b0,t0, c0, d0,G0,M0), Y,5000,10000, P, 0.001, 5),
color = blue, key = "Aggregate Supply, SRAS", explicit(1.5, Y,0.001,8000))$

Result

The equilibrium value of Y can be obtained: apply find_root( ).
The cell below shows that the equilibrium occurs at Y = 7857.2.

Suppose that the AE curve (C + I + G) shifts upward by 50, due to increased G. The AD curve shifts rightward, but by less than 50, because the AE shift causes IS to shift and r to increase, so that investment decreases, partly offsetting the increased G.  The cell below shows that output rises from 7857.2 to 8009.3, and that the multiplier is 3.0433, down from 3.125 that applies when r is constant.

(%i87) AD(Y,1.5,m0,E0,a0,b0,t0, c0, d0,G0,M0);
temp1: find_root(AD(Y,1.5,m0,E0,a0,b0,t0, c0, d0,G0,M0),Y,0.01,20000);
temp2: find_root(AD(Y,1.5,m0,E0,a0,b0,t0, c0, d0,G0+50,M0),Y,0.01,20000);
tempmultiplier: (temp2-temp1)/50;
kill(temp1,temp2,tempmultiplier)$

Result

In some short-run situations, both P and Y are determined simultaneously. The example below provides a simple linear representation of such a case. We suppose that P = 1.9459 and Y = 7800 (values determined by the intersection of the initial AD curve and the long-run AS curve above). We assume that  deviations about P2 (= 1.9459) are proportional to the value of (Y - 7800)/7800.

(%i92) wxdraw2d(user_preamble="set key bottom left",
xrange=[7500,8000],ip_grid=[400,100], yrange=[0,5],
xlabel="Y", ylabel = "P", key = "Aggregate Demand",
implicit(AD(Y,P,m0,E0,a0,b0,t0, c0, d0,G0,M0), Y,7500,8000, P, 0.001, 5),
color = blue, key = "Aggregate Supply, SRAS",
explicit(P2+10*((Y-7800)/7800), Y,7500,8000), key = "LRAS", line_width=2,
color = gray, implicit(Y-7800,Y,7700,7900,P,0, 5)
)$

Result

We can evaluate the effect of a shifted AD curve. Suppose that G increases from G = 900 to G = 950, as above. The resulting effect on Y is an increase from Y = 7800.0 to Y = 7931.6. The price level rises from P2 = 1.9459 to 2.632. This increase implies that the real money supply decreases. This decrease adds upwardpressure to the interest rate, further reducing investment.

(%i93) AD(Y,P2+10*((Y-7800)/7800),m0,E0,a0,b0,t0, c0, d0,G0,M0);
temp1: find_root(AD(Y,P2+10*((Y-7800)/7800),m0,E0,a0,b0,t0, c0, d0,G0,M0),Y,0.01,8000);
temp2: find_root(AD(Y,P2+10*((Y-7800)/7800),m0,E0,a0,b0,t0, c0, d0,G0+50,M0),Y,0.01,8000);
find_root(AD(%,P,m0,E0,a0,b0,t0, c0, d0,G0+50,M0),P,0.01,5);

Result 

Because of the effect of the higher price level that increased G implies, the multiplier now falls from 3.0433 to 2.6321. This decrease reflects the fact that a higher aggregate price level implies a reduced real money supply, given M. The further reduction in M/P cause r to rise, crowding out some investment.

(%i97) (temp2 - temp1)/50; kill(temp1,temp2)$

Result

The graph below illustrates the calculations that appear above.

(%i99) wxdraw2d(xrange=[7500,8000],ip_grid=[400,100], yrange=[0,5],
xlabel="Y", ylabel = "P", key = "AD0",
implicit(AD(Y,P,m0,E0,a0,b0,t0, c0, d0,G0,M0), Y,5000,10000, P, 0.001, 5),
line_width = 2, key = "AD1",
implicit(AD(Y,P,m0,E0,a0,b0,t0, c0, d0,G0+50,M0), Y,5000,10000, P, 0.001, 5),
color = blue, key = "Aggregate Supply, SRAS",
explicit(P2+10*((Y-7800)/7800), Y,7500,8000))$

Result
Created with wxMaxima.
Edited with KompoZer.