GitHub

@@ -93,14 +93,16 @@ class Model(NamedTuple):

9393

α: float # production function parameter

9494959596-

def create_model(β: float = 0.96,

97-

μ: float = 0.0,

98-

s: float = 0.1,

99-

grid_max: float = 4.0,

100-

grid_size: int = 120,

101-

shock_size: int = 250,

102-

seed: int = 1234,

103-

α: float = 0.4) -> Model:

96+

def create_model(

97+

β: float = 0.96,

98+

μ: float = 0.0,

99+

s: float = 0.1,

100+

grid_max: float = 4.0,

101+

grid_size: int = 120,

102+

shock_size: int = 250,

103+

seed: int = 1234,

104+

α: float = 0.4

105+

) -> Model:

104106

"""

105107

Creates an instance of the optimal savings model.

106108

"""

@@ -114,6 +116,17 @@ def create_model(β: float = 0.96,

114116

return Model(β=β, μ=μ, s=s, s_grid=s_grid, shocks=shocks, α=α)

115117

```

116118119+120+

We define utility and production functions globally.

121+122+

```{code-cell} python3

123+

# Define utility and production functions with derivatives

124+

u = lambda c: jnp.log(c)

125+

u_prime = lambda c: 1 / c

126+

u_prime_inv = lambda x: 1 / x

127+

f = lambda k, α: k**α

128+

f_prime = lambda k, α: α * k**(α - 1)

129+

```

117130

Here's the Coleman-Reffett operator using EGM.

118131119132

The key JAX feature here is `vmap`, which vectorizes the computation over the grid points.

@@ -138,10 +151,13 @@ def K(

138151139152

# Define function to compute consumption at a single grid point

140153

def compute_c(s):

154+

# Approximate marginal utility ∫ u'(σ(f(s, α)z)) f'(s, α) z ϕ(z)dz

141155

vals = u_prime(σ(f(s, α) * shocks)) * f_prime(s, α) * shocks

142-

return u_prime_inv(β * jnp.mean(vals))

156+

mu = jnp.mean(vals)

157+

# Calculate consumption

158+

return u_prime_inv(β * mu)

143159144-

# Vectorize over grid using vmap

160+

# Vectorize and calculate on all exogenous grid points

145161

compute_c_vectorized = jax.vmap(compute_c)

146162

c_out = compute_c_vectorized(s_grid)

147163

@@ -151,18 +167,6 @@ def K(

151167

return c_out, x_out

152168

```

153169154-

We define utility and production functions globally.

155-156-

Note that `f` and `f_prime` take `α` as an explicit argument, allowing them to work with JAX's functional programming model.

157-158-

```{code-cell} python3

159-

# Define utility and production functions with derivatives

160-

u = lambda c: jnp.log(c)

161-

u_prime = lambda c: 1 / c

162-

u_prime_inv = lambda x: 1 / x

163-

f = lambda k, α: k**α

164-

f_prime = lambda k, α: α * k**(α - 1)

165-

```

166170167171

Now we create a model instance.

168172

@@ -175,11 +179,13 @@ The solver uses JAX's `jax.lax.while_loop` for the iteration and is JIT-compiled

175179176180

```{code-cell} python3

177181

@jax.jit

178-

def solve_model_time_iter(model: Model,

179-

c_init: jnp.ndarray,

180-

x_init: jnp.ndarray,

181-

tol: float = 1e-5,

182-

max_iter: int = 1000):

182+

def solve_model_time_iter(

183+

model: Model,

184+

c_init: jnp.ndarray,

185+

x_init: jnp.ndarray,

186+

tol: float = 1e-5,

187+

max_iter: int = 1000

188+

):

183189

"""

184190

Solve the model using time iteration with EGM.

185191

"""

Read the original on github.com ↗