Skip to content

Commit bb8ca7b

Browse files
authored
mpec implementation
Master Thesis Pascal Heid
2 parents c29521d + 84913d2 commit bb8ca7b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+4472
-287
lines changed

.conda/meta.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,5 @@ requirements:
2525
- pytest
2626
- pytest-xdist
2727
- scipy
28-
- estimagic >=0.0.30
28+
- estimagic =0.0.30
29+
- nlopt

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,6 @@ ruspy.rst
2222
modules.rst
2323
_generated
2424
*.db
25+
results_ipopt.txt
26+
get_iskhakov_results
2527

docs/source/conf.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@
5454
"numpydoc",
5555
]
5656

57+
autosummary_mock_imports = [
58+
"ipopt",
59+
]
60+
5761

5862
napoleon_numpy_docstring = True
5963
# Add any paths that contain templates here, relative to this directory.

docs/source/economics.rst

Lines changed: 148 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
1-
Economic model
2-
==============
1+
Economic Model & Calibration
2+
==============================
33

4-
Here the economic model of Rust (1987) is documented. It is the theoretic background for
5-
the estimation and simulation modules of ruspy.
4+
Here the economic model of Rust (1987) is documented and two ways of calibrating
5+
its parameters are introduced. The first one is the nested fixed point algorithm
6+
(NFXP) initially suggested by Rust (1987) and the second one is mathematical
7+
programming with equilibrium constraints (MPEC) based on Su and Judd (2012).
8+
This builds the theoretic background for the estimation and simulation modules of ruspy.
69

710

11+
The Economic Model
12+
------------------
13+
814
The model is set up as an infinite horizon regenerative optimal stopping problem. It
9-
considers the dynamic decisions by a maintenance manger, Harold Zurcher, for a fleet of
15+
considers the dynamic decisions by a maintenance manager, Harold Zurcher, for a fleet of
1016
buses. As the buses are all identical and the decisions are assumed to be independent
11-
across buses, there are no indication of the bus in the following notation. Harold
17+
across buses, there are no indications of the bus in the following notation. Harold
1218
Zurcher makes repeated decisions :math:`a` about their maintenance in order to maximize
1319
his expected total discounted utility with respect to the expected mileage usage of the
1420
bus. Each month :math:`t`, a bus arrives at the bus depot in state :math:`s_t = (x_t,
@@ -49,7 +55,7 @@ The discount factor :math:`\delta` weighs the utilities over all periods and the
4955
captures the preference of utility in current and future time periods. As the model
5056
assumes stationary utility, as well as stationary transition probabilities the future
5157
looks the same, whether the agent is at time :math:`t` in state :math:`s` or at any
52-
other time. Therefore the optimal decision in every period can be interferred by the
58+
other time. Therefore the optimal decision in every period can be captures by the
5359
Bellman equation:
5460

5561
.. math::
@@ -101,7 +107,7 @@ where :math:`\theta_2 = 0.577216`, i.e. the Euler-Mascheroni constant.
101107
Rust (1988) shows that these two assumptions, together with the additive separability
102108
between the observed and unobserved state variables in the immediate utilities, imply
103109
that :math:`EV_\theta` is a function independent of :math:`\epsilon_t` and the unique
104-
fix point of a contraction mapping on the reduced space of all state action pairs
110+
fixed point of a contraction mapping on the reduced space of all state action pairs
105111
:math:`(x,a)`. Furthermore, the regenerative property of the process yields for all
106112
states :math:`x`, that the expected value of replacement corresponds to the expected
107113
value of maintenance in state :math:`0`, i.e. :math:`EV_\theta(x, 1) = EV_\theta(0,
@@ -116,6 +122,13 @@ value of maintenance in state :math:`0`, i.e. :math:`EV_\theta(x, 1) = EV_\theta
116122
u(x' , a, \theta_1, RC) + \delta EV_\theta(x'))
117123
\end{equation}
118124
125+
This gives rise to the shorthand notation of the above formula:
126+
127+
.. math::
128+
\begin{equation}
129+
EV_\theta(x) = T_\theta(EV_\theta(x))
130+
\end{equation}
131+
119132
In addition, the conditional choice probabilities :math:`P(a| x, \theta)` have a
120133
closed-form solution given by the multinomial logit formula (McFadden, 1973):
121134

@@ -129,7 +142,7 @@ closed-form solution given by the multinomial logit formula (McFadden, 1973):
129142
These closed form solutions allow to estimate the structural parameters driving
130143
Zurcher's decisions. Given the data :math:`\{a_0, ....a_T, x_0, ..., x_T\}` for a
131144
single bus, one can form the likelihood function :math:`l^f(a_1, ..., a_T, x_1, ....,
132-
x_T | a_0, x_0, \theta)` and estimate the parameter vector $\theta$ by maximum
145+
x_T | a_0, x_0, \theta)` and estimate the parameter vector :math:`\theta` by maximum
133146
likelihood. Rust (1988) proofs that this function has due to the conditional
134147
independence assumption a simple form:
135148

@@ -158,3 +171,129 @@ and
158171
\begin{equation}
159172
l^2(a_1, ..., a_T, x_1, ...., x_T | \theta) = \prod_{t=1}^T P(a_t|x_t, \theta)
160173
\end{equation}
174+
175+
176+
Nested Fixed Point Algorithm
177+
----------------------------
178+
179+
The calibration strategy employed by Rust (1987) involves handing the logarithm
180+
of the above :math:`l^f(a_1, ..., a_T, x_1, ...., x_T | a_0, x_0, \theta)`
181+
to an unconstrained optimization algorithm.
182+
Rust originally suggests a polyalgorithm of the BHHH and the BFGS for this purpose.
183+
This optimizer fixes a guess of the structural parameter vector :math:`\hat\theta`
184+
for which the unique fixed point of the economic model is found.
185+
Through this the conditional choice probabilities :math:`P(a|x, \hat\theta)`
186+
are obtained which in turn are used to evaluate the log likelihood function.
187+
On the basis of this, the optimization algorithm comes up with a new guess for
188+
the structural parameters and the procedure starts over until a certain
189+
convergence criteria is met.
190+
191+
The algorithm consequently corresponds to solving the following optimization
192+
problem in an outer loop:
193+
194+
.. math::
195+
196+
\begin{equation}
197+
\max_{\theta} \; log \; l^f(a_1, ..., a_T, x_1, ...., x_T | a_0, x_0, \theta)
198+
\end{equation}
199+
200+
while finding the unique fixed point of :math:`EV_\theta(x) = T_\theta(EV_\theta(x))`
201+
in an inner loop for a given parameter guess produced in the outer loop.
202+
203+
204+
Mathematical Programming with Equilibrium Constraints
205+
-----------------------------------------------------
206+
207+
The approach developed by Su and Judd (2012) casts this unconstrained nested problem
208+
into a constrained optimization problem. For this they plug the conditional
209+
choice probabilities :math:`P(a|x, \theta)` into the likelihood function :math:`l^f(.)`:
210+
211+
.. math::
212+
213+
\begin{equation}
214+
\begin{split}
215+
l^f_{aug}(. | a_0, x_0, \theta, EV) = & \prod_{t=1}^T \frac{
216+
\exp(u(a, x, RC, \theta_1) + \delta EV((a-1) \cdot x))}{
217+
\sum_{a \in \{0, 1\}} \exp(u(a, x, RC, \theta_1) + \delta EV((a - 1)x))} \\
218+
\\
219+
& \times p(x_t| x_{t-1}, a_{t-1}, \theta_3).
220+
\end{split}
221+
\end{equation}
222+
223+
They coin the term augmented likelihood function for :math:`l^f_{aug}`.
224+
The particular feature now is that the likelihood depends explicitly on both the
225+
structural parameter vector :math:`\theta` as well as the choice of :math:`EV`.
226+
In order to ensure that guesses of both vectors are consistent
227+
in the spirit of the economic model, the contraction mapping of the expected value
228+
function is imposed as a constraint to the augmented likelihood function.
229+
Consequently, the calibration problem boils down to a constrained optimization
230+
looking like the following:
231+
232+
.. math::
233+
234+
\begin{equation}
235+
\max_{(\theta, EV)} \; log \; l^f_{aug}(a_1, ..., a_T, x_1, ...., x_T | a_0, x_0, \theta, EV) \\
236+
\text{subject to } \; EV = T(EV, \theta).
237+
\end{equation}
238+
239+
The constraints are generally nonlinear functions which restricts the use of
240+
optimization algorithms. An non-exhaustive list of optimizers that can handle
241+
the above problem are the commercial KNITRO (see Byrd et al. (2006)), as well
242+
as the open source IPOPT (see Wächter and Biegler (2006)) and the SLSQP (see
243+
Kraft (1994)) provided by NLOPT.
244+
245+
246+
The Implied Demand Function
247+
---------------------------
248+
249+
Rust (1987) shortly describes a way to uncover an implied demand function of engine
250+
replacement from his model and its estimated parameters. Theoretically, for Harold
251+
Zurcher the random annual implied demand function takes the following form:
252+
253+
.. math::
254+
255+
\begin{equation*}
256+
\tilde{d}(RC) = \sum_{t=1}^{12} \sum_{m=1}^{M} \tilde{a}^m_t
257+
\end{equation*}
258+
259+
where :math:`\tilde{a}^m_t` is the replacement decision for a certain bus :math:`m`
260+
in a certain month :math:`t` derived from the process {:math:`a^m_t, x^m_t`}.
261+
262+
For convenience I will drop the index for the bus in the following. Its probability
263+
distribution is therefore the result of the process described by
264+
:math:`P(a_t|x_t; \theta)p(x_t|x_{t-1}, a_{t-1}; \theta_3)`. For simplification
265+
Rust actually derives the expected demand function :math:`d(RC)=E[\tilde{d}(RC)]`.
266+
Assuming that :math:`\pi` is the long-run stationary distribution of the process
267+
{:math:`a_t, x_t`} and that the observed initial state {:math:`a_0, x_0`} is in
268+
the long run equilibrium, :math:`\pi` can be described by the following functional
269+
equation:
270+
271+
.. math::
272+
273+
\begin{equation}
274+
\pi(x, a; \theta) = \int_{y} \int_{j} P(a|x; \theta)p_3(x|y, j, \theta_3)
275+
\pi(dy, dj; \theta).
276+
\end{equation}
277+
278+
Further assuming that the processes of {:math:`a_t, x_t`} are independent across
279+
buses the annual expected implied demand function boils down to:
280+
281+
.. math::
282+
283+
\begin{equation}
284+
d(RC) = 12 M \int_{0}^{\infty} \pi(dx, 1; \theta).
285+
\end{equation}
286+
287+
Given some estimated parameters :math:`\hat\theta` from calibrating the Rust Model
288+
and parametrically varying :math:`RC` results in different estimates of
289+
:math:`P(a_t|x_t; \theta)p(x_t|x_{t-1}, a_{t-1}; \theta_3)` which in turn affects
290+
the probability distribution :math:`\pi` which changes the implied demand.
291+
In the representation above it is clearly assumed that both the mileage state
292+
:math:`x` and the replacement decision :math:`a` are continuous. The replacement
293+
decision is actually discrete, though, and the mileage state has to be discretized
294+
again which in the end results in a sum representation of the function :math:`d(RC)`
295+
that is taken to calculate the expected annual demand.
296+
297+
This demand function can be calculated in the ruspy package for a given
298+
parametrization of the model. A description how to do this can be found in
299+
:ref:`demand_function_calculation`.

0 commit comments

Comments
 (0)