Adding random transport links to a 2D growth model

[This article was first published on datascienceconfidential - r, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

This post is about economic growth in a region in which labour is free to move around.

A colleague recently showed me a paper by Capasso, Engbers and La Torre which describes an extension of the Solow growth model in which a spatial element is added. It seemed to me that the model could be extended in various ways. Most interestingly, the paper only gave an example in which capital and labour move around in a one-dimensional latent space, but I thought it would be more interesting if the space was two-dimensional.

A book called The Price of Time by Edwin Chancellor describes many of the unintended negative consequences of low interest rates, one of which is investment being directed to infrastructure projects which appear to “go nowhere” (think of railways in the 19th century US or 2010s China). I decided to use the Capasso et al model to study the effects of randomly building transport infrastructure. The basic idea is that if a country’s development is modelled by a process in which capital and labour are trying to reach the same location, then any infrastructure will probably speed up growth. But by how much? I want to get a qualitative estimate of that.

Model

The model takes place on a domain $\Omega \subset \mathbb{R}^n$. At each point $x \in \Omega$ and each time $t$, there is a quantity of capital $K(x,t)$ and labour $L(x,t)$. There is a production function $F$ describing how more capital is produced from labour and capital. I will assume that $F$ is the same everywhere. In other words, there’s an industry of sorts at every point of $\Omega$.

Motion of Capital

Capital evolves in space and time according to the equation

\[\frac{\partial K}{\partial t}(x,t) = e\nabla^2 K(x,t) -\delta K(x,t) + Y(x,t)\]

where $Y(x,t) = F(K(x,t), L(x,t))$ is output. Here, $e$ is the (exogenous) coefficient of diffusion and $\delta$ is (exogenous) depreciation.

This is a version of the heat equation. If $F = 0$ then capital will slowly diffuse through the domain $\Omega$ until the value of $K$ is the same everywhere, like in the following picture.

Motion of Labour

In the Capasso et al model, labour diffuses in the same way as capital. But what if we assume that labour moves towards the direction of the highest wages?

Let’s assume that labour is paid its marginal product $w(x,t) = \frac{\partial F}{\partial L}$ and that it moves in the direction of increasing $w$, so we have something like

\[\frac{\partial L}{\partial t}(x,t) = m\nabla \cdot (L(x,t)\nabla w(x,t)) + gL(x,t)\]

where $m$ is a diffusion coefficient and $g$ is an exogenous growth rate. In other words, a proportion $m$ of the labour force will migrate in the direction in which the wages are highest.

Simulation

Now let’s stop pretending that time and space are continuous. The following describes what I actually coded1. Assume that time proceeds in discrete steps $t=0, 1, 2, \dots$ and that the domain $\Omega$ is a graph. At time step $t$, the model evolves in the following way:

  • At each vertex $x$, a proportion $e$ of the current value of capital $K(x)$ is distributed equally among the neighbours of $x$.
  • At each vertex $x$, a proportion $m$ of the current value of labour $L(x)$ moves to the node in ${x}\cup{\text{neighbours of } x}$ with highest wage. If there is a tie for highest, it is distributed equally among the tied nodes.
  • At each vertex $x$, $K(x)$ is incremented by production minus depreciation and $L(x)$ increases by a factor of $(1+g)$.

If you run the model on a grid and start by drawing labour and capital from a uniform distribution, you will see a sort of self-organisation. Labour and capital accumulate into “towns” where there is a relatively high level of production.

Capital

Labour



Here. I used the Cobb-Douglas production function with $TFP = 1$ and $\alpha = 1/3$. Capasso et al chose to use a different production function. The choice of Cobb-Douglas means that growth is unlimited and eventually the spatial distribution of capital and labour will become uniform. I’m really interested in the rate of growth of aggregate output $Y$ where

\[Y(t) = \int_\Omega Y(x, t) dx.\]

The graph below shows how $Y(t)$ grows in the simulation above, starting with a random distribution of capital and labour.

Adding Infrastructure

You can add transportation to the model by adding connections between nodes which weren’t previously connected. For example, here’s what happens to the pattern of capital if you add a “railway line” down the diagonal of the grid which makes all the points on the diagonal adjacent to each other.



Regardless of the initial distribution of labour and capital, the nodes with high adjacency end up having very high relative output. Interestingly, nodes next to nodes with high adjacency end up with lower than average output, even though the model has the property that capital is supposed to trickle outwards due to the $\nabla^2 K$ term. You are better off being in the hinterland than being near, but not in, an area which is connected to a lot of infrastructure. There are real-world reflections of this in places such as Animas City, Colorado which became a ghost town after being bypassed by a railroad which went through Durango, two miles to the south, so it makes some sense.

Example: the US Railroad Boom

Speaking of Colorado, we can try to use this model to estimate how much the railroad boom in the US contributed to growth.

In the 19th century the US experienced a period of railroad mania. According to PBS there were 364 railroads by the time of the Panic of 1873.

Let’s make some wild estimates. Assume that the US is a $10 \times 20$ rectangle (the numbers are chosen to make the simulation run quickly). According to this paper $33\%$ of people migrated inter-county per decade, and according to various sources it took about six months to cross the US prior to the development of railroads. Therefore, labour should be able to move about 40 grid squares in a year, so we need to take each time step to be $1/40$ of a year, and then the migration rate $m$ should be $1/40 \times 0.33/10$. Assuming that capital goods were difficult to transport, we’ll take $e=0$. We also assume an annual capital depreciation rate of $0.1$.

If we start in 1830 with the founding of the Baltimore and Ohio Railroad, the model needs to run for 43 years. The population basically tripled between 1830 and 1873, so we should take an appropriate value of $g$.

In the following R code, we run two models. model0 has no railroads. In model1, railroads are added at regular intervals by joining pairs of random nodes (like the secret passages in Cluedo) so that they become adjacent. We can then calculate the aggregate output of the two models at the end of the simulation and divide one by the other to get the factor by which the presence of the railroads has increased or decreased output.

simulate_us <- function(M=10, N=20, years=43, rr_count=364){
  
  # number of iterations
  its <- 2 * N * years
  
  m <- 0.33/(10*2*N)
  e <- 0 
  g <- 3^(1/its) - 1
  delta <- 0.1 / years / (2*N)
  K <- matrix(runif(M*N), nr=M)
  L <- matrix(runif(M*N), nr=M)
  A <- 1
  alpha <- 1/3
  adjacency <- make_grid(M, N)
  
  model0 <- model1 <- make_model(M, N, K, e, m, delta, g, L, adjacency, A, alpha)
  out <- list()
  
  for (i in 1:its){
    model0 <- update(model0)
    model1 <- update(model1)

    if (!(i %% floor(its/rr_count))){
      # add a connection to model1
      x1 <- x2 <- sample(1:M, 1)
      y1 <- y2 <- sample(1:N, 1)
      while((x1==x2) & (y1==y2)){
        x2 <- sample(1:M, 1)
        y2 <- sample(1:N, 1)
      }
      model1$adjacency <- add_connection(model1$adjacency, x1, y1, x2, y2)
    }
    out[[i]] <- list(model0=model0,
                     model1=model1,
                     Y0 = model0$production_function(model0$K, model0$L,
    model0$A, model0$alpha), 
                     Y1 = model1$production_function(model1$K, model1$L,
     model1$A, model1$alpha))
  }
  out
}

The graph below shows the result of doing the whole simulation 100 times. Adding the railways increased aggregate output at the end of the period by about 20% compared to the no-railway scenario.

set.seed(1873)
sims <- rep(0, 100)
for (i in 1:100){
  sim1 <- simulate_us(M=10, N=20)
  sims[i] <- unlist(lapply(sim1, function(x) sum(x$Y1)))[1720]/
    (unlist(lapply(sim1, function(x) sum(x$Y0))))[1720]
}

That all seems quite reasonable, but the fact that the numbers come out nicely here is largely an artifact of the choice of a $10\times 20$ grid. You can check this by running the simulation on grids of different sizes. If you double the size of the grid, you won’t find any increase in output when adding railways. So what’s going on?

It turns out that the choice of grid size in the above example is just enough to make it very likely that two nodes will become connected in such a way that there is a big boost to growth. If you make the grid larger, then the number of possible random connections grows so large that this becomes less likely to happen. The reason why random infrastructure seems to be boosting growth is because we’ve set things up in such a way that random infrastructure is likely to be useful just by chance.

This sort-of shows that my original idea was wrong. I had the idea that adding random connections to this model might make it easier for labour to move around and thus to reach areas with a large amount of capital. But in fact, if you put in semi-realistic numbers, the random connections only help if there’s a large chance that they happen to be built in the right places. So my initial idea of showing that vanity projects or “railways to nowhere” can contribute to economic growth is probably wrong.

However, I still think this model is quite interesting and could be used for other things. That’s all for today! I’m off to see whether I can sell my labour to the owner of some capital.


1: I’m honestly not 100% sure that it matches the continuous model described in the previous section. I included the continuous version for easy comparison with the paper of Capasso et al.

To leave a comment for the author, please follow the link and comment on their blog: datascienceconfidential - r.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)