Profit maximizing owner of a commercial tree stand must decide when to clearcut the stand.
%matplotlib inline
from warnings import simplefilter
simplefilter('ignore')
from compecon import DPmodel, BasisSpline
from demos.setup import np, plt, demo
Assuming that the unit price of biomass is $p=1$, the cost to clearcut-replant is $\kappa=0.2$, the stand carrying capacity $s_{\max}=0.5$, biomass growth factor is $\gamma=10\%$ per period, and the annual discount factor $\delta=0.9$.
price = 1.0
kappa = 0.2
smax = 0.5
gamma = 0.1
delta = 0.9
The state variable is the stand biomass, $s\in [0,s_{\max}]$.
Here, we represent it with a cubic spline basis, with $n=200$ nodes.
n = 200
basis = BasisSpline(n, 0, smax,
labels=['biomass'])
The action variable is $j\in\{0:\text{'keep'},\quad 1:\text{'clear cut'}\}$.
If the farmer clears the stand, the profit is the value of selling the biomass $ps$ minus the cost of clearing and replanting $\kappa$, otherwise the profit is zero.
def reward(s, x, i , j):
return (price * s - kappa) * j
If the farmer clears the stand, it begins next period with $\gamma s_{\max}$ units. If he keeps the stand, then it grows to $s + \gamma (s_{\max} - s)$.
def transition(s, x, i, j, in_, e):
if j:
return np.full_like(s, gamma * smax)
else:
return s + gamma * (smax - s)
The value of the stand, given that it contains $s$ units of biomass at the beginning of the period, satisfies the Bellman equation
\begin{equation} V(s) = \max\left\{(ps-\kappa) + \delta V(\gamma s_{\max}),\quad \delta V[s+\gamma(s_{\max}-s)] \right\} \end{equation}To solve and simulate this model, use the CompEcon class DPmodel
.
model = DPmodel(basis, reward, transition,
discount=delta,
j=['keep', 'clear-cut'])
S = model.solve()
The solve
method retuns a pandas DataFrame
, which can easily be used with the ggplot package.
demo.qplot('biomass', 'value_j','j',
data=S,
main='Action-Contingent Value functions',
ylab='Value of Stand'
)
S['resid2'] = 100*S.resid / S.value
demo.qplot('biomass', 'resid2',
data=S,
geom='line',
main='Bellman Equation Residual',
ylab='Percent Residual'
)
The path followed by the biomass is computed by the simulate()
method. Here we simulate 31 periods starting with a biomass level $s_0 = 0$.
H = model.simulate(31, 0.0)
demo.qplot('time','biomass',geom='line', data=H)