Dynamic Cournot Oligopoly with Output Adjustment Cost
Chrystie T. Burr, B.S.
Master’s Report
Presented to the Faculty of the Graduate School
of The University of Arizona
in Partial Fulfillment of the Requirements
for the Degree of
Master of Science in Industrial Engineering
The University of Arizona
December 2007
Table of Contents
Abstract ........................................................................................................................1
Introduction …………………………………………………………………..……...2
Mathematical Model ..……………………………………………………………….2
Best Responses with
2.1 Continuous Production Adjustment Cost ..………..…………...6
2.2 Discontinuous Production Adjustment Cost ..………..………..9
Best Response Dynamics and its Equilibrium ……………………………..……..15
Simulation Study …………………………..……………………………………….16
Sensitivity Analysis with
4.1 Continuous Production Adjustment Cost ..………..………….18
4.2 Discontinuous Production Adjustment Cost ..………..……....33
Summary …………………………………………………………………………...36
Reference …………………………………………………………………………..37
Appendix
C++ code for Duopoly Basin Calculator ……………..……………….38-54
List of Figures
1. Plot of best response function with continuous output adjustment costs ……9
2. Plot of best response function with discontinuous output adjustment costs
(case 1) ………………………………………………………………………….14
3. Plot of best response function with discontinuous output adjustment costs
(case 2) ………………………………………………………………………….14
4. Plot of the equilibrium set of the example ……………………………………15
5. Snapshot of the Duopoly Basin Calculator windows program …………..…..17
6. Figure of the equilibrium set of the example …………………………………18
7. Figures of the equilibrium set when A varies …………………………19, 20, 21
8. Figures of the equilibrium set when B varies …………………………22, 23, 24
9. Figures of the equilibrium set when β varies …………………………25, 26, 27
10. Figures of the equilibrium set when L varies ………………………..28, 29, 30
11. Figures of the equilibrium set when ω varies ………………………..31, 32, 33
12. Figures of the equilibrium set when τ varies ………………………...34, 35, 36
Abstract
In the classical Cournot oligopoly game, each rival takes the other rivals’ quantities as
given and then produces and sells its profit maximizing quantity on the market. In this
paper, each firm is assumed to incur linear production-adjustment costs if it increases
output from one business period to the next. This analysis addresses the following
questions: 1) What is the best response of the firms with respect to the total outputs of
other producers? And 2) Can an equilibrium condition be reached? Mathematical
descriptions are used to answer these questions and a computer simulation study is
presented to illustrate the conditions of reaching equilibria.
- 2 -
1. Introduction Since Antoine Cournot published his economic masterpiece, Researches into the
Mathematical Principles of Wealth (1838), researchers have spent nearly two
centuries discussing the oligopoly game and its variants. In Cournot’s oligopoly
model, several rival firms produce indistinguishable goods in the same market. Each
firm is aware of that his rival’s quantity decision will impact on the market price.
Thus each firm will choose a quantity independently that will maximize his profit
subject to the quantity selection of the rivals. The decisions of all firms are to be
made simultaneously. It has been proved in Szidarovszky and Yakowitz (1977) that
concave profit function and convex costs are sufficient to guarantee the existence of
equilibrium. In addition, the price function f and all cost functions Ck are twice
differentiable, f is a decreasing function while Ck is an increasing function, f’ + xkf’’
≤ 0 and f’ – Ck’’ < 0 . In this paper I will consider the dynamic Cournot oligopoly
model taking account the additional cost that a firm would encounter when increasing
its level of production to generate larger profit from one business period to the next,
such as buying more equipments or hiring extra workers. This additional production
cost idea has been explored by Howroyd and Rickard (1981), MacLeod (1985),
Reynold (1987) and Driskill and McCafferty (1989). In these papers, continuous
production adjustment cost was assumed. In this paper, I start with the case of
continuous cost adjustment and extend the analysis to discontinuous cost adjustment.
The best responses of the firms are formulated and the equilibrium state is
determined. A simulation program is used to determine the stability condition of the
equilibria and display it graphically.
2. Mathematical Model
Oligopoly is a market form where a few firms have almost total control of selling of
certain products or services. Characteristic oligopolies in the US are the oil,
- 3 -
telecommunication, airline, and automobile industries. Each firm supplies a
sufficiently large share of the market and any changes in price or quality will affect
the market decision of his rivals.
In Cournot’s model, firms compete on quantity and the price function is a decreasing
function of the total output, since the supply-demand balance determines the price.
The goal of each firm is to maximize its profit. The best response of firm k is to find
the production level, xk, that maximizes its profit function, Πk by assuming its
competitors do not change their output from the previous time period. Profit is
defined as the difference between revenue and total cost. Revenue can be derived by
the product of market price and quantity and the total cost is composed of two parts,
the fixed cost and the marginal cost. In the following discussion, the fixed cost refers
to the expenses that do not vary with output such as the rent, advertisement, personnel
(indirect labor) and amortization of capital goods. The marginal cost is the expense
associated with the change in production level by one unit. For example, it includes
the raw material, energy, and personnel directly involved in production. All firms are
aware of the number of firms in the market and take the output of others as given. The
equilibrium existence conditions of this model have been thoroughly examined in the
past.
An additional question arises when the producer needs to change its production level
in order to meet its best response strategy. If the best response production level is
higher than the current level, the producer may need to buy more machinery or hire
more workers. This adjustment causes an additional cost to the company. A sudden
jump of the adjustment cost arises when the company hires a marketing or recruiting
firm, or when the increase in production level requires setup costs. Continuous
adjustment cost which does not consider these factors and does not exhibit a jump at
x(t - 1), the production level at the last time period. This is therefore easier to analyze
than the discontinuous case.
- 4 -
Mathematically, we can model a simple Cournot oligopoly in terms of linear price
and linear cost functions with the output adjustment cost as:
Let 1. x1, …, xn ≡ the individual production levels of the n firms, 0 ≤ xk ≤ Lk, where Lk is the highest possible production level.
2. s = ∑=
n
iix
1 ≡ the total production of all n firms
3. sk = i ki k
x x≠
−∑ ≡ the total production of all other firms than k
4. αk ≡ the fixed cost of production for firm k
5. βk ≡ the marginal cost of production for firm k
6. Ck(xk) = αk + βk xk ≡ the cost function of firm k
7. ωk ≡ the marginal cost of additional production quantity
8. τ k ≡ the jump coefficient/set-up cost of additional production
9. ( ( ) ( 1))kK x t x t− − ≡ the production adjustment cost
in the continuous case: 0 if ( ) ( 1)
( ( ) ( 1))( ( ) ( 1)) otherwise,k
k
x t x tK x t x t
x t x tω≤ −
− − = − −
in the discontinuous case:
0 if ( ) ( 1)
( ( ) ( 1))( ( ) ( 1)) otherwise.k
k k
x t x tK x t x t
x t x tω τ≤ −
− − = − − +
10. f(s) = A – Bs ≡ the market price A, B > 0
In this definition, the cost function of firm k, Ck, is a strictly increasing function of xk.
The price function, f(s), on the other hand is a strictly decreasing function of s. The
profit function of firm k in the case when current production is higher than that in the
previous time period can be expressed as
Profit = Revenue – Cost – Adjustment Production Cost
( ) ( ) ( ( ) ( 1))k k k kx f s C x K x t x tΠ = − − − −
( ) kkkkkkkk txxxBsAx τωβα −−−−−−−= )1()(
- 5 -
( ) kkkkkkkkkk txxxxsBAx τωβα −−−−−−+−= )1()((
kkkkkkkkk txxBsABx τωαωβ −−+−−−−+−= )1()(2 (2.1)
Otherwise, there is no adjustment cost and the profit function is
( ) ( )k k k kx f s C xΠ = −
2 ( )k k k k kBx A Bs xβ α= − + − − − (2.2)
Since the second derivative of the profit function is always negative (2
2k
kB
x∂ Π
= −∂
&
B > 0), it is a strictly concave function in both intervals [0, xk(t - 1)] and [xk(t - 1), Lk].
Therefore there will always be at lease one local maximum in the interval which can
be derived by examining k
kx∂Π∂
. Later I will show that there is a unique maximum
point in the case of continuous adjustment costs and there are at most two maximum
points in the case of discontinuous adjustment costs.
We can then plot the profit-production level graph as shown in Figures 2.1 and 2.2.
- 6 -
For simplicity, firm k’s best responses will be discussed in the case of without jump
and with jump separately.
2.1 Continuous Adjustment Cost (without jump)
Figure 2.1 presents 5 possible cases for best responses given firm k’s production level
in the last time period, xk(t - 1), Figure 2.1 presents 5 possible cases for best responses.
(i) 00 ≤∂Π∂
=kxk
kx
For a strictly concave function, its derivative is
monotonically decreasing. Therefore the non-positive slope
at the starting point means the function will decrease
further after that. There is no other point in the domain with
larger value than at the initial value. Thus, x = 0 is the best response, xk* = 0. This is
the case when kk
As
Bβ−
≥ .
If the slope at x = 0 is positive, then there are two scenarios as discussed in (ii) and (iii)
below.
(ii) 0&0 )1(0 ≤∂Π∂
>∂Π∂
−== txxk
kx
k
kkkk xx
Since the slope at xk = 0 is positive, and negative at xk =
xk(t - 1), furthermore the profit function is a strictly
concave, the maximum has to occur somewhere between xk
= 0 and xk = xk(t - 1). In this region it’s unnecessary to
consider the adjustment cost and therefore it is very similar
to the classical Cournot model. To find the vertex, one may take the first derivative of
the profit function. Since 2 ( )k k k k k kBx A Bs xβ αΠ = − + − − −
- 7 -
equation 0=∂Π∂
k
kx
has the form 02 =−−+− kkk BsABx β
from which we have *2 2
k kk
A sx
Bβ−
= − .
The condition 0 ( 1)0k k k
k kx x x t
k kx x= = −∂Π ∂Π
> ≥∂ ∂
can be rewritten as
0 2 ( 1)k k k k kA Bs Bx t A Bsβ β− − > > − − + − −
or
2 ( 1)k k k kA Bs Bx t Aβ β− > > − − + −
that is,
2 ( 1)k kk k
A As x t
B Bβ β− −
> > − − .
(iii) 0 ( 1)0 & 0k k k
k kx x x t
k kx x= = −∂Π ∂Π
> >∂ ∂
The adjustment production cost produces a significant effect when the best response
is more than the previous production level. There are three possible locations for the
vertices associated with the positive slope at xk(t - 1). Since the function is still
increasing at this point, the maximum should occur either at this point or on its right
hand side.
(a) 0k k
kx L
kx =∂Π
≥∂
If the function is increasing at xk(t - 1) and continues to
increase until the maximum production level, Lk, it is
straightforward that for a concave parabola the global
maximum occurs beyond Lk and the local maximum within
the range from 0 to Lk is at Lk, so xk* = Lk.
Condition (a) can be rewritten as 2k kk k
As LBβ ω− −
≤ − .
- 8 -
(b) 0k k
kx L
kx =∂Π
<∂
Given that the profit function is a strictly concave parabola
and the slope is positive at xk = xk(t -1) and negative at xk =
Lk, the maximum must occur between xk(t - 1) and Lk. One
may find the vertex by solving the first order condition.
In this case,
kkkkkkkkkk txxBsABx )1()(2 −+−−−−+−=Π ωαωβ
Solving 0=∂Π∂
k
kx
, we have equation
02 =−−−+− kkkk BsABx ωβ
so
*2 2
k k kk
A sx
Bβ ω− −
= − .
Condition (b) states ( 1) 0k k k k
k kx x t x L
k kx x= − =∂Π ∂Π
> >∂ ∂
which can be rewritten as
2 ( 1) 0 2k k k k k k k kBx t A Bs BL A Bsβ ω β ω− − + − − − > > − + − − −
or
2 ( 1) 2k k k kk k k
A Ax t s L
B Bβ ω β ω− − − −
− − > > − .
(c) ( ) ( )
0k k k k
k k
k kx x t x x tx x
= − = +
∂Π ∂Π≥ ≥
∂ ∂
Here ( 1)k kx x t= − + denotes the right hand side derivative
at xk(t – 1). If the left side derivative at one point is
nonnegative and the right side derivative is non-positive, by
definition, this point is the maximum. Therefore, xk* =
xk(t – 1).
Again, condition (c) can be rewritten as
- 9 -
2 ( 1) 2 ( 1)k k kk k k
A Ax t s x t
B Bβ β ω− − −
− − > > − − .
The best response xk* versus the total production level of all other firms is shown in
Figure 2.3 with all of the cases described above.
Figure 2.3 Best response function with continuous output adjustment costs
2.2 Discontinuous Adjustment Cost (with jump)
From Figure 2.2, it is clear that scenarios (i) and (ii) have the same best responses as
in the continuous case. In these cases the maximum occurs before the drop/jump of
the profit function and therefore the jump doesn’t affect the best responses. However,
Scenario (iii) needs special attention, since the drop may be large enough so that the
local maximum in (xk(t - 1), Lk) can be smaller than that in (0, xk(t - 1)). There are 9
possible scenarios to be considered. They are as follows:
(i) 00 ≤∂Π∂
=kxk
kx
The same argument applies as in the continuous case,
xk* = 0 if kk
As
Bβ−
≥
- 10 -
(ii) 0&0 )1(0 ≤∂Π∂
>∂Π∂
−== txxk
kx
k
kkkk xx
Also discussed in the continuous case,
22* kk
ks
BA
x −−
=β
when
2 ( 1)k kk k
A As x t
B Bβ β− −
> > − − .
(iii) 0 ( 1)0 & 0k k k
k kx x x t
k kx x= = −∂Π ∂Π
> >∂ ∂
This is the case when the adjustment cost needs to be taken into account in order to
find the best response of each firm. Because there is a jump, one needs to find the
local maximum in both intervals (0, xk(t - 1)) and (xk(t - 1), Lk) and compare the two
optimum values.
(a) 0k k
kx L
kx =∂Π
≥∂
This condition can be expanded as 2k kk k
As LBβ ω− −
≤ − . From the given conditions,
the maximum on the left side of xk = xk(t - 1) is xk(t - 1) and on the right side is Lk. We
have again several cases to consider.
1) Π(xk(t - 1)) > Π (Lk)
In this case, the best response of firm k is xk* = xk(t - 1)
This condition can be rewritten as
2
2
( 1) ( ) ( 1)
( ) ( 1)k k k k k
k k k k k k k k k
Bx t A Bs x t
BL A Bs L x t
β α
β ω α ω τ
− − + − − − − >
− + − − − − + − −
After rearranging the terms, the condition becomes
( ) ( ) ( )2 20 ( 1) ( ) ( 1) ( 1)k k k k k k k k k kB L x t A L x t Bs L x tβ ω τ> − − − + − − − − − − − −
Moving the sk term to the right hand side of the inequality and dividing both sides by
- 11 -
B(Lk - xk(t - 1)) which is always nonnegative, yields
( ) ( )( 1)
( 1)k k k
k k kk k
As L x t
B B L x tβ ω τ− −
> − + − + −+ −
2) Π (xk(t - 1)) < Π (Lk)
The condition can be rewritten as
( ) ( )( 1)
( 1)k k k
k k kk k
As L x t
B B L x tβ ω τ− −
< − + − + −+ −
The best response is therefore xk* = Lk.
3) Π( xk(t - 1)) = Π (Lk)
Two best responses exist xk* = {xk(t - 1), Lk} for
( ) ( )( 1)
( 1)k k k
k k kk k
As L x t
B B L x tβ ω τ− −
= − + − + −+ −
(b) 0k k
kx L
kx =∂Π
<∂
In terms of sk, the condition is 2k kk k
As LBβ ω− −
> − .
The maximum on the left side of xk = xk(t - 1) is xk(t - 1) and in order to find the
maximum in (xk(t - 1), Lk ) we need to solve the first order condition. Since
kΠ kkkkkkkkk txxBsABx τωαωβ −−+−−−−+−= )1()(2 ,
the first order condition is
02 =−−−+− kkkk BsABx ωβ
or
2 2c k k kk
A sx
Bβ ω− −
= −
Again, one needs to compare the two local maximum values.
- 12 -
1) Π (xk(t - 1)) > Π( xkc)
Rewriting the condition in terms of sk
( ( 1) ) ( 1)
( ) ( 1)k k k k kc ck k k k k k k k k
A Bx t Bs x t
A Bx Bs x x t
β α
β ω α ω τ
− − − − − − >
− − − − − + − −
or
0 ( ) ( ( 1) ) ( 1)c ck k k k k k k k k k kA Bx Bs x A Bx t Bs x tβ ω τ β ω> − − − − − − − − − − − −
Substituting ckx value into this relation:
0 ( )2 2 2 2
( ( 1) ) ( 1) .
k k k k k kk k k
k k k k k k
A Bs A sA Bs
BA Bx t Bs x t
β ω β ωβ ω
β ω τ
− − − − > − − − − − −
− − − − − − − −
Rearranging terms on the left of the inequality, we get 2
20 2 ( 1) ( 1)2 2 2 2
k k k k k kk k k
A s A sB Bx t Bx t
B Bβ ω β ω
τ− − − − > − − − − + − −
or 2
0 ( 1)2 2
k k kk k
A sB x t
Bβ ω
τ− − > − − − −
or
2 ( 1) 2k k kk k
As x t
B Bβ ω τ− −
> − − − .
The best response is xk* = xk(t - 1).
2) Π (xk(t - 1)) < Π (xkc)
The best response is 22
* kkkk
sB
Ax −
−−=
ωβ,
and this is the case when
2 ( 1) 2k k kk k
As x t
B Bβ ω τ− −
< − − − .
- 13 -
3) Π (xk(t - 1) = Π (xkc)
In the case there are two best responses of firm k:
* , ( 1)2 2
k k kk k
A sx x t
Bβ ω− − = − −
,
with the condition
2 ( 1) 2k k kk k
As x t
B Bβ ω τ− −
= − − − .
Condition (b) can be rewritten as
2 ( 1) 2k k k kk k k
A Ax t s L
B Bβ ω β ω− − − −
− − > > − .
(c) ( ) ( )
0 .k k k k
k k
k kx x t x x tx xπ π
= − = +
∂ ∂≥ ≥
∂ ∂
In this case the maximum profit occurs at xk(t - 1) and the
jump does not affect the best response:
xk* = xk(t - 1).
The above condition is equivalent to
2 ( 1) 2 ( 1)k k kk k k
A Ax t s x t
B Bβ β ω− − −
− − > > − − .
Because of scenario (iiia1), (iiib2) and (iiib3), the form of the best response depends
on the relationship between ( 1)k kL x t− − and kBτ
.
If ( 1) kk kL x t
Bτ
− − > , the best response is shown in Figure 2.4,
- 14 -
Figure 2.4 Best response with discontinuous output adjustment costs in the first case
On the other hand, if ( 1) kk kL x t
Bτ
− − < , the best response is shown in Figure 2.5.
Figure 2.5 Best response with discontinuous output adjustment costs in the second case
- 15 -
3. Best Response Dynamics and its Equilibrium
An output vector * *1( , , )nx xK is a steady state (or equilibrium) if and only if for all k ,
*kx is a best response of firm k with given *
k ll k
s x≠
= ∑ . That is, when
* *0 00
k k k k
k kx x x xk kx x= + = +
∂Π ∂Π≤ ≤
∂ ∂ (3.1)
If * 0kx = , then only the left hand side of the relation is required, and in the case of
*k kx L= , only the right hand side is needed. Equation (3.1) can be rewritten as
*k
k k kA As x s
B Bβ ω β− − −
− < < − (3.2)
with the additional constraint *0 k kx L≤ ≤ .
There are usually infinitely many equilibria which forms a polyhedron. We can
examine this by a simple duopoly example with continuous output adjustment costs.
Let A = 20, B = 1, L1 = L2 = 10, β1 = β2 = ω1 = ω2 = 5. From (3.2), one can derive the
equilibrium condition
1 2 1,2 1 210 ( ) 15 ( )x x x x x− + ≤ ≤ − + .
The equilibrium set is shown in Figure 3.1.
Figure 3.1 Equilibrium set of the example
- 16 -
4. Simulation Study
Because there are infinitely many equilibria instead of a single point, it is very
difficult to find out the stability conditions analytically. In order to resolve this issue,
it is necessary to study the Cournot’s Oligopoly model with adjustment costs using a
computer simulation. I modified Matt Dabkowski’s Duopoly Basin Calculator which
is a deployable Windows program written in C++ to fit the context of this paper. In
addition to the original input parameters, A, B, βx, βy, Lx, Ly, I added ωx, ωy, τx, τy,
which are the parameters associated with the additional adjustment output cost.
Meanwhile the speed of adjustment and the cost effective threshold coefficients are
disregarded since they are not of concern in this paper. What this program does is to
iterate all possible initial production levels (x0, y0) within the domain ([0, Lx] x [0, Ly])
to find the corresponding equilibria. These initial values are increment by a suitable
small, uniform step size. The number of steps for each starting point to converge to
the equilibrium is then categorized and plotted by different colors- yellow represent
one step, blue represent 2 to 10 steps, green represent 11 to 50 steps and fuchsia is
more than 50 steps. Therefore it is visually easy to tell from the resulting plot whether
the system is globally and asymptotically stable, and how fast is the convergence. A
snapshot of the duopoly basin calculator is shown in Figure 4.1.
During each iteration step, t = 1, 2, …, with the given initial production level (x0, y0),
the program search for the local maximum within the two intervals (0, xk(t - 1)) and
(xk(t - 1), Lk). After comparing the maximum values, the program then chooses the
one with the higher value or if the two values are equal, then the smaller production
output is chosen as the production level for the next time period. This process is
repeated until the next production level is below 0.0001.
I used the example introduced in the previous section to assign the following values
to the simulation: A = 20, B = 1, Lx = Ly = 10, βx = βy = ωx = ωy = 5, τx = τy = 0. The
- 17 -
resulting plot is shown in Figure 4.2. The red lines defines the theoretical boundary of
the equilibrium set (3.2). Notice that the equilibrium set matches with the analytical
result shown in Figure 3.1. Moreover, it determines the average speed of convergence
to the equilibria in the specified domain. In this case, it takes an average of 2.975
steps for the program to converge, given a step size of 0.03 and 100 iterations in each
step.
Figure 4.1 Snapshot of the Duopoly Basin Calculator Program
- 18 -
Figure 4.2 Output of the equilibrium set for the example
A detailed sensitivity analysis is thus performed in two stages. In the first stage, no
jump in the additional cost function is assumed, and the parameters A, B, ωx = ωy and
βx = βy are systematically varied. The results are shown in Figures 4.3 to 4.18. In the
second stage, the discontinuous output adjustment cost is applied. These results are
shown in Figure 4.26 to 4.30.
4.1 Continuous Adjustment Cost
I. A changes from 20, 25, 30, 35 to 40.
- 19 -
Figure 4.3 Equilibrium set when A = 20
Figure 4.4 Equilibrium set when A = 25
- 20 -
Figure 4.5 Equilibrium set when A = 30
Figure 4.6 Equilibrium set when A = 35
- 21 -
Figure 4.7 Equilibrium set when A = 40
As the value of A increases from 20 to 40, the size of the equilibrium set does not
change but the yellow area shifts away from, and out of the feasible region. The green
areas are also displaced from the feasible region. Therefore the number of iterations
to convergence first decreases and then increases as the equilibrium set moves beyond
the feasible region.
II. B changes from 0.1, 0.3, 0.5, 0.8, 1.
- 22 -
Figure 4.8 Equilibrium set when B = 0.1
Figure 4.9 Equilibrium set when B = 0.3
- 23 -
Figure 4.10 Equilibrium set when B = 0.5
Figure 4.11 Equilibrium set when B = 0.7
- 24 -
Figure 4.12 Equilibrium set when B = 0.9
From Figure 4.8 to 4.12 we can see that the size of the equilibrium set decreases as B
increases which means the average steps towards convergence increases. However,
the equilibrium set is not in the feasible region initially and later moves into it. This is
why the convergence rate increases and decreases again when the green areas move
into the window.
III. β changes from 1, 3, 5, 7, 9.
- 25 -
Figure 4.13 Equilibrium set when β = 1
Figure 4.14 Equilibrium set when β = 3
- 26 -
Figure 4.15 Equilibrium set when β = 5
Figure 4.16 Equilibrium set when β = 7
- 27 -
Figure 4.17 Equilibrium set when β = 9
We observe that when the marginal cost increases, the size of the equilibrium set is
unchanged and the green area moves out of the feasible region. The convergence rate
is therefore faster.
IV. L changes from 2, 4, 6, 8, 10.
- 28 -
Figure 4.18 Equilibrium set when L =2
Figure 4.19 Equilibrium set when L = 4
- 29 -
Figure 4.19 Equilibrium set when L = 6
Figure 4.19 Equilibrium set when L = 8
- 30 -
Figure 4.20 Equilibrium set when L = 10
Notice the size of the window changes here since the feasible region is defined by the
maximum production level. The number of steps to convergence first decreases when
the equilibrium set moves into the window. Later it increases again when the green
areas appear.
V. ω changes from 1, 3, 5, 7, 9.
- 31 -
Figure 4.21 Equilibrium set when ω = 1
Figure 4.22 Equilibrium set when ω = 3
- 32 -
Figure 4.23 Equilibrium set when ω = 5
Figure 4.24 Equilibrium set when ω = 7
- 33 -
Figure 4.25 Equilibrium set when ω = 9
The size of the equilibrium set grows from Figure 4.21 to Figure 4.25. The green
areas decrease in size and moves out of the feasible region as ω increases in value.
The convergence rate is faster when the marginal cost of additional production
increases.
4.2 Discontinuous Adjustment Cost
The equilibrium condition representing the case when the output adjustment cost is
discontinuous is simulated in Figures 4.26 to 4.30. This case shows the equilibrium
sets when A = 20, B = 1, Lx = Ly = 10, βx = βy = ωx = ωy = 5, while the jump
coefficients τx = τy vary from 0.1, 0.5, 1, 1.5 to 1.9.
- 34 -
Figure 4.26 Equilibrium set when τ = 0.1
Figure 4.27 Equilibrium set when τ = 0.5
- 35 -
Figure 4.28 Equilibrium set when τ =1
Figure 4.29 Equilibrium set when τ = 1.5
- 36 -
Figure 4.30 Equilibrium set when τ = 1.9
In this case, the size of the equilibrium set increases as the value of τ increases.
Therefore the rate of convergence is faster.
5. Summary
N-firm single product oligopolies were examined without product differentiation and
with production adjustment cost. The best response function of the firms were first
determined in terms of the outputs of the rest of the industry and the firm’s own
outputs of the previous time period. This function is always decreasing, not
necessarily continuous, and might have two different values. We showed that this
function might have infinitely many values leading to infinitely many equilibria. A
complete description of the equilibrium set was also given. A detailed simulation
study shows the sensitivity of the equilibrium set and that of the convergence speed
on model parameters. In this study the price and cost function were all linear. The
corresponding nonlinear cases will be the subject of my future research.
- 37 -
References
Cournot, A. (1838), Recherches sur les Principles Mathematiques de la Theorie de
Richessess. Hachette, Paris. (English translation (1960): Researches into the
Mathematical Principles of the Theory of Wealth. Kelly, New York).
Dabkowski, M. (2007) When the best response is not the Best Decision. MS report,
System and Industrial Engineering Department, the University of Arizona, Tucson,
Arizona.
Okuguchi, K. (1976) Expectations and Stability in Oligopoly Models. Springer-
Verlag, Berlin/Heidelberg/New York.
Okuguchi, K. and F. Szidarovszky (1999) The Theory of Oligopoly with Multiproduct
Firms. Springer-Verlag, Berlin/Heidelberg/New York.
Reynolds, S.S. (1991) Dynamic Oligopoly with Capacity Adjustment Costs. J. of
Econ. Dynamics and Control 15, 419-514.
Szidarovszky, F., and J. Yen (1995) Dynamic Cournot Oligopoly with Production
Adjustment Costs. J. Math. Econ. 24, 95-101.
Szidarovszky, F., and S. Yakowitz (1982) Contributions to Cournot Oligopoly Theory.
J. Econ. Theory. 28, 51-70.
Szidarovszky, F. (2008) Submitted for publication.
- 38 -
Appendix
C++ code for Duopoly Basin Calculator
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Duopoly_Basin_Form.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Generate_Basin_ButtonClick(TObject *Sender)
{
// Copy the Edit Box Entries into the Model's Parameters
UpdateParameters();
if (status == 0)
return;
// Clear the current data arrays and erase the existing chart titles
ClearSeriesAndTitles();
Basin_Of_Attraction_Chart->Title->Text->Add( "Duopoly Basin Of Attraction");
Basin_Of_Attraction_Chart->SubTitle->Text->Add("Color = Steps to Convergence:"
" Yellow = 1, Blue = 2-10, Green = 11-50, Fuchsia = >50");
Basin_Of_Attraction_Chart->Foot->Text->Add( "Number of Iterations per Step = " +
FloatToStr(Number_Iterations) + ", Step Size = " + FloatToStr(Step_Size) +
- 39 -
", Convergence Threshold = " + FloatToStr(Threshold));
ProgressBar1->Max=((X_Max-X_Min)/Step_Size)*((Y_Max-Y_Min)/Step_Size);
ProgressBar1->Step=1;
ProgressBar1->Position=ProgressBar1->Min; // this starts the bar at the Min
if (Price_Function == 1) { // the Price Function is Linear
Basin_Of_Attraction_Chart->Title->Text->Add("(Linear Price Function)");
Basin_Of_Attraction_Chart->Title->Text->Add( "A = " + FloatToStr(A) +
", B = " + FloatToStr(B) + ", bx = " + FloatToStr(beta_x) +
", by = " + FloatToStr(beta_y) + ", ox = " + FloatToStr(omega_x) +
", oy = " + FloatToStr(omega_y) + ", tx = " + FloatToStr(tau_x) +
", ty = " + FloatToStr(tau_y) + ", Kx = " + FloatToStr(Kx) +
", Ky = " + FloatToStr(Ky));
if (tau_x != 0 || tau_y != 0) {
// SERIES2 (Line Series): firm x's top line; draw it
if ((A-beta_x)/B<L_y) {
Series2->AddXY(0, (A-beta_x)/B, NULL, clRed);
Series2->AddXY((A-beta_x)/(2*B), 0, NULL, clRed);
}
else
Series2->AddXY(0,(A-beta_x)/B, NULL, clRed);
Series2->AddXY(((A-beta_x)/B-L_y)/2,L_y, NULL, clRed);
Series2->AddXY((A-beta_x)/(2*B),0, NULL, clRed);
if ((A-beta_x)/(2*B)>L_x)
Series2->AddXY(L_x,((A-beta_x)/B)-2*L_x, NULL, clRed);
// SERIES3 (Line Series): firm x's bottom line; draw it
if ((A-beta_x-omega_x)/B-2*sqrt(tau_x/B)<L_y) {
Series3->AddXY(0, (A-beta_x-omega_x)/B-2*sqrt(tau_x/B), NULL, clRed);
Series3->AddXY((A-beta_x-omega_x)/(2*B)-sqrt(tau_x/B), 0, NULL, clRed);
- 40 -
}
else
Series3->AddXY(0,(A-beta_x-omega_x)/B-2*sqrt(tau_x/B), NULL, clRed);
Series3->AddXY(((A-beta_x-omega_x)/B-L_y)/2-sqrt(tau_x/B),L_y, NULL, clRed);
Series3->AddXY((A-beta_x-omega_x)/(2*B)-sqrt(tau_x/B),0, NULL, clRed);
if ((A-beta_x-omega_x)/(2*B)-sqrt(tau_x/B)>L_x)
Series3->AddXY(L_x,((A-beta_x-omega_x)/B)-2*L_x-2*sqrt(tau_x/B), NULL,
clRed);
// SERIES4 (Line Series): firm y's top line; draw it
if ((A-beta_y)/B<L_x) {
Series4->AddXY((A-beta_y)/B,0, NULL, clRed);
Series4->AddXY(0,(A-beta_y)/(2*B), NULL, clRed);
}
else
Series4->AddXY((A-beta_y)/B,0, NULL, clRed);
Series4->AddXY(L_x,((A-beta_y)/B-L_x)/2, NULL, clRed);
Series4->AddXY(0,(A-beta_y)/(2*B), NULL, clRed);
if ((A-beta_y)/(2*B)>L_y)
Series4->AddXY(((A-beta_y)/B)-2*L_y, L_y, NULL, clRed);
// SERIES5 (Line Series): firm y's bottom line; draw it
if ((A-beta_y-omega_y)/B-2*sqrt(tau_y/B)<L_x) {
Series5->AddXY((A-beta_y-omega_y)/B-2*sqrt(tau_y/B),0, NULL, clRed);
Series5->AddXY(0,(A-beta_y-omega_y)/(2*B)-sqrt(tau_y/B), NULL, clRed);
}
else
Series5->AddXY((A-beta_y-omega_y)/B-2*sqrt(tau_y/B), 0, NULL, clRed);
Series5->AddXY(L_x,((A-beta_y-omega_y)/B-L_x)/2-sqrt(tau_y/B), NULL, clRed);
Series5->AddXY(0,(A-beta_y-omega_y)/(2*B)-sqrt(tau_y/B), NULL, clRed);
if ((A-beta_y-omega_y)/(2*B)-sqrt(tau_y/B)>L_y)
- 41 -
Series5->AddXY(((A-beta_y-omega_y)/B)-2*L_y-2*sqrt(tau_y/B),L_y, NULL, clRed);
}
else {
// SERIES2 (Line Series): firm x's top line; draw it
if ((A-beta_x)/B<L_y) {
Series2->AddXY(0, (A-beta_x)/B, NULL, clRed);
Series2->AddXY((A-beta_x)/(2*B), 0, NULL, clRed);
}
else
Series2->AddXY(0,(A-beta_x)/B, NULL, clRed);
Series2->AddXY(((A-beta_x)/B-L_y)/2,L_y, NULL, clRed);
Series2->AddXY((A-beta_x)/(2*B),0, NULL, clRed);
if ((A-beta_x)/(2*B)>L_x)
Series2->AddXY(L_x,((A-beta_x)/B)-2*L_x, NULL, clRed);
// SERIES3 (Line Series): firm x's bottom line; draw it
if ((A-beta_x-omega_x)/B<L_y) {
Series3->AddXY(0, (A-beta_x-omega_x)/B, NULL, clRed);
Series3->AddXY((A-beta_x-omega_x)/(2*B), 0, NULL, clRed);
}
else
Series3->AddXY(0,(A-beta_x-omega_x)/B, NULL, clRed);
Series3->AddXY(((A-beta_x-omega_x)/B-L_y)/2,L_y, NULL, clRed);
Series3->AddXY((A-beta_x-omega_x)/(2*B),0, NULL, clRed);
if ((A-beta_x-omega_x)/(2*B)>L_x)
Series3->AddXY(L_x,((A-beta_x-omega_x)/B)-2*L_x, NULL, clRed);
// SERIES4 (Line Series): firm y's top line; draw it
if ((A-beta_y)/B<L_x) {
Series4->AddXY((A-beta_y)/B,0, NULL, clRed);
Series4->AddXY(0,(A-beta_y)/(2*B), NULL, clRed);
- 42 -
}
else
Series4->AddXY((A-beta_y)/B,0, NULL, clRed);
Series4->AddXY(L_x,((A-beta_y)/B-L_x)/2, NULL, clRed);
Series4->AddXY(0,(A-beta_y)/(2*B), NULL, clRed);
if ((A-beta_y)/2*B>L_y)
Series4->AddXY(((A-beta_y)/B)-2*L_y, L_y, NULL, clRed);
// SERIES5 (Line Series): firm y's bottom line; draw it
if ((A-beta_y-omega_y)/B<L_x) {
Series5->AddXY((A-beta_y-omega_y)/B,0, NULL, clRed);
Series5->AddXY(0,(A-beta_y-omega_y)/(2*B), NULL, clRed);
}
else
Series5->AddXY((A-beta_y-omega_y)/B, 0, NULL, clRed);
Series5->AddXY(L_x,((A-beta_y-omega_y)/B-L_x)/2, NULL, clRed);
Series5->AddXY(0,(A-beta_y-omega_y)/(2*B), NULL, clRed);
if ((A-beta_y-omega_y)/(2*B)>L_y)
Series5->AddXY(((A-beta_y-omega_y)/B)-2*L_y,L_y, NULL, clRed);
}
// the actual simulation code
long int count;
double x0, y0, xt, yt, xt_1, yt_1, vert_x1, vert_x2, vert_y1, vert_y2, max_x1, max_x2,
max_y1, max_y2, RHS_x, LHS_x, RHS_y, LHS_y;
bool CONVERGENCE;
for (y0 = Y_Min; y0 <=Y_Max; y0 = y0 + Step_Size) {
for (x0 = X_Min; x0 <=X_Max; x0 = x0 + Step_Size) {
Total_Runs = Total_Runs + 1;
for (count = 1; count <= Number_Iterations; count++) {
- 43 -
if (count == 1) { // assign the initial xt and yt values
xt = x0;
yt = y0;
CONVERGENCE = false;
}
/* determine whether firm x changes its production level in the next time
period, and (if it does) make the appropriate adjustment; o/w no change */
/* find the vertex of the parabola between 0 to xt */
vert_x1 = (A-beta_x)/(2*B)-yt/2;
if (vert_x1 < 0)
max_x1 = 0;
else if (vert_x1 > xt)
max_x1 = xt;
else
max_x1 = vert_x1;
/* find the vertex of the parabola between xt to Lx */
vert_x2 = (A-beta_x-omega_x)/(2*B)-yt/2;
if (vert_x2 < xt)
max_x2 = xt;
else if (vert_x2 > L_x)
max_x2 = L_x;
else
max_x2 = vert_x2;
/*Calculate the profit of each vertex and the solution is the production level that
generates more profit*/
RHS_x = max_x1*(A-B*(max_x1+yt))-alpha_x-beta_x*max_x1;
LHS_x = max_x2*(A-B*(max_x2+yt))-alpha_x-beta_x*max_x2-omega_x*(max_x2-
xt)-tau_x;
if (RHS_x < LHS_x)
- 44 -
xt_1 = max_x2;
else
xt_1 = max_x1;
/* determine whether firm y changes its production level in the next time
period, and (if it does) make the appropriate adjustment; o/w no change */
/* find the vertex of the parabola between 0 to yt */
vert_y1 = (A-beta_y)/(2*B)-xt/2;
if (vert_y1 < 0)
max_y1 = 0;
else if (vert_y1 > yt)
max_y1 = yt;
else
max_y1 = vert_y1;
/* find the vertex of the parabola between yt to Ly */
vert_y2 = (A-beta_y-omega_y)/(2*B)-xt/2;
if (vert_y2 < yt)
max_y2 = yt;
else if (vert_y2 > L_y)
max_y2 = L_y;
else
max_y2 = vert_y2;
/*Calculate the profit of each vertex and the solution is the production level that
generates more profit*/
RHS_y = max_y1*(A-B*(max_y1+xt))-alpha_y-beta_y*max_y1;
LHS_y = max_y2*(A-B*(max_y2+xt))-alpha_y-beta_y*max_y2-omega_y*(max_y2-
yt)-tau_y;
if (RHS_y < LHS_y)
yt_1 = max_y2;
else
- 45 -
yt_1 = max_y1;
// determine whether the duopoly has convergened to an equilibrium
if ((fabs(xt - xt_1) <= Threshold) && (fabs(yt - yt_1) <= Threshold)) {
CONVERGENCE = true; // the duopoly has converged
break;
}
else { // the duopoloy has not converged; update xt & yt and continue
xt = xt_1;
yt = yt_1;
}
} // end for count
if (CONVERGENCE == true) { // plot x0 and y0 to the Basin
Convergent_Runs = Convergent_Runs + 1;
Total_Convergent_Steps = Total_Convergent_Steps + count;
if (count == 1) // x0 and y0 are in the basin
Series1->AddXY(x0, y0, NULL, clYellow);
else if (count > 1 && count <= 10)
Series1->AddXY(x0, y0, NULL, clBlue);
else if (count > 10 && count <= 50)
Series1->AddXY(x0, y0, NULL, clLime);
else
Series1->AddXY(x0, y0, NULL, clFuchsia);
}
ProgressBar1->StepIt();
} // end for x0
} // end for y0
- 46 -
Relative_Basin_Size = Convergent_Runs / Total_Runs;
Relative_Size_Result_Label->Caption = FloatToStrF(Relative_Basin_Size,
ffGeneral, 4, 4);
Mean_Convergent_Steps = Total_Convergent_Steps / Convergent_Runs;
Mean_Steps_Result_Label->Caption = FloatToStrF(Mean_Convergent_Steps,
ffGeneral, 4, 4);
} // end if (Price_Function == 1)
else { // the Price Function is Hyperbolic
//To be implemented
} // end Price Function is Hyperbolic
ProgressBar1->Position=ProgressBar1->Max;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Copy_Chart_ButtonClick(TObject *Sender)
{
Basin_Of_Attraction_Chart->CopyToClipboardMetafile(True);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Plot_Trajectory_ButtonClick(TObject *Sender)
{
// Copy the Edit Box Entries into the Model's Parameters
UpdateParameters();
if (status == 0)
return;
// Clear the current data arrays and erase the existing chart titles
ClearSeriesAndTitles();
Basin_Of_Attraction_Chart->Title->Text->Add( "Convergence Trajectory" );
Basin_Of_Attraction_Chart->SubTitle->Text->Add("X Seed = " + FloatToStr(X_Seed)
- 47 -
+ ", Y Seed = " + FloatToStr(Y_Seed));
Basin_Of_Attraction_Chart->Foot->Text->Add( "Maximum Number of Iterations = " +
FloatToStr(Number_Iterations) + ", Step Size = " + FloatToStr(Step_Size) +
", Convergence Threshold = " + FloatToStr(Threshold));
ProgressBar1->Max=Number_Iterations;
ProgressBar1->Step=1;
ProgressBar1->Position=ProgressBar1->Min; // this starts the bar at the Min
if (Price_Function == 1) { // the Price Function is Linear
Basin_Of_Attraction_Chart->Title->Text->Add("(Linear Price Function)");
Basin_Of_Attraction_Chart->Title->Text->Add( "A = " + FloatToStr(A) +
", B = " + FloatToStr(B) + ", bx = " + FloatToStr(beta_x) +
", by = " + FloatToStr(beta_y) + ", ox = " + FloatToStr(omega_x) +
", oy = " + FloatToStr(omega_y) + ", tx = " + FloatToStr(tau_x) +
", ty = " + FloatToStr(tau_y) + ", Kx = " + FloatToStr(Kx) +
", Ky = " + FloatToStr(Ky));
if (tau_x != 0 || tau_y != 0) {
// SERIES2 (Line Series): firm x's top line; draw it
if ((A-beta_x)/B<L_y) {
Series2->AddXY(0, (A-beta_x)/B, NULL, clRed);
Series2->AddXY((A-beta_x)/(2*B), 0, NULL, clRed);
}
else
Series2->AddXY(0,(A-beta_x)/B, NULL, clRed);
Series2->AddXY(((A-beta_x)/B-L_y)/2,L_y, NULL, clRed);
Series2->AddXY((A-beta_x)/(2*B),0, NULL, clRed);
if ((A-beta_x)/(2*B)>L_x)
Series2->AddXY(L_x,((A-beta_x)/B)-2*L_x, NULL, clRed);
- 48 -
// SERIES3 (Line Series): firm x's bottom line; draw it
if ((A-beta_x-omega_x)/B-2*sqrt(tau_x/B)<L_y) {
Series3->AddXY(0, (A-beta_x-omega_x)/B-2*sqrt(tau_x/B), NULL, clRed);
Series3->AddXY((A-beta_x-omega_x)/(2*B)-sqrt(tau_x/B), 0, NULL, clRed);
}
else
Series3->AddXY(0,(A-beta_x-omega_x)/B-2*sqrt(tau_x/B), NULL, clRed);
Series3->AddXY(((A-beta_x-omega_x)/B-L_y)/2-sqrt(tau_x/B),L_y, NULL, clRed);
Series3->AddXY((A-beta_x-omega_x)/(2*B)-sqrt(tau_x/B),0, NULL, clRed);
if ((A-beta_x-omega_x)/(2*B)-sqrt(tau_x/B)>L_x)
Series3->AddXY(L_x,((A-beta_x-omega_x)/B)-2*L_x-2*sqrt(tau_x/B), NULL,
clRed);
// SERIES4 (Line Series): firm y's top line; draw it
if ((A-beta_y)/B<L_x) {
Series4->AddXY((A-beta_y)/B,0, NULL, clRed);
Series4->AddXY(0,(A-beta_y)/(2*B), NULL, clRed);
}
else
Series4->AddXY((A-beta_y)/B,0, NULL, clRed);
Series4->AddXY(L_x,((A-beta_y)/B-L_x)/2, NULL, clRed);
Series4->AddXY(0,(A-beta_y)/(2*B), NULL, clRed);
if ((A-beta_y)/(2*B)>L_y)
Series4->AddXY(((A-beta_y)/B)-2*L_y, L_y, NULL, clRed);
// SERIES5 (Line Series): firm y's bottom line; draw it
if ((A-beta_y-omega_y)/B-2*sqrt(tau_y/B)<L_x) {
Series5->AddXY((A-beta_y-omega_y)/B-2*sqrt(tau_y/B),0, NULL, clRed);
- 49 -
Series5->AddXY(0,(A-beta_y-omega_y)/(2*B)-sqrt(tau_y/B), NULL, clRed);
}
else
Series5->AddXY((A-beta_y-omega_y)/B-2*sqrt(tau_y/B), 0, NULL, clRed);
Series5->AddXY(L_x,((A-beta_y-omega_y)/B-L_x)/2-sqrt(tau_y/B), NULL, clRed);
Series5->AddXY(0,(A-beta_y-omega_y)/(2*B)-sqrt(tau_y/B), NULL, clRed);
if ((A-beta_y-omega_y)/(2*B)-sqrt(tau_y/B)>L_y)
Series5->AddXY(((A-beta_y-omega_y)/B)-2*L_y-2*sqrt(tau_y/B),L_y, NULL, clRed);
}
else {
// SERIES2 (Line Series): firm x's top line; draw it
if ((A-beta_x)/B<L_y) {
Series2->AddXY(0, (A-beta_x)/B, NULL, clRed);
Series2->AddXY((A-beta_x)/(2*B), 0, NULL, clRed);
}
else
Series2->AddXY(0,(A-beta_x)/B, NULL, clRed);
Series2->AddXY(((A-beta_x)/B-L_y)/2,L_y, NULL, clRed);
Series2->AddXY((A-beta_x)/(2*B),0, NULL, clRed);
if ((A-beta_x)/(2*B)>L_x)
Series2->AddXY(L_x,((A-beta_x)/B)-2*L_x, NULL, clRed);
// SERIES3 (Line Series): firm x's bottom line; draw it
if ((A-beta_x-omega_x)/B<L_y) {
Series3->AddXY(0, (A-beta_x-omega_x)/B, NULL, clRed);
Series3->AddXY((A-beta_x-omega_x)/(2*B), 0, NULL, clRed);
}
else
Series3->AddXY(0,(A-beta_x-omega_x)/B, NULL, clRed);
Series3->AddXY(((A-beta_x-omega_x)/B-L_y)/2,L_y, NULL, clRed);
Series3->AddXY((A-beta_x-omega_x)/(2*B),0, NULL, clRed);
- 50 -
if ((A-beta_x-omega_x)/(2*B)>L_x)
Series3->AddXY(L_x,((A-beta_x-omega_x)/B)-2*L_x, NULL, clRed);
// SERIES4 (Line Series): firm y's top line; draw it
if ((A-beta_y)/B<L_x) {
Series4->AddXY((A-beta_y)/B,0, NULL, clRed);
Series4->AddXY(0,(A-beta_y)/(2*B), NULL, clRed);
}
else
Series4->AddXY((A-beta_y)/B,0, NULL, clRed);
Series4->AddXY(L_x,((A-beta_y)/B-L_x)/2, NULL, clRed);
Series4->AddXY(0,(A-beta_y)/(2*B), NULL, clRed);
if ((A-beta_y)/2*B>L_y)
Series4->AddXY(((A-beta_y)/B)-2*L_y, L_y, NULL, clRed);
// SERIES5 (Line Series): firm y's bottom line; draw it
if ((A-beta_y-omega_y)/B<L_x) {
Series5->AddXY((A-beta_y-omega_y)/B,0, NULL, clRed);
Series5->AddXY(0,(A-beta_y-omega_y)/(2*B), NULL, clRed);
}
else
Series5->AddXY((A-beta_y-omega_y)/B, 0, NULL, clRed);
Series5->AddXY(L_x,((A-beta_y-omega_y)/B-L_x)/2, NULL, clRed);
Series5->AddXY(0,(A-beta_y-omega_y)/(2*B), NULL, clRed);
if ((A-beta_y-omega_y)/(2*B)>L_y)
Series5->AddXY(((A-beta_y-omega_y)/B)-2*L_y,L_y, NULL, clRed);
}
// the actual simulation code
int count;
- 51 -
double x0, y0, xt, yt, xt_1, yt_1, vert_x1, vert_x2, vert_y1, vert_y2, max_x1, max_x2,
max_y1, max_y2, RHS_x, LHS_x, RHS_y, LHS_y;
bool CONVERGENCE;
for (count = 1; count <= Number_Iterations; count++) {
// assign the initial xt and yt values
if (count == 1) {
xt = X_Seed;
yt = Y_Seed;
Series6->AddXY(xt, yt, IntToStr(0), clAqua);
CONVERGENCE = false;
}
/* determine whether firm x changes its production level in the next time
period, and (if it does) make the appropriate adjustment; o/w no change */
/* find the vertex of the parabola between 0 to xt */
vert_x1 = (A-beta_x)/(2*B)-yt/2;
if (vert_x1 < 0)
max_x1 = 0;
else if (vert_x1 > xt)
max_x1 = xt;
else
max_x1 = vert_x1;
/* find the vertex of the parabola between xt to Lx */
vert_x2 = (A-beta_x-omega_x)/(2*B)-yt/2;
if (vert_x2 < xt)
max_x2 = xt;
else if (vert_x2 > L_x)
max_x2 = L_x;
else
- 52 -
max_x2 = vert_x2;
/*Calculate the profit of each vertex and the solution is the production level that
generates more profit*/
RHS_x = max_x1*(A-B*(max_x1+yt))-alpha_x-beta_x*max_x1;
LHS_x = max_x2*(A-B*(max_x2+yt))-alpha_x-beta_x*max_x2-omega_x*(max_x2-
xt)-tau_x;
if (RHS_x < LHS_x)
xt_1 = max_x2;
else
xt_1 = max_x1;
/* determine whether firm y changes its production level in the next time
period, and (if it does) make the appropriate adjustment; o/w no change */
/* find the vertex of the parabola between 0 to yt */
vert_y1 = (A-beta_y)/(2*B)-xt/2;
if (vert_y1 < 0)
max_y1 = 0;
else if (vert_y1 > yt)
max_y1 = yt;
else
max_y1 = vert_y1;
/* find the vertex of the parabola between yt to Ly */
vert_y2 = (A-beta_y-omega_y)/(2*B)-xt/2;
if (vert_y2 < yt)
max_y2 = yt;
else if (vert_y2 > L_y)
max_y2 = L_y;
else
max_y2 = vert_y2;
- 53 -
/*Calculate the profit of each vertex and the solution is the production level that
generates more profit*/
RHS_y = max_y1*(A-B*(max_y1+xt))-alpha_y-beta_y*max_y1;
LHS_y = max_y2*(A-B*(max_y2+xt))-alpha_y-beta_y*max_y2-omega_y*(max_y2-
yt)-tau_y;
if (RHS_y < LHS_y)
yt_1 = max_y2;
else
yt_1 = max_y1;
// determine whether the duopoly has converged to an equilibrium
if ((fabs(xt - xt_1) <= Threshold) && (fabs(yt - yt_1) <= Threshold)) {
CONVERGENCE = true; // the duopoly has converged
break;
}
else { // the duopoloy has not converged; update xt & yt and continue
xt = xt_1;
yt = yt_1;
Series6->AddXY(xt, yt, IntToStr(count), clAqua);
}
} // end for count
if (CONVERGENCE == true) {
if (count == 1)
; // do not overwrite the "0" box
else
Series6->AddXY(xt_1, yt_1, IntToStr(count-1), clAqua);
}
ProgressBar1->StepIt();
Basin_Of_Attraction_Chart->SubFoot->Text->Add( "Number of Iterations = " +
FloatToStr(count-1));
ProgressBar1->Position=ProgressBar1->Max;
- 54 -
} // end if (Price_Function == 1)
else { // the Price Function is Hyperbolic
//To be developed
} // end the Price Function is Hyperbolic
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Exit_BitBtnClick(TObject *Sender)
{
exit(0);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Price_Function_RadioGroupClick(TObject *Sender)
{
if (Price_Function_RadioGroup->ItemIndex == 0) {
B_Label->Visible = true;
B_Edit->Visible = true;
Price_Function = 1; // Linear Price Function
}
else {
B_Label->Visible = false;
B_Edit->Visible = false;
Price_Function = 2; // Hyperbolic Price Function
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
Price_Function = 1;
}
//------------------------------------------------------------------------------------------------------------