Note: I change Moretti’s 2010 model by removing capital, which implies that population changes affect wages.

Model Setup

The indirect utility for consumer \(i\) in city \(c\) is:

\[U_{ic}=w_c-r_c+A_c+\epsilon_{ic}\tag{1}\] The idiosyncratic term is distributed uniformly such that:

\[\epsilon_{ia}-\epsilon_{ib}\sim U[-s,s]\tag{2} \] The production function for firms is concave in labor. Note that I am modifying Moretti’s model by excluding capital so that population affects wages.

\[ln(y_c)=X_c+h N_c, \ \ \ \text{where} \ \ 0<h<1\tag{4.alt}\]

The key conditions for the model are the migration equation (3), written as inverse labor supply: \[w_b=w_a+(r_b-r_a)+(A_a-A_b)+s\frac{N_b-N_a}{N}\tag{3}\] The labor demand equation, given the omission of capital, is (here I write just for \(b\)): \[w_b=X_b-(1-h)N_b+ln(h)\tag{5.alt}\] The housing demand equation (from the migration equation): \[r_b=(w_b-w_a)+r_a+(A_b-A_a)-s\frac{N_b-N_a}{N}\tag{6}\] And, the housing supply equation (written here for \(b\)): \[r_b=z+k_bN_b\tag{7}\]

Partial Equilibrium

I will first look at comparative statics where I fix the characteristics of city \(a\) but allow the city \(b\)’s population to change in response to changes in city \(a\) characteristics (amenities, productivity, etc…). I call this partial equilibrium because it ignore the fact that inflows into city \(a\) come from city \(b\), and outflows from city \(a\) go to \(b\), and thus the wages and rents of both cities are affected by a change in a single city. This interpretation is similar to the basic Roback model in which population flows in and out from a national population, but there are no direct city-to-city effects.

Since equations \(3\) and \(6\) are just rearrangements of the same migration equation, there are just three equations we need for partial equilibrium: a migration equation (\(3\) or \(6\)), the labor demand equation (\(5\)), and the housing supply equation (\(7\)). These equations show that wages and rents in a given city are linked because both depend on population. By inserting equation \(7\) into equation \(5\) we can derive an equation linking wages and rents to firm-side factors, such as labor productivity \(X_c\) or housing elasticity \(k_c\). Similarly, inserting \(7\) into \(6\) (or \(3\)) yields an equation that depends on consumer-side factors, such as city amenities \(A_c\). This allows us to create a plot of wages and rents similar to the indifference curves and isocost curves plots in Roback’s model. Inserting \(7\) into \(5\) yields:

\[r_b=-\frac{k_b}{1-h}w_b+z+\frac{k_b}{1-h}(X_b+ln(h))\tag{PE1}\] The above equation shows how rent and wages vary in the (inverse) labor demand function. I will call it “partial equilibrium labor demand,” but this is obviously not a perfect phrase. Inserting \(7\) into \(6\) yields:

\[r_b=\frac{N k_b}{N k_b+s}w_b+\frac{N k_b}{N k_b+s}\left[-(w_a-r_a)+(A_b-A_a)\right]+\frac{s(k_bN_a+z)}{N k_b+s}\tag{PE2}\] This equation shows how rent and wages vary in the (inverse) labor supply function. I will call this “partial equilibrum labor supply.” We can see from eq \(PE1\) that rent is decreasing in wages for firms, and in \(PE2\) the rent is increasing in wages for consumers. While there are many terms in each equation, both are simply lines and can be rewritten as \(r_b=-\gamma_1 w_b+\Gamma_1\) and \(r_b=\gamma_2 w_b+\Gamma_2\). Then we have that:

\[r_b^*=\frac{\Gamma_1-\Gamma_2}{\gamma_1+\gamma_2} \ \ \ \ \text{and} \ \ \ \ w_b^*=\frac{\gamma_2\Gamma_1+\gamma_1\Gamma_2}{\gamma_1+\gamma_2}\tag{PE3}\]

Solving the Model

\[N_a=\frac{N}{2s}(s-(A_b-A_a))+-w_b\frac{N}{2s}+r_b\frac{N}{2s}+w_a\frac{N}{2s}-r_a\frac{N}{2s}\tag{1}\] \[N_b=\frac{N}{2s}(s+(A_b-A_a))+w_b\frac{N}{2s}-r_b\frac{N}{2s}-w_a\frac{N}{2s}+r_a\frac{N}{2s}\tag{2}\] Inserting into inverse housing supply, \(r_c=z+k_cN_c\), and subtracting \(r_c\) from both sides yields the market clearing conditions for the housing market: \[0=z+\frac{k_a N}{2s}(s-(A_b-A_a))+-w_b\frac{N}{2s}+r_b\frac{k_a N}{2s}+w_a\frac{k_a N}{2s}-r_a\frac{2s+k_a N}{2s}\tag{3}\] \[0=z+\frac{k_b N}{2s}(s+(A_b-A_a))+w_b\frac{k_b N}{2s}-r_b\frac{2s+k_b N}{2s}-w_a\frac{k_b N}{2s}+r_a\frac{k_b N}{2s}\tag{4}\] Next, we insert \(N_a\) and \(N_b\) into the labor market demand conditions, \(w_c=x_c-(1-h)N_c+ln(h)\): \[0=[X_a+ln(h)]-\frac{(1-h)N}{2s}(s-(A_b-A_a))+w_b\frac{(1-h)N}{2s}-r_b\frac{(1-h)N}{2s}-w_a\frac{2s+(1-h)N}{2s}+r_a\frac{(1-h)N}{2s}\tag{5}\] \[0=[X_b+ln(h)]-\frac{(1-h)N}{2s}(s+(A_b-A_a))-w_b\frac{2s+(1-h)N}{2s}+r_b\frac{(1-h)N}{2s}+w_a\frac{(1-h)N}{2s}-r_a\frac{(1-h)N}{2s}\tag{6}\] I can then rearrange these into matrix form \[w_bA+r_bB+w_aC+r_aD=E\] for solving: \[w_b\frac{-k_aN}{2s}+r_b\frac{k_a N}{2s}+w_a\frac{k_a N}{2s}+r_a\frac{-(2s+k_a N)}{2s}=-\left[z+\frac{k_a N}{2s}(s-(A_b-A_a))\right]\tag{H_a}\] \[w_b\frac{k_b N}{2s}+r_b\frac{-(2s+k_b N)}{2s}+w_a\frac{-k_b N}{2s}+r_a\frac{k_b N}{2s}=-\left[z+\frac{k_b N}{2s}(s+(A_b-A_a))\right]\tag{H_b}\] \[w_b\frac{(1-h)N}{2s}+r_b\frac{-(1-h)N}{2s}+w_a\frac{-(2s+(1-h)N)}{2s}+r_a\frac{(1-h)N}{2s}=-\left[X_a+ln(h)-\frac{(1-h)N}{2s}(s-(A_b-A_a))\right]\tag{L_a}\] \[w_b\frac{-(2s+(1-h)N)}{2s}+r_b\frac{(1-h)N}{2s}+w_a\frac{(1-h)N}{2s}+r_a\frac{-(1-h)N}{2s}=-\left[X_b+ln(h)-\frac{(1-h)N}{2s}(s+(A_b-A_a))\right]\tag{L_b}\]

Graphical Analysis

#Functions
#Inverse labor supply: returns w.c at N.c
invLS<-function(N.c,w.n,r.c,r.n,A.n,A.c,s,N.n,N){ 
  w.n+(r.c-r.n)+(A.n-A.c)+s*(N.c-N.n)/N
}
#Inverse labor demand from firms: returns w.c at N.c
invLD<-function(N.c,X.c,h){
    X.c+-1*(1-h)*N.c+log(h)
}
#Inverse housing supply: returns r.c at N.c
invHS<-function(N.c,z,k.c){
    z+k.c*N.c
}
#Inverse housing demand: returns r.c at N.c
invHD<-function(N.c,w.c,w.n,r.n,A.c,A.n,s,N.n,N){
    (w.c-w.n)+r.n+(A.c-A.n)-s*(N.c-N.n)/N
}

#Partial equilibrium functions--------------------------------------------------
#PE1: Firm-side, rent as function of wage
r1w<-function(w.c,z,k.c,X.c,h){
  -(k.c*w.c)/(1-h) +z +k.c*(X.c+log(h))/(1-h)
}
#PE2: Consumer-side, rent as function of wage
r2w<-function(w.c,w.n,r.n,A.c,A.n,k.c,N.n,s,N){
  m1=(N*k.c)/(N*k.c+s)
  m1*w.c+m1*(-1*(w.n-r.n)+(A.c-A.n))+s*(k.c*N.n+z)/(N*k.c+s)
}

#Return partial equilibrium rent and wages
retPE<-function(w.n,r.n,N.n,A.n,z,N,h,s,k.c,X.c,A.c){
  g1=k.c/(1-h)
  G1=z+k.c*(X.c+log(h))/(1-h)
  m1=(N*k.c)/(N*k.c+s)
  g2=m1
  G2=m1*(-1*(w.n-r.n)+(A.c-A.n))+s*(k.c*N.n+z)/(N*k.c+s)
  r.eq<-(G1-G2)/(g1+g2)
  w.eq<-(g2*G1+g1*G2)/(g1+g2)
  return(c(r.eq,w.eq))
}

#Solve for equilibrium
retEq<-function(s,h,k.a,k.b,N,z,A.a,A.b,X.a,X.b){
  #Define matrix coefficients
  kaN=(k.a*N)/(2*s)
  Ha.1=-kaN
  Ha.2=kaN
  Ha.3=kaN
  Ha.4=-1*(2*s+k.a*N)/(2*s)
  Ha.5=-1*(z+kaN*(s-(A.b-A.a)))
  
  kbN=(k.b*N)/(2*s)
  Hb.1=kbN
  Hb.2=-1*(2*s+k.b*N)/(2*s)
  Hb.3=-kbN
  Hb.4=kbN
  Hb.5=-1*(z+kbN*(s+(A.b-A.a)))
  
  hN=(1-h)*N/(2*s)
  La.1=hN
  La.2=-hN
  La.3=-1*(2*s+(1-h)*N)/(2*s)
  La.4=hN
  La.5=-1*(X.a+log(h)-hN*(s-(A.b-A.a)))
  
  Lb.1=-1*(2*s+(1-h)*N)/(2*s)
  Lb.2=hN
  Lb.3=hN
  Lb.4=-hN
  Lb.5=-1*(X.b+log(h)-hN*(s+(A.b-A.a)))
  
  #Now solve
  A<-rbind(c(Ha.1, Ha.2, Ha.3, Ha.4),
           c(Hb.1, Hb.2, Hb.3, Hb.4),
           c(La.1, La.2, La.3, La.4),
           c(Lb.1, Lb.2, Lb.3, Lb.4))
  B<-c(Ha.5,Hb.5,La.5,Lb.5)
  sol.vec=solve(A,B) #c(w.b,r.b,w.a,r.a)
  return(c(sol.vec[3],sol.vec[1],sol.vec[4],sol.vec[2]))
}

#Set up parameters
s=100
h=0.5
k.a=1
k.b=1
N=1000
z=1
A.b=100
A.a=1
X.a=10+(1-h)*N #these have to be bigger than (1-h)*N.c
X.b=10+(1-h)*N

First, understand basic intuition with simple cases. Simplest is if population is fixed in a city, \(N_c=\bar{N_c}\)

eqVals<-retEq(s,h,k.a,k.b,N,z,A.a,A.b,X.a,X.b) #c(w.a,w.b,r.a,r.b)
N.a=(eqVals[3]-z)/k.a
#pdf(file="Moretti_g1.pdf",width=9, height=5)
curve(invHS(x,z,k.a),from=0,to=N,xlab="Population of city a, N_a",ylab="City a wages (w_a) and rents (r_a)",main="Labor and housing market in city a",col="blue")
curve(invLD(x,X.a,h),from=0,to=N,col="red",add=TRUE)
r.a1=k.a*N.a+z
w.a1=X.a-(1-h)*N.a+log(h)
abline(v=N.a,col="black",lwd=2)
text(N.a-100,w.a1,"w_a*")
abline(h=r.a1,lty=2,lwd=1)
text(N.a-100,r.a1,"r_a*")
abline(h=w.a1,lty=2,lwd=1)
legend(50,850, legend=c("Housing Supply","Labor Demand","Inelastic population"),col=c("blue","red","black"),lty=1,cex=0.8)

#dev.off()

Now we can allow for migration, but no general equilibrium effects from one city to another. This is similar to basic Roback model with an enormous national population and an atomistic city.

eqVals<-retEq(s,h,k.a,k.b,N,z,A.a,A.b,X.a,X.b) #c(w.a,w.b,r.a,r.b)
w.a<-eqVals[1]
w.b<-eqVals[2]
r.a<-eqVals[3]
r.b<-eqVals[4]
N.a=(r.a-z)/k.a
N.b=N-N.a
#pdf(file="Moretti_g2.pdf",width=9, height=5)
curve(invHS(x,z,k.a),from=0,to=N,xlab="Population of city a, N_a",ylab="Wage/rents in city a; w_a,r_a",main="Labor  and housing market in city a",col="blue")
curve(invHD(x,w.a,w.b,r.b,A.a,A.b,s,N.b,N),from=0,to=N,col="lightblue",add=TRUE)
curve(invLD(x,X.a,h),from=0,to=N,col="red",add=TRUE)
curve(invLS(x,w.b,r.a,r.b,A.b,A.a,s,N.b,N),from=0,to=N,col="indianred1",add=TRUE)
abline(v=N.a,col="black",lwd=1)
legend(50,950, legend=c("Housing Supply","Housing Demand","Labor Demand","Labor Supply"),col=c("blue","lightblue","red","indianred1"),lty=1,cex=0.8)

#dev.off()

Notice that the housing markets and labor markets are linked through population. If there is a shift in one curve–say amenities \(A_a\) increase–we can’t calculate the new population in the city without looking at both markets.

eqVals<-retEq(s,h,k.a,k.b,N,z,A.a,A.b,X.a,X.b) #c(w.a,w.b,r.a,r.b)
w.a<-eqVals[1]
w.b<-eqVals[2]
r.a<-eqVals[3]
r.b<-eqVals[4]
N.a=(r.a-z)/k.a
#pdf(file="Moretti_g3.pdf",width=9, height=5)
curve(invHS(x,z,k.a),from=0,to=N,xlab="Population of city a, N_a",ylab="Wage/rents in city a; w_a,r_a",main="Labor and housing market in city a",col="blue")
curve(invHD(x,w.a,w.b,r.b,A.a,A.b,s,N.b,N),from=0,to=N,col="lightblue",add=TRUE)
curve(invLD(x,X.a,h),from=0,to=N,col="red",add=TRUE)
curve(invLS(x,w.b,r.a,r.b,A.b,A.a,s,N.b,N),from=0,to=N,col="indianred1",add=TRUE)
curve(invLS(x,w.b,r.a,r.b,A.b,A.a+100,s,N.b,N),from=0,to=N,col="indianred1",lty=2,lwd=2,add=TRUE)
abline(v=N.a,col="black",lwd=1)
legend(50,950, legend=c("Housing Supply","Housing Demand","Labor Demand","Labor Supply"),col=c("blue","lightblue","red","indianred1"),lty=1,cex=0.8)

#dev.off()

For this reason, it can be useful to graph curves against rent and wages simultaneously. This can be done by substituting for population \(N_c\) in one market using a condition in another. Here, I insert the labor demand equation into housing supply and housing demand by replacing population with wage.

eqVals<-retEq(s,h,k.a,k.b,N,z,A.a,A.b,X.a,X.b) #c(w.a,w.b,r.a,r.b)
w.a<-eqVals[1]
w.b<-eqVals[2]
r.a<-eqVals[3]
r.b<-eqVals[4]
maxW.a<- X.a +log(h)
#pdf(file="Moretti_g4.pdf",width=9, height=5)
curve(r1w(x,z,k.a,X.a,h),from=0,to=maxW.a,col="blue",xlab="Wage w_a",ylab="Rent r_a",main="Partial equilibrium in the housing and labor market")
curve(r2w(x,w.b,r.b,A.a,A.b,k.a,N.b,s,N),from=0,to=maxW.a,col="red",add=TRUE)
abline(v=w.a,lty=2)
text(w.a,200,"w_a*")
abline(h=r.a,lty=2)
text(200,r.a,"r_a*")
legend(300,980, legend=c("PE Labor demand: r1(w)","PE Labor supply: r2(w)"),col=c("blue","red"),lty=1,cex=0.8)

#dev.off()

These graphs are similar to the basic Roback plots of indirect utility and costs against rents and wages. For example, if amenities increase then rent will increase and wages will decrease.

eqVals<-retEq(s,h,k.a,k.b,N,z,A.a,A.b,X.a,X.b) #c(w.a,w.b,r.a,r.b)
w.a<-eqVals[1]
w.b<-eqVals[2]
r.a<-eqVals[3]
r.b<-eqVals[4]
maxW.a<- X.a +log(h)
#pdf(file="Moretti_g5.pdf",width=9, height=5)
curve(r1w(x,z,k.a,X.a,h),from=0,to=maxW.a,col="blue",xlab="Wage w_a",ylab="Rent r_a",main="Partial equilibrium in the housing and labor market")
curve(r2w(x,w.b,r.b,A.a,A.b,k.a,N.b,s,N),from=0,to=maxW.a,col="red",add=TRUE)
curve(r2w(x,w.b,r.b,A.a+100,A.b,k.a,N.b,s,N),from=0,to=maxW.a,col="red",lty=2,add=TRUE)
peVals<-retPE(w.b,r.b,N.b,A.b,z,N,h,s,k.a,X.a,A.a+100)
abline(h=peVals[2],lty=2)
abline(v=peVals[1],lty=2)
legend(300,980, legend=c("PE Labor demand: r1(w)","PE Labor supply: r2(w)"),col=c("blue","red"),lty=1,cex=0.8)

#dev.off()

If instead, a productive amenity increases, \(X_a\), then both wages and rents increase:

eqVals<-retEq(s,h,k.a,k.b,N,z,A.a,A.b,X.a,X.b) #c(w.a,w.b,r.a,r.b)
w.a<-eqVals[1]
w.b<-eqVals[2]
r.a<-eqVals[3]
r.b<-eqVals[4]
maxW.a<- X.a +log(h)
#pdf(file="Moretti_g6.pdf",width=9, height=5)
curve(r1w(x,z,k.a,X.a,h),from=0,to=maxW.a,col="blue",xlab="Wage w_a",ylab="Rent r_a",main="Partial equilibrium in the housing and labor market")
curve(r2w(x,w.b,r.b,A.a,A.b,k.a,N.b,s,N),from=0,to=maxW.a,col="red",add=TRUE)
curve(r1w(x,z,k.a,X.a+100,h),from=0,to=maxW.a,col="blue",lty=2,add=TRUE)
peVals<-retPE(w.b,r.b,N.b,A.b,z,N,h,s,k.a,X.a+100,A.a)
abline(h=peVals[2],lty=2)
abline(v=peVals[1],lty=2)
legend(300,980, legend=c("PE Labor demand: r1(w)","PE Labor supply: r2(w)"),col=c("blue","red"),lty=1,cex=0.8)

#dev.off()

If both increase then rent must increase, but the effect on wages depends on the parameters. This is because higher amenities and higher productivity both raise rents, but have opposing effects on wages.

eqVals<-retEq(s,h,k.a,k.b,N,z,A.a,A.b,X.a,X.b) #c(w.a,w.b,r.a,r.b)
w.a<-eqVals[1]
w.b<-eqVals[2]
r.a<-eqVals[3]
r.b<-eqVals[4]
maxW.a<- X.a +log(h)
#pdf(file="Moretti_g7.pdf",width=9, height=5)
curve(r1w(x,z,k.a,X.a,h),from=0,to=maxW.a,col="blue",xlab="Wage w_a",ylab="Rent r_a",main="Partial equilibrium in the housing and labor market")
curve(r2w(x,w.b,r.b,A.a,A.b,k.a,N.b,s,N),from=0,to=maxW.a,col="red",add=TRUE)
curve(r1w(x,z,k.a,X.a+100,h),from=0,to=maxW.a,col="blue",lty=2,add=TRUE)
curve(r2w(x,w.b,r.b,A.a+100,A.b,k.a,N.b,s,N),from=0,to=maxW.a,col="red",lty=2,add=TRUE)
peVals<-retPE(w.b,r.b,N.b,A.b,z,N,h,s,k.a,X.a+100,A.a+100)
abline(h=peVals[2],lty=2)
abline(v=peVals[1],lty=2)
legend(225,990, legend=c("PE Labor demand: r1(w)","PE Labor supply: r2(w)"),col=c("blue","red"),lty=1,cex=0.8)

#dev.off()

Finally, we can compare partial equilibrium to general equilibrium by allowing for changes in one city to affect the other. For example, what happens if amenities in city \(a\) increase, causing a flow from \(b\) to \(a\)? People will flow into city \(a\), raising rents, and lowering the marginal productivity of labor, thus lowering wages. However, this flow from \(b\) to \(a\) will lower rents in \(b\) and raise wages in \(b\), increasing the utility of living in \(b\). Thus, utility rises in \(a\) due to the increase in amenities, but it also will rise somewhat in \(b\). This means that the difference is not as large as in the partial equilibrium analysis, where we assume everything is fixed in \(b\), and thus the general equilibrium change will not be as large.

eqVals<-retEq(s,h,k.a,k.b,N,z,A.a,A.b,X.a,X.b) #c(w.a,w.b,r.a,r.b)
w.a<-eqVals[1]
w.b<-eqVals[2]
r.a<-eqVals[3]
r.b<-eqVals[4]
eqVals2<-retEq(s,h,k.a,k.b,N,z,A.a+100,A.b,X.a,X.b) #c(w.a,w.b,r.a,r.b)
maxW.a<- X.a +log(h)
#pdf(file="Moretti_g8.pdf",width=9, height=5)
curve(r1w(x,z,k.a,X.a,h),from=0,to=maxW.a,col="blue",xlab="Wage w_a",ylab="Rent r_a",main="Increase in amenites in city a: partial and general equilibrium")
curve(r2w(x,w.b,r.b,A.a,A.b,k.a,N.b,s,N),from=0,to=maxW.a,col="red",add=TRUE)
curve(r2w(x,w.b,r.b,A.a+100,A.b,k.a,N.b,s,N),from=0,to=maxW.a,col="red",lty=2,add=TRUE)
curve(r2w(x,eqVals2[2],eqVals2[4],A.a+100,A.b,k.a,N.b,s,N),from=0,to=maxW.a,col="green",add=TRUE)
legend(150,300, legend=c("PE Labor demand: r1(w)","PE Labor supply: r2(w)","PE Labor supply: r2(w)","GE Labor supply: r2(w)"),col=c("blue","red","red","green"),lty=c(1,1,2,1),cex=0.8)

#dev.off()