Profit Maximization
For a firm that sells all units of a product for the same price, the profit function is p*z - c(z), where z is the quantity produced of the product. The output level is governed by a production function f(x1,...), so profit can be rephrased as p*f(.) -c(f(.)). This workbook addresses some basic aspects of selecting the quantity of z that maximizesthe firm's profits.
1 Maximizing Profit, One Variable Factor
Begin with the simple production function z = x1^b and derive the profit function for that product. Assume that the per-unit cost of factor x1, w, is not affected by the number of units that the firm employs. Also, assume that the product price is not affected by the value of z. [Either assumption could be relaxed by positing an explicit relationship between x1 and w or between z and p.] The constant C is the cost that does not vary with x1.
(%i1) |
/* housekeeping */ kill(all)$ ratprint:false$ fpprintprec:5$ /* end housekeeping */ f(x1, b):= x1^b; p*f(x1,b) - w*x1 - C$ profit(x1,b,p,w, C) := ''%; |
The graph below shows this function for two values of C, given the w = p = 1. The graph shows that the profit function reaches its maximum value at x1 = 0.2, approximately, for either value of C.
(%i6) |
wxdraw2d(xlabel = "Employment, x1", ylabel = "$", xaxis=true, key="C = 0", explicit(profit(x1,0.6,1,1,0),x1, 0.001, 1), color=black, key = "C = .05", explicit(profit(x1,0.6,1,1,0.055),x1, 0.001, 1) )$ |
To determine the profit-maximizing employment level for x1 (which is independent of C), solve for the x1 value at which the derivative of profit(.) equalszero.
(%i7) |
assume(b>0,p>0,w>0)$ declare(b, noninteger)$ diff(profit(x1,b,p,w,C),x1); soln: solve(%, x1); |
We can simplify this expression to x1 = (w/b*p)^(1/(b-1)) or, equivalently, to x1 = (b*p/w)^(1/(1-b)). Given b = 0.6, the relationship is as below. The profit-maximizing employment level is directly related to the product price and inversely related to the way rate. We can rewrite this as x1 = 0.279*(p/w)^2.5, so that a one-percent change in p/w causes a 2.5 percent increase in x1.
(%i11) | ev(rhs(soln[1]), b=.6 ); |
Given values of p and w (p = w = 1, here), we obtain the optimal (profit-maximizing) employment level, x1opt = 0.279, approximately. To repeat, this value is not affected by the constant term C.
(%i12) | x1opt : ev(rhs(soln[1]), b=.6, p=1, w=1 ); |
We check the second-order conditions to ensure that we have not found the pessimum, the value of x1 to minimizes profits. Given that 0 < b < 1, and that p and x1 are positive, the second derivative is negative. Given the parameters used here, the second derivative evaluates to approximately -1.434 at x = x1opt.
(%i13) |
diff(profit(x1,b,p,w,C),x1, 2); ev(%, b=.6, p=1, x1=x1opt); |
2 Profit with a Cobb-Douglas Production Function
The production function above is a degenerate form of the Cobb-Douglas function, with x2 = 1. Generalizing the production function to allow several factors can be treated much as above. First, we redefine the profit function. For simplicity, we set a = 1. The input prices are w1 and w2. We also omit C, because its value does not affect the analysis.
(%i15) | profit(x1,x2,p,w1,w2) := p*x1^(1/3)*x2^(1/4) - w1*x1 - w2*x2; |
2.1 Graphing the Function
Choose units such that w1 = w2 = p = 1 and set b = 0.6. The three-dimensional profit function appears below.
(%i16) |
wxdraw3d(view = [50,300],contour=base,xtics=.075,ytics=.05,xlabel="x1", explicit( profit(x1,x2,1,1,1),x1,0.0001,.2,x2,0.0001,.2))$ |
This production function must have decreasing returns to scale, given
that the product price and wage rates are unrelated to the quantities
employed. If the function has constant returns to scale, the output
would be either zero of undetermined. The per-unit cost would be
constant, so a price lower than that cost would result in no
employment. A price equal to the cost would make the firm's profits the
same no matter how many units it employed. A price higher than the cost
would result in an arbitrarily large employment level.
Exercise: Explain would happen if this firm's production function exhibited increasing returns to scale.
The graph below shows the iso-profit lines for four profit levels. It
indicates that a profit level just over 0.1 can be attained (at a point
inside the profit = 1 iso-profit line.
(%i17) |
wxdraw3d(dimensions = [480,480], xlabel="x1",ylabel="x2", user_preamble = "set size ratio -1", view = [45,315],xtics=0.05,ytics=0.05, ztics=0.1, contour=map,contour_levels = {0.10,0.05, 0.0, -0.05}, explicit(profit(x1,x2,1,1,1),x1,0.0001,.4,x2,.0001,.4) )$ |
2.2 Partial Derivatives and the Solution
The optimal values of x1 and x2 are those for which the first partial derivatives of profit equal zero. We derive the derivatives below.
(%i18) | [D1,D2] : [diff(profit(x1,x2,p,w1,w2),x1), diff(profit(x1,x2,p,w1,w2),x2)]; |
Trying to apply Maxima's solve command results in the appearance that no solution exists. This appearance is wrong; it merely reflects that solve is not equipped to handle this type of expression.
(%i19) |
ratprint:false$ solve([D1,D2],[x1,x2]); |
For the moment, suppose that we accept the (false) message that no
analytical solution exists. (This message might be correct for some
production functions.) We could move to a numerical method. We use the
multiple newton approach below. This requires that we provide Maxima
with three lists: the expressions, the variable, and initial guesses
for variable values. For the last, we use 0.075, based on a quick
reading of the graph above.
The profit-maximizing employment mix is x1 = 0.0602 and x2 = 0.0452, so that profit = 0.0753 (all values are approximate).
(%i21) |
load(mnewton)$ mnewton( [diff(profit(x1,x2,1,1,1),x1), diff(profit(x1,x2,1,1,1),x2)], [x1,x2],[0.075,0.075] ); ev(profit(x1,x2,1,1,1),%[1]); |
We
can, however, determine the general nature of profit maximization in
this case. The assume( ) command below lets us avoid dialog with Maxima
in the process that follows.
The necessary (first-order) conditions for profit maximization are D1 = D2 = 0. First, Determine the implication of D1 = 0.
(%i24) |
assume(p>0,w1>0,w2>0,x1>0,x2>0)$ solve(D1,x1); |
Only the positive solution applies here, so we evaluate D2, given that D1 has been solved.
(%i26) | ev(D2,%[1]); solve(%,x2); |
Only the fifth solution is real, so we use it below.
(%i28) |
x2opt: rhs(%[5]); ev(D1,x2=x2opt); solve(%,x1); |
We use the first, positive solution above. The float and radcan commands yield the relatively simple expression. Often some experimentation with simplification commands (sometimes combined with hand calculations) is required to make expressions relatively easy to read.
(%i31) |
x1opt: rhs(%[1]); float( profit(x1opt,x2opt,p,w1,w2) ); maxprofit : radcan(%); |
We confirm that the results obtained above with the mnewton numerical method are the ones implied by the expressions derived above.
(%i34) |
[x1opt0,x2opt0]: float( ev([x1opt,x2opt],p=1,w1=1,w2=1) ); maxprofit0 : float(profit(x1opt0,x2opt0,1,1,1) ); |
3 Comparative Statics
Once we have solved for an optimal choice, we want to see how it
responds to changes in the economic environment. In the current context
that means examining how the demand functions respond to changes in
prices. In Mathematica the easiest way to do is is by using total
derivatives. Consider a function g(x,a). The first-order condition that
a maximum value of x must satisfy is diff(g(x,a)=0.
Totally differentiating this first-order condition (FOC) and solving for x yields the results below.
(%i36) |
diff(diff(g(x,a),x) = 0); solve(%, del(x)); |
We can simplify this result using somewhat more standard notation: dx = -(g_ax / g_xx)*da, where g_ax is the cross partial derivative and g_xx is the second derivative of g with respect to x. The second order condition for a maximum requires that g_xx < 0, so dx/da has the same sign as g_ax.
3.1 Profit maximization with one input
Applying the procedure above to the example with a single input, x1, yields this result: d(x1) is inversely related to d(w) and positively related to both d(p) and d(b). Note that the denominator is negative for b < 1. We have already noted that x1 is undefined if b = 1.
(%i38) |
diff(p*f(x1, b) - w*x1, x1); diff(%=0); solve(%,del(x1)); |
The example used in Section 1, with b = 0.6, yields these results: d(x1) = -((25/6)*x1^(7/5)/p)*d(w) + (15/6)*(x1/p)*d(p). This presentation of the result emphasizes that the ratio of price to wage, not their levels, matters.
(%i41) |
diff(p*f(x1, 0.6) - w*x1, x1); diff(%=0); solve(%,del(x1)); |
3.2 Maximization with several variables
The logic of the illustration above can be extended to functions that involve more than one variable. Extend function g to g(x1,x2,a). For a given value of a, the first-order condition (FOC) consists of g_x1 = g_x2 = 0.
(%i44) | FOC : [diff(g(x1,x2,a),x1), diff(g(x1,x2,a),x2)]; |
We take the derivative of the items in this list with respect to a and then solve for del(x1) and del(x2). The result is long and rather messy. We use the matrix command to format the output; it is not required for the analysis.
(%i45) |
soln: solve(diff(FOC), [del(x1),del(x2)])[1]$ matrix([soln[1]], [soln[2] ] ); |
The expressions above are not as cumbersome as they first appear. They share a denominator, which is the determinant of the Hessian of g(x2,x2,a), as shown below. If this determinant can be signed, then d(x1)/d(a) and d(x2)/d(a) have signs that depend on the relatively simple functions of the cross-partial and second-partial derivatives in the denominator.
(%i47) |
hessian(g(x1,x2,a),[x1,x2]); determinant(%); |
3.3 Application to Production
As before, the objective is to maximize profits, as defined earlier. The first-order conditions (FOC) are below. Note that we set the first condition equal to zero explicitly, but not the second one. This is to point out that, unless told otherwise, Maxima assumes an expression to be differentiated equals zero.
(%i49) |
kill(FOC, soln)$ FOC: [ diff(profit(x1,x2,p,w1,w2),x1)=0, diff(profit(x1,x2,p,w1,w2),x2) ]; |
We extract the total differential for the FOC list. Note that Maxima
applies the diff( ) command to the items in a list and returns a list.
The second command line creates a list of solutions. Note the [1] that
is appended to this command. The solve( ) command generates a list of
lists; the [1] extracts that list. Exercise: remove the [1] and execute
the commands once more.
We use the matrix() command to create a table that is relatively easy
to read. The expand() command is used to generate relatively easily
interpreted coefficients of del(w1), del(w2), and del(w3).
(%i51) |
DFOC: diff(FOC)$ solve(diff(FOC), [del(x1),del(x2)] )[1]$ solnFOC: expand(%)$ matrix([DFOC[1]] , [DFOC[2]]); matrix([solnFOC[1] ] , [solnFOC[2] ] ); |
(%i56) |
ev( rhs(solnFOC[1]), x1=x1opt0, x2=x2opt0 ) ; ev( rhs(solnFOC[2]), x1=x1opt0, x2=x2opt0 ) ; |