Cournot Quantity Games

with Linear Demand

This file (Cournot.ma)contains some of the same material as the previous file (React.ma) but extends it to provide a numerical solution and additional graphics.  Many of the comments are from the React.ma are preserved in Cournot.ma so that each program can be clearly understood independant of the others.

General Setup for Quantity Games

Mathematica notes are presented in this format.

Economic notes are in this format.

Setup for the problem.

Because we want to study the analytical solution to this simply problem, we need to tell Mathematica what the parameters (or constants) of the model are.  Everything else will be treated as a variable.  The semi-colons at the end of input lines suppress the display of output.

SetAttributes[a, Constant] 
SetAttributes[b, Constant] 
SetAttributes[c1, Constant] 
SetAttributes[c2, Constant]

The Clear command tells Mathematica to wipe out any previous values associated with the listed variables.

Clear[a,b,c1,c2,temp1,temp2,pie1,pie2]; 
Clear[Q1,Q2,eqPr1,eqPr1,focPr1,focPr2,R2,pie1c,pie2c];

Total market quantity (Q) is the sum of firm 1's qty (Q1) and firm 2's qty (Q2).

Q = Q1 + Q2 ;

Next, we specify a functional form for the inverse market demand faced by the duopolists; in this case a linear function.

Price = a - b*Q ;

Cournot Game

Similar to the model first ananlyzed by Cournot in 1838, this Cournot quantity game assumes that there are two firms producing identicle goods each at a per unit cost "c".  Because market price is a function of market output (as determined by the inverse demand function) each firm's profits depend on their output choice as well as the output of their competitor.  Therefore, the task of the two firms is to choose their levels of output without knowing the output of the other firm with certainty.  A Nash equilibrium for this game is a set of outputs in which each firm chooses its optimal level of output as a best response to the hypothesized output of its competitor, and each firm's beliefs about its competitor's output is correct. 
Because the Cournot game is a simultaneous move game, it does not matter whether we consider firm 1's or firm 2's optimization problem first.  However, to be consistent with the sequential move Stackelberg game (where order is important) we will consider firm 2's optimization problem first.

Firm 2's payoff is simply its profit.

Firm 2's profits are equal to the difference between the revenue from selling the quantity Q2 and the cost of selling this quantity.  Revenue is firm 2's own quantity (Q2) times market price which is a function of firm 2's own quantity as well as firm 1's quantity (i.e.: P[Q1,Q2]).  Firm 2's total cost of production is quantity Q2 times a constant unit cost c.

eqPr2 = Profit2 == Q2(P[Q1,Q2] - c2) ;

Because a linear inverse demand function is given, we want to replace the general form of the price function with the linear demand given above (Price = a - bQ).

In Mathematica % refers to the last result generated (ie: %% uses the 2nd to last result generated) and /. is the replacement identifier.  So below, we take the original profit equation (defined above) and replace the general form of our demand equation P[Q1,Q2] with our explicit linear inverse demand equation "Price" which is specified above.

eqPr2 = Expand[%/. P[Q1,Q2] -> Price]

To find firm 2's profit maximizing quantity define a new equation focPr2 (firm 2's first order condition) to be the derivative (D[ ]) of firm 2's profit (payoff) function with respect to its choice of its own quantity Q2.

focPr2 = D[eqPr2, Q2]

Use the Mathematica Solve statement to solve the first order condition for Q2 and name the output temp2.  It is helpful to note that the output from a solve statement is a list of solutions.  Consequently, temp2 is the name of the list of solutions.  In the case below, the list temp2 has only one solution and therefore a single element.

temp2 = Solve[focPr2, Q2]

It is clear from the first order condition above that firm 2's optimal choice of Q2 will depend on firm 1's optimal choice Q1.  This is the key to game theoretic problems; each party must consider what the other parties will do.  Because firm 2's choice of Q2 is a function of firm 1's choice Q1, we call the expression above firm 2's Best Response or Reaction Function.  As its name implies, this function dictates how firm 2 chooses Q2 as a best response (or in reaction) to firm 1's choice Q1.  In the simply linear case, we can solve for firm 2's best response quantity (R2[Q1]) explicitly.

Note: In the next line of code, we create an expression called React2 (firm 2's reaction function) that represents firm 2's optimal response (R2[Q1]) to firm 1's quantity choice Q1.  The right hand side of this expression is simply the solution for Q2 that we found above.  In other words, R2[Q1] is equal to Q2 where Q2 is replaced ( /. ) by the first solution ( [[1]] ) from the output list "temp2".  R2[Q1] is just another name for Q2 that reflects the fact that this quantity is chosen in response to Q1.

React2 = R2[Q1] == Q2 /. temp2[[1]]

Firm 1's payoff is simply its profit.

In the simultaneous move Cournot game, firm 1 solves for its own Best Response quantity in the same manner as firm 2 has. 
Firm 1's profits are equal to the difference between the revenue from selling its own quantity Q1 and the cost of selling this quantity.

eqPr1 = Profit1 == Q1*(P[Q1,Q2]-c1) ;

Once again, because a linear demand function is given, we replace the general form of the price function with the linear demand given above (Price = a - bQ).

eqPr1 = Expand[%/. P[Q1,Q2] -> Price]

To find firm 1's profit maximizing quantity define a new equation focPr1 (firm 1's first order condition) to be the derivative (D[ ]) of firm 1's profit (payoff) function with respect to its choice of its own quantity Q1.

focPr1 = D[eqPr1, Q1]

Use the Mathematica Solve statement to solve the first order condition for Q1 and name the output temp1.

temp1 = Solve[focPr1, Q1];

Note: We name the function relating firm 1's optimal response (R1[Q2]) to firm 2's quantity choice "React1".

React1 = R1[Q2] == Simplify[Q1 /. temp1[[1]]]

Solution to the simply Cournot Game.

At this point we have the reaction functions (or best response functions) for both of the Cournot firms.  Each of these functions specifies how the firm will choose its optimal quantity in response to the quantity choice of the other firm.  If we knew firm 1's choice of Q1 we could solve firm two's reaction function for its optimal choice of Q2.  Similarly, if we knew firm 2's choice Q2 we could solve firm one's reaction function for its optimal choice of Q1.  The difficulty with the Cournot game is that the players simultaneously choose their respective quantities.  Therefore, the solution to the simultaneous move Cournot game is found by solving both firms' reaction functions simultaneously for the quantities Q1 and Q2.  Intuitively, the solution to the Counot game has each firm choosing its best response quantity in reaction to the hypothesized quantity of the other firm.

The Solve statement is used to simultaneously solve the two reaction functions which we have called React1 and React2 for the optimal quantities Q1 and Q2.  NOTE: Before solving these simultaneous equations, it is necessary to first rename firm 1's best response quantity, R1[Q2], to be Q1 and to rename firm 2's best response quantity, R2[Q1], to be Q2.

cournotQ = Simplify[ 
	      Solve[{React1 /. R1[Q2] -> Q1, 
		     React2 /. R2[Q1] -> Q2}, 
		    {Q1, Q2}]]

Because we eventually want to compare the results from this Cournot game to the results form a Stackelberg game, we rename the optimal outputs for firms one and two from the Cournot game to be Q1c and Q2c respectively.

In Mathematica this is accomplished be creating a new variable Q1c that is equal to Q1 where Q1 is replaced ( /. ) with its first solution value ( [[1]] ) from the previous line of output ( % ).  Similarly, the new variable Q2c is set equal to Q2 where Q2 is replaced ( /. ) with its first solution value ( [[1]] ) from the second to last line of output ( %% ) .

Q1c = Q1 /.%[[1]] ;

Q2c = Q2 /.%%[[1]] ;

The resulting market quantity and market price for the Cournot game are calculated by substituting the firms' optimal quantities into the quantity and price equations.

Note: In the next two input lines we replacing a list of variables (not a single variable substitution).  The Mathematica syntax requires that, following the replacement  switch ( /. ), your list of replacements be enclosed in brackets, { }, and that the individual substitutions be separated by commas.

Qcour = Q /.{Q1 -> Q1c, Q2 -> Q2c}

Pcour = Simplify[Price /.{Q1 -> Q1c, Q2 -> Q2c}]

The profits from playing the Cournot Game to firm 1 and firm 2 respectively are:

pie1c = Simplify[Q1c*(Pcour - c1)]

pie2c = Simplify[Q2c*(Pcour - c2)]

SENSATIVITY ANALYSIS: This 3-D plot shows sensativity of Firm 1's Cournot output to its own marginal cost as well as the costs of the competitor.

Pieplot =  
	Plot3D[Q1c /. {a -> 1, b -> 1}, 
	       {c1, .1, 1}, {c2, .1, 1}, 
	       PlotRange -> {0,1}, 
	       AxesLabel -> { c1, c2, Qty}, 
	       PlotLabel->"Quantity Choice of Firm 1"]

The x and y axis of this 3-D plot are firm 1's cost, c1, and firm 2's cost, c2, respectively.  The lists {c1, , } and {c2, , } specify the range these values are allowed to take in our plot.  In addition, because only positive outputs are feasible we specify a range of values that the z-axis (firm one's output Q1) is allowed to take with the option "PlotRange -> {Min, Max}.

reactPlot =  
	Plot[{Q2 /. Solve[focPr1 /.{a -> 1, b -> 1, c1 -> .5}, Q2][[1]], 
              Q2 /. Solve[focPr2 /.{a -> 1, b -> 1, c2 -> .5}, Q2][[1]]}, 
	     {Q1, 0, .55}, 
	     PlotRange -> {0, .55}, 
	     PlotStyle->{{RGBColor[0,0,1],Thickness[0.001]}, 
			 {RGBColor[1,0,0],Thickness[0.010]} 
			}, 
	     AxesLabel->{"Q1","Q2"}, 
	     PlotLabel->"Reaction Curves"]

Using the above graphic, observe that Firm 1's optimal output decreases with its own marginal cost and increases with its competitors marginal cost.  To understand why this is the case, it is helpful to look at the reaction functions.

reactPlot =  
	Plot[{Q2 /. Solve[focPr1 /.{a -> 1, b -> 1, c1 -> .5}, Q2][[1]], 
              Q2 /. Solve[focPr2 /.{a -> 1, b -> 1, c2 -> .5}, Q2][[1]]}, 
	     {Q1, 0, .55}, 
	     PlotRange -> {0, .55}, 
	     PlotStyle->{{RGBColor[0,0,1],Thickness[0.001]}, 
			 {RGBColor[1,0,0],Thickness[0.010]} 
			}, 
	     AxesLabel->{"Q1","Q2"}, 
	     PlotLabel->"Reaction Curves"]

reactPlot =  
	Plot[{Q2 /. Solve[focPr1 /.{a -> 1, b -> 1, c1 -> .5}, Q2][[1]], 
	      Q2 /. Solve[focPr1 /.{a -> 1, b -> 1, c1 -> .6}, Q2][[1]], 
	      Q2 /. Solve[focPr2 /.{a -> 1, b -> 1, c2 -> .5}, Q2][[1]]}, 
	     {Q1, 0, .55}, 
	     PlotRange -> {0, .55}, 
	     PlotStyle->{{RGBColor[0,0,1],Thickness[0.001],                  }, 
                         {RGBColor[0,0,1],Thickness[0.001],Dashing[{.03,.02}]}, 
		         {RGBColor[1,0,0],Thickness[0.010],                  }}, 
	     AxesLabel->{"Q1","Q2"}, 
	     PlotLabel->"Reaction Curves"]