load(draw)$ 
set_draw_defaults(draw_realpart=false)$
fpprintprec:5$ ratprint:false$ kill(all)$

# Oligopoly

## Introduction and Overview

## The Cournot Model

## The Stackelberg Model

## The Bertrand Model

## Nonidentical Products

This section considers cases in which a pair of duopolists sell similar 
but not identical products. The specification of such models is a bit more
involved than the identical-product model, but the analysis is easier.

### The Bertrand Model

The cell below contains a linear specification for demand and marginal cost 
functions. We change notation slightly, because two demand curves must be specified. 

The coefficients of Firm 1's price, p1, are a1 and a2. The coefficients 
of Firm 2's price, p2 are b1 and b2.

The expressions with EG appended to the name are derived by
applying the specified parameter values.

kill(all)$
[mc1:C1 + c1*x1, mc2:C2 + c2*x2];
[x1:A1 + a1*p1 + b1*p2, x2: A2 + a2*p1 + b2*p2];
paramsEG: [A1=1000,A2=1500,a1=-2,b1=1,a2=2,b2=-5,
   C1=10,c1=0.2,C2=20,c2=0.1]$
[x1EG,x2EG]:subst([paramsEG],[x1,x2]);

The next cell shows P1 as a function of Firm1's output rate (ignoring fixed cost), 
along with the implied reaction curve. The first input line contains two commands that
determine the expression for total variable cost. The second line defines Firm1's 
profit. The third line creates a named expression for Firm1's reaction curve. 
The last line shows the function given the parameter list.

integrate(C1+c1*x,x)$  TVC1:subst(x1,x,%);
P1:radcan(p1*x1-TVC1);
rcBertrand1: solve(diff(P1,p1),p1)[1];
rcBertrand1EG: radcan(subst(paramsEG,%));

The next cell shows the same information for Firm2.

TVC2:subst(x2,x,integrate(C2+c2*x,x));
P2:p2*x2-TVC2;
rcBertrand2: solve(diff(P2,p2),p2)[1];
rcBertrand2EG: radcan(subst(paramsEG,%));

The Nash equilibrium values appear below.

pricesEG: float(solve([rcBertrand1EG,rcBertrand2EG],
  [p1,p2]))[1];
subst(pricesEG,[x1EG,x2EG]); 
%[1]+%[2];

The cell below graphs the reaction curves.

[p1EGmax,p2EGmax]:
   [1.25*rhs(pricesEG[1]),1.25*rhs(pricesEG[2])]$

wxdraw2d(user_preamble="set key left",xlabel="p1",
 title="Bertrand Reaction Curves",
 user_preamble="set key bottom left",
 ylabel="p2",line_width=2,key="Reaction Curve 1",
 implicit(rcBertrand1EG,p1,0,p1EGmax,p2,0,p2EGmax),
 color=red,key="Reaction Curve 2",
 implicit(rcBertrand2EG,p1,0,p1EGmax,p2,0,p2EGmax))$

### The Cournot Model

To analyze the Cournot and Stackelberg models with nonidentical products 
cast the analysis in terms of the inverse demand curves. 

The first cell derives the relevant expressions.

kill(all)$  
[mc1:C1 + c1*x1,     mc2:C2 + c2*x2];
solnDem:solve([x1=A1+a1*p1+b1*p2,x2=A2+a2*p1+b2*p2],[p1,p2]);
[p1,p2]:[rhs(solnDem[1][1]),rhs(solnDem[1][2])]$

These are the inverse demand curves for this illustration.

paramsEG: [A1=1000,A2=1500,a1=-2,b1=1,a2=2,b2=-5,
   C1=10,c1=0.2,C2=20,c2=0.1]$
[p1EG,p2EG]:radcan(subst([paramsEG],[p1,p2]));

Profit functions are derived as before.

TVC1: integrate(C1+c1*x1,x1);
P1:radcan(p1*x1-TVC1);
rcCournot1: solve(diff(P1,x1),x1)[1];
rcCournot1EG: radcan(subst(paramsEG,%));

The counterparts for Firm 2 are determined in like fashion.

TVC2: integrate(C2+c2*x1,x1);
P2:radcan(p2*x2-TVC2);
rcCournot2: solve(diff(P2,x2),x2)[1];
rcCournot2EG: radcan(subst(paramsEG,%));

Solving the system of reaction curves provides values for each firm's 
output. The first output line shows these values, along with the total
output. The second output line shows the implied prices

[CournotQuantitiesEG: float(solve([rcCournot1EG,rcCournot2EG],
  [x1,x2]))[1],  CournotQuantitiesEG[1]+CournotQuantitiesEG[2]];  
subst(CournotQuantitiesEG,[p1EG,p2EG]);

The graph below shows the two reaction curves and the values 
produced above. This graph differs slightly from its Bertrand 
counterpart. Rather than using \verb!implicit!, we solve the 
Cournot reaction curve for $x2$, so that we can use the 
\verb!explicit! command, which produces somewhat clearer
graphs.

temp:solve(rcCournot1EG,x2);
wxdraw2d(user_preamble="set key bottom left",
 xlabel="x1",ylabel="x2",yrange=[0,1500],line_width=2,
 key="Firm 1 Reaction Curve", explicit(rhs(temp[1]),x1,0,600), 
 color=red,key="Firm 2 Reaction Curve",
 explicit(rhs(rcCournot2EG),x1,0,600))$

### The Stackelberg Model

For the Stackelberg model, we insert Firm 2's Cournot reaction function into
Firm 1's inverse demand curve and proceed as before. The demand curve and
the associated profit function appear below.

p1Stack: rhs(subst(rcCournot2,solnDem[1][1]));
p1StackEG: float(subst(paramsEG,%));
P1Stack: p1Stack*x1 - TVC1;
P1StackEG: radcan(subst(paramsEG,P1Stack));

The next cell shows the output for Firm1.

x1Stack:solve(diff(P1Stack,x1),x1);
x1StackEG:subst(paramsEG,x1Stack);

Substituting Firm1's output into Firm2's reaction curve yields x2.

subst(x1Stack,rcCournot2); subst(paramsEG,%);
%+x1StackEG[1];