Matlab Programs for Last-In First-Out Oligopoly Dynamics

This document lists and describes the programs used for the calculations of Abbring and Campbell (2009).

 ✶ We are grateful to R. Andrew Butters for his superlative research assistance. § Tilburg University. e-mail: J.H.Abbring@uvt.nl † Federal Reserve Bank of Chicago. e-mail: jcampbell@frbchi.org

This document describes the Matlab computer programs used for the calculations described in Abbring and Campbell (2009) in detail. These calcualte the value functions from the “pencil-and-paper” example in Figure 2, the value functions from the example of an equilibrium without threshold-based strategies in Figure 3, the equilibrium thresholds reported in Table I, and the “static” ordered-probit estimates of thresholds and producers' surplus per customer in Table II. For each of these, the relevant program embeds the calculated results in LaTeX code and writes the results to text files for direct inclusion in the paper's document.

#### Literate Programs

To facilitate the replication and extension of our work by others, we have written this in a style like that advocated by Knuth (1984).

Instead of imagining that our main task is to instruct a computer what to do, let us concentrate rather on explaining to human beings what we want a computer to do.

He called instructions written in this way literate programs. The concept is familiar to anyone who has read Press, Teukolsky, Vetterling, and Flannery (1992) or any other volume of the Numerical Recipes series. To create this, we have embedded this text into the comments of the Matlab programs and processed the result with the Comments++ tool of Campbell and Peters (2010). This reads logical formatting commands similar to those of LaTeX in the comments of its source files and produces an X-HTML page with associated .png image files containing any mathematics. The result freely intersperses code with formatted comments and places relevant mathematics in proximity to the code implementing it.

#### Viewing This

Below, working code is displayed in areas formatted with “bars” similar to those on “old-style” computer paper for dot-matrix printers. Figure 1 shows a screen shot of a few lines of code from this document. The source file name is to the left, and the line number from the source file preceeds each line. In this example, Line 18 is highlighted blue because the mouse was hovering over it when screen shot was taken.

If you find our explanation tiresome, you can change this document to show only the working code. Figure 2 shows how to do this for Firefox.1 The default value for Page Style is Display All. Changing this to Display Only Code hides our comments.

#### Printing This

So that the displayed line numbers match with the actual line numbers, your browser preserves all line breaks in the displayed source code. That is, a long line cannot break into multiple lines after you resize your browser window. The same principle applies to printing. If a line of code is too long to be displayed on the page, its right end will be cut off. For this reason, this document is best printed in landscape mode.2

The remainder of this document proceeds as follows. The next section covers pencil.m, the program we use to calculate the value functions from the pencil-and-paper example plotted in Figure 2. Of course, this really can be done with pencil and paper. Nevertheless, find it useful to automate the figure's construction to ensure that its content really is consistent with the theory. We start with this file because it works alone to produce results included in the text. As such, it provides a good introduction to our workflow strategy. Section 2B presents the programs we use to calculate the unique LIFO equilibrium that defaults to inactivity, and Section contains the code that applies these to create the results in Figure 3 and Tables I and II. Section 4D lists possible exercises for the interested student. Several appendices contain material necessary for our undertaking but nevertheless of secondary interest.

# 1APencil-and-Paper Example

Section 2.2 of the paper coinsiders the model's unique LIFO equilibrium that defaults to inactivity in the special case where with probability and equals a draw from a uniform distribution over with the complementaryu probability. Since the equilibrium continuation thresholds are solutions to quadratic equations, we call this the “pencil-and-paper example.” The Matlab program pencil.m calcualtes the equilibrium value functions, continuation thresholds, and exit thresholds for particular parameter values. We use the following ones.

 pencil.m 7 beta=1.05^(-5); Firms' common discount factor. pencil.m 8 kappa=1.25; Per period fixed cost of production. pencil.m 9 phi=@(N) 1; Sunk cost of entry, which we set to equal a trivial function of the number of incumbent firms. pencil.m 10 pi = @(N) 2-2*(N>2); Per customer producer surplus, which is zero when three more more firms are active. pencil.m 11 chat=0.1; Lower bound of demand state. pencil.m 12 ccheck=2.5; Upper bound of demand state. pencil.m 13 lambda=0.1; Probability of the demand state changing.

The calculated results are used by the LaTeX code in Appendix 3C to create Figure 2. The calculations proceed as outlined in the text. We first solve the dynamic programming problem of a firm that enters the market with a single incumbent in place. We then use the entry and continuation decisions of such a firm to specify and solve the dynamic programming problem of a firm that is the oldest incumbent.

#### Second Firm's Dynamic Programming Problem

Recall from the text that value function for a firm with rank 2 is piecewise linear and satisfies

(1)

where

(0)

Since the value function is uniquely characterized by we can construct a contraction mapping on this scalar “average continuation value” and iterate on it to calculate . For this, we first write the optimal choice of as a function of . Define as the value of demand that exactly sets the value of continuation to zero.

(2)

If , then optimality requires that . If , then continuation is always optimal and . Similarly, exit is always optimal and if Putting these results together, we get the desired function.

(3)

With so defined, we can use Equation (1) and the definition of to write the mapping of interest.

 (4)

The right-hand side of Equation (4) implicitly defines a mapping from the interval into itself. This is monotone and, since satisfies Blackwell's definition of discounting.See Theorem 3.3 of Stokey, Lucas, and Prescott (1989). Hence, it is a contraction mapping. We can calculate its unique fixed point to arbitrary precision by iterating on it from an arbitrary initial starting value.

To implement this in Matlab, we define three inline functions, One calculates from the intial guess at (which we denote with vtilde in the code), one which uses this to calculate from , and one that uses both of these to calculate the nex trival value of (vtildeprime) using Equation (4).

 pencil.m 55 cstar2 = @(vtilde2) (kappa-lambda*vtilde2/(1-lambda))*2/pi(2); from (2). pencil.m 56 cunderbar2 = @(vtilde2) min(max(chat,cstar2(vtilde2)),ccheck); from (3). pencil.m 57 vtildeprime2 = @(vtilde2) 0.25*(ccheck+chat)*pi(2)-kappa + ... pencil.m 58 +beta*((1-lambda)*(ccheck^2*pi(2)*0.25 - ccheck*kappa)... pencil.m 59 +lambda*ccheck*vtilde2)/((1-beta*(1-lambda))*(ccheck-chat))... pencil.m 60 -beta*((1-lambda)*(cunderbar2(vtilde2)^2*pi(2)*0.25 - cunderbar2(vtilde2)*kappa)... pencil.m 61 +cunderbar2(vtilde2)*lambda*vtilde2)/((1-beta*(1-lambda))*(ccheck-chat));

With these inline functions defined, calculating to any desired accuracy requires only a simple iteration. We know that the contraction mapping has modulus , so iterating

(0)

guarantees that the final calculated is within of the actual value.

 pencil.m 67 epsilon=1e-5; pencil.m 68 T = (log(epsilon)-log(ccheck*pi(1)/(1-beta)))/log(beta)+1; pencil.m 69 pencil.m 70 vtilde2=0; pencil.m 71 t=0; Used to count the number of iterations pencil.m 72 pencil.m 73 while t

With the approximate fixed point in hand, we can calculate the entry and exit thresholds. For the exit threshold, we just use the inline function cunderbar.

Just as with the exit threshold, three possible cases govern the entry threshold. Although this is computational overkill, we maintain presentational symmetry wiith the calculation of by defining here two functions for its calculation.

 pencil.m 82 cstarstar2 = @(vtilde2) (phi(2)*(1-beta*(1-lambda))/(beta*(1-lambda))... pencil.m 83 + kappa-lambda*vtilde2/(1-lambda))*2/pi(2); pencil.m 84 coverbar2 = @(vtilde2) min(max(chat,cstarstar2(vtilde2)),ccheck);

#### First Firm's Dynamic Programming Problem

The dynamic programming problem for a firm with rank 1 has an additional state indicating the presence or absence of a competitor. In the text, we noted that the equilibrium value function has a simple piecewise linear structure. The value of beginning the period without a competitor at the demand state is

(0)

If the firm begins the period instead with a younger rival, the value function equals

(0)

Here, the exit threshold is the greatest value of such that , and the expected values following a change in for a monopolist and a duopolist are

The entry and exit thresholds for a younger firm ( and ) are already in hand. With these, we mimic the calculation of to compute for . For any , we define as the solution to

(0)

Define the mapping from vtilde to cunderbar

 pencil.m 125 cstar1= @(vtilde1) (kappa-lambda*vtilde1(1)/(1-lambda))/pi(1);

Since vtilde1(1) weakly exceeds vitilde2, we know that cstar1(vtilde1) cannot exceed cunderbar2(vtilde2). Therefore,

(0)

 pencil.m 131 cunderbar1 = @(vtilde1) max(chat,cstar1(vtilde1));

Deriving the mapping from to proceeds just as it did above.

To keep the inline function implementing this manageable, we write each of its two elements as a separate inline function and then concatinate them. Since vectors in Matlab have a unit offset, vtilde(1) and vtilde(2) refer to and respectively.

 pencil.m 149 vtildeprime10 = @(vtilde1) ((chat+ccheck)/2)*pi(1) - kappa + beta/((1-beta*(1-lambda))*(ccheck-chat))... pencil.m 150 *((1-lambda)*(coverbar2(vtilde2)^2*pi(1)/2-kappa*coverbar2(vtilde2))... pencil.m 151 +lambda*vtilde1(1)*coverbar2(vtilde2)... pencil.m 152 -((1-lambda)*(cunderbar1(vtilde1)^2*pi(1)/2-kappa*cunderbar1(vtilde1))... pencil.m 153 +lambda*vtilde1(1)*cunderbar1(vtilde1)) ... pencil.m 154 +(1-lambda)*(ccheck^2*pi(2)/4-kappa*ccheck)... pencil.m 155 +lambda*vtilde1(2)*ccheck ... pencil.m 156 -((1-lambda)*(coverbar2(vtilde2)^2*pi(2)/4-kappa*coverbar2(vtilde2))... pencil.m 157 +lambda*vtilde1(2)*coverbar2(vtilde2))); pencil.m 158 pencil.m 159 vtildeprime11 = @(vtilde1) ((chat+ccheck)/2)*pi(2)/2 - kappa + beta/((1-beta*(1-lambda))*(ccheck-chat))... pencil.m 160 *((1-lambda)*(cunderbar2(vtilde2)^2*pi(1)/2-kappa*cunderbar2(vtilde2))... pencil.m 161 +lambda*vtilde1(1)*cunderbar2(vtilde2)... pencil.m 162 -((1-lambda)*(cunderbar1(vtilde1)^2*pi(1)/2-kappa*cunderbar1(vtilde1))... pencil.m 163 +lambda*vtilde1(1)*cunderbar1(vtilde1)) ... pencil.m 164 +(1-lambda)*(ccheck^2*pi(2)/4-kappa*ccheck)... pencil.m 165 +lambda*vtilde1(2)*ccheck ... pencil.m 166 -((1-lambda)*(cunderbar2(vtilde2)^2*pi(2)/4-kappa*cunderbar2(vtilde2))... pencil.m 167 +lambda*vtilde1(2)*cunderbar2(vtilde2))); pencil.m 168 pencil.m 169 vtildeprime1 = @(vtilde1) [vtildeprime10(vtilde1) vtildeprime11(vtilde1)];

With the Bellman operator suitably defined, we iterate beginning with As shown in the appendix, this produces a monotone increasing sequence of expected continuation values that converge to the fixed point of interest.

 pencil.m 173 vtilde1=[vtilde2 vtilde2]; pencil.m 174 t=0; pencil.m 175 while t

With the value function calculated, we tidy up the loose end of calculating .

 pencil.m 184 cstarstar1 = @(vtilde1) (phi(1)*(1-beta*(1-lambda))/beta/(1-lambda) ... pencil.m 185 + kappa-lambda*vtilde1(1)/(1-lambda))/pi(1); pencil.m 186 coverbar1 = @(vtilde1) min(max(chat,cstarstar1(vtilde1)),ccheck);

#### Value Function Figure

The paper's text presents the results of this equilibrium calculation in Figure 2, which is reproduced here as Figure 3. It consists of two panels. The top one plots and as functions of . Since these overlap over most of their domains, we present these as two “branches”. The monopoly branch gives the value of a firm with rank that begins as a monopolist and will remain so, and the duopoly branch gives the same firm's value when beginning as and remaining a duopolist. We denote the entry and exit of a younger rival with gray vertical arrows above and . The panel also includes a legend to label these branches. The second panel plots the much simpler value function for a duopolist with rank 2. Both panels include gray horiontal lines at a height equal to the sunk cost of entry for a firm of that rank.

Creating these elements requires the following information.

• and , to set the x-axis limits and place tick marks on them.
• and , to place tick marks on the first firm's continuation and entry thresholds.
• and , to place tick marks on the second firm's continuation and entry thresholds.
• , , for drawing a vertical line across the two firms' sunk costs of entry.
• , for plotting the monopoly branch and setting the upper limit of the y-axis.
• , for plotting the monopoly branch and placing the entry transition arrow.
• , for plotting the duopoly branch and placing the exit transition arrow.
• , for plotting the duopoly branch.
• , used as the slope of the legend's sample lines.

We implement the figure's creation within the LaTeX document using the pgfplots package of and the pgf/TikZ package of Tantau (2008). Appendix 3C presents the relevant LaTeX code in more detail. It requires appropriately named macros to return the values of interest. We write the LaTeX code to create them into compute/pgfTikZ/ac2apencilConstants.tex. The next line opens this file for output and assigns it the file handle f1.

 pencil.m 213 f1=fopen('pgfTikZ/ac2aPencilConstants.tex','w');

All of the macros' names begin with “pencil”.3 We write the LaTeX code creating them using Matlab's fprintf command, which has very similar syntax to C's printf function.

 pencil.m 219 fprintf(f1,'\\def\\pencilChat{%3.2f}\n',chat); pencil.m 220 fprintf(f1,'\\def\\pencilCcheck{%3.2f}\n',ccheck); pencil.m 221 fprintf(f1,'\\def\\pencilCunderbarOne{%3.2f}\n',cunderbar1(vtilde1)); pencil.m 222 fprintf(f1,'\\def\\pencilCoverbarOne{%3.2f}\n',coverbar1(vtilde1)); pencil.m 223 fprintf(f1,'\\def\\pencilCunderbarTwo{%3.2f}\n',cunderbar2(vtilde2)); pencil.m 224 fprintf(f1,'\\def\\pencilCoverbarTwo{%3.2f}\n',coverbar2(vtilde2));

Add the two values of the entry costs.

 pencil.m 228 fprintf(f1,'\\def\\pencilPhiTwo{%3.2f}\n',phi(2)); pencil.m 229 fprintf(f1,'\\def\\pencilPhiOne{%3.2f}\n',phi(1));

Calculate and write .

 pencil.m 233 v11coverbar2=beta*((1-lambda)*(coverbar2(vtilde2)*pi(1)-kappa)... pencil.m 234 +lambda*vtilde1(1))/(1-beta*(1-lambda)); pencil.m 235 fprintf(f1,'\\def\\pencilVOneOneCoverbarTwo{%3.2f}\n',v11coverbar2);

Calculate and write .

 pencil.m 239 v12cunderbartwo=beta*((1-lambda)*(cunderbar2(vtilde2)*pi(2)/2-kappa)... pencil.m 240 +lambda*vtilde1(2))/(1-beta*(1-lambda)); pencil.m 241 fprintf(f1,'\\def\\pencilVOneTwoCunderbarTwo{%3.2f}\n',v12cunderbartwo);

Calculate and write .

 pencil.m 245 v12ccheck=beta*((1-lambda)*(ccheck*pi(2)/2-kappa)... pencil.m 246 +lambda*vtilde1(2))/(1-beta*(1-lambda)); pencil.m 247 fprintf(f1,'\\def\\pencilVOneTwoCcheck{%3.2f}\n',v12ccheck);

Calculate the highest point of the second entrant's value function

 pencil.m 251 v2ccheck=beta*((1-lambda)*(ccheck*pi(2)/2-kappa)... pencil.m 252 +lambda*vtilde2)/(1-beta*(1-lambda)); pencil.m 253 fprintf(f1,'\\def\\pencilVTwoCcheck{%3.2f}\n',v2ccheck);

Write the value of and close the output file.

 pencil.m 257 fprintf(f1,'\\def\\pencilPiOne{%3.2f}\n',pi(1)); pencil.m 258 fclose(f1);

#### Quit Matlab

We only wish to quit if we are running this from the makefile. Since this probelm arises repeatedly, we place the code for such a conditional exit in the script makequit.

 pencil.m 264 makequit

The code detects whether or not Matlab has ben started by make by importing the MAKELEVEL environment variable. If we are running this from within make, this will be nonempty. Since we do not run make under Windows, this function does nothing unless the operating system is either Unix or Mac.

 makequit.m 7 if ( isunix || ismac ) makequit.m 8 makequit.m 9 makelevel=getenv('MAKELEVEL'); makequit.m 10 makequit.m 11 if ~strcmp(makelevel,'') && ~exist('stay','var') makequit.m 12 quit makequit.m 13 end makequit.m 14 makequit.m 15 end

# 2BLIFO Model

This section presents programs for calculating the LIFO equilibrium of interest in the general model without imposing the pencil-and-paper specificationfor the demand process. Section 4.1 of the text outlines our approach to equilibrium computation. We begin with approximating the given demand process with a Markov chain and calculating an uper bound on the number of active firms, , and we then proceed to recursively calculate the equilibrium continuation values and continuation strategies for firms with ranks . These computations also yield the strategies of potential entrants that would take on those ranks. With the equilibrium strategies in hand, we can simulate the model from any initial market structure. Alternatively, the ergodic distribution of might be calculated if that is the object of interest.

The approximation of a given demand process with a Markov chain is routine. For the examples in this section, we do so by hand. Some of the experiments described in Section 3C use the approximation to an autoregression described in the text. Appendix 1A presents the code for its implementation.

We break the code for the equilibrium calculation given the Markov chain into two parts, the solution of an optimal stopping problem, and the use of these solutions to calculate the equilibrium continuation values and strategies. We finish this section with the code for calculating the equilibrium's ergodic distribution.

## 2B.1Optimal Stopping Problems

Calculating the LIFO model's unique equilibrium that defaults to inactivity requires us to solve a sequence of optimal stopping problems, each corresponding to the exit decision of an incumbent firm of a particular rank. For this task, we develop a general procedure for calculating optimal stopping problems values and optimal rules.

In the general formulation of an optimal stopping problem, a decision maker faces an exogenous and payoff-relevent state . A Markov process governs its evolution, and the integer is the problem's dimensionality. The decision maker always begins the problem in the “active” state, which yields the flow payoff . At the end of the period the decision maker must choose between “continue” and “stop”. Continuing preserves the option to stop in the future, while stopping is irreversible. The one-time payoff to stopping is . The decision maker discounts future payoffs with the discount rate , so this problem's corresponding Bellman equation is

(5)

Under well-known regularity conditions for , , and , Equation 5 defines a contraction mapping. The most conceptually straightforward method for calculating its unique fixed point is iteration on the Bellman operator implicitly defined by its right-hand side, . The iteration terminates when the sup norm of falls below a prespecified tolerance, .

An optimal stopping problem has a discrete state space if has a finite number of distinct values, . In this case, the Markov process governing the evolution of is a Markov chain with transition matrix . Its typical element gives .

The function solveOptimalStoppingProblem implements Bellman equation iteration for this solution for optimal stopping problems with discrete state spaces. Its single input, ARG is a structure with fields corresponding to the problem's primitives.

stateSpace
An matrix. Each row represents a distinct element of .
transitionMatrix
The Markov transition matrix .
flowPayoff
An anonymous function handle yielding the flow payoff function . This accept a vector of vector-valued inputs and return a vector of function values.
outsideValue
An anonymous function handle containing the value of stopping, . This should also accept a vector of vector-valued inputs.
discountFactor
The decision maker's discount factor, .
convergenceTolerance
The tolerance for measuring convergence of the value-function iteration, .
valueFunction
An vector. Its 'th element contains a prospective value of .

The function uses ARG.valueFunction as an initial value for the Bellman equation iteration. The function's single output, OUT, contains exactly the same fields. On return, OUT.valueFunction will equal the value function at the termination of the Bellman equation iteration.

 solveOptimalStoppingProblem.m 44 function OUT = solveOptimalStoppingProblem(ARG) solveOptimalStoppingProblem.m 45

Start by setting the output structure to the input structure.

 solveOptimalStoppingProblem.m 47 OUT=ARG; solveOptimalStoppingProblem.m 48

Assign the problem's primitives to variables with conventional names.

 solveOptimalStoppingProblem.m 50 calX = ARG.stateSpace; solveOptimalStoppingProblem.m 51 Pi = ARG.transitionMatrix; solveOptimalStoppingProblem.m 52 f = ARG.flowPayoff; solveOptimalStoppingProblem.m 53 S = ARG.outsideValue; solveOptimalStoppingProblem.m 54 beta = ARG.discountFactor; solveOptimalStoppingProblem.m 55 eps = ARG.convergenceTolerance; solveOptimalStoppingProblem.m 56 V = ARG.valueFunction; solveOptimalStoppingProblem.m 57

Next, evaluate the flow payoffs and stopping values over the entire state space.

 solveOptimalStoppingProblem.m 61 fX = f(calX); solveOptimalStoppingProblem.m 62 SX = S(calX); solveOptimalStoppingProblem.m 63

Initialize an indicator for the distance between and to exceed .

 solveOptimalStoppingProblem.m 67 vDistance=eps+1; solveOptimalStoppingProblem.m 68

Everything is now in place for the Bellman-equation iteration.

 solveOptimalStoppingProblem.m 71 while vDistance>eps solveOptimalStoppingProblem.m 72 solveOptimalStoppingProblem.m 73 Vprime=max([SX beta*(Pi*(fX+V))],[],2); solveOptimalStoppingProblem.m 74 vDistance=max(abs(Vprime-V)); solveOptimalStoppingProblem.m 75 V=Vprime; solveOptimalStoppingProblem.m 76 solveOptimalStoppingProblem.m 77 end solveOptimalStoppingProblem.m 78

All that remains is to replace OUT.valueFunction with V and end the function.

 solveOptimalStoppingProblem.m 82 OUT.valueFunction=V; solveOptimalStoppingProblem.m 83 end solveOptimalStoppingProblem.m 84

Our test of solveOptimalStoppingProblem applies it to the dynamic programming problem of the firm with rank 2 in the pencil and paper example from the text. Start this by creating the discrete state space and the associated Markov transition matrix.

 solveOptimalStoppingProblemTest.m 6 chat=0.1; solveOptimalStoppingProblemTest.m 7 ccheck=2.5; solveOptimalStoppingProblemTest.m 8 step=0.01; solveOptimalStoppingProblemTest.m 9 omega=(chat:step:ccheck)'; solveOptimalStoppingProblemTest.m 10 N = length(omega); solveOptimalStoppingProblemTest.m 11 solveOptimalStoppingProblemTest.m 12 lambda=0.1; solveOptimalStoppingProblemTest.m 13 Pi=(1-lambda)*eye(N)+lambda*ones(N,N)/N;

Next, create the anonymous function handles for the flow payoff and outside value.

 solveOptimalStoppingProblemTest.m 17 pi=2; solveOptimalStoppingProblemTest.m 18 kappa=1.25; solveOptimalStoppingProblemTest.m 19 f = @(x) x*pi/2-kappa; solveOptimalStoppingProblemTest.m 20 S = @(x) zeros(size(x,1),1);

Set the discount factor

 solveOptimalStoppingProblemTest.m 24 beta=1.05^(-5);

Choose a convergence tolerance

 solveOptimalStoppingProblemTest.m 28 eps=1e-7;

Choose an initial value function.

 solveOptimalStoppingProblemTest.m 32 V=zeros(N,1);

Place the problem's primitive's into the required structure, which we call PENCIL to remind us of its source.

 solveOptimalStoppingProblemTest.m 36 PENCIL.stateSpace = omega; solveOptimalStoppingProblemTest.m 37 PENCIL.transitionMatrix = Pi; solveOptimalStoppingProblemTest.m 38 PENCIL.flowPayoff = f; solveOptimalStoppingProblemTest.m 39 PENCIL.outsideValue = S; solveOptimalStoppingProblemTest.m 40 PENCIL.discountFactor = beta; solveOptimalStoppingProblemTest.m 41 PENCIL.convergenceTolerance = eps; solveOptimalStoppingProblemTest.m 42 PENCIL.valueFunction = V;

Solve the stopping problem.

 solveOptimalStoppingProblemTest.m 46 PENCIL = solveOptimalStoppingProblem(PENCIL);

We inspect the results with a plot of the calculated value function. Its horizontal axis marks , , the exit threshold , and the associated entry threshold . We also include a horizontal line at the entry cost .

 solveOptimalStoppingProblemTest.m 52 cunderbarIndex=find(PENCIL.valueFunction==0,1,'last'); solveOptimalStoppingProblemTest.m 53 cunderbar=PENCIL.stateSpace(cunderbarIndex); solveOptimalStoppingProblemTest.m 54 solveOptimalStoppingProblemTest.m 55 coverbarIndex=find(PENCIL.valueFunction<1,1,'last'); solveOptimalStoppingProblemTest.m 56 coverbar=PENCIL.stateSpace(coverbarIndex); solveOptimalStoppingProblemTest.m 57 plot(PENCIL.stateSpace,ones(length(PENCIL.stateSpace),1),'-','LineWidth',1.5,'Color',[0.8 0.8 0.8]); solveOptimalStoppingProblemTest.m 58 hold solveOptimalStoppingProblemTest.m 59 plot(PENCIL.stateSpace,PENCIL.valueFunction,'-k','LineWidth',2); solveOptimalStoppingProblemTest.m 60 solveOptimalStoppingProblemTest.m 61 set(gca,'box','off','FontSize',14,'Xtick',[chat cunderbar coverbar ccheck]); solveOptimalStoppingProblemTest.m 62 xlim([chat ccheck]); solveOptimalStoppingProblemTest.m 63 set(gcf,'Color',[1 1 1]);

Save the figure to a .jpg file.

 solveOptimalStoppingProblemTest.m 67 set(gcf,'Position',[-3 5 1280 950],... solveOptimalStoppingProblemTest.m 68 'PaperUnits','in','PaperSize',[5 3],... solveOptimalStoppingProblemTest.m 69 'PaperPositionMode','manual',... solveOptimalStoppingProblemTest.m 70 'PaperPosition',[0 0 5 3]); Set the figure to the desired size. solveOptimalStoppingProblemTest.m 71 print -djpeg -painters solveOptimalStoppingProblemTest.jpg solveOptimalStoppingProblemTest.m 72 makequit;

Figure 4 presents the resulting value function. As we can see, it is piecewise linear as expected. Furthermore, the entry and exit thresholds exactly equal their counterparts from the pencil and paper example above; which used a continuous state space instead of using a grid.

## 2B.2LIFO Equilibrium

With the procedure for solving optimal stopping problems in place, we can proceed with the equilibrium calculation as outlined in the text. The function calculateLifoEquilibrium carries this out. The fields of its single argument are

pi
A handle for an anonymous function that returns , the per consumer producers' surplus earned when firms are active.
kappa
The scalar per period fixed cost of production, .
phi
A handle for an anonymous function that returns , the sunk cost of entry of a firm with prospective rank .
omega
An vector, the discrete state space for .
Pi
The Markov transition matrix for .
beta
Firms' common discount factor.
convergenceTolerance
A convergence tolerance for Bellman-equation iteration. Passed through to solveOptimalStoppingProblem.
nCheck
Either empty or an upper bound on the number of firms possibly active in the market.
V
Either empty or an array. Its (i,j,k) element gives the value of an incumbent firm with rank i before the period's continuation and entry decisions are made when equals omega(j) and there are k firms active this period.
nPrime
Either empty or an array. Its element gives the number of active firms at the beginning of the next period if equals omega(j) and there are k firms active this period.

 calculateLifoEquilibrium.m 24 function OUT = calculateLifoEquilibrium(ARG) calculateLifoEquilibrium.m 25

Begin by assigning the fields of ARG to variables.

 calculateLifoEquilibrium.m 28 pi = ARG.pi; calculateLifoEquilibrium.m 29 kappa = ARG.kappa; calculateLifoEquilibrium.m 30 phi = ARG.phi; calculateLifoEquilibrium.m 31 omega = ARG.omega; calculateLifoEquilibrium.m 32 Pi = ARG.Pi; calculateLifoEquilibrium.m 33 beta = ARG.beta; calculateLifoEquilibrium.m 34 eps = ARG.convergenceTolerance; calculateLifoEquilibrium.m 35 nCheck = ARG.nCheck; calculateLifoEquilibrium.m 36 calculateLifoEquilibrium.m 37

We begin by assembling the per period producer surplus function. The resulting anonymous function f accepts a matrix as input. Its first column is the demand state, and the second column is the number of firms active in the period.

 calculateLifoEquilibrium.m 45 f = @(x) x(:,1).*pi(x(:,2))./x(:,2)-kappa; calculateLifoEquilibrium.m 46

If nCheck is empty, then calculate the upper bound on the number of active firms

 calculateLifoEquilibrium.m 50 if isempty(nCheck) calculateLifoEquilibrium.m 51 nCheck=1; calculateLifoEquilibrium.m 52 cCheck=max(omega); calculateLifoEquilibrium.m 53 while f([cCheck nCheck])>0 calculateLifoEquilibrium.m 54 nCheck=nCheck+1; calculateLifoEquilibrium.m 55 end calculateLifoEquilibrium.m 56 ARG.nCheck=nCheck-1; calculateLifoEquilibrium.m 57 nCheck=ARG.nCheck; calculateLifoEquilibrium.m 58 end calculateLifoEquilibrium.m 59

Set up storage for V and nPrime.

 calculateLifoEquilibrium.m 61 n=length(omega); calculateLifoEquilibrium.m 62 V = zeros(nCheck,n,nCheck); calculateLifoEquilibrium.m 63 nPrime = ones(n,1)*(1:1:nCheck); calculateLifoEquilibrium.m 64 calculateLifoEquilibrium.m 65

Cycle through the dynamic programming problems.

 calculateLifoEquilibrium.m 67 for i=nCheck:-1:1 calculateLifoEquilibrium.m 68 calculateLifoEquilibrium.m 69

Calculate the state space and transition matrix for this firm's problem.

 calculateLifoEquilibrium.m 71 ARG_TRANSITION.transitionMatrixForC = Pi; calculateLifoEquilibrium.m 72 ARG_TRANSITION.supportForC = omega; calculateLifoEquilibrium.m 73 ARG_TRANSITION.minimumN = i; calculateLifoEquilibrium.m 74 ARG_TRANSITION.maximumN = nCheck; calculateLifoEquilibrium.m 75 ARG_TRANSITION.nextN = nPrime(:,i:nCheck); calculateLifoEquilibrium.m 76 calculateLifoEquilibrium.m 77 TRANSITION=calculateLifoTransitionMatrix(ARG_TRANSITION); calculateLifoEquilibrium.m 78

Set up the argument for solveOptimalStoppingProblem and call it.

 calculateLifoEquilibrium.m 80 STOPPING.stateSpace = TRANSITION.supportForCandN; calculateLifoEquilibrium.m 81 STOPPING.transitionMatrix = TRANSITION.transitionMatrixForCandN; calculateLifoEquilibrium.m 82 STOPPING.flowPayoff = f; calculateLifoEquilibrium.m 83 STOPPING.outsideValue = @(x) zeros(size(x,1),1); calculateLifoEquilibrium.m 84 STOPPING.discountFactor = beta; calculateLifoEquilibrium.m 85 STOPPING.convergenceTolerance= eps; calculateLifoEquilibrium.m 86 STOPPING.valueFunction = zeros(length(TRANSITION.supportForCandN),1); calculateLifoEquilibrium.m 87 calculateLifoEquilibrium.m 88 STOPPING=solveOptimalStoppingProblem(STOPPING); calculateLifoEquilibrium.m 89

Reshape the value function so that each row corresponds to a value of and each column to a value of .

 calculateLifoEquilibrium.m 92 vMatrix=reshape(STOPPING.valueFunction,n,nCheck-i+1); calculateLifoEquilibrium.m 93

Adjust nPrime for the exit of the firm with rank .

 calculateLifoEquilibrium.m 95 nPrime(:,i:nCheck)=nPrime(:,i:nCheck)-(vMatrix==0); calculateLifoEquilibrium.m 96

Adjust nPrime for the entry of the firm with rank .

 calculateLifoEquilibrium.m 98 nPrime(:,1:i-1)=nPrime(:,1:i-1)+(vMatrix(:,1)*ones(1,i-1)>phi(i)); calculateLifoEquilibrium.m 99

Save the value function

 calculateLifoEquilibrium.m 101 if i>1 calculateLifoEquilibrium.m 102 V(i,:,:)=[NaN(n,i-1) vMatrix]; calculateLifoEquilibrium.m 103 else calculateLifoEquilibrium.m 104 V(i,:,:)=vMatrix; calculateLifoEquilibrium.m 105 end calculateLifoEquilibrium.m 106 calculateLifoEquilibrium.m 107 end calculateLifoEquilibrium.m 108

Create the first column of nPrime, that associated with an initially empty industry.

 calculateLifoEquilibrium.m 111 nPrimeZero=zeros(n,1); calculateLifoEquilibrium.m 112 calculateLifoEquilibrium.m 113 for j=1:nCheck; calculateLifoEquilibrium.m 114 vj=squeeze(V(j,:,j))'; This call to squeeze returns a column vector. calculateLifoEquilibrium.m 115 nPrimeZero=nPrimeZero+(vj>phi(j)); calculateLifoEquilibrium.m 116 end calculateLifoEquilibrium.m 117 nPrime = [nPrimeZero nPrime]; calculateLifoEquilibrium.m 118 calculateLifoEquilibrium.m 119

Assemble the final output.

 calculateLifoEquilibrium.m 122 OUT=ARG; calculateLifoEquilibrium.m 123 OUT.nCheck=nCheck; calculateLifoEquilibrium.m 124 OUT.valueFunction=V; calculateLifoEquilibrium.m 125 OUT.equilibriumFirmCount=nPrime; calculateLifoEquilibrium.m 126

The test of calculateLifoEquilibrium uses the parameter values from the pencil-and-paper example.

 calculateLifoEquilibriumTest.m 6 chat=0.1; calculateLifoEquilibriumTest.m 7 ccheck=2.5; calculateLifoEquilibriumTest.m 8 step=0.01; calculateLifoEquilibriumTest.m 9 omega=(chat:step:ccheck)'; calculateLifoEquilibriumTest.m 10 N = length(omega); calculateLifoEquilibriumTest.m 11 lambda=0.1; calculateLifoEquilibriumTest.m 12 Pi=(1-lambda)*eye(N)+lambda*ones(N,N)/N; calculateLifoEquilibriumTest.m 13 kappa=1.25; calculateLifoEquilibriumTest.m 14 pi = @(x) 2*ones(size(x,1),1); calculateLifoEquilibriumTest.m 15 beta=1.05^(-5); calculateLifoEquilibriumTest.m 16 phi = @(x) ones(length(x),1); calculateLifoEquilibriumTest.m 17

We use the convergence tolerance from solveOptimalStoppingProblemTest.m.

 calculateLifoEquilibriumTest.m 21 eps=1e-7;

Assemble the input structure, and calculate the equilibrium

 calculateLifoEquilibriumTest.m 25 ARG.pi = pi; calculateLifoEquilibriumTest.m 26 ARG.kappa = kappa; calculateLifoEquilibriumTest.m 27 ARG.phi = phi; calculateLifoEquilibriumTest.m 28 ARG.omega = omega; calculateLifoEquilibriumTest.m 29 ARG.Pi = Pi; calculateLifoEquilibriumTest.m 30 ARG.beta = beta; calculateLifoEquilibriumTest.m 31 ARG.convergenceTolerance = 1e-7; calculateLifoEquilibriumTest.m 32 ARG.nCheck = []; calculateLifoEquilibriumTest.m 33 ARG.V = []; calculateLifoEquilibriumTest.m 34 ARG.nPrime = []; calculateLifoEquilibriumTest.m 35 calculateLifoEquilibriumTest.m 36 OUT=calculateLifoEquilibrium(ARG);

We examine the equilibrium calculations by plotting the value functions. The resulting figure has one panel for each of the continuation values.

 calculateLifoEquilibriumTest.m 40 nCheck=OUT.nCheck; calculateLifoEquilibriumTest.m 41 V=OUT.valueFunction; calculateLifoEquilibriumTest.m 42 calculateLifoEquilibriumTest.m 43 figure(1) calculateLifoEquilibriumTest.m 44 for i=1:nCheck; calculateLifoEquilibriumTest.m 45 subplot(nCheck,1,i)

Place a horizontal line at the sunk cost of entry.

 calculateLifoEquilibriumTest.m 49 plot(omega,phi(i)*ones(size(omega)),'LineWidth',2,'Color',[0.8 0.8 0.8]);

Set the axes' limits so that all panels are on the same scale.

 calculateLifoEquilibriumTest.m 53 xlim([min(omega) max(omega)]); calculateLifoEquilibriumTest.m 54 ylim([0 ceil(max(V(1,:,1)))]);

Label this panel.

 calculateLifoEquilibriumTest.m 58 title(['R = ' int2str(i)],'FontSize',16,'Interpreter','latex'); calculateLifoEquilibriumTest.m 59 hold; calculateLifoEquilibriumTest.m 60 calculateLifoEquilibriumTest.m 61 for j=i:nCheck;

Since the value function is discontinuous at some points, we use no line and instead mark each value with a dot. Where the value function is continuous, these blend together to form the appereance of continuity.

 calculateLifoEquilibriumTest.m 66 plot(omega,V(i,:,j),'LineStyle','none','Marker','.'); calculateLifoEquilibriumTest.m 67 end calculateLifoEquilibriumTest.m 68 set(gca,'box','off','FontSize',14) calculateLifoEquilibriumTest.m 69 calculateLifoEquilibriumTest.m 70 end calculateLifoEquilibriumTest.m 71 set(gcf,'Color',[1 1 1])

Save the figure as a .jpg file.

 calculateLifoEquilibriumTest.m 75 set(gcf,... calculateLifoEquilibriumTest.m 76 'PaperUnits','in','PaperSize',[5 10],... calculateLifoEquilibriumTest.m 77 'PaperPositionMode','manual',... calculateLifoEquilibriumTest.m 78 'PaperPosition',[0 0 5 10]); Set the figure to the desired size. calculateLifoEquilibriumTest.m 79 calculateLifoEquilibriumTest.m 80 print -djpeg -painters calculateLifoEquilibriumTest.jpg calculateLifoEquilibriumTest.m 81 calculateLifoEquilibriumTest.m 82 makequit;

Figure 5 presents the calculated equilibrium value functions. The format is the same as that used in Figure . The light-gray horizontal lines mark the sunk cost of entry for each potential competitor. The value functions' piecewise linearity arises from the same specification of the demand process that simplified the pencil and paper example. The value of a firm with rank 3 never equals or exceeds its cost of entry, so the simplifying assumption that at most two firms serve the industry was without loss of generality if we only concern ourselves with the industry's ergodic distribution.

## 2B.3The Ergodic Distribution

The calculation of the equilibrium's ergodic distribution over has two steps.

1. Create the Markov transition matrix for this pair.
2. Calculate the eigenvector associated with its unit eigenvalue.

The functions calculateLifoTransitionMatrix and calculateLifoErgodicDistribution handle these tasks.

### 2B.3.1The Markov Transition Matrix

The function that calculates the LIFO equilibrium transition matrix for takes its input from a single structure, ARG, with the following fields.

transitionMatrixForC
The n n Markov transition matrix governing the exogenous evolution of .
supportForC
A column vector with n elements, each giving one possible value for .
minimumN
The minimum value of .
maximumN
The maximum value of .
nextN
An n |(nCheck-nHat+1) matrix of integers in nCat,...,nCheck. The 'th element gives the number of firms active at the end of the period if the period starts with omega(i) and nHat+j-1.

The values for all of these can be easily constructed from the output structure of calculateLifoEquilibrium.

The function's output structure has two fields.

supportForCandN
The n(nCheck-nHat+1) 2 matrix of all possible pairs.
transitionMatrixForCandN
The n(nCheck-nhat+1) n(nCheck-nHat+1) Markov transition matrix on supportForCandN

 calculateLifoTransitionMatrix.m 28 function OUT = calculateLifoTransitionMatrix(ARG) calculateLifoTransitionMatrix.m 29 calculateLifoTransitionMatrix.m 30 Pi = ARG.transitionMatrixForC; calculateLifoTransitionMatrix.m 31 omega = ARG.supportForC; calculateLifoTransitionMatrix.m 32 n = length(omega); calculateLifoTransitionMatrix.m 33 nHat = ARG.minimumN; calculateLifoTransitionMatrix.m 34 nCheck = ARG.maximumN; calculateLifoTransitionMatrix.m 35 nPrime = ARG.nextN;

First, construct the support for the . This vertically tiles nCheck-nHat+1copies of omega and concatinates it with nHat:1:nCheck ones(n,1).

 calculateLifoTransitionMatrix.m 39 OUT.supportForCandN = [repmat(omega,nCheck-nHat+1,1) kron((nHat:1:nCheck)',ones(n,1))]; calculateLifoTransitionMatrix.m 40 m = length(OUT.supportForCandN);

The transition matrix for simply distributes the elements of Pi across an m m using the transition rule for . Except in the case where nHat equals nCheck, this matrix is sparse, so we set it up as such. Using a sparse matrix for this cuts computation time here and in calculateLifoEquilibrium tremendously.

The matrix of non-zero coefficients.

 calculateLifoTransitionMatrix.m 49 nonZeroCoefficients = repmat(Pi,nCheck-nHat+1,1);

Matrix of row indices for the elements of nonZeroCoefficients.

 calculateLifoTransitionMatrix.m 53 rowIndices=(1:1:m)'*ones(1,n);

Matrix of column indices for the elements of nonZeroCoefficients.

 calculateLifoTransitionMatrix.m 57 columnIndices = ones(m,1)*(1:1:n) + (nPrime(:)-nHat)*ones(1,n)*n; calculateLifoTransitionMatrix.m 58 calculateLifoTransitionMatrix.m 59 OUT.transitionMatrixForCandN=sparse(rowIndices(:),columnIndices(:),nonZeroCoefficients(:),m,m);

### 2B.3.2Eigenvector Calcualtion

The eigenvalue calculation takes place within calculateLifoErgodicDistribution. It gets its input from the structure EQUILIBRIUM, which has the same fields as the output of calculateLifoEquilibrium. With this it constructs the required inputs for calculateLifoTransitionMatrix, calculates the eigenvector of interest, and scales the result so that its elements sum to one.

Its single output, the structure ERGODIC has three fields.

transitionMatrix
The calculated transition matrix for
support
A vector with two columns. Each row is one possible combination of .
distribution
The ergodic distribution over support.

 calculateLifoErgodicDistribution.m 20 function ERGODIC = calculateLifoErgodicDistribution(EQUILIBRIUM)

 calculateLifoErgodicDistribution.m 25 TRANSITION_ARG.supportForC = EQUILIBRIUM.omega; calculateLifoErgodicDistribution.m 26 TRANSITION_ARG.transitionMatrixForC = EQUILIBRIUM.Pi; calculateLifoErgodicDistribution.m 27 TRANSITION_ARG.minimumN = 0; calculateLifoErgodicDistribution.m 28 TRANSITION_ARG.maximumN = EQUILIBRIUM.nCheck; calculateLifoErgodicDistribution.m 29 TRANSITION_ARG.nextN = EQUILIBRIUM.equilibriumFirmCount; calculateLifoErgodicDistribution.m 30 calculateLifoErgodicDistribution.m 31 TRANSITION=calculateLifoTransitionMatrix(TRANSITION_ARG);

Get the transition matrix for and calculate the eigenvector associated with the unit eigenvalue.

 calculateLifoErgodicDistribution.m 35 P = TRANSITION.transitionMatrixForCandN; calculateLifoErgodicDistribution.m 36 calculateLifoErgodicDistribution.m 37 [e,d] = eigs(P',1,1); The final “1” tells eigs to search around 1. calculateLifoErgodicDistribution.m 38 if abs(d-1)>EQUILIBRIUM.convergenceTolerance calculateLifoErgodicDistribution.m 39 error(['Eigenvalue calculation failed. d = ' num2str(d,'%10.5f')]); calculateLifoErgodicDistribution.m 40 end calculateLifoErgodicDistribution.m 41 calculateLifoErgodicDistribution.m 42 e = e/sum(e); This ensures that the majority of e's elements are positive. calculateLifoErgodicDistribution.m 43 e(e<0) = 0; A few that are actually zero are numerically small and negative. Set these to zero. calculateLifoErgodicDistribution.m 44 e = e/sum(e); Norm the eigenvector again. Now its elements represent probabilities. calculateLifoErgodicDistribution.m 45

Assemble the output structure and finish.

 calculateLifoErgodicDistribution.m 49 ERGODIC.transitionMatrix=P; calculateLifoErgodicDistribution.m 50 ERGODIC.support=TRANSITION.supportForCandN; calculateLifoErgodicDistribution.m 51 ERGODIC.distribution = e; calculateLifoErgodicDistribution.m 52 calculateLifoErgodicDistribution.m 53 end

To test the calculation of the LIFO equilibrium's transition matrix and ergodic distribution, we apply the code to a model with very few demand states and inspect the output. Except for the reduced dimensionality of , the parameters used are the same as those in calculateLifoEquilibriumTest.

 calculateLifoErgodicDistributionTest.m 7 chat=0.1; calculateLifoErgodicDistributionTest.m 8 ccheck=2.5; calculateLifoErgodicDistributionTest.m 9 step=1.2; calculateLifoErgodicDistributionTest.m 10 omega=(chat:step:ccheck)'; This has three points. calculateLifoErgodicDistributionTest.m 11 N = length(omega); calculateLifoErgodicDistributionTest.m 12 lambda=0.1; calculateLifoErgodicDistributionTest.m 13 Pi=(1-lambda)*eye(N)+lambda*ones(N,N)/N; calculateLifoErgodicDistributionTest.m 14 calculateLifoErgodicDistributionTest.m 15 kappa=1.25; calculateLifoErgodicDistributionTest.m 16 pi = @(x) 2*ones(size(x,1),1); calculateLifoErgodicDistributionTest.m 17 calculateLifoErgodicDistributionTest.m 18 beta=1.05^(-5); calculateLifoErgodicDistributionTest.m 19 phi = @(x) ones(length(x),1); calculateLifoErgodicDistributionTest.m 20 calculateLifoErgodicDistributionTest.m 21 eps=1e-7; calculateLifoErgodicDistributionTest.m 22 calculateLifoErgodicDistributionTest.m 23 ARG.pi = pi; calculateLifoErgodicDistributionTest.m 24 ARG.kappa = kappa; calculateLifoErgodicDistributionTest.m 25 ARG.phi = phi; calculateLifoErgodicDistributionTest.m 26 ARG.omega = omega; calculateLifoErgodicDistributionTest.m 27 ARG.Pi = Pi; calculateLifoErgodicDistributionTest.m 28 ARG.beta = beta; calculateLifoErgodicDistributionTest.m 29 ARG.convergenceTolerance = 1e-7; calculateLifoErgodicDistributionTest.m 30 ARG.nCheck = []; calculateLifoErgodicDistributionTest.m 31 ARG.V = []; calculateLifoErgodicDistributionTest.m 32 ARG.nPrime = []; calculateLifoErgodicDistributionTest.m 33 calculateLifoErgodicDistributionTest.m 34 LIFO_EQUILIBRIUM = calculateLifoEquilibrium(ARG); calculateLifoErgodicDistributionTest.m 35 LIFO_ERGODIC = calculateLifoErgodicDistribution(LIFO_EQUILIBRIUM); calculateLifoErgodicDistributionTest.m 36 calculateLifoErgodicDistributionTest.m 37 makequit;

Inspection of the results shows that the function is accurate in this case.

# 3CThe Experiments

## 3C.1Equilibrium without Threshold Rules

The paper's first substantial equilibrium calculation using the general model is the example of equilibrium without threshold rules in Section 3. For it, and is on an evenly spaced grid of 3000 points between -1.5 and 1.5. The probability of remaining unchanged is . With probability it falls to , and with the same probability it rises to . The model's other parameters in this example are , , , and .

#### Equilibrium Calculation

Setting up the problem's parameters is straightforward. We place the support of into omega.

 equilibriumWithoutThresholds.m 15 omega=exp(-1.5:0.001:1.5)'; equilibriumWithoutThresholds.m 16 N=length(omega);

For omega(1)...omega(300), negative innovations bring to omega(1). This code could be cleaner if we calculated this index as a function of the grid step length, but it suffices for the purposes of a counterexample.

 equilibriumWithoutThresholds.m 21 Pi=eye(length(omega)); equilibriumWithoutThresholds.m 22 for i=1:1:300 equilibriumWithoutThresholds.m 23 Pi(i,i)=0.5; equilibriumWithoutThresholds.m 24 Pi(i,1)=Pi(i,1)+0.25; equilibriumWithoutThresholds.m 25 Pi(i,i+300)=0.25; equilibriumWithoutThresholds.m 26 end

For omega(N-299)...omega(N), positive innovations bring to omega(N).

 equilibriumWithoutThresholds.m 30 for i=N-300+1:1:N; equilibriumWithoutThresholds.m 31 Pi(i,i)=0.5; equilibriumWithoutThresholds.m 32 Pi(i,i-300)=0.25; equilibriumWithoutThresholds.m 33 Pi(i,end)=Pi(i,end)+0.25; equilibriumWithoutThresholds.m 34 end

For all other values of , the bounded state space does not constraint positive or negative innovations to .

 equilibriumWithoutThresholds.m 38 for i=301:1:N-300 equilibriumWithoutThresholds.m 39 Pi(i,i)=0.5; equilibriumWithoutThresholds.m 40 Pi(i,i-300)=0.25; equilibriumWithoutThresholds.m 41 Pi(i,i+300)=0.25; equilibriumWithoutThresholds.m 42 end

Create the anonymous function handle for the producers' surplus per customer.

 equilibriumWithoutThresholds.m 46 pi = @(x) 2*ones(size(x,1),1);

Set the per period fixed cost.

 equilibriumWithoutThresholds.m 50 kappa=1.0;

Set the discount factor.

 equilibriumWithoutThresholds.m 54 beta=1.05^(-1);

Create the anonymous function handle for the sunk cost of entry.

 equilibriumWithoutThresholds.m 58 phi = @(x) 10*ones(length(x),1);

Choose a convergence tolerance.

 equilibriumWithoutThresholds.m 62 eps=1e-7;

To calculate the equilibrium, we assemble the model's parameters into the required structure and call calculateLifoEquilibrium.

 equilibriumWithoutThresholds.m 66 ARG.pi = pi; equilibriumWithoutThresholds.m 67 ARG.kappa = kappa; equilibriumWithoutThresholds.m 68 ARG.phi = phi; equilibriumWithoutThresholds.m 69 ARG.omega = omega; equilibriumWithoutThresholds.m 70 ARG.Pi = Pi; equilibriumWithoutThresholds.m 71 ARG.beta = beta; equilibriumWithoutThresholds.m 72 ARG.convergenceTolerance = eps; equilibriumWithoutThresholds.m 73 ARG.nCheck = 2; equilibriumWithoutThresholds.m 74 ARG.V = []; equilibriumWithoutThresholds.m 75 ARG.nPrime = []; equilibriumWithoutThresholds.m 76 equilibriumWithoutThresholds.m 77 OUT=calculateLifoEquilibrium(ARG); equilibriumWithoutThresholds.m 78

#### Reporting

Figure 3 in the text plots the equilibrium value functions from this example. Just as with the pencil and papaer example, we save the relevant results to external files and use pgfTikz code in Appendix 3C to create the plot within the LaTeX file.

The horizontal axis plots in logarithms, so we transform the state space accordingly.

 equilibriumWithoutThresholds.m 86 omega=log(omega);

Just as with the pencil and paper example, the figure has two panels. The first gives the initial entrant's value function and the second gives value function of the later entrant. For the later, we require the entry and exit thresholds.

 equilibriumWithoutThresholds.m 91 v2=squeeze(OUT.valueFunction(2,:,:)); equilibriumWithoutThresholds.m 92 v2=v2(:,2); equilibriumWithoutThresholds.m 93 if min(v2)<=phi(2); equilibriumWithoutThresholds.m 94 overlineC=omega(find(v2<=phi(2),1,'last')); equilibriumWithoutThresholds.m 95 else equilibriumWithoutThresholds.m 96 overlineC=omega(1); equilibriumWithoutThresholds.m 97 end equilibriumWithoutThresholds.m 98 equilibriumWithoutThresholds.m 99 if min(v2)==0; equilibriumWithoutThresholds.m 100 underlineC=omega(find(v2==0,1,'last')); equilibriumWithoutThresholds.m 101 else equilibriumWithoutThresholds.m 102 underlineC=omega(1); equilibriumWithoutThresholds.m 103 end

The first entrant's value function crosses the cost of entry twice. We call the two non-overlapping segments of the state space where it exceeds and . The plot requires both of these segments' boundaries.

 equilibriumWithoutThresholds.m 108 v1=squeeze(OUT.valueFunction(1,:,:)); equilibriumWithoutThresholds.m 109 Alow=min(omega(v1(:,1)>=phi(1))); equilibriumWithoutThresholds.m 110 Ahigh=min(omega(v1(:,1)<=phi(1) & omega>Alow)); equilibriumWithoutThresholds.m 111 Clow=min(omega(v1(:,1)>=phi(1) & omega>Ahigh)); equilibriumWithoutThresholds.m 112 Chigh=max(omega);

The LaTeX file uses these results by loading them into macros, which we store in the file equilibriumWithoutThresholdsConstants.tex.

 equilibriumWithoutThresholds.m 116 f1=fopen('pgfTikZ/equilibriumWithoutThresholdsConstants.tex','w'); equilibriumWithoutThresholds.m 117 equilibriumWithoutThresholds.m 118 fprintf(f1,'\\def\\ymax{%3.2f}\n',max(v1(:,1))); equilibriumWithoutThresholds.m 119 fprintf(f1,'\\def\\cunderbartwo{%3.2f}\n',underlineC); equilibriumWithoutThresholds.m 120 fprintf(f1,'\\def\\coverbartwo{%3.2f}\n',overlineC); equilibriumWithoutThresholds.m 121 fprintf(f1,'\\def\\phione{%3.2f}\n',phi(1)); equilibriumWithoutThresholds.m 122 fprintf(f1,'\\def\\phitwo{%3.2f}\n',phi(2)); equilibriumWithoutThresholds.m 123 fprintf(f1,'\\def\\chat{%3.2f}\n',min(omega)); equilibriumWithoutThresholds.m 124 fprintf(f1,'\\def\\ccheck{%3.2f}\n',max(omega)); equilibriumWithoutThresholds.m 125 fprintf(f1,'\\def\\Alow{%3.2f}\n',Alow); equilibriumWithoutThresholds.m 126 fprintf(f1,'\\def\\Ahigh{%3.2f}\n',Ahigh); equilibriumWithoutThresholds.m 127 fprintf(f1,'\\def\\Clow{%3.2f}\n',Clow); equilibriumWithoutThresholds.m 128 fprintf(f1,'\\def\\Chigh{%3.2f}\n',Chigh); equilibriumWithoutThresholds.m 129 equilibriumWithoutThresholds.m 130 fclose(f1);

The final task is to export the calculated value functions themselves. Since the first entrant's value function is quite choppy, the pgfTikZ code only places markers at each of the grid points. Nevertheless, we save the “monopoly” and “duopoly” values to separate files so that the code can give them separate colors. As always, we place a dummy variable at the end to overcome the table loading bug in pgfplots.

 equilibriumWithoutThresholds.m 136 v11=[omega(omega<=overlineC) v1(omega<=overlineC,1)]; Note that fprintf spits out its input in column order. equilibriumWithoutThresholds.m 137 equilibriumWithoutThresholds.m 138 f1=fopen('pgfTikZ/equilibriumWithoutThresholdsV11.csv','w'); equilibriumWithoutThresholds.m 139 fprintf(f1,'C, v11, dummy\n'); equilibriumWithoutThresholds.m 140 fprintf(f1,'%3.3f, %3.3f, 1.0\n',v11'); equilibriumWithoutThresholds.m 141 fclose(f1); equilibriumWithoutThresholds.m 142 equilibriumWithoutThresholds.m 143 v12=[omega(omega>underlineC) v1(omega>underlineC,2)]; equilibriumWithoutThresholds.m 144 f1=fopen('pgfTikZ/equilibriumWithoutThresholdsV12.csv','w'); equilibriumWithoutThresholds.m 145 fprintf(f1,'C, v12, dummy\n'); equilibriumWithoutThresholds.m 146 fprintf(f1,'%3.3f, %3.3f, 1.0\n',v12'); equilibriumWithoutThresholds.m 147 fclose(f1); equilibriumWithoutThresholds.m 148 equilibriumWithoutThresholds.m 149 v2=[omega v2]; equilibriumWithoutThresholds.m 150 f1=fopen('pgfTikZ/equilibriumWithoutThresholdsV2.csv','w'); equilibriumWithoutThresholds.m 151 fprintf(f1,'C, v2, dummy\n'); equilibriumWithoutThresholds.m 152 fprintf(f1,'%3.3f, %3.3f, 1.0\n',v2'); equilibriumWithoutThresholds.m 153 fclose(f1); equilibriumWithoutThresholds.m 154 equilibriumWithoutThresholds.m 155 makequit;

Figure 6 presents the equilibrium plot. It is identical to that in the text. It would be desirable to scale this up for this document, but changing the scale of the tikzpicture environment does not properly change plots using points defined by the axis coordinate system provided by pgfplots.

## 3C.2Table of Equilibrium Thresholds

Table I in Section 4.3 of the text presents the equilibrium entry and continuation thresholds for four parameterizations of the model, each calculated with and without an artificial barrier to entry beyond the fourth firm. In each of these, the Markov chain of the demand process approximates a random walk, as described in Section . The parameterizations only differ in this process's innovation variance. The four values of interest are in the vector sigma

 tableOfThresholds.m 13 sigma=[0 0.05 0.1 0.15];

We hold the model's remaining parameters constant across experiments. Since the calculations for Table II use these same values, we call the code for their assignment from a file accessible by both programs, lifoTableParameters.

 tableOfThresholds.m 18 lifoTableParameters;

The model parameters held constant across experiments can be divided into two groups. The first is used only to construct the Markov chain. We place these into the structure markovChainARG, which has all of the fields required by the input to markovChain.

Set the parameters describe the Markov chain's support.

 lifoTableParameters.m 10 markovChainARG.omega.center = 0; lifoTableParameters.m 11 markovChainARG.omega.step = 0.005; lifoTableParameters.m 12 markovChainARG.omega.width = 3;

Set the parameters that describe the underlying autoregression.

 lifoTableParameters.m 16 markovChainARG.autoRegression.rho = 1.0; lifoTableParameters.m 17 markovChainARG.autoRegression.sigma = sigma(1); This is a dummy argument that the loop below will replace.

Set the parameters describing the underlying innovation distribution and its approximation with a mixture of uniform distributions.

 lifoTableParameters.m 21 approximate.F = @(x) (1+erf(x/sqrt(2)))./2; lifoTableParameters.m 22 approximate.Frange = 4.0; lifoTableParameters.m 23 approximate.k = 51; lifoTableParameters.m 24 lifoTableParameters.m 25 markovChainARG.uniformMixtureApproximation = approximate;

The second set of parameters describe payoffs. We place these into the structure lifoARG.

 lifoTableParameters.m 29 lifoARG.beta = 1/1.05; lifoTableParameters.m 30 lifoARG.pi = @(x) 4*ones(size(x,1),1); lifoTableParameters.m 31 lifoARG.kappa = 1.75; lifoTableParameters.m 32 lifoARG.phi = @(x) 0.25*lifoARG.beta/(1-lifoARG.beta)*ones(size(x,1),1);

Equilibrium calculation requires us to choose a convergence tolerance for the Bellman equation iteration.

 lifoTableParameters.m 37 lifoARG.convergenceTolerance = 1e-7;

So that we can preallocate the matrices storing the equilibrium thresholds, we calculate here , an upper bound on the number of active firms. To do so, we set up an anonymous function that yields each firm's flow profit as a function of and then search for the lowest number of firms that makes it negative. Since is constant in this exercise, we could just as easily have calculated algebraically. We adopt this code so that our program can be more easily generalized.

 lifoTableParameters.m 44 f = @(x) x(:,1).*lifoARG.pi(x(:,2))./x(:,2)-lifoARG.kappa; lifoTableParameters.m 45 lifoTableParameters.m 46 nCheck=1; lifoTableParameters.m 47 cCheck=exp(markovChainARG.omega.width/2); lifoTableParameters.m 48 while f([cCheck nCheck])>0 lifoTableParameters.m 49 nCheck=nCheck+1; lifoTableParameters.m 50 end lifoTableParameters.m 51 nCheck = nCheck-1; lifoTableParameters.m 52 lifoARG.nCheck = nCheck;

To construct the table, we cycle through the values in sigma. For each one, we first build the approximating Markov chain. Then, we calculate the equilibrium with and without the exogenous barrier to entry. We store the resulting threshold calculations in

 tableOfThresholds.m 27 freeEntryThresholds = zeros(length(sigma),nCheck); tableOfThresholds.m 28 freeContinuationThresholds = zeros(length(sigma),nCheck); tableOfThresholds.m 29 fourEntryThresholds = zeros(length(sigma),4); tableOfThresholds.m 30 fourContinuationThresholds = zeros(length(sigma),4); tableOfThresholds.m 31 tableOfThresholds.m 32 freeEntryExitRate = zeros(length(sigma),1);

Footnote 13 of the text reports the exit rates from three of the experiments. Accordingly, we calculate the barrier-free equilibrium's ergodic distribution over and use this and the Markov chain to calculate the ergodic distribution's exit rate.

 tableOfThresholds.m 38 for i=1:length(sigma); tableOfThresholds.m 39 tableOfThresholds.m 40 Construct the Markov Chain and use it to finish lifoARG. tableOfThresholds.m 41 markovChainARG.autoRegression.sigma = sigma(i); tableOfThresholds.m 42 MARKOVCHAIN = markovChain(markovChainARG); tableOfThresholds.m 43 tableOfThresholds.m 44 lifoARG.Pi = MARKOVCHAIN.transitionMatrix; tableOfThresholds.m 45 lifoARG.omega = exp(MARKOVCHAIN.support'); tableOfThresholds.m 46 tableOfThresholds.m 47 Calculate the equilibrium without a barrier to entry. tableOfThresholds.m 48 lifoARG.nCheck = nCheck; tableOfThresholds.m 49 freeEntryEQUILIBRIUM = calculateLifoEquilibrium(lifoARG); tableOfThresholds.m 50 tableOfThresholds.m 51 Calculate the entry and continuation thresholds. tableOfThresholds.m 52 THRESHOLDS = calculateThresholds(freeEntryEQUILIBRIUM); tableOfThresholds.m 53 tableOfThresholds.m 54 Store the results. tableOfThresholds.m 55 freeEntryThresholds(i,:) = THRESHOLDS.entry; tableOfThresholds.m 56 freeContinuationThresholds(i,:) = THRESHOLDS.continuation; tableOfThresholds.m 57 tableOfThresholds.m 58 Repeat the analysis with an exogenous barrier to entry. tableOfThresholds.m 59 lifoARG.nCheck = 4; tableOfThresholds.m 60 fourEntryEQUILIBRIUM = calculateLifoEquilibrium(lifoARG); tableOfThresholds.m 61 THRESHOLDS = calculateThresholds(fourEntryEQUILIBRIUM); tableOfThresholds.m 62 fourEntryThresholds(i,:) = THRESHOLDS.entry; tableOfThresholds.m 63 fourContinuationThresholds(i,:) = THRESHOLDS.continuation; tableOfThresholds.m 64 tableOfThresholds.m 65 if sigma(i)>0 tableOfThresholds.m 66 Calculate the barrier-free equilibrium's ergodic distribution. tableOfThresholds.m 67 ERGODIC=calculateLifoErgodicDistribution(freeEntryEQUILIBRIUM); tableOfThresholds.m 68 ERGODIC.nPrime=freeEntryEQUILIBRIUM.equilibriumFirmCount; tableOfThresholds.m 69 tableOfThresholds.m 70 Use these results to calculate equilibrium statistics tableOfThresholds.m 71 STATS = tabulateEquilibriumStatistics(ERGODIC); tableOfThresholds.m 72 freeEntryExitRate(i) = STATS.exitRate; tableOfThresholds.m 73 end tableOfThresholds.m 74 tableOfThresholds.m 75 end

Now, we proceed with the reporting of the results. The entry and exit thresholds for a rank with zero probability in the ergodic distribution are left blank in the table. To indicate this, we replace them with NaN. We do this only for the barrier-free equilibrium, because it turns out to be unnecessary with a barrier.

Eliminate any columns beginning with NaN.

 tableOfThresholds.m 89 keepColumns=find(blankMask(1,:)==0); tableOfThresholds.m 90 freeEntryThresholds=freeEntryThresholds(:,keepColumns); tableOfThresholds.m 91 freeContinuationThresholds=freeContinuationThresholds(:,keepColumns);

Export the results to LaTeX files for inclusion in the paper, using the code in tableOfThresholdsLaTeX. Appendix 4D presents that code in detail.

 tableOfThresholds.m 95 tableOfThresholdsLaTeX; tableOfThresholds.m 96 tableOfThresholds.m 97 makequit; tableOfThresholds.m 98

## 3C.3Table of Ordered Probit Thresholds

The paper concludes by examining what a static analysis of market size and market structure, such as that of Bresnahan and Reiss (1991), would uncover if it used data drawn from the ergodic distribution of our model. For this, we suppose that the researcher renders the LIFO model essentially static using the following assumptions.

• .
• for all .
• for all .

That is, the market begins with no incumbents, at which time the initial value of is drawn. This value never changes. In such an environment, there is no distinction between fixed and sunk costs, so we set the later to zero.

In equilibrium, all entry occurs in the first period, and there is no subsequent exit. Equilibrium requires that all entering firms earn a positive profit and that the potential entrant choosing to stay inactive would earn a nonpostive profit.

 (6) (7)

Suppose that we have observations of and from a cross section of independent markets, and we wish to combine these observations with (6) and (7) to infer the values of scaled by . Let denote the market size at which firms choose to enter and an 'th entering firm would earn exactly zero profit. The free-entry conditions can be rearranged to yield

(8)

In (8), and . By observing the market size at which the number of active firms jumps from to , we can determine and therefore .

Of course, markets differ in unobservable ways from each other, so real data do not display such jumps. To make the model suitable for empirical use, we can follow and suppose that the fixed cost of production is stochastic across markets but the same for each potential participant in a given market. We denote this common cost with , where . With this change, the free-entry conditions become

(0)

and

(0)

With these free-entry conditions, the probability that exactly firms serve an industry with market-size is

(0)

Here, the parameter vector . This is just the standard ordered-probit likelihood function.

Given any joint distribution of , the population likelihood function,

(0)

is concave in . Therefore, we can always define as the unique maximizer of . It is with this tool in hand that we approach the problem of evaluating the consequences of actual dynamics for static market-size/market-structure analysis. Given the joint distribution of from the LIFO model, we calculate and thereby quantify the effects of dynamic model misspecification.

The function orderedProbitMaximumLikelihoodEstimation contains the code implementing these calculations. Appendix 2B describes this in detail. It has a single argument with three fields. The first two have identical names to those in the output structure of calculateLifoErgodicDistribution.

support
An matrix. Each row gives one element of the support for .
distribution
A column vector of length . Its 'th element gives the probability of equaling the 'th row of support
epsilon
A scalar close to zero. The function uses this to avoid problems with taking the logarithm of zero.

The fields of its single output are

sigma
The estimated value of .
thresholds
A vector containing the estimated ordered-probit thresholds.
indices
A vector the same size as thresholds containing the number of firms corresponding to each threshold. Both this and thresholds are sorted in ascending order.

To construct the table of ordered probit thresholds, we cycle through the non-zero elements of used for Table I and calculate the LIFO equilibrium without a barrier to entry.

 tableOfOrderedProbitThresholds.m 71 sigma=[0.05 0.1 0.15];

The other model parameters can be divided into two groups. The first is used only to construct the Markov chain. We place these into the structure markovChainARG, which has all of the fields required by the input to markovChain.

Set the parameters describe the Markov chain's support.

 tableOfOrderedProbitThresholds.m 80 markovChainARG.omega.center = 0; tableOfOrderedProbitThresholds.m 81 markovChainARG.omega.step = 0.005; tableOfOrderedProbitThresholds.m 82 markovChainARG.omega.width = 3;

Set the parameters that describe the underlying autoregression.

 tableOfOrderedProbitThresholds.m 86 markovChainARG.autoRegression.rho = 1.0; tableOfOrderedProbitThresholds.m 87 markovChainARG.autoRegression.sigma = sigma(1); This is a dummy argument that the loop below will replace.

Set the parameters describing the underlying innovation distribution and its approximation with a mixture of uniform distributions.

 tableOfOrderedProbitThresholds.m 91 approximate.F = @(x) (1+erf(x/sqrt(2)))./2; tableOfOrderedProbitThresholds.m 92 approximate.Frange = 4.0; tableOfOrderedProbitThresholds.m 93 approximate.k = 51; tableOfOrderedProbitThresholds.m 94 tableOfOrderedProbitThresholds.m 95 markovChainARG.uniformMixtureApproximation = approximate; tableOfOrderedProbitThresholds.m 96

The second set of parameters describe payoffs. We place these into the structure lifoARG.

 tableOfOrderedProbitThresholds.m 100 lifoARG.beta = 1/1.05; tableOfOrderedProbitThresholds.m 101 lifoARG.pi = @(x) 4*ones(size(x,1),1); tableOfOrderedProbitThresholds.m 102 lifoARG.kappa = 1.75; tableOfOrderedProbitThresholds.m 103 lifoARG.phi = @(x) 0.25*lifoARG.beta/(1-lifoARG.beta)*ones(size(x,1),1);

Equilibrium calculation also requires us to choose a convergence tolerance for % the Bellman equation iteration.

 tableOfOrderedProbitThresholds.m 107 lifoARG.convergenceTolerance = 1e-7;

So that we can preallocate the matrices storing the equilibrium thresholds, we calculate here , an upper bound on the number of active firms. To do so, we set up an anonymous function that yields each firm's flow profit as a function of and then search for the lowest number of firms that makes it negative. Since is constant in this exercise, we could just as easily have calculated algebraically. We adopt this code so that our program can be more easily generalized.

 tableOfOrderedProbitThresholds.m 114 f = @(x) x(:,1).*lifoARG.pi(x(:,2))./x(:,2)-lifoARG.kappa; tableOfOrderedProbitThresholds.m 115 tableOfOrderedProbitThresholds.m 116 nCheck=1; tableOfOrderedProbitThresholds.m 117 cCheck=exp(markovChainARG.omega.width/2); tableOfOrderedProbitThresholds.m 118 while f([cCheck nCheck])>0 tableOfOrderedProbitThresholds.m 119 nCheck=nCheck+1; tableOfOrderedProbitThresholds.m 120 end tableOfOrderedProbitThresholds.m 121 nCheck = nCheck-1; tableOfOrderedProbitThresholds.m 122 lifoARG.nCheck = nCheck;

To construct the table, we cycle through the values in sigma. For each one, we first build the approximating Markov chain. Then, we calculate the equilibrium with and without the exogenous barrier to entry. We store the resulting threshold calculations in

 tableOfOrderedProbitThresholds.m 128 probitThresholds = zeros(length(sigma),nCheck); tableOfOrderedProbitThresholds.m 129 piRatios = zeros(length(sigma),nCheck); tableOfOrderedProbitThresholds.m 130 tableOfOrderedProbitThresholds.m 131 for i=1:length(sigma);

Construct the Markov Chain and use it to finish lifoARG.

 tableOfOrderedProbitThresholds.m 135 markovChainARG.autoRegression.sigma = sigma(i); tableOfOrderedProbitThresholds.m 136 MARKOVCHAIN = markovChain(markovChainARG); tableOfOrderedProbitThresholds.m 137 tableOfOrderedProbitThresholds.m 138 lifoARG.Pi = MARKOVCHAIN.transitionMatrix; tableOfOrderedProbitThresholds.m 139 lifoARG.omega = exp(MARKOVCHAIN.support');

Calculate the equilibrium.

 tableOfOrderedProbitThresholds.m 143 lifoARG.nCheck = nCheck; tableOfOrderedProbitThresholds.m 144 freeEntryEQUILIBRIUM = calculateLifoEquilibrium(lifoARG);

Calculate the equilibrium's ergodic distribution.

 tableOfOrderedProbitThresholds.m 148 ERGODIC=calculateLifoErgodicDistribution(freeEntryEQUILIBRIUM);

Use the ergodic distribution to calculate the ordered-probit thresholds.

 tableOfOrderedProbitThresholds.m 152 ERGODIC.epsilon=1e-7; tableOfOrderedProbitThresholds.m 153 PROBIT=orderedProbitMaximumLikelihoodEstimation(ERGODIC);

Store the estimated thresholds.

 tableOfOrderedProbitThresholds.m 157 probitThresholds(i,PROBIT.indices)=PROBIT.thresholds;

Calculate estimates of (up to scale).

 tableOfOrderedProbitThresholds.m 161 piHat=PROBIT.indices./PROBIT.thresholds;

Calculate the implied values of .

 tableOfOrderedProbitThresholds.m 165 piHatChange=piHat(2:end)./piHat(1:end-1);

Accumulate these changes to get the implied values of .

 tableOfOrderedProbitThresholds.m 169 piHatRatio=cumprod(piHatChange);

Pad piHatRatio with a one on the left-hand side and save it.

 tableOfOrderedProbitThresholds.m 173 piRatios(i,PROBIT.indices)=[1 piHatRatio]; tableOfOrderedProbitThresholds.m 174 tableOfOrderedProbitThresholds.m 175 end

Following the construction of Table I, we place NaN's in probitThresholds and piRatios in the positions corresponding to blank elements in the two panels, and we then remove columns containing only NaN's

 tableOfOrderedProbitThresholds.m 180 probitThresholds(probitThresholds==0)=NaN; tableOfOrderedProbitThresholds.m 181 piRatios(piRatios==0)=NaN; tableOfOrderedProbitThresholds.m 182 tableOfOrderedProbitThresholds.m 183 keepColumns=find(~isnan(probitThresholds(1,:))); tableOfOrderedProbitThresholds.m 184 probitThresholds=probitThresholds(:,keepColumns); tableOfOrderedProbitThresholds.m 185 piRatios=piRatios(:,keepColumns);

This completes the required calculations for Table II. The file tableOfOrderedProbitThresholdsLaTeX.m contains the code for creating the table itself. See Appendix 4D for its description.

 tableOfOrderedProbitThresholds.m 190 tableOfOrderedProbitThresholdsLaTeX; tableOfOrderedProbitThresholds.m 191 tableOfOrderedProbitThresholds.m 192 makequit;

# 4DExercises for the Student

1. Footnote 7 in the text notes that the requirement that be weakly increasing is not necessary for the LIFO equilibrium and (essential) uniqueness results of Propositions 1 and 2 to go through. Show with an example that Proposition 3, which gives sufficient conditions for the entry and continuation decisions of all firms to follow threshold-based rules, does require this assumption.
2. Show with a counterexample that the Assumption 3 in the text is not necessary for firms of all ranks to use threshold rules for their entry and continuation decisions. (Hint, modify the demand process from the Pencil-and-paper example.)
3. The specification underlying Tables I and II sets equal to a constant, so entry does not change producers' surplus per customer. Recalculate these tables using a different specification arising from an oligopoly model where markups fall with entry. Explain how the results do and do not change.
4. Consider a version of the paper's game in which all play ends after periods. Because all actions in this game occur sequentially, the subgame perfect equilibrium of this game in strategies that default to inactivity is unique. Show that for a fixed , the equilibrium payoffs and strategies converge to those of the infinite horizon game's LIFO equilibrium as .
5. The theory of industrial organization is filled with two-period models of entry deterrence. In the first period, an incumbent can take an action that changes the payoffs and incentives in the second-stage game. If these actions credibly lower the payoff to entry enough, then a firm with the option to enter between the periods might not choose to exercise it. This exercise asks you to use the LIFO oligopoly dynamics model to explore this in a dynamic environment with uncertainty. Using the parameters underlying Tables I and II, calculate the equilibrium continuation value to an incumbent monopolist as a function of for a grid of values for . Plot the results. Use this plot and similar ones created with alternative parameter values to discuss the effects of dynamics and uncertainty on the incentives to lower .
6. For this exercise, we suppose that incumbent producers make their continuation decisions sequentially, youngest first, and we look for a Markov-perfect equilibrium in which an incumbent producer rationally expects to outlive any competitor with a lower name. We call this a First-In First-Out (FIFO) equilibrium. This exercise also requires the following assumptions.
• The stochastic process governing the evolution of demand is that from the Pencil-and-paper example.
• At most two firms can serve the industry.
Characterize the set of FIFO equilibria with the following steps.
1. Sketch a portion of the game tree for this game. (See Figure 1 in the text.)
2. Define a symmetric FIFO equilibrium that defaults to inactivity.
3. Write the Bellman equation that necessarily characterizes the equilibrium payoff to a duopolist facing a rival with a higher rank, and show that its solution is piecewise linear in .
4. Suppose that a potential entrant to the market expects all future potential entrants facing a single incumbent to enter if and only if for some arbitrary entry set . Write the Bellman equation that necessarily characterizes the equilibrium payoff to the potential entrant from actually entering.
5. Use the Bellman equation to show that the potential entrant actually enters if , where this entry threshold is a function of the presupposed entry set .
6. Show that if and the Lebegue measure of is strictly less than that of , then
7. Use the previous results to prove that there exists a unique FIFO equilibrium that defaults to inactivity. Characterize its equilibrium survival and entry sets.
7. The paper's introduction claims

Modifying our model to make fixed costs decline deterministically with age is straightforward, and we obtain the LIFO equilibrium as the limit of the sequence of “natural” (in Cabral's sense) equilibria to our model as we send the learning curve's slope to zero.

This exercise consists of the verification of this claim. For it, we suppose that

• The fixed cost of production for firm after it has produced for periods is , where , , , , and . Since fixed costs decline exogenously over time, this is a “learning-by-ageing” technology. We make the fixed costs of earlier entrants decline faster than those of later entrants so that no two firms that entered in the same period have the same costs.
• Incumbent producers make their continuation decisions simultaneously. Potential entrants then make their entry decisions, as in the LIFO model.
Cabral (1993) defines a “natural” equilibrium as

Natural equilibrium definition here.

1. Sketch the game tree of the modified model.
2. Define a natural Markov-perfect equilibrium that defaults to inactivity. (Note: Since each player has different fixed costs of production, we have no interest in symmetric equilibria.)
3. Constructively prove the existence of a natural Markov-perfect equilibrium that defaults to inactivity. (For this, you can adapt the proof of Proposition 1. Be careful to define each player's strategy.)
4. Demonstrate the uniqueness of the natural Markov-perfect equilibrium that defaults to inactivity constructed above.
5. Consider a sequence of values for that converge to zero. The unique natural Markov-perfect equilibrium that defaults to inactivity defines corresponding sequences of equilibrium payoffs and strategies. Show that these converge to the LIFO equilibrium payoffs and strategies.
8. This exercise modifies the model to include a once-and-for-all investment at the time of entry. Denote a firm's level of investment with , so the total cost at entry is . The producers' surplus per customer for a monopolist is , while that for a duopolist facing a rival with investment is . We make the following assumptions.
• .
• .
• and are concave and twice differentiable in for any given with

This last restriction requires two firms' investments to be strategic substitutes in a static game.
1. Sketch the game tree of the modified model.
2. Define a Markovian strategy and a LIFO strategy for this game.
3. Constructively prove the existence of a symmetric Markov-perfect equilibrium in a LIFO strategy.
4. Following , decompose the derivative of a first-entrant's continuation value with respect to into direct and strategic effects.
5. Write a Matlab program for calculating the Markov-perfect equilibrium constructed above. For a particular specification of and , calculate the equilibrium and the direct and strategic effects of investment on the first-mover's continuation value. Plot these as a function of and interpret the results.
9. This exercise extends the LIFO model to study optimal merger policy. For this extension, we suppose that . Before firms continuation decisions are made, a high-ranked firm can make a take-it-or-leave-it offer to buy out a lower ranked rival. (Assume that the rival accepts if the offer exactly equals the payoff from continuation.) The buy-out results in the acquired firm's closure.
1. Sketch the game tree of the modified model.
2. Define a Markovian strategy and a LIFO strategy for this game.
3. Show that the higher ranked firm will make an offer worth accepting only if .
4. Constructively prove the existence of a symmetric Markov-perfect equilibrium in a LIFO strategy.
5. Write a Matlab program for calculating the Markov-perfect equilibrium constructed above. Suppose that each consumer has a linear demand curve , and that duopolists compete in quantities. Use your program to calculate the equilibrium for given values of and .
6. Modify the game further by adding a competition authority, with the authority to impede a proposed merger. Suppose that the authority's policy is to approve a merger if and only if . Modify your Matlab program to calculate this model's LIFO equilibrium. Use it to compare welfare in the unregulated equilibrium with that from the regulated equilibrium for various values of . (This will be a function of , the initial demand state.) Interpret the results.

# 1AApproximating an Autoregressive Demand Process

For the experiments generating Tables I and II, we specify to approximate a first-order autoregression with a normally-distributed error.

(0)

with . For this, we begin with the approximation of as a mixture of uniform random variables all centered at zero.

#### Distribution Approximation with Mixtures of Uniform Random Variables

We denote the random variable to be approximated with and its c.d.f. with . The function uniformMixtureApproximation contains the code for producing a uniform-mixture approximation to a given distribution. Its single input, ARG, is a structure with three fields.

F
A handle to an anonymous function that equals .
Frange
A scaler, half of the width of the symmetric support for
k
An integer, the number of uniform distributions to use in the approximation.

Its output is also a structure, OUT, with three fields

ranges
A vector. Each element gives half of the width of an approximating uniform distribution's support.
mixingProbabilities
A vector of mixing probabilities over the distributions defined by OUT.ranges.
uniformCDF
A handle to an anonymous function that evaluates the uniform distribution's c.d.f..

 uniformMixtureApproximation.m 23 function OUT = uniformMixtureApproximation(ARG) uniformMixtureApproximation.m 24 uniformMixtureApproximation.m 25 F=ARG.F; uniformMixtureApproximation.m 26 Frange=ARG.Frange; uniformMixtureApproximation.m 27 k=ARG.k;

The approximation's construction proceeds by first selecting the uniform distriubtions to be employed. These are all centered on zero and have ranges from an evently spaced grid on [0,Frange].

 uniformMixtureApproximation.m 32 r=(Frange/k):(Frange/k):Frange;

Denote the c.d.f. of a uniform distribution on with . Our approximation proceeds by choosing the vector of mixing probabilities so that on an evenly spaced grid of points . This calculation requires us only to solve a set of linear equations. For their construction, we require only and an anonymous function to return .

 uniformMixtureApproximation.m 38 x=-Frange*(k-1)/k:Frange/k:0; uniformMixtureApproximation.m 39 x=x'; Turn x into a column vector.

Below, it will be helpful to let the anonymous function representing to accept matrix-valued arguments. In the implementation here, arg.x is the c.d.f.'s argument and arg.r is half the width of its support.

 uniformMixtureApproximation.m 44 G=@(arg) (-arg.r=arg.r); Otherwise, return one if the argument is to the right of r.

We write the system of linear equations as

(0)

where and

 uniformMixtureApproximation.m 52 f=F(x); Value of the true c.d.f. at the approximation points

The anonymous function G was carefully constructed to accept matrix-valued inputs, so we can form the matrix with just one call to G.

 uniformMixtureApproximation.m 56 arg.x=kron(x,ones(1,k)); uniformMixtureApproximation.m 57 arg.r=kron(ones(k,1),r); uniformMixtureApproximation.m 58 A=G(arg);

We are now prepared to calculate the mixing probabilities, construct the output, and end the function.

 uniformMixtureApproximation.m 62 p=A\f; uniformMixtureApproximation.m 63 uniformMixtureApproximation.m 64 OUT.ranges=r; uniformMixtureApproximation.m 65 OUT.mixingProbabilities=p; uniformMixtureApproximation.m 66 OUT.uniformCDF=G; uniformMixtureApproximation.m 67 uniformMixtureApproximation.m 68 end

#### Test of uniformMixtureApproximation

The program uniformMixtureApproximationTest.m tests this approxiation routine. For this, we calcuate several approximations to a normal distribution and plot the resulting c.d.f. with the original. The approximations use different numbers of uniform distributions, but they share the same support - 5 standard deviations to either side of zero.

Set the fields of ARG that are held fixed across approximations.

 uniformMixtureApproximationTest.m 11 ARG.F=@(x) (1+erf(x/sqrt(2)))./2; Standard normal c.d.f. uniformMixtureApproximationTest.m 12 ARG.Frange=5;

Initialize the figure with the exact c.d.f.. We evaluate it on a very fine grid covering the approximation's support. We call this x.

 uniformMixtureApproximationTest.m 16 x=-ARG.Frange:0.001:ARG.Frange; uniformMixtureApproximationTest.m 17 x=x';

Since ARG.F accepts vector-valued arguments, we can evaluate the exact c.d.f. on x with a single function call.

 uniformMixtureApproximationTest.m 21 yExact=ARG.F(x);

The plot of the exact c.d.f. uses an extra thick gray line so that the finer approximations can be distinguished from it.

 uniformMixtureApproximationTest.m 25 plot(x,yExact,'Color',[0.7 0.7 0.7],'LineWidth',8);

We will add the approximations' c.d.f's to this figure, so we wish to hold it.

 uniformMixtureApproximationTest.m 29 hold;

Style the plot

 uniformMixtureApproximationTest.m 33 set(gca,'Box','off','FontSize',14) Increase font size and turn off the box around the plot. uniformMixtureApproximationTest.m 34 set(gcf,'Color',[1 1 1]); Set the background color to white.

Now we proceed to calculate each of the approximations and add them to the figure. The following vector stores the number of uniform distributions for each approximation.

 uniformMixtureApproximationTest.m 38 kVec=[4 6 10];

To distinguish the approximations from each other, we assign them line styles and colors when plotting them.

 uniformMixtureApproximationTest.m 42 lineStyles=cell(3,1); uniformMixtureApproximationTest.m 43 lineStyles{1}='--r'; uniformMixtureApproximationTest.m 44 lineStyles{2}=':b'; uniformMixtureApproximationTest.m 45 lineStyles{3}='-k';

Cycle through the elements of kVec creating the approximations and adding them to the figure.

 uniformMixtureApproximationTest.m 49 for i=1:length(kVec); uniformMixtureApproximationTest.m 50 uniformMixtureApproximationTest.m 51 ARG.k=kVec(i); uniformMixtureApproximationTest.m 52 uniformMixtureApproximationTest.m 53 OUT=uniformMixtureApproximation(ARG);

Evaluating the approximation merely requires us to evaluate the relevant uniform c.d.f.s and calcualte their weighted sums.

 uniformMixtureApproximationTest.m 57 G=OUT.uniformCDF; uniformMixtureApproximationTest.m 58 p=OUT.mixingProbabilities; uniformMixtureApproximationTest.m 59 r=OUT.ranges; uniformMixtureApproximationTest.m 60 uniformMixtureApproximationTest.m 61 arg.x=kron(x,ones(1,ARG.k)); uniformMixtureApproximationTest.m 62 arg.r=kron(ones(length(x),1),r); uniformMixtureApproximationTest.m 63 uniformMixtureApproximationTest.m 64 yApproximate=G(arg)*p; uniformMixtureApproximationTest.m 65 uniformMixtureApproximationTest.m 66 plot(x,yApproximate,lineStyles{i},'LineWidth',2); Add this approximation to the figure. uniformMixtureApproximationTest.m 67 uniformMixtureApproximationTest.m 68 end

Create a legend for the plot.

 uniformMixtureApproximationTest.m 72 h1=legend('Original Distribution','k=4','k=6','k=10','Location','NorthWest'); uniformMixtureApproximationTest.m 73 set(h1,'box','off');

Finally export the figure to a .jpg file and quit if we are running this from make.

 uniformMixtureApproximationTest.m 77 set(gcf,'Position',[-3 5 1280 950],... uniformMixtureApproximationTest.m 78 'PaperUnits','in','PaperSize',[5 3],... uniformMixtureApproximationTest.m 79 'PaperPositionMode','manual',... uniformMixtureApproximationTest.m 80 'PaperPosition',[0 0 5 3]); Set the figure to the desired size. uniformMixtureApproximationTest.m 81 print -djpeg -painters uniformMixtureApproximationTest.jpg uniformMixtureApproximationTest.m 82 makequit;

Figure 7 presents the resulting figure. As we can see, the approximation is very accurate even when mixing over 10 uniform distributions.

In the paper, the process governing the evolution of demand is bounded and Markovian. To approximate this with a Markov chain, we begin with an eveny spaced grid

(0)

Given each , we approximate with a mixture of uniformly distributed random variables. Each of these has a straightforward approximation over .

#### Constructing the Markov Chain

The function markovChain takes care of constructing the actual Markov chain. Mimicing uniformMixtureApproximation, it takes a single input, ARG, which is a structure with the following fields.

omega
A structure with parameters describing the Markov chain's support. This is constructed as an evenly spaced grid over [omega.center-omega.width/2,omega.center+omega.width/2] with distance omega.step between each of the points.
sigma
A structure with parameters describing the autoregression to be approximated.
rho
The autoregressive parameter.
sigma
The innovation's standard deviation.
uniformMixtureApproximation
A structure with parameters describing the approximation of the innovation error with a mixture of uniform random variables. This is fed directly to the function of the same name.

The function's single output is a structure, OUT with fields

support
A vector containing the elements of the Markov chain's support.
transitionMatrix
The Markov chain's transition matrix. Its elements are conformable with those of support.

 markovChain.m 25 function OUT=markovChain(ARG)

Begin by calling uniformMixtureApproximation to calculate the mixing probabilities and approximating uniform distributions used for the approximation of the autoregression's innovation.

 markovChain.m 30 innovationApproximation=uniformMixtureApproximation(ARG.uniformMixtureApproximation); markovChain.m 31 p=innovationApproximation.mixingProbabilities; markovChain.m 32 r=innovationApproximation.ranges; markovChain.m 33 k=ARG.uniformMixtureApproximation.k;

Set up state space,

 markovChain.m 37 omega=(ARG.omega.center-0.5*ARG.omega.width):ARG.omega.step:(ARG.omega.center+0.5*ARG.omega.width); markovChain.m 38 nOmega=length(omega);

Construct the Markov chain.

 markovChain.m 42 rho=ARG.autoRegression.rho; markovChain.m 43 sigma=ARG.autoRegression.sigma;

Scale the uniform distributions' ranges by sigma.

 markovChain.m 47 r=sigma*r;

Allocate the transition matrix.

 markovChain.m 51 Pi=zeros(nOmega,nOmega);

Calculate the transition matrix conditional on the uniform mixing distribution chosen. For the 'th element of r, we call this Pii. Their weighted sum over all equals the Markov chain's transition matrix.

 markovChain.m 56 for i=1:k markovChain.m 57 Pii=zeros(nOmega,nOmega); markovChain.m 58 markovChain.m 59 for j=1:nOmega Calculate the transition probabilities for each state.

%Calculate the conditional mean and support of the underlying continuous distribution.

 markovChain.m 63 EC=rho*(omega(j)-ARG.omega.center)+ARG.omega.center; markovChain.m 64 lowlim=EC-r(i); markovChain.m 65 highlim=EC+r(i);

If the the random variable could leave , then adjust the lower or upper limit of the random variable's support accordingly. Since the maximum value of ri equals omega(end)-omega(1), we never need adjust both of them.

 markovChain.m 70 if lowlimomega(end); markovChain.m 74 lowlim=omega(end)-2*r(i); markovChain.m 75 highlim=omega(end); markovChain.m 76 end

Find the states with positive probability, count them, and set the appropriate elements of Pii

 markovChain.m 80 cindx=find((lowlim<=omega).*(highlim>=omega)); A vector of indices for omega of points between lowlim and highlim. markovChain.m 81 nMoves=length(cindx); The number of different possible values for given . markovChain.m 82 Pii(j,cindx)=1/nMoves; Distribute the probability evenly over the possible values for . markovChain.m 83 markovChain.m 84 end

Multiply Pii by the mixing probability and add it to Pi.

 markovChain.m 88 Pi=Pi+p(i)*Pii; markovChain.m 89 markovChain.m 90 end

The construction of the Markov transition matrix is now complete. All that remains is the output structure's assembly.

 markovChain.m 94 OUT.support=omega; markovChain.m 95 OUT.transitionMatrix=Pi; markovChain.m 96 markovChain.m 97 end

#### Test of markovChain

To test markovChain, we use it to approximate a random walk with normal innovation variance . The approximation lives on an evenly spaced grid of 301 points The error distribution's uniform mixture approximation uses 10 distributions and extends three standard deviations to either side of zero.

 markovChainTest.m 9 ARG.omega.center=0.0; markovChainTest.m 10 ARG.omega.step=0.01; markovChainTest.m 11 ARG.omega.width=3; markovChainTest.m 12 markovChainTest.m 13 ARG.autoRegression.rho=1; markovChainTest.m 14 ARG.autoRegression.sigma=0.3; markovChainTest.m 15 markovChainTest.m 16 ARG.uniformMixtureApproximation.F=@(x) (1+erf(x/sqrt(2)))./2; markovChainTest.m 17 ARG.uniformMixtureApproximation.Frange=3; markovChainTest.m 18 ARG.uniformMixtureApproximation.k=10; markovChainTest.m 19 markovChainTest.m 20 OUT=markovChain(ARG); markovChainTest.m 21 markovChainTest.m 22 omega=OUT.support; markovChainTest.m 23 Pi=OUT.transitionMatrix;

To examine the output, plot the 10th, 25th, 50th, 75th and 90th conditional percentiles of as functions of . Denote these with . We begin with the calculation of the conditional c.d.f.

 markovChainTest.m 28 cdf=100*cumsum(Pi,2); The “2” indicates summation along each row. Express the result in percentage points.

Since the approximate distribution is discrete, it typically has no exact percentiles for any given probability. Therefore, we set to the value of with the value of closest to .

 markovChainTest.m 33 pvec = [10 25 50 75 90]; Put the probability values of interest (in percentage points) into a vector. markovChainTest.m 34 Q = zeros(length(pvec),length(omega)); Allocate a matrix to hold the conditional quantiles. markovChainTest.m 35 markovChainTest.m 36 for i=1:length(pvec) markovChainTest.m 37 markovChainTest.m 38 [F,indx]=min(abs(cdf-pvec(i)),[],2); Matlab syntax requires an empty matrix as the second argument to min when calculating minima across rows, as the “2” indicates. markovChainTest.m 39 Q(i,:)=omega(indx); The vector indx gives the index in omega of each percentile. markovChainTest.m 40 markovChainTest.m 41 end

For comparison, it is helpful to plot the exact conditional percentiles of the autoregression being approximated.

 markovChainTest.m 45 QExact=zeros(length(pvec),length(omega)); markovChainTest.m 46 markovChainTest.m 47 for i=1:length(pvec); markovChainTest.m 48 markovChainTest.m 49 q=sqrt(2)*erfinv(2*pvec(i)/100-1); Calculate the innovation's percentile. markovChainTest.m 50 QExact(i,:) = ARG.autoRegression.rho*omega+ARG.autoRegression.sigma*q; Transform it into the conditional percentile. markovChainTest.m 51 markovChainTest.m 52 end

Since the percentiles are naturally ordered vertically, there is no need to visually distinguish one from the other. We first plot the approximation's percentiles and then the exact distribution's percentiles. The latter are gray and a little thick, so that they can be seen along with with the thin black lines representing the approximation's percentiles.

 markovChainTest.m 58 plot(omega,QExact,'Color',[0.8 0.8 0.8],'LineWidth',3); markovChainTest.m 59 hold markovChainTest.m 60 plot(omega,Q,'Color','k','LineWidth',1);

All that remains is to style the plot and save it to a .jpg file.

 markovChainTest.m 64 Chat=ARG.omega.center-0.5*ARG.omega.width; markovChainTest.m 65 Ccheck=ARG.omega.center+0.5*ARG.omega.width; markovChainTest.m 66 Cmiddle=ARG.omega.center; markovChainTest.m 67 markovChainTest.m 68 set(gca,'box','off','FontSize',14,'Xtick',[Chat Cmiddle Ccheck]); markovChainTest.m 69 set(gcf,'Color',[1 1 1]); markovChainTest.m 70 markovChainTest.m 71 set(gcf,'Position',[-3 5 1280 950],... markovChainTest.m 72 'PaperUnits','in','PaperSize',[5 3],... markovChainTest.m 73 'PaperPositionMode','manual',... markovChainTest.m 74 'PaperPosition',[0 0 5 3]); Set the figure to the desired size. markovChainTest.m 75 print -djpeg -painters markovChainApproximationTestPercentiles.jpg

Figure 8 presents the plot. As expected, the approximation accurately reproduces the underlying random walk in the middle of and deviates substantially towards the boundaries.

For a final test, we calculate the ergodic distribution associated with the Markov chain and plot it. This is a “test” only to the extent that we confirm the existence of a unit eigenvalue of and an associated left eigenvector, which satisfies.

(0)

For the calculation, we use the eigs command, which accepts an optional integer argument i requesting the calculation of the i largest eigenvalues and their associated eigenvectors. Of course, we are interested in only the largest eigenvalue, which should equal one. In the output, p is the eigenvector, d is its associated eigenvalue, and flag is an indicator that should equal zero if the calculations of eigs converged.

 markovChainTest.m 98 [p,d,flag]=eigs(Pi',1); markovChainTest.m 99 markovChainTest.m 100 if abs(d-1)>10e-10 || flag~=0 markovChainTest.m 101 error('Calculation of ergodic distribution failed.') markovChainTest.m 102 end markovChainTest.m 103

Normalize the eigen vector to have unit, plot it, and save the plot to a.jpg file.

 markovChainTest.m 106 p=p/sum(p); markovChainTest.m 107 markovChainTest.m 108 figure(2) markovChainTest.m 109 plot(omega,p','-k','LineWidth',2.5) markovChainTest.m 110 set(gca,'FontSize',14) markovChainTest.m 111 box off markovChainTest.m 112 set(gcf,'Color',[1 1 1]); markovChainTest.m 113 markovChainTest.m 114 set(gca,'box','off','FontSize',14,'Xtick',[Chat Cmiddle Ccheck]); markovChainTest.m 115 set(gcf,'Color',[1 1 1]); markovChainTest.m 116 markovChainTest.m 117 set(gcf,'Position',[-3 5 1280 950],... markovChainTest.m 118 'PaperUnits','in','PaperSize',[5 3],... markovChainTest.m 119 'PaperPositionMode','manual',... markovChainTest.m 120 'PaperPosition',[0 0 5 3]); Set the figure to the desired size. markovChainTest.m 121 print -djpeg -painters markovChainApproximationTestErgodicDistribution.jpg markovChainTest.m 122 makequit;

Figure 9 presents the resulting figure. In spite of using a reasonably fine grid for , the distribution has a “toothy” look. Nevertheless, it is roughly bell-shaped.

# 2BOrdered Probit Estimation

We enclose the code for calculating given supports for and and a joint distribution over that support into the function orderedProbitMaximumLikelihoodEstimation.

 orderedProbitMaximumLikelihoodEstimation.m 8 function OUT = orderedProbitMaximumLikelihoodEstimation(ARG)

Its single argument has three fields, as described above. The function begins with extracting these and assigning them convenient names.

 orderedProbitMaximumLikelihoodEstimation.m 12 C = ARG.support(:,1); orderedProbitMaximumLikelihoodEstimation.m 13 N = ARG.support(:,2); orderedProbitMaximumLikelihoodEstimation.m 14 p = ARG.distribution; orderedProbitMaximumLikelihoodEstimation.m 15 eps = ARG.epsilon;

The estimation requires repeated evaluation of the standard Gaussian c.d.f, so we place this in an inline function.

 orderedProbitMaximumLikelihoodEstimation.m 19 Phi = @(x) 0.5*(x>=0).*(erf(abs(x)/sqrt(2))+1)+0.5*(x<0).*erfc(abs(x)/sqrt(2));

In any given application, some elements of the support for have zero or nearly zero probability of occuring. L'Hoptial's rule tells us that the contribution of a zero-probability event to the expected log likelhood function equals zero, but Matlab does not know anything of L'Hopital. Instead, it will dutifully try to calculate the logarithm of 0, yielding NaN, multiply this by 0, and add the result to the expected likelihood function. In this way, the calculated expected log likelihood function always equals NaN. To eliminate this problem, we remove near-zero probability events from the support. This is the first use of eps.

 orderedProbitMaximumLikelihoodEstimation.m 26 C=C(p>eps); N=N(p>eps); p=p(p>eps); p=p/sum(p);

We seek the maximum likelihoood estimates of the k-1 thresholds corresponding to the elements of Noutcomes. Although the ordered-probit likelihood function is concave in these unknown paramters, good starting values make its optimization easier. Accordingly, we begin with estimating these thresholds using binary probit estimates with the events for values of in Noutcomes as the depenent variables. Given a trial threshold , the likelihood function is

(0)

We implement this with an inline function with a single input, x. Its three elements are

x(1)
The trial threshold, .
x(2)
The trial value of the error variance, .
x(3)
, the number of firms defining the dependent variable.

 orderedProbitMaximumLikelihoodEstimation.m 40 lf = @(x) p'*((N>=x(3)).*log(Phi(log(C/x(1))/x(2))) ... orderedProbitMaximumLikelihoodEstimation.m 41 + (N

The following loop uses lf(x) to calcualte the binary probit maximum likelihood estimates we require. These get stored in startC and startSigma.

 orderedProbitMaximumLikelihoodEstimation.m 45 Nlow=min(N); orderedProbitMaximumLikelihoodEstimation.m 46 Nhigh=max(N); orderedProbitMaximumLikelihoodEstimation.m 47 startC = zeros(Nhigh-Nlow,1); orderedProbitMaximumLikelihoodEstimation.m 48 startSigma = zeros(Nhigh-Nlow,1); orderedProbitMaximumLikelihoodEstimation.m 49 orderedProbitMaximumLikelihoodEstimation.m 50 for R=Nlow+1:Nhigh;

Specialize the likelihood function for this event.

 orderedProbitMaximumLikelihoodEstimation.m 54 f = @(x) -lf([x R]);

Minimize the likelihood function. For the threshold's starting value,use the average value of C conditional on firms being in the market. The choice of variance is arbitrary.

 orderedProbitMaximumLikelihoodEstimation.m 58 C0=p(N==R)'*C(N==R)/sum(p(N==R)); orderedProbitMaximumLikelihoodEstimation.m 59 [x,fval,exitflag]=fminsearch(f,[C0 0.2]); orderedProbitMaximumLikelihoodEstimation.m 60 if exitflag~=1 orderedProbitMaximumLikelihoodEstimation.m 61 error(['Binary probit maximization failed with fR=' int2str(R) ' and fval = ' num2str(fval,'%5.3f')]) orderedProbitMaximumLikelihoodEstimation.m 62 end orderedProbitMaximumLikelihoodEstimation.m 63 startC(R-Nlow)=x(1); orderedProbitMaximumLikelihoodEstimation.m 64 startSigma(R-Nlow)=x(2); orderedProbitMaximumLikelihoodEstimation.m 65 end

With the starting values in hand, it is time to create the full ordered-probit likelihood function. For this, we first create an inline function that calculates the probability of any given outcome as a function of the error variance and thresholds, logprobs(x). Its single argument contains

x(1)
The trial likelihood function variance.
x(2:end)
The ordered-probit thresholds. The first and last of these should be set to very small and large numbers, respectively. They stand-in for 0 and .

 orderedProbitMaximumLikelihoodEstimation.m 77 logprobs = @(x) log(Phi(log(C./x(N-Nlow+2)')/x(1))... Note that indexing a vector with another vector always produces a row vector. orderedProbitMaximumLikelihoodEstimation.m 78 -Phi(log(C./x(N-Nlow+3)')/x(1)));

Calculating the likelihood function for a given variance and set of thresholds merely requires evaluating logprobs and calculating its expected value.

 orderedProbitMaximumLikelihoodEstimation.m 82 lf = @(x) p'*logprobs([ x(1) 1e-10 x(2:end) 1e10]);

We are now prepared to maximize the ordered probit likelihood function. The maximization uses starting values for the thresholds calculated above. The starting value for equals the average estimate from the binary probits.

 orderedProbitMaximumLikelihoodEstimation.m 86 f= @(x) -lf(x); orderedProbitMaximumLikelihoodEstimation.m 87 [x,fval,exitflag]=fminsearch(f,[mean(startSigma) startC']); orderedProbitMaximumLikelihoodEstimation.m 88 orderedProbitMaximumLikelihoodEstimation.m 89 if exitflag~=1 orderedProbitMaximumLikelihoodEstimation.m 90 error(['Ordered probit estimation failed at fval = ' num2str(fval,'%5.2f')]) orderedProbitMaximumLikelihoodEstimation.m 91 end

This complete's the required calculations, and all that remains is to package the required results into the output structure, OUT. It has three fields.

 orderedProbitMaximumLikelihoodEstimation.m 95 OUT.sigma = x(1); orderedProbitMaximumLikelihoodEstimation.m 96 OUT.thresholds = x(2:end); orderedProbitMaximumLikelihoodEstimation.m 97 OUT.indices = Nlow+1:1:Nhigh;

#### Test of orderedProbitMaximumLikelihoodEstimation

We test this function using inputs created by running calculateLifoEquilibriumTest.

 orderedProbitMaximumLikelihoodEstimationTest.m 8 stay=1; Defining stay overrides makequit. orderedProbitMaximumLikelihoodEstimationTest.m 9 calculateLifoEquilibriumTest; orderedProbitMaximumLikelihoodEstimationTest.m 10 clear stay;

Close the figure this program produces.

 orderedProbitMaximumLikelihoodEstimationTest.m 14 close all;

Recall that this program leaves the equilibrium calculations in the structure OUT. To calculate the support of and its accompanying ergodic distribution, we feed this to calculateLifoErgodicDistribution.

 orderedProbitMaximumLikelihoodEstimationTest.m 19 ERGODIC=calculateLifoErgodicDistribution(OUT);

Adding the field epsilon to ERGODIC allows us to use it as input for orderedProbitMaximumLikelihoodEstimation.

 orderedProbitMaximumLikelihoodEstimationTest.m 23 ERGODIC.epsilon=1e-7; orderedProbitMaximumLikelihoodEstimationTest.m 24 ESTIMATES=orderedProbitMaximumLikelihoodEstimation(ERGODIC); orderedProbitMaximumLikelihoodEstimationTest.m 25 makequit;

# 3CLaTeX Figure Code

## 3C.1Pencil-and-Paper Example

Figure 1A contains two panels, one for each firm's value function. To create it, we use the pgfplots package of Feuersänger (2008) to make an axis for each panel and then draw the value functions directly using the equilibrium entry thresholds, exit thresholds, and value functions calculated by pencil.m and saved in pgfTikZ/ac2apencilConstants.tex. The following TikZ code requires those constants to be defined, and atikzpicture environment must enclose it. For example

 pgfTikZ/ac2apencilWrapper.tex 25 \begin{tikzpicture}[scale=1.4] pgfTikZ/ac2apencilWrapper.tex 26 \input{ac2apencilColor} pgfTikZ/ac2apencilWrapper.tex 27 \end{tikzpicture}

The code below resides within /compute/pgfTikZ.4

### 3C.1.1Top Panel

We begin with opening the first axis, which contains the value function for a firm with rank 1. We set several TikZ keys to control the axes appearance, including the location, style, and labeling of tick marks.

 pgfTikZ/ac2apencilColor.tex 10 \begin{axis}[width=4.5in,height=2.5in, pgfTikZ/ac2apencilColor.tex 11 title=First Entrant's Value Function, Title placed over the axis. pgfTikZ/ac2apencilColor.tex 12 name=v1, An axis name used to place the next axis. pgfTikZ/ac2apencilColor.tex 13 ylabel={}, pgfTikZ/ac2apencilColor.tex 14 axis x line=bottom, Place the x-axis at the bottom of the plotted area. pgfTikZ/ac2apencilColor.tex 15 every outer x axis line/.append style={-,color=gray,line width=0.75pt}, pgfTikZ/ac2apencilColor.tex 16 axis y line=left, Place the y-axis at the left of the ploted area pgfTikZ/ac2apencilColor.tex 17 every outer y axis line/.append style={-,color=gray,line width=0.75pt}, pgfTikZ/ac2apencilColor.tex 18 Place x-axis tick marks at , , , and . pgfTikZ/ac2apencilColor.tex 19 xtick={\pencilChat,\pencilCunderbarOne,\pencilCoverbarOne,\pencilCcheck}, pgfTikZ/ac2apencilColor.tex 20 Only label the middle two tick marks. Manually adjust the second one's vertical offset. pgfTikZ/ac2apencilColor.tex 21 xticklabels={,\raisebox{-2.3mm}{$\underline{C}_1$},$\overline{C}_1$, }, pgfTikZ/ac2apencilColor.tex 22 Place y-axis tick marks at 0, , and . pgfTikZ/ac2apencilColor.tex 23 ytick={0,\pencilPhiOne,\pencilVOneOneCoverbarTwo}, pgfTikZ/ac2apencilColor.tex 24 Only label the first two tick marks. pgfTikZ/ac2apencilColor.tex 25 yticklabels={$0$,\makebox[0pt][r]{$\varphi(1)$},}, pgfTikZ/ac2apencilColor.tex 26 Style the tick marks. pgfTikZ/ac2apencilColor.tex 27 major tick length=2.5mm, pgfTikZ/ac2apencilColor.tex 28 every tick/.append style={line width=0.75pt}, pgfTikZ/ac2apencilColor.tex 29 Set the plotted area's horizontal and vertical limits. pgfTikZ/ac2apencilColor.tex 30 xmin=\pencilChat, pgfTikZ/ac2apencilColor.tex 31 xmax=\pencilCcheck, pgfTikZ/ac2apencilColor.tex 32 ymin=0, pgfTikZ/ac2apencilColor.tex 33 ymax=\pencilVOneOneCoverbarTwo]

#### The cost of entry

The next task at hand is to draw the horizontal line demarking the cost of the first firm's entry. We do this with the axis coordinate system, which selects points based on their locations in the Cartisian plane (See page 21 of Feuersänger (2008) ).

 pgfTikZ/ac2apencilColor.tex 36 \draw[color=gray,line width=0.75pt,dashed] pgfTikZ/ac2apencilColor.tex 37 (axis cs:\pencilChat,\pencilPhiOne) -- (axis cs:\pencilCcheck,\pencilPhiOne);

#### Plot of

We now proceed to plot and . Each of these is piecewise linear with exactly one discontinuity. Since they overlap outside of , it is useful to conceive of them as consisting of two branches. The “monopoly” branch plots over . This is flat from to and thereafter slopes up at the rate . To draw this, we simply connect two points on each line segments using the \path command. The line is colored black to distinguish it from the gray helper lines. We give two of these points names for later use using the coordinate directive.

 pgfTikZ/ac2apencilColor.tex 40 \path[draw,color=black,line width=0.75pt] pgfTikZ/ac2apencilColor.tex 41 (axis cs: \pencilChat,0) -- (axis cs: \pencilCunderbarOne,0) coordinate (monopolyMin) pgfTikZ/ac2apencilColor.tex 42 -- (axis cs: \pencilCoverbarTwo,\pencilVOneOneCoverbarTwo) coordinate (monopolyMax);

The “duopoly” branch, which gives over completes the two value functions. Its red color distinguishes it from the monopoly branch.

 pgfTikZ/ac2apencilColor.tex 44 \path[draw,color=red!75,line width=0.75pt] pgfTikZ/ac2apencilColor.tex 45 (axis cs: \pencilCunderbarTwo,\pencilVOneTwoCunderbarTwo) coordinate (duopolyMin) pgfTikZ/ac2apencilColor.tex 46 -- (axis cs: \pencilCcheck,\pencilVOneTwoCcheck) coordinate (duopolyMax);

#### Transition Arrows

As passes through , the change in the potential entrant's actual entry decision causes to drop discontinously. We denote this discontinuity with a gray vertical array from the monopoly branch to the duopoly branch. Its origin is at the point we denoted above with monopolyMax. Theoretically, its destination is where the duopoly branch crosses a vertical line from monopolyMax to the x axis. We calculate this point using the intersection coordinate system of TikZ. Practically, the arrow looks better if we end it just above this point.

 pgfTikZ/ac2apencilColor.tex 50 Find the intersection of interest. pgfTikZ/ac2apencilColor.tex 51 \path(axis cs:\pencilCoverbarTwo,0) coordinate (Xaxis1); pgfTikZ/ac2apencilColor.tex 52 \path(intersection cs: pgfTikZ/ac2apencilColor.tex 53 first line={(duopolyMin)--(duopolyMax)}, pgfTikZ/ac2apencilColor.tex 54 second line={(monopolyMax) -- (Xaxis1)}) coordinate pgfTikZ/ac2apencilColor.tex 55 (duopolyEntry); pgfTikZ/ac2apencilColor.tex 56 Set the arrow's target slightly above this intersection. pgfTikZ/ac2apencilColor.tex 57 \path(duopolyEntry) ++ (0,5pt) coordinate(duopolyTarget); pgfTikZ/ac2apencilColor.tex 58 Draw the arrow. pgfTikZ/ac2apencilColor.tex 59 \draw[-stealth,dashed,line width=0.5pt,color=gray] (monopolyMax) -- (duopolyTarget); pgfTikZ/ac2apencilColor.tex 60

The analogous discontinuity in associated with a younger rival's exit occurs at . Again, the arrow's source coordinate is in hand, duopolyMin. Its destination is at the intersection of the monopoly branch with a vertical line through duopolyMin. We place the arrow tip just below this point.

 pgfTikZ/ac2apencilColor.tex 63 Find the intersection of interest. pgfTikZ/ac2apencilColor.tex 64 \path(axis cs:\pencilCunderbarTwo,0) coordinate (Xaxis2); pgfTikZ/ac2apencilColor.tex 65 \path(intersection cs: pgfTikZ/ac2apencilColor.tex 66 first line={(monopolyMin)--(monopolyMax)}, pgfTikZ/ac2apencilColor.tex 67 second line={(duopolyMin)--(Xaxis2)}) coordinate (monopolyExit); pgfTikZ/ac2apencilColor.tex 68 Set the arrow's target slightly below this intersection. pgfTikZ/ac2apencilColor.tex 69 \path(monopolyExit) ++ (0,-5pt) coordinate (monopolyTarget); pgfTikZ/ac2apencilColor.tex 70 Draw the arrow. pgfTikZ/ac2apencilColor.tex 71 \draw[-stealth,dashed,line width=0.5pt,color=gray] (duopolyMin) -- (monopolyTarget); pgfTikZ/ac2apencilColor.tex 72

#### The Legend

To aid the reader, we create a legend to label the two value-function branches. Rather than rely on the legend-creation capabilities of pgfplots, we create our own by placing a similar line next to a textual explanation. The first task is to calculate the beginning and end points for the line in the monopoly branch's legend entry. We place its start point 4/5 of the way up the vertical axis and half way from the origin to . To calculate these points, we use \pgfmathsetmacro and the axis coordinate system.

 pgfTikZ/ac2apencilColor.tex 76 \pgfmathsetmacro{\legendxOne}{0.5*(\pencilCunderbarOne-\pencilChat)} pgfTikZ/ac2apencilColor.tex 77 \pgfmathsetmacro{\legendyOne}{0.8*\pencilVOneOneCoverbarTwo} pgfTikZ/ac2apencilColor.tex 78 \path(axis cs: \legendxOne,\legendyOne) coordinate (legendStartMonopoly); pgfTikZ/ac2apencilColor.tex 79

The line rises at the slope , which is saved in \pencilPiOne, and ends just above .

 pgfTikZ/ac2apencilColor.tex 82 \pgfmathsetmacro{\legendyTwo}{\legendyOne+\pencilPiOne*\pencilCunderbarOne*0.5} pgfTikZ/ac2apencilColor.tex 83 \pgfmathsetmacro{\legendxTwo}{\pencilCunderbarOne} pgfTikZ/ac2apencilColor.tex 84 \path(axis cs: \legendxTwo,\legendyTwo) coordinate(legendStopMonopoly); pgfTikZ/ac2apencilColor.tex 85

We place the text for the monopoly branch's legend entry to the right of .

 pgfTikZ/ac2apencilColor.tex 87 \pgfmathsetmacro{\legendxThree}{2*\pencilCunderbarOne} pgfTikZ/ac2apencilColor.tex 88 \pgfmathsetmacro{\legendyThree}{\legendyOne+\pencilPiOne*\pencilCunderbarOne*0.25} pgfTikZ/ac2apencilColor.tex 89 \path(axis cs: \legendxThree,\legendyThree) coordinate (legendTextMonopoly); pgfTikZ/ac2apencilColor.tex 90

With the coordinates in hand, we draw the legend entry and place its label text.

 pgfTikZ/ac2apencilColor.tex 92 \path[draw,color=black,line width=0.75pt] pgfTikZ/ac2apencilColor.tex 93 (legendStartMonopoly) -- (legendStopMonopoly) pgfTikZ/ac2apencilColor.tex 94 (legendTextMonopoly) node{Monopoly Branch}; pgfTikZ/ac2apencilColor.tex 95

The duopoly branch's legend entry locations are just those from the monopoly branch shifted down by half a centemeter.

 pgfTikZ/ac2apencilColor.tex 98 \path(legendStartMonopoly) ++(0,-0.5cm) coordinate (legendStartDuopoly); pgfTikZ/ac2apencilColor.tex 99 \path(legendStopMonopoly) ++(0,-0.5cm) coordinate (legendStopDuopoly); pgfTikZ/ac2apencilColor.tex 100 \path(legendTextMonopoly) ++(0,-0.5cm) coordinate (legendTextDuopoly); pgfTikZ/ac2apencilColor.tex 101 pgfTikZ/ac2apencilColor.tex 102 \draw[color=red!75,line width=0.75pt] (legendStartDuopoly) -- (legendStopDuopoly) pgfTikZ/ac2apencilColor.tex 103 (legendTextDuopoly) node[color=black]{Duopoly Branch}; pgfTikZ/ac2apencilColor.tex 104

The words “Monopoly Branch” and “Duopoly Branch” are centered in their nodes. It would be great to left-justify them so that their left-ends were properly aligned. In any case, this panel and its corresponding axis environment are complete.

 pgfTikZ/ac2apencilColor.tex 107 \end{axis} pgfTikZ/ac2apencilColor.tex 108

### 3C.1.2Bottom Panel

The bottom panel gives the value function of a firm with rank 2. This is considerably simpler to plot. We begin by calculating a point below the top panel for its location.

 pgfTikZ/ac2apencilColor.tex 111 \path(v1.origin) ++(0,-2.50in) coordinate (v2 plot position);

As before, we use the axis environment to create the bottom panel.

 pgfTikZ/ac2apencilColor.tex 113 \begin{axis}[width=4.5in,height=2.5in, pgfTikZ/ac2apencilColor.tex 114 title=Second Entrant's Value Function, pgfTikZ/ac2apencilColor.tex 115 name=v2, pgfTikZ/ac2apencilColor.tex 116 at = {(v2 plot position)}, pgfTikZ/ac2apencilColor.tex 117 anchor={origin}, pgfTikZ/ac2apencilColor.tex 118 ylabel={}, pgfTikZ/ac2apencilColor.tex 119 axis x line=bottom, pgfTikZ/ac2apencilColor.tex 120 every outer x axis line/.append style={-,color=gray,line width=0.75pt}, pgfTikZ/ac2apencilColor.tex 121 axis y line=left, pgfTikZ/ac2apencilColor.tex 122 every outer y axis line/.append style={-,color=gray,line width=0.75pt}, pgfTikZ/ac2apencilColor.tex 123 We place x-axis tick marks at , , , and pgfTikZ/ac2apencilColor.tex 124 xtick={\pencilChat,\pencilCunderbarTwo,\pencilCoverbarTwo,\pencilCcheck}, pgfTikZ/ac2apencilColor.tex 125 All four x-axis tick marks get labels. pgfTikZ/ac2apencilColor.tex 126 xticklabels={$\hat{C}$,\raisebox{-2.3mm}{$\underline{C}_2$}, pgfTikZ/ac2apencilColor.tex 127 $\overline{C}_2$, $\check{C}$}, pgfTikZ/ac2apencilColor.tex 128 ytick={0,\pencilPhiTwo,\pencilVOneOneCoverbarTwo}, pgfTikZ/ac2apencilColor.tex 129 yticklabels={$0$,\makebox[0pt][r]{$\varphi(2)$},}, pgfTikZ/ac2apencilColor.tex 130 major tick length=2.5mm, pgfTikZ/ac2apencilColor.tex 131 every tick/.append style={line width=0.75pt}, pgfTikZ/ac2apencilColor.tex 132 ymin=0, pgfTikZ/ac2apencilColor.tex 133 ymax=\pencilVOneOneCoverbarTwo, pgfTikZ/ac2apencilColor.tex 134 xmin=\pencilChat, pgfTikZ/ac2apencilColor.tex 135 xmax=\pencilCcheck] pgfTikZ/ac2apencilColor.tex 136

The actual plotting of the cost of entry and the value function is very straightforward.

 pgfTikZ/ac2apencilColor.tex 138 \draw[color=gray,line width=0.75pt,dashed] pgfTikZ/ac2apencilColor.tex 139 (axis cs:\pencilChat,\pencilPhiOne) -- (axis cs:\pencilCcheck,\pencilPhiOne); pgfTikZ/ac2apencilColor.tex 140 pgfTikZ/ac2apencilColor.tex 141 \draw[color=black,line width=0.75pt] (axis cs: \pencilChat,0) pgfTikZ/ac2apencilColor.tex 142 -- (axis cs: \pencilCunderbarTwo,0) pgfTikZ/ac2apencilColor.tex 143 -- (axis cs: \pencilCcheck,\pencilVTwoCcheck); pgfTikZ/ac2apencilColor.tex 144

The bottom panel is done, so close the axis environment

 pgfTikZ/ac2apencilColor.tex 146 \end{axis}

## 3C.2Equilibrium without Thresholds

The plot of continuation values from the example equilibrium without threshold-based strategies uses the data created by equilibriumWithoutThresholds.m and saved in

• pgfTikZ/equilibriumWithoutThresholdsV11.csv
• pgfTikZ/equilibriumWithoutThresholdsV12.csv
• pgfTikZ/equilibriumWithoutThresholdsV2.csv
• pgfTikZ/equilibriumWithoutThresholdsConstants.tex

Just as with the pencil-and-paper example, the code below resides in /compute/pgfTikZ and requires certain macros defined by this last file to be in place. 5

### 3C.2.1Top Panel

We place no labelled tick marks on the horizontal axis to make room for the illustration of the entry set. Otherwise, the formatting of the top panel is pretty similar to that from the pencil-and-paper example.

 pgfTikZ/ac2aNoThresholdsColor.tex 13 \begin{axis}[width=4.5in,height=2.5in, pgfTikZ/ac2aNoThresholdsColor.tex 14 title=First Entrant's Value Function, pgfTikZ/ac2aNoThresholdsColor.tex 15 name=v1, pgfTikZ/ac2aNoThresholdsColor.tex 16 ylabel={}, pgfTikZ/ac2aNoThresholdsColor.tex 17 axis x line=bottom, pgfTikZ/ac2aNoThresholdsColor.tex 18 every outer x axis line/.append style={-,color=gray,line width=0.75pt}, pgfTikZ/ac2aNoThresholdsColor.tex 19 axis y line=left, pgfTikZ/ac2aNoThresholdsColor.tex 20 every outer y axis line/.append style={-,color=gray,line width=0.75pt}, pgfTikZ/ac2aNoThresholdsColor.tex 21 xtick={\chat,\ccheck}, pgfTikZ/ac2aNoThresholdsColor.tex 22 xticklabels={}, pgfTikZ/ac2aNoThresholdsColor.tex 23 ytick={0,\phione,\ymax}, pgfTikZ/ac2aNoThresholdsColor.tex 24 yticklabels={$0$,\makebox[0pt][r]{$\varphi(1)=\phione$},$\pgfmathprintnumber{\ymax}$}, pgfTikZ/ac2aNoThresholdsColor.tex 25 major tick length=2.5mm, pgfTikZ/ac2aNoThresholdsColor.tex 26 every tick/.append style={line width=0.75pt}, pgfTikZ/ac2aNoThresholdsColor.tex 27 ymin=0, pgfTikZ/ac2aNoThresholdsColor.tex 28 ymax=\ymax, pgfTikZ/ac2aNoThresholdsColor.tex 29 scaled ticks=false, pgfTikZ/ac2aNoThresholdsColor.tex 30 scaled ticks=false, pgfTikZ/ac2aNoThresholdsColor.tex 31 /pgf/number format/precision=2, pgfTikZ/ac2aNoThresholdsColor.tex 32 /pgf/number format/set thousands separator={}]

Place the text describing the entry rule into the top panel.

 pgfTikZ/ac2aNoThresholdsColor.tex 34 \node[color=black] at (axis cs:0.65,6) {Enter if $\ln C\in \cal{A}\cup \cal{B}$}; pgfTikZ/ac2aNoThresholdsColor.tex 35 Draw a horizontal line at the cost of entry pgfTikZ/ac2aNoThresholdsColor.tex 36 \draw[color=gray,line width=0.75pt,dashed] (axis cs:\chat,\phione) -- (axis cs:\ccheck,\phione);

Create the two value-function “branches” for an incumbent with rank 1.

 pgfTikZ/ac2aNoThresholdsColor.tex 38 \addplot[color=black,mark=square*,only marks,mark size=0.05mm] table[x=C,y=v11,col sep=comma]{equilibriumWithoutThresholdsV11.csv}; pgfTikZ/ac2aNoThresholdsColor.tex 39 \addplot[color=red!75,mark=square*,only marks,mark size=0.05mm] table[x=C,y=v12,col sep=comma]{equilibriumWithoutThresholdsV12.csv}; pgfTikZ/ac2aNoThresholdsColor.tex 40

This is complicated enough to merit a legend. Note that its location is hard-wired. Changing the example might make this poorly placed.

 pgfTikZ/ac2aNoThresholdsColor.tex 42 \draw[color=black,line width=0.75pt] (axis cs: -1.3,35) -- (axis cs: -1.05,39) (axis cs: -1.05,36)--(axis cs:-0.925,38) (axis cs: -0.5,38) node{Monopoly Branch}; pgfTikZ/ac2aNoThresholdsColor.tex 43 \draw[color=red!75,line width=0.75pt] (axis cs: -1.3,30) -- (axis cs: -1.05,34) (axis cs: -1.05,31)--(axis cs:-0.925,33) (axis cs: -0.5,33) node[color=black]{Duopoly Branch};

Mark locations for drawing the entry set. We do the actual drawing below (outside of the axis environment) to avoid having our beautiful work being clipped.

 pgfTikZ/ac2aNoThresholdsColor.tex 45 \path(axis cs:\chat,0) coordinate (Chat); pgfTikZ/ac2aNoThresholdsColor.tex 46 \path(axis cs:\ccheck,0) coordinate (Ccheck); pgfTikZ/ac2aNoThresholdsColor.tex 47 \path(axis cs:\Alow,0) coordinate (Alow); pgfTikZ/ac2aNoThresholdsColor.tex 48 \path(axis cs:\Ahigh,0) coordinate (Ahigh); pgfTikZ/ac2aNoThresholdsColor.tex 49 \path(axis cs:\Clow,0) coordinate (Clow); pgfTikZ/ac2aNoThresholdsColor.tex 50 \path(axis cs:\Chigh,0) coordinate (Chigh); pgfTikZ/ac2aNoThresholdsColor.tex 51 pgfTikZ/ac2aNoThresholdsColor.tex 52 \end{axis}

Draw the entry set.

 pgfTikZ/ac2aNoThresholdsColor.tex 54 \draw[color=green!20!white,line width=10pt] (Alow) -- node[midway,above,color=black]{$\cal A$} (Ahigh); pgfTikZ/ac2aNoThresholdsColor.tex 55 \draw[color=green!20!white,line width=10pt] (Clow) -- node[midway,above,color=black]{$\cal B$} (Chigh);

The entry set just covered the horizontal axis, so we need to redraw it and its tick marks.

 pgfTikZ/ac2aNoThresholdsColor.tex 57 \draw[color=gray,line width=0.75pt](Alow)--(Chigh); pgfTikZ/ac2aNoThresholdsColor.tex 58 Draw a tick mark at Ccheck and label it. pgfTikZ/ac2aNoThresholdsColor.tex 59 \draw[color=gray,line width=0.75pt](Ccheck) ++(0,1.25mm) -- ++ (0,-2.5mm) ++ (0,-3mm) node[color=black]{\makebox[0pt][r]{$\ln \check C = \ccheck$}};

Draw a tick mark at Chat and label it.

 pgfTikZ/ac2aNoThresholdsColor.tex 61 \draw[color=gray,line width=0.75pt] (Chat) ++ (0,1.25mm) -- ++ (0,-2.5mm) ++ (0,-2.5mm) pgfTikZ/ac2aNoThresholdsColor.tex 62 node[color=black]{\makebox[0pt][l]{$\ln \hat C = \chat$}}; pgfTikZ/ac2aNoThresholdsColor.tex 63 Draw a tick mark at Ahigh and label it with its value. pgfTikZ/ac2aNoThresholdsColor.tex 64 \draw[color=gray,line width=0.75pt] (Ahigh) ++(0,1.25mm) -- ++ (0,-2.5mm) ++(0,-3mm) node[color=black]{$\pgfmathprintnumber{\Ahigh}$}; pgfTikZ/ac2aNoThresholdsColor.tex 65

### 3C.2.2Bottom Panel

The bottom panel's construction involves considerably less coding. We begin by choosing its location.

 pgfTikZ/ac2aNoThresholdsColor.tex 68 \path(v1.origin) ++(0,-2.5in) coordinate (v2 plot position);

The formatting of the axis is straightforward.

 pgfTikZ/ac2aNoThresholdsColor.tex 70 \begin{axis}[width=4.5in,height=2.5in, pgfTikZ/ac2aNoThresholdsColor.tex 71 title=Second Entrant's Value Function, pgfTikZ/ac2aNoThresholdsColor.tex 72 name=v2, pgfTikZ/ac2aNoThresholdsColor.tex 73 at = {(v2 plot position)}, pgfTikZ/ac2aNoThresholdsColor.tex 74 anchor={origin}, pgfTikZ/ac2aNoThresholdsColor.tex 75 ylabel={}, pgfTikZ/ac2aNoThresholdsColor.tex 76 axis x line=bottom, pgfTikZ/ac2aNoThresholdsColor.tex 77 every outer x axis line/.append style={-,color=gray,line width=0.75pt}, pgfTikZ/ac2aNoThresholdsColor.tex 78 axis y line=left, pgfTikZ/ac2aNoThresholdsColor.tex 79 every outer y axis line/.append style={-,color=gray,line width=0.75pt}, pgfTikZ/ac2aNoThresholdsColor.tex 80 xtick={\chat,\cunderbartwo,\coverbartwo,\ccheck}, pgfTikZ/ac2aNoThresholdsColor.tex 81 xticklabels={\makebox[0pt][r]{},\raisebox{-2.8mm}{$\ln \underline C_2 = \pgfmathprintnumber{\cunderbartwo}$},\makebox[0pt][c]{$\ln \overline C_2 = \pgfmathprintnumber{\coverbartwo}$},\makebox[0pt][r]{}}, pgfTikZ/ac2aNoThresholdsColor.tex 82 ytick={0,\phitwo,\ymax}, pgfTikZ/ac2aNoThresholdsColor.tex 83 yticklabels={$0$,\makebox[0pt][r]{$\varphi(2)=\phitwo$},$\pgfmathprintnumber{\ymax}$}, pgfTikZ/ac2aNoThresholdsColor.tex 84 major tick length=2.5mm, pgfTikZ/ac2aNoThresholdsColor.tex 85 every tick/.append style={line width=0.75pt}, pgfTikZ/ac2aNoThresholdsColor.tex 86 ymin=0, pgfTikZ/ac2aNoThresholdsColor.tex 87 ymax=\ymax, pgfTikZ/ac2aNoThresholdsColor.tex 88 scaled ticks=false, pgfTikZ/ac2aNoThresholdsColor.tex 89 /pgf/number format/precision=2, pgfTikZ/ac2aNoThresholdsColor.tex 90 /pgf/number format/set thousands separator={}]

Draw a horizontal line at the cost of entry.

 pgfTikZ/ac2aNoThresholdsColor.tex 92 \draw[color=gray,line width=0.75pt,dashed] (axis cs:\chat,\phitwo) -- (axis cs:\ccheck,\phitwo);

Plot the value function for an incumbent with rank 2 and close the axis.

 pgfTikZ/ac2aNoThresholdsColor.tex 94 \addplot[color=black,line width=1pt] table[x=C,y=v2,col sep=comma]{equilibriumWithoutThresholdsV2.csv}; pgfTikZ/ac2aNoThresholdsColor.tex 95 pgfTikZ/ac2aNoThresholdsColor.tex 96 \end{axis}

# 4DCreation of LaTeX Tables and Text

## 4D.1Table I

Reporting the results requires us to make a LaTeX file that creates macros embodying the numbers included in the text.

 tableOfThresholdsLaTeX.m 7 f1=fopen('tableOfThresholdsText.tex','w');

for and

 tableOfThresholdsLaTeX.m 11 fprintf(f1,'\\def\\cFiveSigmaTwo{$%3.2f$}\n',freeEntryThresholds(3,5)); tableOfThresholdsLaTeX.m 12 fprintf(f1,'\\def\\cFiveSigmaThree{$%3.2f$}\n',freeEntryThresholds(4,5));

for and

 tableOfThresholdsLaTeX.m 16 fprintf(f1,'\\def\\cSixSigmaOne{$%3.2f$}\n',freeEntryThresholds(2,6)); tableOfThresholdsLaTeX.m 17 fprintf(f1,'\\def\\cSixSigmaTwo{$%3.2f$}\n',freeEntryThresholds(3,6));

for and

 tableOfThresholdsLaTeX.m 21 fprintf(f1,'\\def\\cSevenSigmaZero{$%3.2f$}\n',freeEntryThresholds(1,7)); tableOfThresholdsLaTeX.m 22 fprintf(f1,'\\def\\cSevenSigmaOne{$%3.2f$}\n',freeEntryThresholds(2,7));

The first static exit threshold.

 tableOfThresholdsLaTeX.m 26 fprintf(f1,'\\def\\cOneSigmaZero{$%3.2f$}\n',freeContinuationThresholds(1,1));

Exit rates

 tableOfThresholdsLaTeX.m 30 fprintf(f1,'\\def\\exitRateOne{$%2.1f$}\n',freeEntryExitRate(2)); tableOfThresholdsLaTeX.m 31 fprintf(f1,'\\def\\exitRateTwo{$%2.1f$}\n',freeEntryExitRate(3)); tableOfThresholdsLaTeX.m 32 fprintf(f1,'\\def\\exitRateThree{$%2.1f$}\n',freeEntryExitRate(4)); tableOfThresholdsLaTeX.m 33 tableOfThresholdsLaTeX.m 34 fclose(f1);

We place the table of equilibrium thresholds into ac2atableOfThresholds.tex

 tableOfThresholdsLaTeX.m 38 f1=fopen('tableOfThresholds.tex','w');

The next two panels report the entry and continuation thresholds from the barrier-free equilibrium with different values of . We construct each of these with a separate tabular environment.

#### Entry Thresholds from Barrier-Free Experiment

We construct each panel by writing its contents to cell arrays and then using fprintf to place them into the LaTeX file.

Open the tabular environment.

 tableOfThresholdsLaTeX.m 50 header{1} = ['\begin{tabular}{*{' num2str(size(freeEntryThresholds,2)+1) '}{c}}'];

The first row labels the experiment being undertaken.

 tableOfThresholdsLaTeX.m 58 header{3} = ['\multicolumn{' num2str(size(freeEntryThresholds,2)+1) '}{c}{ $\pi(N)=4$ }\\ \\'];

The second row describes the results being reported.

 tableOfThresholdsLaTeX.m 62 header{4} = [' & \multicolumn{' num2str(size(freeEntryThresholds,2)) '}{c}{Entry Thresholds} \\'];

The third row labels the contents of each column and draws a line across the table.

 tableOfThresholdsLaTeX.m 66 header{5} = ['$\sigma$' num2str(1:1:size(freeEntryThresholds,2),' & $\\overline{C}_{%1.0f}$') ' \\ \hline'];

Next comes the content. There is one row for each value of

 tableOfThresholdsLaTeX.m 70 content=cell(length(sigma),size(freeEntryThresholds,2)+2); tableOfThresholdsLaTeX.m 71 tableOfThresholdsLaTeX.m 72 for i=1:length(sigma) tableOfThresholdsLaTeX.m 73 content{i,1}=num2str(sigma(i),'%2.2f'); tableOfThresholdsLaTeX.m 74 for j=1:size(freeEntryThresholds,2); tableOfThresholdsLaTeX.m 75 if ~isnan(freeEntryThresholds(i,j)) tableOfThresholdsLaTeX.m 76 content{i,j+1}=num2str(freeEntryThresholds(i,j),' & \\makebox[24pt]{%2.2f}'); tableOfThresholdsLaTeX.m 77 end tableOfThresholdsLaTeX.m 78 end tableOfThresholdsLaTeX.m 79 content{i,end}='\\'; tableOfThresholdsLaTeX.m 80 end

End the tabular environment,

 tableOfThresholdsLaTeX.m 84 footer=cell(1,1); tableOfThresholdsLaTeX.m 85 footer{1}='\end{tabular}';

and write the first panel to the output file.

 tableOfThresholdsLaTeX.m 89 for i=1:5 tableOfThresholdsLaTeX.m 90 fprintf(f1,'%s\n',char(header{i})); tableOfThresholdsLaTeX.m 91 end tableOfThresholdsLaTeX.m 92 for i=1:length(sigma) tableOfThresholdsLaTeX.m 93 for j=1:size(freeEntryThresholds,2)+2 tableOfThresholdsLaTeX.m 94 fprintf(f1,'%s',char(content{i,j})); tableOfThresholdsLaTeX.m 95 end tableOfThresholdsLaTeX.m 96 fprintf(f1,'\n'); tableOfThresholdsLaTeX.m 97 end tableOfThresholdsLaTeX.m 98 tableOfThresholdsLaTeX.m 99 fprintf(f1,'%s\n\n',char(footer{1}));

#### Continuation Thresholds from Barrier-Free Experiment

The panel with the continuation thresholds has no double line and a blank line (taking space) in place of the experiment label;

and the results being reported are different.

 tableOfThresholdsLaTeX.m 109 header{4} = [' & \multicolumn{' num2str(size(freeEntryThresholds,2)) '}{c}{Exit Thresholds} \\'];

% The row of column labels uses the notation for continuation thresholds.

 tableOfThresholdsLaTeX.m 113 header{5} = ['$\sigma$' num2str(1:1:size(freeEntryThresholds,2),' & $\\underline{C}_{%1.0f}$') ' \\ \hline'];

The content also obviously changes.

 tableOfThresholdsLaTeX.m 117 content=cell(length(sigma),size(freeEntryThresholds,2)+2); tableOfThresholdsLaTeX.m 118 tableOfThresholdsLaTeX.m 119 for i=1:length(sigma) tableOfThresholdsLaTeX.m 120 content{i,1}=num2str(sigma(i),'%2.2f'); tableOfThresholdsLaTeX.m 121 for j=1:size(freeEntryThresholds,2); tableOfThresholdsLaTeX.m 122 if ~isnan(freeContinuationThresholds(i,j)) tableOfThresholdsLaTeX.m 123 content{i,j+1}=num2str(freeContinuationThresholds(i,j),' & \\makebox[24pt]{%2.2f}'); tableOfThresholdsLaTeX.m 124 end tableOfThresholdsLaTeX.m 125 end tableOfThresholdsLaTeX.m 126 content{i,end}='\\'; tableOfThresholdsLaTeX.m 127 end

This panel is now ready for output.

 tableOfThresholdsLaTeX.m 131 for i=1:5 tableOfThresholdsLaTeX.m 132 fprintf(f1,'%s\n',char(header{i})); tableOfThresholdsLaTeX.m 133 end tableOfThresholdsLaTeX.m 134 for i=1:length(sigma) tableOfThresholdsLaTeX.m 135 for j=1:size(freeEntryThresholds,2)+2 tableOfThresholdsLaTeX.m 136 fprintf(f1,'%s',char(content{i,j})); tableOfThresholdsLaTeX.m 137 end tableOfThresholdsLaTeX.m 138 fprintf(f1,'\n'); tableOfThresholdsLaTeX.m 139 end tableOfThresholdsLaTeX.m 140 tableOfThresholdsLaTeX.m 141 fprintf(f1,'%s\n\n',char(footer{1}));

Put a \bigskip between the two experiments

 tableOfThresholdsLaTeX.m 145 fprintf(f1,'\n\\bigskip\n');

#### Entry Thresholds for Experiments with Barrier

This panel also has no double line but does get a label.

 tableOfThresholdsLaTeX.m 150 header{3} = ['\multicolumn{' num2str(size(freeEntryThresholds,2)+1) '}{c}{ $\pi(N)=4\times I\left\{N\leq 4\right\}$ }\\ \\']; tableOfThresholdsLaTeX.m 151 header{4} = [' & \multicolumn{' num2str(size(freeEntryThresholds,2)) '}{c}{Entry Thresholds} \\']; tableOfThresholdsLaTeX.m 152 header{5} = ['$\sigma$' num2str(1:1:size(freeEntryThresholds,2),' & $\\overline{C}_{%1.0f}$') ' \\ \hline'];

Pad fourEntryThresholds with NaNs so that it is the same width as freeEntryThresholds.

 tableOfThresholdsLaTeX.m 156 fourEntryThresholds=[fourEntryThresholds NaN(length(sigma),size(freeEntryThresholds,2)-4)]; tableOfThresholdsLaTeX.m 157 tableOfThresholdsLaTeX.m 158 content=cell(length(sigma),size(freeEntryThresholds,2)+2); tableOfThresholdsLaTeX.m 159 tableOfThresholdsLaTeX.m 160 for i=1:length(sigma) tableOfThresholdsLaTeX.m 161 content{i,1}=num2str(sigma(i),'%2.2f'); tableOfThresholdsLaTeX.m 162 for j=1:size(fourEntryThresholds,2); tableOfThresholdsLaTeX.m 163 if ~isnan(fourEntryThresholds(i,j)) tableOfThresholdsLaTeX.m 164 content{i,j+1}=num2str(fourEntryThresholds(i,j),' & \\makebox[24pt]{%2.2f}'); tableOfThresholdsLaTeX.m 165 else tableOfThresholdsLaTeX.m 166 content{i,j+1}='& \makebox[24pt]{}'; tableOfThresholdsLaTeX.m 167 end tableOfThresholdsLaTeX.m 168 end tableOfThresholdsLaTeX.m 169 content{i,end}='\\'; tableOfThresholdsLaTeX.m 170 end

Send this panel to the output.

 tableOfThresholdsLaTeX.m 174 for i=1:5 tableOfThresholdsLaTeX.m 175 fprintf(f1,'%s\n',char(header{i})); tableOfThresholdsLaTeX.m 176 end tableOfThresholdsLaTeX.m 177 for i=1:length(sigma) tableOfThresholdsLaTeX.m 178 for j=1:size(fourEntryThresholds,2)+2 tableOfThresholdsLaTeX.m 179 fprintf(f1,'%s',char(content{i,j})); tableOfThresholdsLaTeX.m 180 end tableOfThresholdsLaTeX.m 181 fprintf(f1,'\n'); tableOfThresholdsLaTeX.m 182 end tableOfThresholdsLaTeX.m 183 tableOfThresholdsLaTeX.m 184 fprintf(f1,'%s\n\n',char(footer{1}));

#### Exit Thresholds for Experiments with Barrier

This panel mimics that for the exit thresholds from the barrier-free experiments.

 tableOfThresholdsLaTeX.m 189 header{3} = '\\'; tableOfThresholdsLaTeX.m 190 header{4} = [' & \multicolumn{' num2str(size(freeEntryThresholds,2)) '}{c}{Exit Thresholds} \\']; tableOfThresholdsLaTeX.m 191 header{5} = ['$\sigma$' num2str(1:1:size(freeEntryThresholds,2),' & $\\underline{C}_{%1.0f}$') ' \\ \hline'];

The panel's content comes from fourContinuationThresholds. Pad it with NaNs so that the relevant columns are filled with an empty box.

 tableOfThresholdsLaTeX.m 195 fourContinuationThresholds=[fourContinuationThresholds NaN(length(sigma),size(freeEntryThresholds,2)-4)]; tableOfThresholdsLaTeX.m 196 tableOfThresholdsLaTeX.m 197 content=cell(length(sigma),size(fourEntryThresholds,2)+2); tableOfThresholdsLaTeX.m 198 tableOfThresholdsLaTeX.m 199 for i=1:length(sigma) tableOfThresholdsLaTeX.m 200 content{i,1}=num2str(sigma(i),'%2.2f'); tableOfThresholdsLaTeX.m 201 for j=1:size(fourContinuationThresholds,2); tableOfThresholdsLaTeX.m 202 if ~isnan(fourContinuationThresholds(i,j)) tableOfThresholdsLaTeX.m 203 content{i,j+1}=num2str(fourContinuationThresholds(i,j),' & \\makebox[24pt]{%2.2f}'); tableOfThresholdsLaTeX.m 204 else tableOfThresholdsLaTeX.m 205 content{i,j+1}='& \makebox[24pt]{}'; tableOfThresholdsLaTeX.m 206 end tableOfThresholdsLaTeX.m 207 end tableOfThresholdsLaTeX.m 208 content{i,end}='\\'; tableOfThresholdsLaTeX.m 209 end

Send this panel to the output.

 tableOfThresholdsLaTeX.m 213 for i=1:5 tableOfThresholdsLaTeX.m 214 fprintf(f1,'%s\n',char(header{i})); tableOfThresholdsLaTeX.m 215 end tableOfThresholdsLaTeX.m 216 for i=1:length(sigma) tableOfThresholdsLaTeX.m 217 for j=1:size(fourEntryThresholds,2)+2 tableOfThresholdsLaTeX.m 218 fprintf(f1,'%s',char(content{i,j})); tableOfThresholdsLaTeX.m 219 end tableOfThresholdsLaTeX.m 220 fprintf(f1,'\n'); tableOfThresholdsLaTeX.m 221 end tableOfThresholdsLaTeX.m 222 tableOfThresholdsLaTeX.m 223 fprintf(f1,'%s\n\n',char(footer{1}));

This completes this table's construction. All that remains is to close the output file.

 tableOfThresholdsLaTeX.m 227 fclose(f1);

## 4D.2Table II

We place the table of equilibrium thresholds into tableOfOrderedProbitThresholds.tex

 tableOfOrderedProbitThresholdsLaTeX.m 7 f1=fopen('tableOfOrderedProbitThresholds.tex','w');

#### Threshold Estimates

The first panel reports the estimated ordered Probit thresholds. Each row corresponds to a different value of .

Open the tabular environment.

 tableOfOrderedProbitThresholdsLaTeX.m 16 header{1} = ['\begin{tabular}{*{' num2str(size(probitThresholds,2)+1) '}{c}}'];

The first row labels the results

 tableOfOrderedProbitThresholdsLaTeX.m 24 header{3} = ['\multicolumn{' num2str(size(probitThresholds,2)+1) '}{c}{ Implied Static Entry Thresholds }\\ \\'];

The second row labels the contents of each column and draws a line across the table.

 tableOfOrderedProbitThresholdsLaTeX.m 28 header{4} = ['$\sigma$' num2str(1:1:size(probitThresholds,2),' & $\\overline{C}_{%1.0f}$') ' \\ \hline'];

Next comes the content. There is one row for each value of .

 tableOfOrderedProbitThresholdsLaTeX.m 32 content=cell(length(sigma),size(probitThresholds,2)+2); tableOfOrderedProbitThresholdsLaTeX.m 33 tableOfOrderedProbitThresholdsLaTeX.m 34 for i=1:length(sigma) tableOfOrderedProbitThresholdsLaTeX.m 35 content{i,1}=num2str(sigma(i),'%2.2f'); tableOfOrderedProbitThresholdsLaTeX.m 36 for j=1:size(probitThresholds,2); tableOfOrderedProbitThresholdsLaTeX.m 37 if ~isnan(probitThresholds(i,j)) tableOfOrderedProbitThresholdsLaTeX.m 38 content{i,j+1}=num2str(probitThresholds(i,j),' & \\makebox[24pt]{%2.2f}'); tableOfOrderedProbitThresholdsLaTeX.m 39 end tableOfOrderedProbitThresholdsLaTeX.m 40 end tableOfOrderedProbitThresholdsLaTeX.m 41 content{i,end}='\\'; tableOfOrderedProbitThresholdsLaTeX.m 42 end

End the tabular environment,

 tableOfOrderedProbitThresholdsLaTeX.m 46 footer=cell(1,1); tableOfOrderedProbitThresholdsLaTeX.m 47 footer{1}='\end{tabular}';

and write the first panel to the output file.

 tableOfOrderedProbitThresholdsLaTeX.m 51 for i=1:4 tableOfOrderedProbitThresholdsLaTeX.m 52 fprintf(f1,'%s\n',char(header{i})); tableOfOrderedProbitThresholdsLaTeX.m 53 end tableOfOrderedProbitThresholdsLaTeX.m 54 for i=1:length(sigma) tableOfOrderedProbitThresholdsLaTeX.m 55 for j=1:size(probitThresholds,2)+2 tableOfOrderedProbitThresholdsLaTeX.m 56 fprintf(f1,'%s',char(content{i,j})); tableOfOrderedProbitThresholdsLaTeX.m 57 end tableOfOrderedProbitThresholdsLaTeX.m 58 fprintf(f1,'\n'); tableOfOrderedProbitThresholdsLaTeX.m 59 end tableOfOrderedProbitThresholdsLaTeX.m 60 tableOfOrderedProbitThresholdsLaTeX.m 61 fprintf(f1,'%s\n\n',char(footer{1}));

#### Producers' Surplus Estimates

The second panel reports the ratios of per customer producers' surplus in piRatios. Its format is similar to the first panel's, but it has no double line at the top, the label for the results is different, and its first row lists the value of rather than the notation for the static entry thresholds.

 tableOfOrderedProbitThresholdsLaTeX.m 67 header{2}=''; tableOfOrderedProbitThresholdsLaTeX.m 68 header{3}= ['\multicolumn{' num2str(size(piRatios,2)+1) '}{c}{Implied $\pi(N)/\pi(1)$ for $N=$}\\ \\']; tableOfOrderedProbitThresholdsLaTeX.m 69 header{4} = ['$\sigma$' num2str(1:1:size(probitThresholds,2),' & $%1.0f$') ' \\ \hline'];

The code for creating the second panel's content is identical to that of the first panel.

 tableOfOrderedProbitThresholdsLaTeX.m 73 content=cell(length(sigma),size(piRatios,2)+2); tableOfOrderedProbitThresholdsLaTeX.m 74 tableOfOrderedProbitThresholdsLaTeX.m 75 for i=1:length(sigma) tableOfOrderedProbitThresholdsLaTeX.m 76 content{i,1}=num2str(sigma(i),'%2.2f'); tableOfOrderedProbitThresholdsLaTeX.m 77 for j=1:size(piRatios,2); tableOfOrderedProbitThresholdsLaTeX.m 78 if ~isnan(piRatios(i,j)) tableOfOrderedProbitThresholdsLaTeX.m 79 content{i,j+1}=num2str(piRatios(i,j),' & \\makebox[24pt]{%2.2f}'); tableOfOrderedProbitThresholdsLaTeX.m 80 end tableOfOrderedProbitThresholdsLaTeX.m 81 end tableOfOrderedProbitThresholdsLaTeX.m 82 content{i,end}='\\'; tableOfOrderedProbitThresholdsLaTeX.m 83 end

We can now write the second panel to the output file.

 tableOfOrderedProbitThresholdsLaTeX.m 87 for i=1:4 tableOfOrderedProbitThresholdsLaTeX.m 88 fprintf(f1,'%s\n',char(header{i})); tableOfOrderedProbitThresholdsLaTeX.m 89 end tableOfOrderedProbitThresholdsLaTeX.m 90 for i=1:length(sigma) tableOfOrderedProbitThresholdsLaTeX.m 91 for j=1:size(piRatios,2)+2 tableOfOrderedProbitThresholdsLaTeX.m 92 fprintf(f1,'%s',char(content{i,j})); tableOfOrderedProbitThresholdsLaTeX.m 93 end tableOfOrderedProbitThresholdsLaTeX.m 94 fprintf(f1,'\n'); tableOfOrderedProbitThresholdsLaTeX.m 95 end tableOfOrderedProbitThresholdsLaTeX.m 96 tableOfOrderedProbitThresholdsLaTeX.m 97 fprintf(f1,'%s\n\n',char(footer{1}));

This completes the creation of the LaTeX table. All that remains is to close the output file.

 tableOfOrderedProbitThresholdsLaTeX.m 101 fclose(f1);

One final task remains undone. The text references the ordered probit estimate of for the case with . To include this in the text automatically, we write the command to create a LaTeX macro containing its value to a text file.

 tableOfOrderedProbitThresholdsLaTeX.m 106 f1=fopen('tableOfOrderedProbitThresholdsText.tex','w'); tableOfOrderedProbitThresholdsLaTeX.m 107 fprintf(f1,'\\def\\piRatioFourTwo{$%3.2f$}\n',piRatios(3,2)); tableOfOrderedProbitThresholdsLaTeX.m 108 fclose(f1);

• Abbring, Jaap H. and Jeffrey R. Campbell. 2009. Last-In First-Out Oligopoly Dynamics. forthcoming in Econometrica.
• Bresnahan, Timothy F. and Peter C. Reiss. 1991. Entry and Competition in Concentrated Markets. Journal of Political Economy 99(5) 977-1009.
• Cabral, Lu\'{i}s M. 1993. Experience Advantages and Entry Dynamics. Journal of Economic Theory 59 403-416.
• Campbell, Jeffrey R. and Ryan Peters. 2010. Comments ++
• Feuesänger, Christian. 2009. Manual for Package pgfplots: Version 1.1. Institut für Numerische Simulation, Universität Bonn
• Knuth, Donald E. 1984. Literate Programming. The Computer Journal 27 97-101.
• Press, William H., Saul A. Teukolsky, William T. Vetterling, and Brian P. Flannery. (1992) Numerical Recipes in Fortran 77: The Art of Scientific Computing. Second Edition. Cambridge University Press. Cambridge, U.K.
• Stokey, Nancy L. and Robert E. Lucas (with Edward C. Prescott). 1989. Recursive Methods in Economic Dynamics. Harvard University Press. Cambridge, MA.
• Tantau, Till. 2008. The TikZ and PGF Packages: Manual for version 2.00. Institüt für Theoretische Informatik, Universität zu Lübeck.

 1 A similar option is available on Microsoft Internet Explorer. We use Cascading Style Sheets (CSS2) for all formatting. Since IE implements this standard poorly, we cannot guarantee that it will display this document well. 2 We have successfully printed this using Firefox for the Macintosh and Firefox for Linux. Sadly, not all browsers are so cooperative. This document apparently triggers a bug in Safari that causes multiple blank pages to be printed after each actual page. 3 It would probably be better to do this with pgfkeys. 4 The “file” ac2apencilColor.tex within /compute is only a link to the file used by LaTeX when compiling the program. 5 Again, the “file ac2aNoThresholdsColor.tex within compute| is only a link to the file used by LaTeX when compiling the program.
 pencil.m 7 beta=1.05^(-5); pencil.m 8 kappa=1.25; pencil.m 9 phi=@(N) 1; pencil.m 10 pi = @(N) 2-2*(N>2); pencil.m 11 chat=0.1; pencil.m 12 ccheck=2.5; pencil.m 13 lambda=0.1; pencil.m 55 cstar2 = @(vtilde2) (kappa-lambda*vtilde2/(1-lambda))*2/pi(2); pencil.m 56 cunderbar2 = @(vtilde2) min(max(chat,cstar2(vtilde2)),ccheck); pencil.m 57 vtildeprime2 = @(vtilde2) 0.25*(ccheck+chat)*pi(2)-kappa + ... pencil.m 58 +beta*((1-lambda)*(ccheck^2*pi(2)*0.25 - ccheck*kappa)... pencil.m 59 +lambda*ccheck*vtilde2)/((1-beta*(1-lambda))*(ccheck-chat))... pencil.m 60 -beta*((1-lambda)*(cunderbar2(vtilde2)^2*pi(2)*0.25 - cunderbar2(vtilde2)*kappa)... pencil.m 61 +cunderbar2(vtilde2)*lambda*vtilde2)/((1-beta*(1-lambda))*(ccheck-chat)); pencil.m 67 epsilon=1e-5; pencil.m 68 T = (log(epsilon)-log(ccheck*pi(1)/(1-beta)))/log(beta)+1; pencil.m 69 pencil.m 70 vtilde2=0; pencil.m 71 t=0; pencil.m 72 pencil.m 73 while teps solveOptimalStoppingProblem.m 72 solveOptimalStoppingProblem.m 73 Vprime=max([SX beta*(Pi*(fX+V))],[],2); solveOptimalStoppingProblem.m 74 vDistance=max(abs(Vprime-V)); solveOptimalStoppingProblem.m 75 V=Vprime; solveOptimalStoppingProblem.m 76 solveOptimalStoppingProblem.m 77 end solveOptimalStoppingProblem.m 78 solveOptimalStoppingProblem.m 82 OUT.valueFunction=V; solveOptimalStoppingProblem.m 83 end solveOptimalStoppingProblem.m 84 solveOptimalStoppingProblemTest.m 6 chat=0.1; solveOptimalStoppingProblemTest.m 7 ccheck=2.5; solveOptimalStoppingProblemTest.m 8 step=0.01; solveOptimalStoppingProblemTest.m 9 omega=(chat:step:ccheck)'; solveOptimalStoppingProblemTest.m 10 N = length(omega); solveOptimalStoppingProblemTest.m 11 solveOptimalStoppingProblemTest.m 12 lambda=0.1; solveOptimalStoppingProblemTest.m 13 Pi=(1-lambda)*eye(N)+lambda*ones(N,N)/N; solveOptimalStoppingProblemTest.m 17 pi=2; solveOptimalStoppingProblemTest.m 18 kappa=1.25; solveOptimalStoppingProblemTest.m 19 f = @(x) x*pi/2-kappa; solveOptimalStoppingProblemTest.m 20 S = @(x) zeros(size(x,1),1); solveOptimalStoppingProblemTest.m 24 beta=1.05^(-5); solveOptimalStoppingProblemTest.m 28 eps=1e-7; solveOptimalStoppingProblemTest.m 32 V=zeros(N,1); solveOptimalStoppingProblemTest.m 36 PENCIL.stateSpace = omega; solveOptimalStoppingProblemTest.m 37 PENCIL.transitionMatrix = Pi; solveOptimalStoppingProblemTest.m 38 PENCIL.flowPayoff = f; solveOptimalStoppingProblemTest.m 39 PENCIL.outsideValue = S; solveOptimalStoppingProblemTest.m 40 PENCIL.discountFactor = beta; solveOptimalStoppingProblemTest.m 41 PENCIL.convergenceTolerance = eps; solveOptimalStoppingProblemTest.m 42 PENCIL.valueFunction = V; solveOptimalStoppingProblemTest.m 46 PENCIL = solveOptimalStoppingProblem(PENCIL); solveOptimalStoppingProblemTest.m 52 cunderbarIndex=find(PENCIL.valueFunction==0,1,'last'); solveOptimalStoppingProblemTest.m 53 cunderbar=PENCIL.stateSpace(cunderbarIndex); solveOptimalStoppingProblemTest.m 54 solveOptimalStoppingProblemTest.m 55 coverbarIndex=find(PENCIL.valueFunction<1,1,'last'); solveOptimalStoppingProblemTest.m 56 coverbar=PENCIL.stateSpace(coverbarIndex); solveOptimalStoppingProblemTest.m 57 plot(PENCIL.stateSpace,ones(length(PENCIL.stateSpace),1),'-','LineWidth',1.5,'Color',[0.8 0.8 0.8]); solveOptimalStoppingProblemTest.m 58 hold solveOptimalStoppingProblemTest.m 59 plot(PENCIL.stateSpace,PENCIL.valueFunction,'-k','LineWidth',2); solveOptimalStoppingProblemTest.m 60 solveOptimalStoppingProblemTest.m 61 set(gca,'box','off','FontSize',14,'Xtick',[chat cunderbar coverbar ccheck]); solveOptimalStoppingProblemTest.m 62 xlim([chat ccheck]); solveOptimalStoppingProblemTest.m 63 set(gcf,'Color',[1 1 1]); solveOptimalStoppingProblemTest.m 67 set(gcf,'Position',[-3 5 1280 950],... solveOptimalStoppingProblemTest.m 68 'PaperUnits','in','PaperSize',[5 3],... solveOptimalStoppingProblemTest.m 69 'PaperPositionMode','manual',... solveOptimalStoppingProblemTest.m 70 'PaperPosition',[0 0 5 3]); solveOptimalStoppingProblemTest.m 71 print -djpeg -painters solveOptimalStoppingProblemTest.jpg solveOptimalStoppingProblemTest.m 72 makequit; calculateLifoEquilibrium.m 24 function OUT = calculateLifoEquilibrium(ARG) calculateLifoEquilibrium.m 25 calculateLifoEquilibrium.m 28 pi = ARG.pi; calculateLifoEquilibrium.m 29 kappa = ARG.kappa; calculateLifoEquilibrium.m 30 phi = ARG.phi; calculateLifoEquilibrium.m 31 omega = ARG.omega; calculateLifoEquilibrium.m 32 Pi = ARG.Pi; calculateLifoEquilibrium.m 33 beta = ARG.beta; calculateLifoEquilibrium.m 34 eps = ARG.convergenceTolerance; calculateLifoEquilibrium.m 35 nCheck = ARG.nCheck; calculateLifoEquilibrium.m 36 calculateLifoEquilibrium.m 37 calculateLifoEquilibrium.m 45 f = @(x) x(:,1).*pi(x(:,2))./x(:,2)-kappa; calculateLifoEquilibrium.m 46 calculateLifoEquilibrium.m 50 if isempty(nCheck) calculateLifoEquilibrium.m 51 nCheck=1; calculateLifoEquilibrium.m 52 cCheck=max(omega); calculateLifoEquilibrium.m 53 while f([cCheck nCheck])>0 calculateLifoEquilibrium.m 54 nCheck=nCheck+1; calculateLifoEquilibrium.m 55 end calculateLifoEquilibrium.m 56 ARG.nCheck=nCheck-1; calculateLifoEquilibrium.m 57 nCheck=ARG.nCheck; calculateLifoEquilibrium.m 58 end calculateLifoEquilibrium.m 59 calculateLifoEquilibrium.m 61 n=length(omega); calculateLifoEquilibrium.m 62 V = zeros(nCheck,n,nCheck); calculateLifoEquilibrium.m 63 nPrime = ones(n,1)*(1:1:nCheck); calculateLifoEquilibrium.m 64 calculateLifoEquilibrium.m 65 calculateLifoEquilibrium.m 67 for i=nCheck:-1:1 calculateLifoEquilibrium.m 68 calculateLifoEquilibrium.m 69 calculateLifoEquilibrium.m 71 ARG_TRANSITION.transitionMatrixForC = Pi; calculateLifoEquilibrium.m 72 ARG_TRANSITION.supportForC = omega; calculateLifoEquilibrium.m 73 ARG_TRANSITION.minimumN = i; calculateLifoEquilibrium.m 74 ARG_TRANSITION.maximumN = nCheck; calculateLifoEquilibrium.m 75 ARG_TRANSITION.nextN = nPrime(:,i:nCheck); calculateLifoEquilibrium.m 76 calculateLifoEquilibrium.m 77 TRANSITION=calculateLifoTransitionMatrix(ARG_TRANSITION); calculateLifoEquilibrium.m 78 calculateLifoEquilibrium.m 80 STOPPING.stateSpace = TRANSITION.supportForCandN; calculateLifoEquilibrium.m 81 STOPPING.transitionMatrix = TRANSITION.transitionMatrixForCandN; calculateLifoEquilibrium.m 82 STOPPING.flowPayoff = f; calculateLifoEquilibrium.m 83 STOPPING.outsideValue = @(x) zeros(size(x,1),1); calculateLifoEquilibrium.m 84 STOPPING.discountFactor = beta; calculateLifoEquilibrium.m 85 STOPPING.convergenceTolerance= eps; calculateLifoEquilibrium.m 86 STOPPING.valueFunction = zeros(length(TRANSITION.supportForCandN),1); calculateLifoEquilibrium.m 87 calculateLifoEquilibrium.m 88 STOPPING=solveOptimalStoppingProblem(STOPPING); calculateLifoEquilibrium.m 89 calculateLifoEquilibrium.m 92 vMatrix=reshape(STOPPING.valueFunction,n,nCheck-i+1); calculateLifoEquilibrium.m 93 calculateLifoEquilibrium.m 95 nPrime(:,i:nCheck)=nPrime(:,i:nCheck)-(vMatrix==0); calculateLifoEquilibrium.m 96 calculateLifoEquilibrium.m 98 nPrime(:,1:i-1)=nPrime(:,1:i-1)+(vMatrix(:,1)*ones(1,i-1)>phi(i)); calculateLifoEquilibrium.m 99 calculateLifoEquilibrium.m 101 if i>1 calculateLifoEquilibrium.m 102 V(i,:,:)=[NaN(n,i-1) vMatrix]; calculateLifoEquilibrium.m 103 else calculateLifoEquilibrium.m 104 V(i,:,:)=vMatrix; calculateLifoEquilibrium.m 105 end calculateLifoEquilibrium.m 106 calculateLifoEquilibrium.m 107 end calculateLifoEquilibrium.m 108 calculateLifoEquilibrium.m 111 nPrimeZero=zeros(n,1); calculateLifoEquilibrium.m 112 calculateLifoEquilibrium.m 113 for j=1:nCheck; calculateLifoEquilibrium.m 114 vj=squeeze(V(j,:,j))'; calculateLifoEquilibrium.m 115 nPrimeZero=nPrimeZero+(vj>phi(j)); calculateLifoEquilibrium.m 116 end calculateLifoEquilibrium.m 117 nPrime = [nPrimeZero nPrime]; calculateLifoEquilibrium.m 118 calculateLifoEquilibrium.m 119 calculateLifoEquilibrium.m 122 OUT=ARG; calculateLifoEquilibrium.m 123 OUT.nCheck=nCheck; calculateLifoEquilibrium.m 124 OUT.valueFunction=V; calculateLifoEquilibrium.m 125 OUT.equilibriumFirmCount=nPrime; calculateLifoEquilibrium.m 126 calculateLifoEquilibriumTest.m 6 chat=0.1; calculateLifoEquilibriumTest.m 7 ccheck=2.5; calculateLifoEquilibriumTest.m 8 step=0.01; calculateLifoEquilibriumTest.m 9 omega=(chat:step:ccheck)'; calculateLifoEquilibriumTest.m 10 N = length(omega); calculateLifoEquilibriumTest.m 11 lambda=0.1; calculateLifoEquilibriumTest.m 12 Pi=(1-lambda)*eye(N)+lambda*ones(N,N)/N; calculateLifoEquilibriumTest.m 13 kappa=1.25; calculateLifoEquilibriumTest.m 14 pi = @(x) 2*ones(size(x,1),1); calculateLifoEquilibriumTest.m 15 beta=1.05^(-5); calculateLifoEquilibriumTest.m 16 phi = @(x) ones(length(x),1); calculateLifoEquilibriumTest.m 17 calculateLifoEquilibriumTest.m 21 eps=1e-7; calculateLifoEquilibriumTest.m 25 ARG.pi = pi; calculateLifoEquilibriumTest.m 26 ARG.kappa = kappa; calculateLifoEquilibriumTest.m 27 ARG.phi = phi; calculateLifoEquilibriumTest.m 28 ARG.omega = omega; calculateLifoEquilibriumTest.m 29 ARG.Pi = Pi; calculateLifoEquilibriumTest.m 30 ARG.beta = beta; calculateLifoEquilibriumTest.m 31 ARG.convergenceTolerance = 1e-7; calculateLifoEquilibriumTest.m 32 ARG.nCheck = []; calculateLifoEquilibriumTest.m 33 ARG.V = []; calculateLifoEquilibriumTest.m 34 ARG.nPrime = []; calculateLifoEquilibriumTest.m 35 calculateLifoEquilibriumTest.m 36 OUT=calculateLifoEquilibrium(ARG); calculateLifoEquilibriumTest.m 40 nCheck=OUT.nCheck; calculateLifoEquilibriumTest.m 41 V=OUT.valueFunction; calculateLifoEquilibriumTest.m 42 calculateLifoEquilibriumTest.m 43 figure(1) calculateLifoEquilibriumTest.m 44 for i=1:nCheck; calculateLifoEquilibriumTest.m 45 subplot(nCheck,1,i) calculateLifoEquilibriumTest.m 49 plot(omega,phi(i)*ones(size(omega)),'LineWidth',2,'Color',[0.8 0.8 0.8]); calculateLifoEquilibriumTest.m 53