# Extension to Three Goods

The two expressions below define CES utility functions. The units
for x, y, and z are normalized so that each has a coefficient of 1.
This reduces the number of parameters that must be treated.

kill(all)$ ratprint:false$ fpprintprec:5$ 
[v: (x^-a + z^-a)^-(1/a), w: (y^-b+ z^-b)^-(1/b)];

Suppose that v is a consumer's utility function (the consumer 
selects combinations of two goods, x and z). What is the 
elasticity of substitution between x and z? If w is the 
utility function, what is the elasticity of substitution
between y and z?

/*Input. Execute (ctrl-enter) for results */
[1/(1+a), 1/(1+b)];

Combine the two expressions into a single expression for the
consumer's utility function. Specifically, make the utility 
function the square root of the product of the two expressions 
above. This option gives equal weight to expressions v and w. 
Other weightings could be used, but this relatively simple one 
supports the illustrative material that follows and, again, 
avoids adding a parameter to keep in mind.

Create the function f(x,y,z,a,b) = sqrt(v*w). You must use the
double quote -- ''( expression)-- operator for the functional 
representation.

/*Input. Execute (ctrl-enter) for results */
f(x,y,z,a,b) := ''(sqrt(v*w));

Apply radcan to f(...) to see that z is weighted
diffferently than x and y.

/*Input. Execute (ctrl-enter) for results */
radcan(f(x,y,z,a,b));

Evaluate f(x,y,z,a,b) for a = 0.5 and b = -0.5, the values used 
throughout this exercise set. With these values of a and b, 
what utility level results if x=2, y=5, and z=3?

/*Input. Execute (ctrl-enter) for results */
[f(x,y,z,.5,-.5),"<--expression, value -->",
  float(f(2,5,3,.5,-.5) ) ];

Use gr3d to create three scenarios named grapx, graphy, and graphz. 
In graphx hold x=5 and draw f(5,y,z,0.5,-0.5). Then set
y = 5 and let x and z vary. Finally, set z = 5 and let 
x and y vary. Use wxdraw(graphx,graphy,graphz,dimensions= 
[480,640]) to show the three graphs.

In each of the scenes, label two of the axes and 
insert a title to indicate which variable is being held 
constant. Set view = [80,300] in all scenarios. In wxdraw( ),
set dimensions=[640,640].

/*Input. Execute (ctrl-enter) for results */
graphx: gr3d(title="u, given x=5",xlabel="y",
 ylabel="z",view=[55,300],
 xtics=20, ytics=20, ztics=5,
 explicit(f(5,y,z,.5,-.5),y,0.001,50,z,0.001,50) )$
graphy: gr3d(title="u, given y=5",xlabel="x",
 ylabel="z",view=[55,300],
 xtics=20,ytics=20,ztics=5,
  explicit(f(x,5,z,.5,-.5),x,0.001,50,z,0.001,50) )$
graphz: gr3d(title="u, given z=5",xlabel="x",ylabel="y",
xtics = 20,ytics=20,ztics=5,
  view=[55,300], contour=both, 
  explicit(f(x,y,5,.5,-.5),x,0.001,50,y,0.001,50), 
  dimensions=[480,480] )$
wxdraw(graphx,graphy,graphz,columns=2,dimensions=[640,640])$

The figure below shows an indifference surface. Remove the wx and execute
the resulting draw( ) command. Then rotate the figure to consider how it
compares to indifference curves for two-goods utility functions.

wxdraw3d(xtics=5,ytics=5,ztics=5, xlabel="x", ylabel="y",
zlabel="z", key="Indifference surface, utility = 25",
implicit(15 - f(x,y,z,.5,-.5),x,0.001,25,y,0.001,25, z, 0.001, 25),
view=[75,160],dimensions=[640,480])$

Marginal utilities all decrease. This characteristic
is easily observed for mux and muy below, but not
apparent for muz. 

/*Input. Execute (ctrl-enter) for results */
assume(x>0,y>0,z>0,a>-1,b>-1)$
mux: radcan(diff(f(x,y,z,a,b),x)); 
muy: radcan(diff(f(x,y,z,a,b),y)); 
muz: radcan(diff(f(x,y,z,a,b),z));

Confirm the result above by determining that all three expressions 
below (after the minus sign) are ratios of sums of positive values 
and, therefore, are negative. Follow each derivative with 
subst([x=5,y=5,z=5,a=.5,b=-.5],%); to confirm that the value 
is negative when these values pertain.

/*Input. Execute (ctrl-enter) for results */
radcan(diff(f(x,y,z,a,b),x,2));
subst([x=5,y=5,z=5,a=.5,b=-.5],%);

/*Input. Execute (ctrl-enter) for results */
radcan(diff(f(x,y,z,a,b),y,2));
subst([x=5,y=5,z=5,a=.5,b=-.5],%);

/*Input. Execute (ctrl-enter) for results */
radcan(diff(f(x,y,z,a,b),z,2));
subst([x=5,y=5,z=5,a=.5,b=-.5],%);

Compute the cross derivatives to confirm that d(mux)/dy > 0,d(mux)dz > 0, 
and d(muy)/dz > 0 for the parameter values used above.

/*Input. Execute (ctrl-enter) for results */
radcan(diff(f(x,y,z,a,b),x,1,y,1));subst([x=5,y=5,z=5,a=.5,b=-.5],%);
radcan(diff(f(x,y,z,a,b),x,1,z,1));subst([x=5,y=5,z=5,a=.5,b=-.5],%);
radcan(diff(f(x,y,z,a,b),y,1,z,1));subst([x=5,y=5,z=5,a=.5,b=-.5],%);

Create expressions for the three marginal rates of substitution.

/*Input. Execute (ctrl-enter) for results */
mrsxy: radcan(diff(f(x,y,z,a,b),x)/diff(f(x,y,z,a,b),y));
mrsxz: radcan(diff(f(x,y,z,a,b),x)/diff(f(x,y,z,a,b),z));
mrsyz: radcan(diff(f(x,y,z,a,b),y)/diff(f(x,y,z,a,b),z));

Confirm that this utility function is homogeneous, degree 1.

/*Input. Execute (ctrl-enter) for results */
f(k*x,k*y,k*z,a,b)/f(x,y,z,a,b);  radcan(%);

Confirm that this utility function is homothetic.

/*Input. Execute (ctrl-enter) for results */
subst([x=k*x,y=k*y,z=k*z],
         [mrsxy,mrsxz,mrsyz])/[mrsxy,mrsxz,mrsyz];
radcan(%);

Let all three prices equal to 1. The first-order conditions
can be stated as mrsxy-1, mrsxz-1, and mrsyz-1, with Maxima
treating the "= 0" as implicit. Create named expressions for
these two conditions.

/*Input. Execute (ctrl-enter) for results */
focxy: subst([a=0.5,b=-.5],mux/muy-1);
focxz: subst([a=0.5,b=-.5],mux/muz-1);

Determine the utility-maximizing quantities of x, y, and z
given the two first-order conditions and the budget 
constraint 25-y-x-z=0.

/*Input. Execute (ctrl-enter) for results */
load(mnewton)$
soln1: mnewton([focxy,focxz,25-x-y-z],[x,y,z],[5,5,5]);

Determine the utility level and confirm that total spending
equals 25. Assign the utility level the name u1.

/*Input. Execute (ctrl-enter) for results */
[u1:f(rhs(soln1[1][1]),rhs(soln1[1][2]),
   rhs(soln1[1][3]),0.5,-0.5),
rhs(soln1[1][1])+ rhs(soln1[1][2])+ rhs(soln1[1][3])];

Let the price of x rise from 1 to 1.5. Determine the new utility-
maximizing quantities and the utility level. Also, confirm that
25 is still being spent on x, y, and z. Assign the name u2 to the
new, lower utility level.

/*Input. Execute (ctrl-enter) for results */
[focxy2,focxz2]: subst([a=0.5,b=-.5],[mux/muy-1.5,mux/muz-1.5]);
soln2:mnewton([focxz2,focxy,25-1.5*x-y-z],[x,y,z],[5,5,5]);
[u2: f(rhs(soln2[1][1]),rhs(soln2[1][2]),rhs(soln2[1][3]),0.5,-0.5),
1.5* rhs(soln2[1][1])+ rhs(soln2[1][2])+ rhs(soln2[1][3])];

Calculate the price elasticity of demand for good x over this range. Use
the midpoint formula.

/*Input. Execute (ctrl-enter) for results */
((5.424-8.9178)/(5.424+8.9178))/((1.5-1)/2.5);

Set the prices of x and y to 1 and the price of z to 1.5. 
Determine the new utility-maximizing values of x, y, and z.
Determine the utility level and assign it the name u3. 
Confirm once more that 25 is the expenditure level.

/*Input. Execute (ctrl-enter) for results */
[focxy3,focxz3]: subst([a=0.5,b=-.5],[mux/muy-1,mux/muz-2/3]);
soln3:mnewton([focxy3,focxz3,25-x-y-1.5*z],[x,y,z],[5,5,5]); 

u3:f(rhs(soln3[1][1]),rhs(soln3[1][2]),rhs(soln3[1][3]),0.5,-0.5);
rhs(soln3[1][1])+ rhs(soln3[1][2])+ 1.5*rhs(soln3[1][3]);

Compensation. One way to separate income and substitution effects is to 
return the consumer to the utility level that pertained before
the price of z increased. Use the two first-order condtions 
above, but replace the budget line with f(x,y,z,0.5,-0.5)=u1
to determine the resulting quantities. 

/*Input. Execute (ctrl-enter) for results */
soln4:mnewton([focxy3,focxz3,f(x,y,z,0.5,-0.5)=u1],[x,y,z],[5,5,5]);

Use the result above to determine how much of the change in z is due
to income and how much is due to substitution.

/*Input. Execute (ctrl-enter) for results */
print("Change due to substitution = ", 10.499 - 14.221)$
print("Change due to income = ", 8.5095-10.499)$
print("Total effect of price increase = ", 8.5095 - 14.221)$

Determine the price elasticity of demand for good z. Use the midpoint formula.

/*Input. Execute (ctrl-enter) for results */
((8.5095-14.221)/(8.5095+14.221))/(0.5/2.5);

Determine the requisite income required to return the consumer
to the initial utility level given the increased price of z.

/*Input. Execute (ctrl-enter) for results */
rhs(soln4[1][1])+ rhs(soln4[1][2] + 1.5*rhs(soln4[1][3]));

Calculate the income elasticity of demand for good z over this range.
Use the midpoint formula.

/*Input. Execute (ctrl-enter) for results */
((10.449-8.9095)/(10.449+8.9095))/((30.846-25)/(30.846+25));

Instead of returning the consumer to the initial utility level, determine the income
that would be required to return that consumer to the lower utility level but with
the price of z equal to 1. 

Use the values of z and the required income level to determine the income 
elasticity over this range.

/*Input. Execute (ctrl-enter) for results */
soln5:mnewton([focxy,focxz,f(x,y,z,0.5,-0.5)=u3],[x,y,z],[5,5,5]);

/*Input. Execute (ctrl-enter) for results */
rhs(soln5[1][1])+ rhs(soln5[1][2] + rhs(soln5[1][3]));

/*Input. Execute (ctrl-enter) for results */
((14.449-10.655)/(14.449+10.655))/((25-20.262)/(25-20.262));